/** * 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(); Display display = this.display; cancelled = false; tracking = true; window = (NSWindow) new NSWindow().alloc(); NSArray screens = NSScreen.screens(); double /*float*/ minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE; double /*float*/ minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE; int count = (int) /*64*/ screens.count(); for (int i = 0; i < count; i++) { NSScreen screen = new NSScreen(screens.objectAtIndex(i)); NSRect frame = screen.frame(); double /*float*/ x1 = frame.x, x2 = frame.x + frame.width; double /*float*/ y1 = frame.y, y2 = frame.y + frame.height; if (x1 < minX) minX = x1; if (x2 < minX) minX = x2; if (x1 > maxX) maxX = x1; if (x2 > maxX) maxX = x2; if (y1 < minY) minY = y1; if (y2 < minY) minY = y2; if (y1 > maxY) maxY = y1; if (y2 > maxY) maxY = y2; } NSRect frame = new NSRect(); frame.x = minX; frame.y = minY; frame.width = maxX - minX; frame.height = maxY - minY; window = window.initWithContentRect( frame, OS.NSBorderlessWindowMask, OS.NSBackingStoreBuffered, false); window.setOpaque(false); window.setLevel(OS.NSStatusWindowLevel); window.setContentView(null); window.setBackgroundColor(NSColor.clearColor()); NSGraphicsContext context = window.graphicsContext(); NSGraphicsContext.static_saveGraphicsState(); NSGraphicsContext.setCurrentContext(context); context.setCompositingOperation(OS.NSCompositeClear); frame.x = frame.y = 0; NSBezierPath.fillRect(frame); NSGraphicsContext.static_restoreGraphicsState(); window.orderFrontRegardless(); drawRectangles(window, rectangles, false); /* * 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; } Point cursorPos; boolean down = false; NSApplication application = NSApplication.sharedApplication(); NSEvent currentEvent = application.currentEvent(); if (currentEvent != null) { switch ((int) /*64*/ currentEvent.type()) { case OS.NSLeftMouseDown: case OS.NSLeftMouseDragged: case OS.NSRightMouseDown: case OS.NSRightMouseDragged: case OS.NSOtherMouseDown: case OS.NSOtherMouseDragged: down = true; } } if (down) { cursorPos = display.getCursorLocation(); } else { if ((style & SWT.RESIZE) != 0) { cursorPos = adjustResizeCursor(true); } else { cursorPos = adjustMoveCursor(); } } if (cursorPos != null) { oldX = cursorPos.x; oldY = cursorPos.y; } Control oldTrackingControl = display.trackingControl; display.trackingControl = null; /* Tracker behaves like a Dialog with its own OS event loop. */ while (tracking && !cancelled) { display.addPool(); try { if (parent != null && parent.isDisposed()) break; display.runSkin(); display.runDeferredLayouts(); NSEvent event = application.nextEventMatchingMask( 0, NSDate.distantFuture(), OS.NSDefaultRunLoopMode, true); if (event == null) continue; int type = (int) /*64*/ event.type(); switch (type) { case OS.NSLeftMouseUp: case OS.NSRightMouseUp: case OS.NSOtherMouseUp: case OS.NSMouseMoved: case OS.NSLeftMouseDragged: case OS.NSRightMouseDragged: case OS.NSOtherMouseDragged: mouse(event); break; case OS.NSKeyDown: case OS.NSKeyUp: case OS.NSFlagsChanged: key(event); break; } boolean dispatch = true; switch (type) { case OS.NSLeftMouseDown: case OS.NSLeftMouseUp: case OS.NSRightMouseDown: case OS.NSRightMouseUp: case OS.NSOtherMouseDown: case OS.NSOtherMouseUp: case OS.NSMouseMoved: case OS.NSLeftMouseDragged: case OS.NSRightMouseDragged: case OS.NSOtherMouseDragged: case OS.NSMouseEntered: case OS.NSMouseExited: case OS.NSKeyDown: case OS.NSKeyUp: case OS.NSFlagsChanged: dispatch = false; } if (dispatch) application.sendEvent(event); if (clientCursor != null && resizeCursor == null) { display.lockCursor = false; clientCursor.handle.set(); display.lockCursor = true; } display.runAsyncMessages(false); } finally { display.removePool(); } } /* * Cleanup: If this tracker was resizing then the last cursor that it created * needs to be destroyed. */ if (resizeCursor != null) resizeCursor.dispose(); resizeCursor = null; if (oldTrackingControl != null && !oldTrackingControl.isDisposed()) { display.trackingControl = oldTrackingControl; } display.setCursor(display.findControl(true)); if (!isDisposed()) { drawRectangles(window, rectangles, true); } if (window != null) window.close(); tracking = false; window = null; return !cancelled; }
void mouse(NSEvent nsEvent) { NSPoint location; if (nsEvent == null || nsEvent.type() == OS.NSMouseMoved) { location = NSEvent.mouseLocation(); } else { location = nsEvent.locationInWindow(); location = nsEvent.window().convertBaseToScreen(location); } location.y = display.getPrimaryFrame().height - location.y; int newX = (int) location.x, newY = (int) location.y; if (newX != oldX || newY != oldY) { Rectangle[] oldRectangles = rectangles; 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; event.y = newY; if ((style & SWT.RESIZE) != 0) { boolean orientationInit = resizeRectangles(newX - oldX, newY - oldY); inEvent = true; sendEvent(SWT.Resize, event); inEvent = false; /* * It is possible (but unlikely), that application * code could have disposed the widget in the move * event. If this happens, return false to indicate * that the tracking has failed. */ if (isDisposed()) { cancelled = true; return; } 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(window, rectsToErase, true); drawRectangles(window, rectangles, false); } Point cursorPos = adjustResizeCursor(orientationInit); if (cursorPos != null) { newX = cursorPos.x; newY = cursorPos.y; } } else { moveRectangles(newX - oldX, newY - oldY); inEvent = true; sendEvent(SWT.Move, event); inEvent = false; /* * It is possible (but unlikely), that application * code could have disposed the widget in the move * event. If this happens, return false to indicate * that the tracking has failed. */ if (isDisposed()) { cancelled = true; return; } 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(window, rectsToErase, true); drawRectangles(window, rectangles, false); } } oldX = newX; oldY = newY; } switch ((int) /*64*/ nsEvent.type()) { case OS.NSLeftMouseUp: case OS.NSRightMouseUp: case OS.NSOtherMouseUp: tracking = false; } }
void key(NSEvent nsEvent) { int nsType = (int) /*64*/ nsEvent.type(); long /*int*/ modifierFlags = nsEvent.modifierFlags(); int nsKeyCode = nsEvent.keyCode(); int keyCode = Display.translateKey(nsKeyCode); switch (nsType) { case OS.NSKeyDown: case OS.NSKeyUp: { Event event = new Event(); event.keyCode = keyCode; int type = nsType == OS.NSKeyDown ? SWT.KeyDown : SWT.KeyUp; if (!setKeyState(event, type, nsEvent)) break; if (!sendKeyEvent(type, event)) return; break; } case OS.NSFlagsChanged: { int mask = 0; switch (keyCode) { case SWT.ALT: mask = OS.NSAlternateKeyMask; break; case SWT.CONTROL: mask = OS.NSControlKeyMask; break; case SWT.COMMAND: mask = OS.NSCommandKeyMask; break; case SWT.SHIFT: mask = OS.NSShiftKeyMask; break; case SWT.CAPS_LOCK: Event event = new Event(); event.keyCode = keyCode; setInputState(event, nsEvent, SWT.KeyDown); sendKeyEvent(SWT.KeyDown, event); setInputState(event, nsEvent, SWT.KeyUp); sendKeyEvent(SWT.KeyUp, event); break; } if (mask != 0) { int type = (mask & modifierFlags) != 0 ? SWT.KeyDown : SWT.KeyUp; Event event = new Event(); event.keyCode = keyCode; setLocationMask(event, nsEvent); setInputState(event, nsEvent, type); if (!sendKeyEvent(type, event)) return; } break; } } int stepSize = (modifierFlags & OS.NSControlKeyMask) != 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE; int xChange = 0, yChange = 0; switch (nsKeyCode) { case 53: /* Esc */ cancelled = true; tracking = false; break; case 76: /* KP Enter */ case 36: /* Return */ tracking = false; break; case 123: /* Left arrow */ xChange = -stepSize; break; case 124: /* Right arrow */ xChange = stepSize; break; case 126: /* Up arrow */ yChange = -stepSize; break; case 125: /* Down arrow */ yChange = stepSize; break; } if (xChange != 0 || yChange != 0) { Rectangle[] oldRectangles = rectangles; 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(); int newX = oldX + xChange; int newY = oldY + yChange; event.x = newX; event.y = newY; Point cursorPos; if ((style & SWT.RESIZE) != 0) { resizeRectangles(xChange, yChange); inEvent = true; sendEvent(SWT.Resize, event); inEvent = false; /* * It is possible (but unlikely) that application * code could have disposed the widget in the move * event. If this happens return false to indicate * that the tracking has failed. */ if (isDisposed()) { cancelled = true; return; } 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(window, rectsToErase, true); drawRectangles(window, rectangles, false); } cursorPos = adjustResizeCursor(true); } else { moveRectangles(xChange, yChange); inEvent = true; sendEvent(SWT.Move, event); inEvent = false; /* * It is possible (but unlikely) that application * code could have disposed the widget in the move * event. If this happens return false to indicate * that the tracking has failed. */ if (isDisposed()) { cancelled = true; return; } 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(window, rectsToErase, true); drawRectangles(window, rectangles, false); } cursorPos = adjustMoveCursor(); } if (cursorPos != null) { oldX = cursorPos.x; oldY = cursorPos.y; } } }
/** * 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(); cancelled = false; tracking = true; window = (NSWindow) new NSWindow().alloc(); NSRect frame = NSScreen.mainScreen().frame(); window = window.initWithContentRect_styleMask_backing_defer_( frame, OS.NSBorderlessWindowMask, OS.NSBackingStoreBuffered, false); window.setOpaque(false); window.setContentView(null); NSGraphicsContext context = window.graphicsContext(); NSGraphicsContext.setCurrentContext(context); context.setCompositingOperation(OS.NSCompositeClear); NSBezierPath.fillRect(frame); window.orderFrontRegardless(); drawRectangles(window, rectangles, false); /* * 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; } Point cursorPos; boolean down = false; NSApplication application = NSApplication.sharedApplication(); NSEvent currentEvent = application.currentEvent(); switch (currentEvent.type()) { case OS.NSLeftMouseDown: case OS.NSRightMouseDown: case OS.NSOtherMouseDown: down = true; } if (down) { cursorPos = display.getCursorLocation(); } else { if ((style & SWT.RESIZE) != 0) { cursorPos = adjustResizeCursor(true); } else { cursorPos = adjustMoveCursor(); } } if (cursorPos != null) { oldX = cursorPos.x; oldY = cursorPos.y; } /* Tracker behaves like a Dialog with its own OS event loop. */ while (tracking && !cancelled) { NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); NSEvent event = application.nextEventMatchingMask( 0, NSDate.distantFuture(), OS.NSDefaultRunLoopMode, true); if (event == null) continue; int type = event.type(); switch (type) { case OS.NSLeftMouseUp: case OS.NSRightMouseUp: case OS.NSOtherMouseUp: case OS.NSMouseMoved: case OS.NSLeftMouseDragged: case OS.NSRightMouseDragged: case OS.NSOtherMouseDragged: mouse(event); break; case OS.NSKeyDown: // case OS.NSKeyUp: case OS.NSFlagsChanged: key(event); break; } /* * Don't dispatch mouse and key events in general, EXCEPT once this * tracker has finished its work. */ boolean dispatch = true; if (!(tracking && !cancelled)) { switch (type) { case OS.NSLeftMouseDown: case OS.NSLeftMouseUp: case OS.NSRightMouseDown: case OS.NSRightMouseUp: case OS.NSOtherMouseDown: case OS.NSOtherMouseUp: case OS.NSMouseMoved: case OS.NSLeftMouseDragged: case OS.NSRightMouseDragged: case OS.NSOtherMouseDragged: case OS.NSMouseEntered: case OS.NSMouseExited: case OS.NSKeyDown: case OS.NSKeyUp: case OS.NSFlagsChanged: dispatch = false; } } if (dispatch) application.sendEvent(event); if (clientCursor != null && resizeCursor == null) { clientCursor.handle.set(); } pool.release(); } if (!isDisposed()) { drawRectangles(window, rectangles, true); } if (window != null) window.close(); tracking = false; window = null; return !cancelled; }
void key(NSEvent nsEvent) { // TODO send event // if (!sendKeyEvent (SWT.KeyDown, theEvent)) return OS.noErr; int modifierFlags = nsEvent.modifierFlags(); int stepSize = (modifierFlags & OS.NSControlKeyMask) != 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE; int xChange = 0, yChange = 0; switch (nsEvent.keyCode()) { case 53: /* Esc */ cancelled = true; tracking = false; break; case 76: /* KP Enter */ case 36: /* Return */ tracking = false; break; case 123: /* Left arrow */ xChange = -stepSize; break; case 124: /* Right arrow */ xChange = stepSize; break; case 126: /* Up arrow */ yChange = -stepSize; break; case 125: /* Down arrow */ yChange = stepSize; break; } if (xChange != 0 || yChange != 0) { Rectangle[] oldRectangles = rectangles; 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(); int newX = oldX + xChange; int newY = oldY + yChange; event.x = newX; event.y = newY; Point cursorPos; if ((style & SWT.RESIZE) != 0) { resizeRectangles(xChange, yChange); inEvent = true; sendEvent(SWT.Resize, event); inEvent = false; /* * It is possible (but unlikely) that application * code could have disposed the widget in the move * event. If this happens return false to indicate * that the tracking has failed. */ if (isDisposed()) { cancelled = true; return; } 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(window, rectsToErase, true); drawRectangles(window, rectangles, false); } cursorPos = adjustResizeCursor(true); } else { moveRectangles(xChange, yChange); inEvent = true; sendEvent(SWT.Move, event); inEvent = false; /* * It is possible (but unlikely) that application * code could have disposed the widget in the move * event. If this happens return false to indicate * that the tracking has failed. */ if (isDisposed()) { cancelled = true; return; } 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(window, rectsToErase, true); drawRectangles(window, rectangles, false); } cursorPos = adjustMoveCursor(); } if (cursorPos != null) { oldX = cursorPos.x; oldY = cursorPos.y; } } }
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; }
int XKeyPress(int w, int client_data, int call_data, int continue_to_dispatch) { int result = super.XKeyPress(w, client_data, call_data, continue_to_dispatch); if (result != 0) return result; XKeyEvent keyEvent = new XKeyEvent(); OS.memmove(keyEvent, call_data, XKeyEvent.sizeof); if (keyEvent.keycode != 0) { int[] keysym = new int[1]; OS.XLookupString(keyEvent, null, 0, keysym, null); keysym[0] &= 0xFFFF; int xChange = 0, yChange = 0; int stepSize = ((keyEvent.state & OS.ControlMask) != 0) ? STEPSIZE_SMALL : STEPSIZE_LARGE; switch (keysym[0]) { case OS.XK_KP_Enter: case OS.XK_Return: tracking = false; /* Eat the subsequent KeyRelease event */ OS.XtAppNextEvent(OS.XtDisplayToApplicationContext(keyEvent.display), call_data); break; case OS.XK_Escape: tracking = false; cancelled = true; /* Eat the subsequent KeyRelease event */ OS.XtAppNextEvent(OS.XtDisplayToApplicationContext(keyEvent.display), call_data); break; case OS.XK_Left: xChange = -stepSize; break; case OS.XK_Right: xChange = stepSize; break; case OS.XK_Up: yChange = -stepSize; break; case OS.XK_Down: yChange = stepSize; break; } if (xChange != 0 || yChange != 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 = oldX + xChange; event.y = oldY + yChange; Point cursorPos; if ((style & SWT.RESIZE) != 0) { resizeRectangles(xChange, yChange); 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); } cursorPos = adjustResizeCursor(); } else { moveRectangles(xChange, yChange); 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); } cursorPos = adjustMoveCursor(); } if (cursorPos != null) { oldX = cursorPos.x; oldY = cursorPos.y; } } } return result; }
/** * 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; }