Example #1
0
  Point adjustResizeCursor() {
    if (bounds == null) return null;
    int newX, newY;

    if ((cursorOrientation & SWT.LEFT) != 0) {
      newX = bounds.x;
    } else if ((cursorOrientation & SWT.RIGHT) != 0) {
      newX = bounds.x + bounds.width;
    } else {
      newX = bounds.x + bounds.width / 2;
    }

    if ((cursorOrientation & SWT.UP) != 0) {
      newY = bounds.y;
    } else if ((cursorOrientation & SWT.DOWN) != 0) {
      newY = bounds.y + bounds.height;
    } else {
      newY = bounds.y + bounds.height / 2;
    }

    final int unused[] = new int[1];
    int actualX[] = new int[1];
    int actualY[] = new int[1];
    int xDisplay = display.xDisplay;
    OS.XWarpPointer(xDisplay, 0, window, 0, 0, 0, 0, newX, newY);
    /*
     * The call to XWarpPointer does not always place the pointer on the
     * exact location that is specified, so do a query (below) to get the
     * actual location of the pointer after it has been moved.
     */
    OS.XQueryPointer(xDisplay, window, unused, unused, actualX, actualY, unused, unused, unused);
    return new Point(actualX[0], actualY[0]);
  }
Example #2
0
 boolean hasCursor() {
   int[] unused = new int[1], buffer = new int[1];
   int xDisplay = OS.XtDisplay(handle);
   int xWindow, xParent = OS.XDefaultRootWindow(xDisplay);
   do {
     if (OS.XQueryPointer(
             xDisplay, xParent, unused, buffer, unused, unused, unused, unused, unused)
         == 0) return false;
     if ((xWindow = buffer[0]) != 0) xParent = xWindow;
   } while (xWindow != 0);
   return handle == OS.XtWindowToWidget(xDisplay, xParent);
 }
Example #3
0
  Point adjustMoveCursor() {
    if (bounds == null) return null;
    final int unused[] = new int[1];
    int actualX[] = new int[1];
    int actualY[] = new int[1];

    int newX = bounds.x + bounds.width / 2;
    int newY = bounds.y;

    int xDisplay = display.xDisplay;
    OS.XWarpPointer(xDisplay, OS.None, window, 0, 0, 0, 0, newX, newY);
    /*
     * The call to XWarpPointer does not always place the pointer on the
     * exact location that is specified, so do a query (below) to get the
     * actual location of the pointer after it has been moved.
     */
    OS.XQueryPointer(xDisplay, window, unused, unused, actualX, actualY, unused, unused, unused);
    return new Point(actualX[0], actualY[0]);
  }
Example #4
0
 int xMouse(int type, int w, int client_data, int call_data, int continue_to_dispatch) {
   int xDisplay = display.xDisplay;
   int[] newX = new int[1], newY = new int[1], unused = new int[1];
   OS.XQueryPointer(xDisplay, window, unused, unused, newX, newY, unused, unused, unused);
   if (oldX != newX[0] || oldY != newY[0]) {
     Rectangle[] oldRectangles = rectangles;
     boolean oldStippled = stippled;
     Rectangle[] rectsToErase = new Rectangle[rectangles.length];
     for (int i = 0; i < rectangles.length; i++) {
       Rectangle current = rectangles[i];
       rectsToErase[i] = new Rectangle(current.x, current.y, current.width, current.height);
     }
     Event event = new Event();
     event.x = newX[0];
     event.y = newY[0];
     if ((style & SWT.RESIZE) != 0) {
       resizeRectangles(newX[0] - oldX, newY[0] - oldY);
       sendEvent(SWT.Resize, event);
       /*
        * It is possible (but unlikely) that application code
        * could have disposed the widget in the resize event.
        * If this happens then return false to indicate that
        * the move failed.
        */
       if (isDisposed()) {
         cancelled = true;
         return 1;
       }
       boolean draw = false;
       /*
        * It is possible that application code could have
        * changed the rectangles in the resize event.  If this
        * happens then only redraw the tracker if the rectangle
        * values have changed.
        */
       if (rectangles != oldRectangles) {
         int length = rectangles.length;
         if (length != rectsToErase.length) {
           draw = true;
         } else {
           for (int i = 0; i < length; i++) {
             if (!rectangles[i].equals(rectsToErase[i])) {
               draw = true;
               break;
             }
           }
         }
       } else {
         draw = true;
       }
       if (draw) {
         drawRectangles(rectsToErase, oldStippled);
         update();
         drawRectangles(rectangles, stippled);
       }
       Point cursorPos = adjustResizeCursor();
       if (cursorPos != null) {
         newX[0] = cursorPos.x;
         newY[0] = cursorPos.y;
       }
     } else {
       moveRectangles(newX[0] - oldX, newY[0] - oldY);
       sendEvent(SWT.Move, event);
       /*
        * It is possible (but unlikely) that application code
        * could have disposed the widget in the move event.
        * If this happens then return false to indicate that
        * the move failed.
        */
       if (isDisposed()) {
         cancelled = true;
         return 1;
       }
       boolean draw = false;
       /*
        * It is possible that application code could have
        * changed the rectangles in the move event.  If this
        * happens then only redraw the tracker if the rectangle
        * values have changed.
        */
       if (rectangles != oldRectangles) {
         int length = rectangles.length;
         if (length != rectsToErase.length) {
           draw = true;
         } else {
           for (int i = 0; i < length; i++) {
             if (!rectangles[i].equals(rectsToErase[i])) {
               draw = true;
               break;
             }
           }
         }
       } else {
         draw = true;
       }
       if (draw) {
         drawRectangles(rectsToErase, oldStippled);
         update();
         drawRectangles(rectangles, stippled);
       }
     }
     oldX = newX[0];
     oldY = newY[0];
   }
   tracking = type != OS.ButtonRelease;
   return 0;
 }
Example #5
0
  /**
   * Displays the Tracker rectangles for manipulation by the user. Returns when the user has either
   * finished manipulating the rectangles or has cancelled the Tracker.
   *
   * @return <code>true</code> if the user did not cancel the Tracker, <code>false</code> otherwise
   * @exception SWTException
   *     <ul>
   *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
   *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
   *     </ul>
   */
  public boolean open() {
    checkWidget();
    int xDisplay = display.xDisplay;
    window = OS.XDefaultRootWindow(xDisplay);
    if (parent != null) {
      window = OS.XtWindow(parent.handle);
      if (window == 0) return false;
    }
    cancelled = false;
    tracking = true;
    update();
    drawRectangles(rectangles, stippled);
    int[] oldX = new int[1], oldY = new int[1];
    int[] unused = new int[1], mask = new int[1];
    OS.XQueryPointer(xDisplay, window, unused, unused, oldX, oldY, unused, unused, mask);

    /*
     * If exactly one of UP/DOWN is specified as a style then set the cursor
     * orientation accordingly (the same is done for LEFT/RIGHT styles below).
     */
    int vStyle = style & (SWT.UP | SWT.DOWN);
    if (vStyle == SWT.UP || vStyle == SWT.DOWN) {
      cursorOrientation |= vStyle;
    }
    int hStyle = style & (SWT.LEFT | SWT.RIGHT);
    if (hStyle == SWT.LEFT || hStyle == SWT.RIGHT) {
      cursorOrientation |= hStyle;
    }

    int mouseMasks = OS.Button1Mask | OS.Button2Mask | OS.Button3Mask;
    boolean mouseDown = (mask[0] & mouseMasks) != 0;
    if (!mouseDown) {
      Point cursorPos = null;
      if ((style & SWT.RESIZE) != 0) {
        cursorPos = adjustResizeCursor();
      } else {
        cursorPos = adjustMoveCursor();
      }
      if (cursorPos != null) {
        oldX[0] = cursorPos.x;
        oldY[0] = cursorPos.y;
      }
    }
    this.oldX = oldX[0];
    this.oldY = oldY[0];

    int ptrGrabResult =
        OS.XGrabPointer(
            xDisplay,
            window,
            0,
            OS.ButtonPressMask | OS.ButtonReleaseMask | OS.PointerMotionMask,
            OS.GrabModeAsync,
            OS.GrabModeAsync,
            OS.None,
            OS.None,
            OS.CurrentTime);
    int kbdGrabResult =
        OS.XGrabKeyboard(xDisplay, window, 0, OS.GrabModeAsync, OS.GrabModeAsync, OS.CurrentTime);

    /* Tracker behaves like a Dialog with its own OS event loop. */
    XAnyEvent anyEvent = new XAnyEvent();
    int xEvent = OS.XtMalloc(XEvent.sizeof);
    int dispatch = OS.XtMalloc(4);
    int xtContext = OS.XtDisplayToApplicationContext(xDisplay);
    while (tracking) {
      if (parent != null && parent.isDisposed()) break;
      OS.XtAppNextEvent(xtContext, xEvent);
      OS.memmove(anyEvent, xEvent, XAnyEvent.sizeof);
      int widget = OS.XtWindowToWidget(anyEvent.display, anyEvent.window);
      switch (anyEvent.type) {
        case OS.MotionNotify:
          XPointerMotion(widget, 0, xEvent, dispatch);
          break;
        case OS.ButtonRelease:
          XButtonRelease(widget, 0, xEvent, dispatch);
          break;
        case OS.KeyPress:
          XKeyPress(widget, 0, xEvent, dispatch);
          break;
        case OS.KeyRelease:
          XKeyRelease(widget, 0, xEvent, dispatch);
          break;
        case OS.ButtonPress:
        case OS.EnterNotify:
        case OS.LeaveNotify:
          /* Do not dispatch these */
          break;
        case OS.Expose:
          update();
          drawRectangles(rectangles, stippled);
          OS.XtDispatchEvent(xEvent);
          drawRectangles(rectangles, stippled);
          break;
        default:
          OS.XtDispatchEvent(xEvent);
      }
    }
    if (xEvent != 0) OS.XtFree(xEvent);
    if (dispatch != 0) OS.XtFree(dispatch);
    if (!isDisposed()) {
      update();
      drawRectangles(rectangles, stippled);
    }
    if (ptrGrabResult == OS.GrabSuccess) OS.XUngrabPointer(xDisplay, OS.CurrentTime);
    if (kbdGrabResult == OS.GrabSuccess) OS.XUngrabKeyboard(xDisplay, OS.CurrentTime);
    window = 0;
    return !cancelled;
  }