001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Michael Danilov
019: * @version $Revision$
020: */package org.apache.harmony.awt.wtk.linux;
021:
022: import java.awt.Frame;
023: import java.awt.Insets;
024: import java.awt.Point;
025: import java.awt.Rectangle;
026: import java.awt.event.FocusEvent;
027: import java.awt.event.InputEvent;
028: import java.awt.event.KeyEvent;
029: import java.awt.event.MouseEvent;
030: import java.awt.event.PaintEvent;
031: import java.awt.event.WindowEvent;
032:
033: import org.apache.harmony.awt.gl.MultiRectArea;
034: import org.apache.harmony.awt.internal.nls.Messages;
035: import org.apache.harmony.awt.nativebridge.CLongPointer;
036: import org.apache.harmony.awt.nativebridge.Int32Pointer;
037: import org.apache.harmony.awt.nativebridge.NativeBridge;
038: import org.apache.harmony.awt.nativebridge.PointerPointer;
039: import org.apache.harmony.awt.nativebridge.linux.X11;
040: import org.apache.harmony.awt.nativebridge.linux.X11Defs;
041: import org.apache.harmony.awt.wtk.NativeEvent;
042:
043: /**
044: * Information about X11 events can be found at http://www.xfree86.org/current/manindex3.html
045: */
046:
047: public final class LinuxEvent extends NativeEvent {
048: private static final X11 x11 = X11.getInstance();
049: private static final NativeBridge bridge = NativeBridge
050: .getInstance();
051: private final LinuxWindowFactory factory;
052:
053: private static final int MOUSE_BUTTONS_MASK = (X11Defs.Button1Mask
054: | X11Defs.Button2Mask | X11Defs.Button3Mask);
055:
056: private static long utcOffset = X11Defs.CurrentTime;
057:
058: private final LinuxEventQueue nativeQueue;
059: /** Clip area of paint event */
060: private MultiRectArea clipRects;
061:
062: /** X event type */
063: private int nativeEventId;
064: /** Invisible auxlitary window for receiving service events */
065: private final long javaWindowId;
066:
067: private Insets insets = new Insets(0, 0, 0, 0);
068:
069: public static long getUTCOffset() {
070: return utcOffset;
071: }
072:
073: LinuxEvent(LinuxWindowFactory factory, LinuxEventQueue nativeQueue,
074: X11.XEvent event) {
075: this .javaWindowId = factory.getJavaWindow();
076: this .nativeQueue = nativeQueue;
077: this .factory = factory;
078: setEvent(event);
079: }
080:
081: public MultiRectArea getClipRects() {
082: return new MultiRectArea(clipRects);
083: }
084:
085: public Rectangle getClipBounds() {
086: return clipRects.getBounds();
087: }
088:
089: public Insets getInsets() {
090: return insets;
091: }
092:
093: public boolean getTrigger() {
094: return ((eventId == MouseEvent.MOUSE_PRESSED) && (mouseButton == MouseEvent.BUTTON3));
095: }
096:
097: private void setEvent(X11.XEvent event) {
098:
099: windowId = event.get_xany().get_window();
100: nativeEventId = event.get_type();
101: eventId = ID_PLATFORM;
102:
103: if (windowId == javaWindowId) {
104: return;
105: }
106: if (!factory.validWindowId(windowId)
107: && windowId != factory.getRootWindow()) {
108: return;
109: }
110:
111: switch (nativeEventId) {
112: case X11Defs.KeyPress:
113: case X11Defs.KeyRelease:
114: X11.XKeyEvent keyEvent = event.get_xkey();
115: validateUTCOffset(keyEvent.get_time());
116: processKeyEvent(keyEvent);
117: break;
118: case X11Defs.ButtonPress:
119: case X11Defs.ButtonRelease:
120: X11.XButtonEvent buttonEvent = event.get_xbutton();
121: validateUTCOffset(buttonEvent.get_time());
122: processButtonEvent(buttonEvent);
123: break;
124: case X11Defs.MotionNotify:
125: X11.XMotionEvent motionEvent = event.get_xmotion();
126: validateUTCOffset(motionEvent.get_time());
127: processMotionEvent(motionEvent);
128: break;
129: case X11Defs.FocusIn:
130: case X11Defs.FocusOut:
131: X11.XFocusChangeEvent focusChangeEvent = event.get_xfocus();
132: processFocusChangeEvent(focusChangeEvent);
133: break;
134: case X11Defs.Expose:
135: X11.XExposeEvent exposeEvent = event.get_xexpose();
136: processExposeEvent(exposeEvent);
137: break;
138: case X11Defs.ConfigureNotify:
139: X11.XConfigureEvent configureEvent = event.get_xconfigure();
140: processConfigureEvent(configureEvent);
141: break;
142: case X11Defs.DestroyNotify:
143: X11.XDestroyWindowEvent destroyWindowEvent = event
144: .get_xdestroywindow();
145: processDestroyWindowEvent(destroyWindowEvent);
146: break;
147: case X11Defs.ClientMessage:
148: X11.XClientMessageEvent clientMessageEvent = event
149: .get_xclient();
150: processClientMessageEvent(clientMessageEvent);
151: break;
152: case X11Defs.PropertyNotify:
153: X11.XPropertyEvent propertyEvent = event.get_xproperty();
154: validateUTCOffset(propertyEvent.get_time());
155: processPropertyEvent(propertyEvent);
156: break;
157: case X11Defs.EnterNotify:
158: case X11Defs.LeaveNotify:
159: X11.XCrossingEvent crossingEvent = event.get_xcrossing();
160: validateUTCOffset(crossingEvent.get_time());
161: processCrossingEvent(crossingEvent);
162: break;
163: case X11Defs.ReparentNotify:
164: X11.XReparentEvent reparentEvent = event.get_xreparent();
165: processReparentEvent(reparentEvent);
166: break;
167: default:
168: eventId = ID_PLATFORM;
169: /*//Other events may be useful in future
170: case X11Defs.UnmapNotify:
171: X11.XUnmapEvent unmapEvent = x11.new XUnmapEvent(event
172: .get_xunmap_ptr());
173: processUnmapEvent(unmapEvent);
174: break;
175: case X11Defs.MapNotify:
176: X11.XMapEvent mapEvent = x11.new XMapEvent(event.get_xmap_ptr());
177: processMapEvent(mapEvent);
178: break;
179: case X11Defs.GraphicsExpose:
180: X11.XGraphicsExposeEvent graphicsExposeEvent = x11.new XGraphicsExposeEvent(event.get_xgraphicsexpose());
181: processGraphicsExposeEvent(graphicsExposeEvent);
182: break;
183: case X11Defs.NoExpose:
184: X11.XNoExposeEvent noExposeEvent = x11.new XNoExposeEvent(event.get_xnoexpose());
185: processNoExposeEventEvent(noExposeEvent);
186: break;
187: case X11Defs.VisibilityNotify:
188: X11.XVisibilityEvent visibilityEvent = x11.new XVisibilityEvent(event.get_xvisibility());
189: processVisibilityEvent(visibilityEvent);
190: break;
191: case X11Defs.MapRequest:
192: X11.XMapRequestEvent mapRequestEvent = x11.new XMapRequestEvent(event.get_xmaprequest());
193: processMapRequestEvent(mapRequestEvent);
194: break;
195: case X11Defs.ConfigureRequest:
196: X11.XConfigureRequestEvent configureRequestEvent = x11.new XConfigureRequestEvent(event.get_xconfigurerequest());
197: processConfigureRequestEvent(configureRequestEvent);
198: break;
199: case X11Defs.GravityNotify:
200: X11.XGravityEvent gravityEvent = x11.new XGravityEvent(event.get_xgravity());
201: processGravityEvent(gravityEvent);
202: break;
203: case X11Defs.ResizeRequest:
204: X11.XResizeRequestEvent resizeRequestEvent = x11.new XResizeRequestEvent(event.get_xresizerequest());
205: processResizeRequestEvent(resizeRequestEvent);
206: break;
207: case X11Defs.CirculateNotify:
208: X11.XCirculateEvent circulateEvent = x11.new XCirculateEvent(event.get_xcirculate());
209: processCirculateEvent(circulateEvent);
210: break;
211: case X11Defs.CirculateRequest:
212: X11.XCirculateRequestEvent circulateRequestEvent = x11.new XCirculateRequestEvent(event.get_xcirculaterequest());
213: processCirculateRequestEvent(circulateRequestEvent);
214: break;
215: case X11Defs.SelectionClear:
216: X11.XSelectionClearEvent selectionClearEvent = x11.new XSelectionClearEvent(event.get_xselectionclear());
217: processSelectionClearEvent(selectionClearEvent);
218: break;
219: case X11Defs.SelectionRequest:
220: X11.XSelectionRequestEvent selectionRequestEvent = x11.new XSelectionRequestEvent(event.get_xselectionrequest());
221: processSelectionRequestEvent(selectionRequestEvent);
222: break;
223: case X11Defs.SelectionNotify:
224: X11.XSelectionEvent selectionEvent = x11.new XSelectionEvent(event.get_xselection());
225: processSelectionEvent(selectionEvent);
226: break;
227: case X11Defs.ColormapNotify:
228: X11.XColormapEvent colormapEvent = x11.new XColormapEvent(event.get_xcolormap());
229: processColormapEvent(colormapEvent);
230: break;
231: case X11Defs.MappingNotify:
232: X11.XMappingEvent mappingEvent = x11.new XMappingEvent(event.get_xmapping());
233: processMappingEvent(mappingEvent);
234: break;
235: case X11Defs.KeymapNotify:
236: X11.XKeymapEvent keymapEvent = x11.new XKeymapEvent(event.get_xkeymap());
237: processKeymapEvent(keymapEvent);
238: break;
239: default:
240: //>X11Defs.LASTEvent => undefined event
241: //<2 => error or reply (XErrorEvent xerror);*/
242: }
243: }
244:
245: private void processReparentEvent(X11.XReparentEvent reparentEvent) {
246: processInsetsChange(null);
247: }
248:
249: private void processKeyEvent(X11.XKeyEvent event) {
250: eventId = (nativeEventId == X11Defs.KeyPress) ? KeyEvent.KEY_PRESSED
251: : KeyEvent.KEY_RELEASED;
252:
253: time = event.get_time() + utcOffset;
254: translateModifiers(event.get_state());
255:
256: keyInfo = KeyCodeTranslator.translateEvent(event);
257: forwardToContent();
258: }
259:
260: private void processButtonEvent(X11.XButtonEvent event) {
261: int button = event.get_button();
262:
263: if (button > X11Defs.Button3) {
264: eventId = MouseEvent.MOUSE_WHEEL;
265: wheelRotation = (button == X11Defs.Button4) ? -1 : 1;
266: } else {
267: eventId = (nativeEventId == X11Defs.ButtonPress) ? MouseEvent.MOUSE_PRESSED
268: : MouseEvent.MOUSE_RELEASED;
269: mouseButton = button - X11Defs.Button1 + MouseEvent.BUTTON1;
270: }
271:
272: time = event.get_time() + utcOffset;
273: localPos = new Point(event.get_x(), event.get_y());
274: screenPos = new Point(event.get_x_root(), event.get_y_root());
275: translateButtonModifiers(event.get_state());
276: if (!updateGrabState(event)) {
277: eventId = ID_MOUSE_GRAB_CANCELED;
278: }
279: }
280:
281: private void processMotionEvent(X11.XMotionEvent event) {
282: LinuxWindow win = (LinuxWindow) factory.getWindowById(windowId);
283:
284: if (win == null) {
285: return;
286: }
287:
288: localPos = new Point(event.get_x(), event.get_y());
289: if (!localPos.equals(win.queryPointer())) {
290: return;
291: }
292: screenPos = new Point(event.get_x_root(), event.get_y_root());
293: if ((event.get_state() & MOUSE_BUTTONS_MASK) > 0) {
294: eventId = MouseEvent.MOUSE_DRAGGED;
295: } else {
296: eventId = MouseEvent.MOUSE_MOVED;
297: }
298: time = event.get_time() + utcOffset;
299: translateModifiers(event.get_state());
300: }
301:
302: private void processCrossingEvent(X11.XCrossingEvent event) {
303: eventId = (nativeEventId == X11Defs.EnterNotify) ? MouseEvent.MOUSE_ENTERED
304: : MouseEvent.MOUSE_EXITED;
305: localPos = new Point(event.get_x(), event.get_y());
306: screenPos = new Point(event.get_x_root(), event.get_y_root());
307: time = event.get_time() + utcOffset;
308: translateModifiers(event.get_state());
309: }
310:
311: private void processFocusChangeEvent(X11.XFocusChangeEvent event) {
312: int detail = event.get_detail();
313: //ignore events sent to windows other than source or destination
314: if (detail == X11Defs.NotifyNonlinearVirtual
315: || detail == X11Defs.NotifyVirtual) {
316: return;
317: }
318: boolean gainedFocus = (nativeEventId == X11Defs.FocusIn);
319: WindowManager wm = factory.wm;
320: long focusedWindow = wm.getFocusedWindow();
321: long serverFocusedWindow = wm.getInputFocus();
322: long newFocusedWindow = gainedFocus ? event.get_window()
323: : serverFocusedWindow;
324: forwardToContent();
325: eventId = gainedFocus ? FocusEvent.FOCUS_GAINED
326: : FocusEvent.FOCUS_LOST;
327:
328: otherWindowId = gainedFocus ? focusedWindow : newFocusedWindow;
329: //have to check if this window belongs to our Java application
330: if (!factory.validWindowId(otherWindowId)) {
331: otherWindowId = 0;
332: //if lost focus to window in some other app, clear focusedWindow:
333: if (!gainedFocus) {
334: wm.setFocusedWindow(0);
335: }
336: } else {
337: otherWindowId = getContentId(otherWindowId);
338: }
339: if (gainedFocus) {
340: wm.setFocusedWindow(newFocusedWindow);
341: }
342: }
343:
344: private void processExposeEvent(X11.XExposeEvent event) {
345: MultiRectArea clip = nativeQueue.getAccumulatedClip(windowId);
346:
347: clip.add(new Rectangle(event.get_x(), event.get_y(), event
348: .get_width(), event.get_height()));
349:
350: if (event.get_count() != 0) {
351: eventId = ID_PLATFORM;
352: } else {
353: eventId = PaintEvent.PAINT;
354:
355: clipRects = clip;
356: nativeQueue.resetAccumulatedClip(windowId);
357: }
358: }
359:
360: private void processConfigureEvent(X11.XConfigureEvent event) {
361: LinuxWindow win = (LinuxWindow) factory.getWindowById(windowId);
362:
363: if (win == null) {
364: return;
365: }
366:
367: boolean child = win.isChild();
368: boolean isSynthetic = event.get_send_event() != 0;
369:
370: windowRect = new Rectangle(event.get_x(), event.get_y(), event
371: .get_width(), event.get_height());
372:
373: //in real configure events new position is reported relative to parent
374: //so have to translate it for top-level(managed by WM)windows
375: //to get root-related coords
376: if (!child && !isSynthetic) {
377: Int32Pointer x = bridge.createInt32Pointer(1, false);
378: Int32Pointer y = bridge.createInt32Pointer(1, false);
379: CLongPointer childWindow = bridge.createCLongPointer(1,
380: false);
381:
382: long parentId = win.getParentID();
383: x11.XTranslateCoordinates(win.getDisplay(), parentId,
384: factory.getRootWindow(), windowRect.x,
385: windowRect.y, x, y, childWindow);
386: windowRect.setLocation(x.get(0), y.get(0));
387: }
388:
389: boolean isContent = (win instanceof ContentWindow);
390:
391: if (!isContent && child && !windowRect.equals(win.getBounds())) {
392: eventId = ID_PLATFORM;
393: return;
394: }
395:
396: eventId = ID_BOUNDS_CHANGED;
397: Rectangle oldRect = win.onBoundsChange(windowRect);
398: if (isContent) {
399: ContentWindow content = (ContentWindow) win;
400: windowRect.setLocation(content.getBounds().getLocation());
401: }
402: if (windowRect.equals(oldRect)) {
403: eventId = /*insetsChanged ? ID_INSETS_CHANGED : */ID_PLATFORM;
404: }
405:
406: LinuxWindow content = win.getContentWindow();
407: if (content != null) {
408: if (win.resized) {
409: Insets ins = win.getInsets();
410: int dw = ins.left + ins.right;
411: int dh = ins.top + ins.bottom;
412: x11.XResizeWindow(win.getDisplay(), content.getId(),
413: windowRect.width + dw, windowRect.height + dh);
414: x11.XFlush(win.getDisplay());
415: }
416: if (isSynthetic && win.moved) {
417: windowId = content.getId();
418: windowRect.setBounds(content.getBounds());
419: }
420:
421: }
422: }
423:
424: private void processDestroyWindowEvent(X11.XDestroyWindowEvent event) {
425: eventId = WindowEvent.WINDOW_CLOSED;
426: factory.onWindowDispose(windowId);
427: }
428:
429: private void processPropertyEvent(X11.XPropertyEvent event) {
430: long atom = event.get_atom();
431: if (atom == factory.wm.NET_WM_STATE) {
432: processWindowStateEvent();
433: } else if (atom == factory.wm.NET_FRAME_EXTENTS
434: || atom == factory.wm.KDE_NET_WM_FRAME_STRUT) {
435: processFrameExtentsEvent(atom);
436: }
437: }
438:
439: /**
440: * @param property - could be NET_FRAME_EXTENTS or KDE_NET_WM_FRAME_STRUT
441: */
442: private void processFrameExtentsEvent(long property) {
443: insets = factory.wm.getNativeInsets(windowId, property);
444: }
445:
446: /**
447: *
448: */
449: private void processInsetsChange(Insets newInsets) {
450: LinuxWindow win = (LinuxWindow) factory.getWindowById(windowId);
451:
452: if ((win == null) || win.isChild() || win.isUndecorated()) {
453: return;
454: }
455:
456: eventId = ID_INSETS_CHANGED;
457:
458: if (newInsets != null) {
459: win.setInsets(newInsets);
460: } else {
461: insets = win.updateInsets();
462: }
463: forwardToContent();
464:
465: }
466:
467: private void processWindowStateEvent() {
468: CLongPointer actualTypeReturn = bridge.createCLongPointer(1,
469: false);
470: Int32Pointer actualFormatReturn = bridge.createInt32Pointer(1,
471: false);
472: CLongPointer nitemsReturn = bridge.createCLongPointer(1, false);
473: CLongPointer bytesAfterReturn = bridge.createCLongPointer(1,
474: false);
475: PointerPointer propReturn = bridge.createPointerPointer(1,
476: false);
477:
478: x11.XGetWindowProperty(factory.getDisplay(), windowId,
479: factory.wm.NET_WM_STATE, 0, Integer.MAX_VALUE,
480: X11Defs.FALSE, X11Defs.AnyPropertyType,
481: actualTypeReturn, actualFormatReturn, nitemsReturn,
482: bytesAfterReturn, propReturn);
483:
484: int count = (int) nitemsReturn.get(0);
485: if (count == 0) {
486: return;
487: }
488: if (actualFormatReturn.get(0) == 32) {
489: CLongPointer types = bridge.createCLongPointer(propReturn
490: .get(0));
491: deriveNewWindowState(count, types);
492: } else {
493: // awt.10=Only 32-bit format is supported for window state operations.
494: throw new RuntimeException(Messages.getString("awt.10")); //$NON-NLS-1$
495: }
496: }
497:
498: private void deriveNewWindowState(int typesCount, CLongPointer types) {
499: LinuxWindow win = (LinuxWindow) factory.getWindowById(windowId);
500:
501: if (win == null) {
502: return;
503: }
504:
505: int oldState = win.getState();
506: int newState = 0;
507: boolean oldAlwaysOnTop = win.alwaysOnTop;
508: boolean newAlwaysOnTop = false;
509:
510: for (int i = 0; i < typesCount; i++) {
511: long type = types.get(i);
512: if (type == factory.wm.NET_WM_STATE_MAXIMIZED_HORZ) {
513: newState |= Frame.MAXIMIZED_HORIZ;
514: } else if (type == factory.wm.NET_WM_STATE_MAXIMIZED_VERT) {
515: newState |= Frame.MAXIMIZED_VERT;
516: } else if (type == factory.wm.NET_WM_STATE_HIDDEN) {
517: newState |= Frame.ICONIFIED;
518: } else if (type == factory.wm.NET_WM_STATE_ABOVE) {
519: newAlwaysOnTop = true;
520: }
521: }
522:
523: win
524: .setMaximized((newState & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH);
525: win
526: .setIconified((newState & Frame.ICONIFIED) == Frame.ICONIFIED);
527: if (newState != oldState) {
528: windowState = newState;
529: eventId = WindowEvent.WINDOW_STATE_CHANGED;
530: }
531: if (oldAlwaysOnTop != oldAlwaysOnTop) {
532: win.alwaysOnTop = newAlwaysOnTop;
533: }
534: forwardToContent();
535: }
536:
537: private void processClientMessageEvent(X11.XClientMessageEvent event) {
538: if (event.get_message_type() == factory.wm.WM_PROTOCOLS) {
539: CLongPointer data = event.get_l();
540: long protocol = data.get(0);
541: if (protocol == factory.wm.WM_DELETE_WINDOW) {
542: LinuxWindow lw = (LinuxWindow) factory
543: .getWindowById(windowId);
544: LinuxWindow cw = lw.getContentWindow();
545: if (lw.isInputAllowed()) {
546: eventId = WindowEvent.WINDOW_CLOSING;
547: if (cw != null) {
548: // forward closing event to the content window:
549: windowId = cw.getId();
550: }
551: }
552: }
553: // TODO: Process other Window Manager's events here
554: }
555: }
556:
557: private void translateButtonModifiers(int state) {
558: translateModifiers(state);
559:
560: final int m = (mouseButton == MouseEvent.BUTTON1) ? InputEvent.BUTTON1_DOWN_MASK
561: : (mouseButton == MouseEvent.BUTTON2) ? InputEvent.BUTTON2_DOWN_MASK
562: : (mouseButton == MouseEvent.BUTTON3) ? InputEvent.BUTTON3_DOWN_MASK
563: : 0;
564:
565: if (eventId == MouseEvent.MOUSE_PRESSED) {
566: modifiers |= m;
567: } else if (eventId == MouseEvent.MOUSE_RELEASED) {
568: modifiers &= ~m;
569: }
570: }
571:
572: private void translateModifiers(int state) {
573: if ((state & X11Defs.Mod1Mask) > 0) {
574: modifiers |= InputEvent.ALT_DOWN_MASK;
575: }
576: if ((state & X11Defs.Mod5Mask) > 0) {
577: modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
578: }
579: if ((state & X11Defs.ControlMask) > 0) {
580: modifiers |= InputEvent.CTRL_DOWN_MASK;
581: }
582: if ((state & X11Defs.ShiftMask) > 0) {
583: modifiers |= InputEvent.SHIFT_DOWN_MASK;
584: }
585: if ((state & X11Defs.Button1Mask) > 0) {
586: modifiers |= InputEvent.BUTTON1_DOWN_MASK;
587: }
588: if ((state & X11Defs.Button2Mask) > 0) {
589: modifiers |= InputEvent.BUTTON2_DOWN_MASK;
590: }
591: if ((state & X11Defs.Button3Mask) > 0) {
592: modifiers |= InputEvent.BUTTON3_DOWN_MASK;
593: }
594: }
595:
596: private boolean updateGrabState(X11.XButtonEvent event) {
597: int mouseState = (event.get_state() & MOUSE_BUTTONS_MASK);
598:
599: switch (event.get_type()) {
600: case X11Defs.ButtonPress:
601: // Only one mouse button is pressed
602: if (mouseState == X11Defs.Button1Mask
603: || mouseState == X11Defs.Button2Mask
604: || mouseState == X11Defs.Button3Mask) {
605:
606: if (!LinuxWindow.startAutoGrab(event.get_window(),
607: event.get_x(), event.get_y())) {
608: return false;
609: }
610: }
611: break;
612: case X11Defs.ButtonRelease:
613: // All mouse buttons were actually released
614: if (mouseState == 0) {
615: LinuxWindow.endAutoGrab();
616: }
617: break;
618: }
619:
620: return true;
621: }
622:
623: private void validateUTCOffset(long time) {
624: if (utcOffset == X11Defs.CurrentTime) {
625: utcOffset = System.currentTimeMillis() - time;
626: }
627: }
628:
629: public String getCompositionString() {
630: return new String();
631: }
632:
633: public int getCompCursorPos() {
634: return 0;
635: }
636:
637: private long getContentId(long winId) {
638: LinuxWindow win = (LinuxWindow) factory.getWindowById(winId);
639:
640: if (win != null) {
641: LinuxWindow content = win.getContentWindow();
642:
643: if (content != null) {
644: long contentId = content.getId();
645:
646: if (factory.validWindowId(contentId)) {
647: return contentId;
648: }
649: }
650: }
651:
652: return winId;
653: }
654:
655: private void forwardToContent() {
656: windowId = getContentId(windowId);
657: }
658:
659: public String toString() {
660: return "window=0x" + Long.toHexString(windowId) + ", event=" + eventId; //$NON-NLS-1$ //$NON-NLS-2$
661: }
662: }
|