169 "rc=" + error.get_request_code() + ", " +
170 "mc=" + error.get_minor_code());
171 }
172 return 0;
173 }
174
175 // Called from the native code when an error occurs
176 private static int globalErrorHandler(long display, long event_ptr) {
177 if (noisyAwtHandler) {
178 XlibWrapper.PrintXErrorEvent(display, event_ptr);
179 }
180 XErrorEvent event = new XErrorEvent(event_ptr);
181 saved_error = event;
182 try {
183 if (current_error_handler != null) {
184 return current_error_handler.handleError(display, event);
185 } else {
186 return SAVED_ERROR_HANDLER(display, event);
187 }
188 } catch (Throwable z) {
189 log.log(Level.FINE, "Error in GlobalErrorHandler", z);
190 }
191 return 0;
192 }
193
194 //---- END OF ERROR HANDLER CODE ----//
195
196 private native static void initIDs();
197 native static void waitForEvents(long nextTaskTime);
198 static Thread toolkitThread;
199 static boolean isToolkitThread() {
200 return Thread.currentThread() == toolkitThread;
201 }
202
203 static void initSecurityWarning() {
204 // Enable warning only for internal builds
205 String runtime = AccessController.doPrivileged(
206 new GetPropertyAction("java.runtime.version"));
207 securityWarningEnabled = (runtime != null && runtime.contains("internal"));
208 }
209
210 static boolean isSecurityWarningEnabled() {
260 public static long getDefaultRootWindow() {
261 awtLock();
262 try {
263 long res = XlibWrapper.RootWindow(XToolkit.getDisplay(),
264 XlibWrapper.DefaultScreen(XToolkit.getDisplay()));
265
266 if (res == 0) {
267 throw new IllegalStateException("Root window must not be null");
268 }
269 return res;
270 } finally {
271 awtUnlock();
272 }
273 }
274
275 void init() {
276 awtLock();
277 try {
278 XlibWrapper.XSupportsLocale();
279 if (XlibWrapper.XSetLocaleModifiers("") == null) {
280 log.finer("X locale modifiers are not supported, using default");
281 }
282
283 AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
284 awt_defaultFg = defaultScreen.get_blackpixel();
285
286 arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
287 XCursorFontConstants.XC_arrow);
288
289 saved_error_handler = XlibWrapper.SetToolkitErrorHandler();
290 } finally {
291 awtUnlock();
292 }
293
294 if (log.isLoggable(Level.FINE)) {
295 PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
296 public Void run() {
297 Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
298 public void run() {
299 if (log.isLoggable(Level.FINE)) {
300 dumpPeers();
301 }
302 }
303 };
304 shutdownThread.setContextClassLoader(null);
305 Runtime.getRuntime().addShutdownHook(shutdownThread);
306 return null;
307 }
308 };
309 AccessController.doPrivileged(a);
310 }
311 }
312
313 static String getCorrectXIDString(String val) {
314 if (val != null) {
315 return val.replace('.', '-');
316 } else {
317 return val;
318 }
319 }
320
321 static native String getEnv(String key);
322
323
324 static String getAWTAppClassName() {
325 return awtAppClassName;
326 }
327
328 static final String DATA_TRANSFERER_CLASS_NAME = "sun.awt.X11.XDataTransferer";
329
330 public XToolkit() {
331 super();
496 XEvent copy = xev.clone();
497 try {
498 for (XEventListener listener : listeners) {
499 listener.eventProcessed(copy);
500 }
501 } finally {
502 copy.dispose();
503 }
504 }
505 }
506
507 private void dispatchEvent(XEvent ev) {
508 final XAnyEvent xany = ev.get_xany();
509
510 if (windowToXWindow(xany.get_window()) != null &&
511 (ev.get_type() == MotionNotify || ev.get_type() == EnterNotify || ev.get_type() == LeaveNotify))
512 {
513 processGlobalMotionEvent(ev);
514 }
515
516 XBaseWindow.dispatchToWindow(ev);
517
518 Collection dispatchers = null;
519 synchronized(winToDispatcher) {
520 Long key = Long.valueOf(xany.get_window());
521 dispatchers = (Collection)winToDispatcher.get(key);
522 if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
523 dispatchers = new Vector(dispatchers);
524 }
525 }
526 if (dispatchers != null) {
527 Iterator iter = dispatchers.iterator();
528 while (iter.hasNext()) {
529 XEventDispatcher disp = (XEventDispatcher)iter.next();
530 disp.dispatchEvent(ev);
531 }
532 }
533 notifyListeners(ev);
534 }
535
559 // For now, we just avoid waitForEvents in the secondary loop.
560 if (!XlibWrapper.XNextSecondaryLoopEvent(getDisplay(),ev.pData)) {
561 break;
562 }
563 } else {
564 callTimeoutTasks();
565 // If no events are queued, waitForEvents() causes calls to
566 // awtUnlock(), awtJNI_ThreadYield, poll, awtLock(),
567 // so it spends most of its time in poll, without holding the lock.
568 while ((XlibWrapper.XEventsQueued(getDisplay(), XlibWrapper.QueuedAfterReading) == 0) &&
569 (XlibWrapper.XEventsQueued(getDisplay(), XlibWrapper.QueuedAfterFlush) == 0)) {
570 callTimeoutTasks();
571 waitForEvents(getNextTaskTime());
572 }
573 XlibWrapper.XNextEvent(getDisplay(),ev.pData);
574 }
575
576 if (ev.get_type() != NoExpose) {
577 eventNumber++;
578 }
579
580 if (XDropTargetEventProcessor.processEvent(ev) ||
581 XDragSourceContextPeer.processEvent(ev)) {
582 continue;
583 }
584
585 if (eventLog.isLoggable(Level.FINER)) {
586 eventLog.log(Level.FINER, "{0}", String.valueOf(ev));
587 }
588
589 // Check if input method consumes the event
590 long w = 0;
591 if (windowToXWindow(ev.get_xany().get_window()) != null) {
592 Component owner =
593 XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
594 if (owner != null) {
595 XWindow ownerWindow = (XWindow) ComponentAccessor.getPeer(owner);
596 if (ownerWindow != null) {
597 w = ownerWindow.getContentWindow();
598 }
1075 }
1076 return false;
1077 }
1078
1079 /**
1080 * Returns the supported cursor size
1081 */
1082 public Dimension getBestCursorSize(int preferredWidth, int preferredHeight) {
1083 return XCustomCursor.getBestCursorSize(
1084 java.lang.Math.max(1,preferredWidth), java.lang.Math.max(1,preferredHeight));
1085 }
1086
1087
1088 public int getMaximumCursorColors() {
1089 return 2; // Black and white.
1090 }
1091
1092 public Map mapInputMethodHighlight(InputMethodHighlight highlight) {
1093 return XInputMethod.mapInputMethodHighlight(highlight);
1094 }
1095
1096 public Clipboard getSystemClipboard() {
1097 SecurityManager security = System.getSecurityManager();
1098 if (security != null) {
1099 security.checkSystemClipboardAccess();
1100 }
1101 synchronized (this) {
1102 if (clipboard == null) {
1103 clipboard = new XClipboard("System", "CLIPBOARD");
1104 }
1105 }
1106 return clipboard;
1107 }
1108
1109 public Clipboard getSystemSelection() {
1110 SecurityManager security = System.getSecurityManager();
1111 if (security != null) {
1112 security.checkSystemClipboardAccess();
1113 }
1114 synchronized (this) {
1351 if (isToolkitThread()) {
1352 XEvent event = new XEvent();
1353 try {
1354 XlibWrapper.XWindowEvent(XToolkit.getDisplay(),
1355 XBaseWindow.getXAWTRootWindow().getWindow(),
1356 XConstants.PropertyChangeMask,
1357 event.pData);
1358 timeFetcher.dispatchEvent(event);
1359 }
1360 finally {
1361 event.dispose();
1362 }
1363 }
1364 else {
1365 while (!timeStampUpdated) {
1366 awtLockWait();
1367 }
1368 }
1369 } catch (InterruptedException ie) {
1370 // Note: the returned timeStamp can be incorrect in this case.
1371 if (log.isLoggable(Level.FINE)) log.fine("Catched exception, timeStamp may not be correct (ie = " + ie + ")");
1372 }
1373 } finally {
1374 awtUnlock();
1375 }
1376 return timeStamp;
1377 }
1378 protected void initializeDesktopProperties() {
1379 desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
1380 desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50));
1381 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5));
1382 // Don't want to call getMultiClickTime() if we are headless
1383 if (!GraphicsEnvironment.isHeadless()) {
1384 desktopProperties.put("awt.multiClickInterval",
1385 Integer.valueOf(getMultiClickTime()));
1386 desktopProperties.put("awt.mouse.numButtons",
1387 Integer.valueOf(getNumMouseButtons()));
1388 }
1389 }
1390
1391 private int getNumMouseButtons() {
1480 * <code>data</code> is the byte array directly from the x server and
1481 * may be in little endian format.
1482 * <p>
1483 * NB: This could be called from any thread if triggered by
1484 * <code>loadXSettings</code>. It is called from the System EDT
1485 * if triggered by an XSETTINGS change.
1486 */
1487 void parseXSettings(int screen_XXX_ignored,Map updatedSettings) {
1488
1489 if (updatedSettings == null || updatedSettings.isEmpty()) {
1490 return;
1491 }
1492
1493 Iterator i = updatedSettings.entrySet().iterator();
1494 while (i.hasNext()) {
1495 Map.Entry e = (Map.Entry)i.next();
1496 String name = (String)e.getKey();
1497
1498 name = "gnome." + name;
1499 setDesktopProperty(name, e.getValue());
1500 log.fine("name = " + name + " value = " + e.getValue());
1501
1502 // XXX: we probably want to do something smarter. In
1503 // particular, "Net" properties are of interest to the
1504 // "core" AWT itself. E.g.
1505 //
1506 // Net/DndDragThreshold -> ???
1507 // Net/DoubleClickTime -> awt.multiClickInterval
1508 }
1509
1510 setDesktopProperty(SunToolkit.DESKTOPFONTHINTS,
1511 SunToolkit.getDesktopFontHints());
1512
1513 Integer dragThreshold = null;
1514 synchronized (this) {
1515 dragThreshold = (Integer)desktopProperties.get("gnome.Net/DndDragThreshold");
1516 }
1517 if (dragThreshold != null) {
1518 setDesktopProperty("DnD.gestureMotionThreshold", dragThreshold);
1519 }
1520
1530
1531 /* Like XKeysymToKeycode, but ensures that keysym is the primary
1532 * symbol on the keycode returned. Returns zero otherwise.
1533 */
1534 static int keysymToPrimaryKeycode(long sym) {
1535 awtLock();
1536 try {
1537 int code = XlibWrapper.XKeysymToKeycode(getDisplay(), sym);
1538 if (code == 0) {
1539 return 0;
1540 }
1541 long primary = XlibWrapper.XKeycodeToKeysym(getDisplay(), code, 0);
1542 if (sym != primary) {
1543 return 0;
1544 }
1545 return code;
1546 } finally {
1547 awtUnlock();
1548 }
1549 }
1550
1551 /* Assign meaning - alt, meta, etc. - to X modifiers mod1 ... mod5.
1552 * Only consider primary symbols on keycodes attached to modifiers.
1553 */
1554 static void setupModifierMap() {
1555 final int metaL = keysymToPrimaryKeycode(XKeySymConstants.XK_Meta_L);
1556 final int metaR = keysymToPrimaryKeycode(XKeySymConstants.XK_Meta_R);
1557 final int altL = keysymToPrimaryKeycode(XKeySymConstants.XK_Alt_L);
1558 final int altR = keysymToPrimaryKeycode(XKeySymConstants.XK_Alt_R);
1559 final int numLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Num_Lock);
1560 final int modeSwitch = keysymToPrimaryKeycode(XKeySymConstants.XK_Mode_switch);
1561 final int shiftLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Shift_Lock);
1562 final int capsLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Caps_Lock);
1563
1564 final int modmask[] = { ShiftMask, LockMask, ControlMask, Mod1Mask,
1565 Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
1566
1567 log.fine("In setupModifierMap");
1568 awtLock();
1569 try {
1973 backingStoreType = XConstants.NotUseful;
1974
1975 if (backingStoreLog.isLoggable(Level.CONFIG)) {
1976 backingStoreLog.config("Backing store is not available on the screen " +
1977 i + ", backingStore=NotUseful");
1978 }
1979
1980 return;
1981 }
1982 }
1983 } finally {
1984 awtUnlock();
1985 }
1986 }
1987
1988 /**
1989 * One of XConstants: NotUseful, WhenMapped or Always.
1990 */
1991 private static int backingStoreType;
1992
1993 static boolean awt_ServerInquired = false;
1994 static boolean awt_IsXsunServer = false;
1995 static boolean awt_XKBInquired = false;
1996 static boolean awt_UseXKB = false;
1997 /**
1998 Try to understand if it is Xsun server.
1999 By now (2005) Sun is vendor of Xsun and Xorg servers; we only return true if Xsun is running.
2000 */
2001 static boolean isXsunServer() {
2002 awtLock();
2003 try {
2004 if( awt_ServerInquired ) {
2005 return awt_IsXsunServer;
2006 }
2007 if( ! XlibWrapper.ServerVendor(getDisplay()).startsWith("Sun Microsystems") ) {
2008 awt_ServerInquired = true;
2009 awt_IsXsunServer = false;
2010 return false;
2011 }
2012 // Now, it's Sun. It still may be Xorg though, eg on Solaris 10, x86.
2013 // Today (2005), VendorRelease of Xorg is a Big Number unlike Xsun.
2014 if( XlibWrapper.VendorRelease(getDisplay()) > 10000 ) {
2015 awt_ServerInquired = true;
2016 awt_IsXsunServer = false;
2017 return false;
2018 }
2019 awt_ServerInquired = true;
2020 awt_IsXsunServer = true;
2021 return true;
2022 } finally {
2023 awtUnlock();
2024 }
2025 }
2026 /**
2027 Query XKEYBOARD extension.
2028 */
2029 static boolean isXKBenabled() {
2030 awtLock();
2031 try {
2032 if( awt_XKBInquired ) {
2033 return awt_UseXKB;
2034 }
2035 awt_XKBInquired = true;
2036 String name = "XKEYBOARD";
2037 awt_UseXKB = XlibWrapper.XQueryExtension( getDisplay(), name, XlibWrapper.larg1, XlibWrapper.larg2, XlibWrapper.larg3);
2038 return awt_UseXKB;
2039 } finally {
2040 awtUnlock();
2041 }
2042 }
2043
2044 private static long eventNumber;
2045 public static long getEventNumber() {
2046 awtLock();
2047 try {
2048 return eventNumber;
2049 } finally {
2050 awtUnlock();
2051 }
2052 }
2053
2054 private static XEventDispatcher oops_waiter;
2055 private static boolean oops_updated;
2056 private static boolean oops_failed;
2057 private XAtom oops;
2058 private static final long WORKAROUND_SLEEP = 100;
2059
2060 /**
2061 * @inheritDoc
2062 */
2082 }
2083
2084 }
2085 }
2086 };
2087 }
2088
2089 if (oops == null) {
2090 oops = XAtom.get("OOPS");
2091 }
2092
2093 awtLock();
2094 try {
2095 addEventDispatcher(win.getWindow(), oops_waiter);
2096
2097 oops_updated = false;
2098 oops_failed = false;
2099 // Wait for selection notify for oops on win
2100 long event_number = getEventNumber();
2101 XAtom atom = XAtom.get("WM_S0");
2102 eventLog.log(Level.FINER, "WM_S0 selection owner {0}", new Object[] {XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom())});
2103 XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(),
2104 XAtom.get("VERSION").getAtom(), oops.getAtom(),
2105 win.getWindow(), XlibWrapper.CurrentTime);
2106 XSync();
2107
2108
2109 eventLog.finer("Requested OOPS");
2110
2111 long start = System.currentTimeMillis();
2112 while (!oops_updated && !oops_failed) {
2113 try {
2114 awtLockWait(timeout);
2115 } catch (InterruptedException e) {
2116 throw new RuntimeException(e);
2117 }
2118 // This "while" is a protection from spurious
2119 // wake-ups. However, we shouldn't wait for too long
2120 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {
2121 throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
2122 }
2123 }
2124 if (oops_failed && getEventNumber() - event_number == 1) {
2125 // If selection update failed we can simply wait some time
2126 // hoping some events will arrive
2127 awtUnlock();
2128 eventLog.log(Level.FINEST, "Emergency sleep");
2129 try {
2130 Thread.sleep(WORKAROUND_SLEEP);
2131 } catch (InterruptedException ie) {
2132 throw new RuntimeException(ie);
2133 } finally {
2134 awtLock();
2135 }
2136 }
2137 return getEventNumber() - event_number > 2;
2138 } finally {
2139 removeEventDispatcher(win.getWindow(), oops_waiter);
2140 eventLog.log(Level.FINER, "Exiting syncNativeQueue");
2141 awtUnlock();
2142 }
2143 }
2144 public void grab(Window w) {
2145 if (w.getPeer() != null) {
2146 ((XWindowPeer)w.getPeer()).setGrab(true);
2147 }
2148 }
2149
2150 public void ungrab(Window w) {
2151 if (w.getPeer() != null) {
2152 ((XWindowPeer)w.getPeer()).setGrab(false);
2153 }
2154 }
2155 /**
2156 * Returns if the java.awt.Desktop class is supported on the current
2157 * desktop.
2158 * <p>
2159 * The methods of java.awt.Desktop class are supported on the Gnome desktop.
2160 * Check if the running desktop is Gnome by checking the window manager.
|
169 "rc=" + error.get_request_code() + ", " +
170 "mc=" + error.get_minor_code());
171 }
172 return 0;
173 }
174
175 // Called from the native code when an error occurs
176 private static int globalErrorHandler(long display, long event_ptr) {
177 if (noisyAwtHandler) {
178 XlibWrapper.PrintXErrorEvent(display, event_ptr);
179 }
180 XErrorEvent event = new XErrorEvent(event_ptr);
181 saved_error = event;
182 try {
183 if (current_error_handler != null) {
184 return current_error_handler.handleError(display, event);
185 } else {
186 return SAVED_ERROR_HANDLER(display, event);
187 }
188 } catch (Throwable z) {
189 if (log.isLoggable(Level.FINE)) {
190 log.log(Level.FINE, "Error in GlobalErrorHandler", z);
191 }
192 }
193 return 0;
194 }
195
196 //---- END OF ERROR HANDLER CODE ----//
197
198 private native static void initIDs();
199 native static void waitForEvents(long nextTaskTime);
200 static Thread toolkitThread;
201 static boolean isToolkitThread() {
202 return Thread.currentThread() == toolkitThread;
203 }
204
205 static void initSecurityWarning() {
206 // Enable warning only for internal builds
207 String runtime = AccessController.doPrivileged(
208 new GetPropertyAction("java.runtime.version"));
209 securityWarningEnabled = (runtime != null && runtime.contains("internal"));
210 }
211
212 static boolean isSecurityWarningEnabled() {
262 public static long getDefaultRootWindow() {
263 awtLock();
264 try {
265 long res = XlibWrapper.RootWindow(XToolkit.getDisplay(),
266 XlibWrapper.DefaultScreen(XToolkit.getDisplay()));
267
268 if (res == 0) {
269 throw new IllegalStateException("Root window must not be null");
270 }
271 return res;
272 } finally {
273 awtUnlock();
274 }
275 }
276
277 void init() {
278 awtLock();
279 try {
280 XlibWrapper.XSupportsLocale();
281 if (XlibWrapper.XSetLocaleModifiers("") == null) {
282 if (log.isLoggable(Level.FINER)) {
283 log.finer("X locale modifiers are not supported, using default");
284 }
285 }
286 tryXKB();
287
288 AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
289 awt_defaultFg = defaultScreen.get_blackpixel();
290
291 arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
292 XCursorFontConstants.XC_arrow);
293
294 saved_error_handler = XlibWrapper.SetToolkitErrorHandler();
295 } finally {
296 awtUnlock();
297 }
298
299 PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
300 public Void run() {
301 Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
302 public void run() {
303 freeXKB();
304 if (log.isLoggable(Level.FINE)) {
305 dumpPeers();
306 }
307 }
308 };
309 shutdownThread.setContextClassLoader(null);
310 Runtime.getRuntime().addShutdownHook(shutdownThread);
311 return null;
312 }
313 };
314 AccessController.doPrivileged(a);
315 }
316
317 static String getCorrectXIDString(String val) {
318 if (val != null) {
319 return val.replace('.', '-');
320 } else {
321 return val;
322 }
323 }
324
325 static native String getEnv(String key);
326
327
328 static String getAWTAppClassName() {
329 return awtAppClassName;
330 }
331
332 static final String DATA_TRANSFERER_CLASS_NAME = "sun.awt.X11.XDataTransferer";
333
334 public XToolkit() {
335 super();
500 XEvent copy = xev.clone();
501 try {
502 for (XEventListener listener : listeners) {
503 listener.eventProcessed(copy);
504 }
505 } finally {
506 copy.dispose();
507 }
508 }
509 }
510
511 private void dispatchEvent(XEvent ev) {
512 final XAnyEvent xany = ev.get_xany();
513
514 if (windowToXWindow(xany.get_window()) != null &&
515 (ev.get_type() == MotionNotify || ev.get_type() == EnterNotify || ev.get_type() == LeaveNotify))
516 {
517 processGlobalMotionEvent(ev);
518 }
519
520 if( ev.get_type() == XConstants.MappingNotify ) {
521 // The 'window' field in this event is unused.
522 // This application itself does nothing to initiate such an event
523 // (no calls of XChangeKeyboardMapping etc.).
524 // SunRay server sends this event to the application once on every
525 // keyboard (not just layout) change which means, quite seldom.
526 XlibWrapper.XRefreshKeyboardMapping(ev.pData);
527 resetKeyboardSniffer();
528 setupModifierMap();
529 }
530 XBaseWindow.dispatchToWindow(ev);
531
532 Collection dispatchers = null;
533 synchronized(winToDispatcher) {
534 Long key = Long.valueOf(xany.get_window());
535 dispatchers = (Collection)winToDispatcher.get(key);
536 if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
537 dispatchers = new Vector(dispatchers);
538 }
539 }
540 if (dispatchers != null) {
541 Iterator iter = dispatchers.iterator();
542 while (iter.hasNext()) {
543 XEventDispatcher disp = (XEventDispatcher)iter.next();
544 disp.dispatchEvent(ev);
545 }
546 }
547 notifyListeners(ev);
548 }
549
573 // For now, we just avoid waitForEvents in the secondary loop.
574 if (!XlibWrapper.XNextSecondaryLoopEvent(getDisplay(),ev.pData)) {
575 break;
576 }
577 } else {
578 callTimeoutTasks();
579 // If no events are queued, waitForEvents() causes calls to
580 // awtUnlock(), awtJNI_ThreadYield, poll, awtLock(),
581 // so it spends most of its time in poll, without holding the lock.
582 while ((XlibWrapper.XEventsQueued(getDisplay(), XlibWrapper.QueuedAfterReading) == 0) &&
583 (XlibWrapper.XEventsQueued(getDisplay(), XlibWrapper.QueuedAfterFlush) == 0)) {
584 callTimeoutTasks();
585 waitForEvents(getNextTaskTime());
586 }
587 XlibWrapper.XNextEvent(getDisplay(),ev.pData);
588 }
589
590 if (ev.get_type() != NoExpose) {
591 eventNumber++;
592 }
593 if (awt_UseXKB_Calls && ev.get_type() == awt_XKBBaseEventCode) {
594 processXkbChanges(ev);
595 }
596
597 if (XDropTargetEventProcessor.processEvent(ev) ||
598 XDragSourceContextPeer.processEvent(ev)) {
599 continue;
600 }
601
602 if (eventLog.isLoggable(Level.FINER)) {
603 eventLog.log(Level.FINER, "{0}", String.valueOf(ev));
604 }
605
606 // Check if input method consumes the event
607 long w = 0;
608 if (windowToXWindow(ev.get_xany().get_window()) != null) {
609 Component owner =
610 XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
611 if (owner != null) {
612 XWindow ownerWindow = (XWindow) ComponentAccessor.getPeer(owner);
613 if (ownerWindow != null) {
614 w = ownerWindow.getContentWindow();
615 }
1092 }
1093 return false;
1094 }
1095
1096 /**
1097 * Returns the supported cursor size
1098 */
1099 public Dimension getBestCursorSize(int preferredWidth, int preferredHeight) {
1100 return XCustomCursor.getBestCursorSize(
1101 java.lang.Math.max(1,preferredWidth), java.lang.Math.max(1,preferredHeight));
1102 }
1103
1104
1105 public int getMaximumCursorColors() {
1106 return 2; // Black and white.
1107 }
1108
1109 public Map mapInputMethodHighlight(InputMethodHighlight highlight) {
1110 return XInputMethod.mapInputMethodHighlight(highlight);
1111 }
1112 @Override
1113 public boolean getLockingKeyState(int key) {
1114 if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
1115 key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
1116 throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
1117 }
1118 awtLock();
1119 try {
1120 return getModifierState( key );
1121 } finally {
1122 awtUnlock();
1123 }
1124 }
1125
1126 public Clipboard getSystemClipboard() {
1127 SecurityManager security = System.getSecurityManager();
1128 if (security != null) {
1129 security.checkSystemClipboardAccess();
1130 }
1131 synchronized (this) {
1132 if (clipboard == null) {
1133 clipboard = new XClipboard("System", "CLIPBOARD");
1134 }
1135 }
1136 return clipboard;
1137 }
1138
1139 public Clipboard getSystemSelection() {
1140 SecurityManager security = System.getSecurityManager();
1141 if (security != null) {
1142 security.checkSystemClipboardAccess();
1143 }
1144 synchronized (this) {
1381 if (isToolkitThread()) {
1382 XEvent event = new XEvent();
1383 try {
1384 XlibWrapper.XWindowEvent(XToolkit.getDisplay(),
1385 XBaseWindow.getXAWTRootWindow().getWindow(),
1386 XConstants.PropertyChangeMask,
1387 event.pData);
1388 timeFetcher.dispatchEvent(event);
1389 }
1390 finally {
1391 event.dispose();
1392 }
1393 }
1394 else {
1395 while (!timeStampUpdated) {
1396 awtLockWait();
1397 }
1398 }
1399 } catch (InterruptedException ie) {
1400 // Note: the returned timeStamp can be incorrect in this case.
1401 if (log.isLoggable(Level.FINE)) {
1402 log.fine("Catched exception, timeStamp may not be correct (ie = " + ie + ")");
1403 }
1404 }
1405 } finally {
1406 awtUnlock();
1407 }
1408 return timeStamp;
1409 }
1410 protected void initializeDesktopProperties() {
1411 desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
1412 desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50));
1413 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5));
1414 // Don't want to call getMultiClickTime() if we are headless
1415 if (!GraphicsEnvironment.isHeadless()) {
1416 desktopProperties.put("awt.multiClickInterval",
1417 Integer.valueOf(getMultiClickTime()));
1418 desktopProperties.put("awt.mouse.numButtons",
1419 Integer.valueOf(getNumMouseButtons()));
1420 }
1421 }
1422
1423 private int getNumMouseButtons() {
1512 * <code>data</code> is the byte array directly from the x server and
1513 * may be in little endian format.
1514 * <p>
1515 * NB: This could be called from any thread if triggered by
1516 * <code>loadXSettings</code>. It is called from the System EDT
1517 * if triggered by an XSETTINGS change.
1518 */
1519 void parseXSettings(int screen_XXX_ignored,Map updatedSettings) {
1520
1521 if (updatedSettings == null || updatedSettings.isEmpty()) {
1522 return;
1523 }
1524
1525 Iterator i = updatedSettings.entrySet().iterator();
1526 while (i.hasNext()) {
1527 Map.Entry e = (Map.Entry)i.next();
1528 String name = (String)e.getKey();
1529
1530 name = "gnome." + name;
1531 setDesktopProperty(name, e.getValue());
1532 if (log.isLoggable(Level.FINE)) {
1533 log.fine("name = " + name + " value = " + e.getValue());
1534 }
1535
1536 // XXX: we probably want to do something smarter. In
1537 // particular, "Net" properties are of interest to the
1538 // "core" AWT itself. E.g.
1539 //
1540 // Net/DndDragThreshold -> ???
1541 // Net/DoubleClickTime -> awt.multiClickInterval
1542 }
1543
1544 setDesktopProperty(SunToolkit.DESKTOPFONTHINTS,
1545 SunToolkit.getDesktopFontHints());
1546
1547 Integer dragThreshold = null;
1548 synchronized (this) {
1549 dragThreshold = (Integer)desktopProperties.get("gnome.Net/DndDragThreshold");
1550 }
1551 if (dragThreshold != null) {
1552 setDesktopProperty("DnD.gestureMotionThreshold", dragThreshold);
1553 }
1554
1564
1565 /* Like XKeysymToKeycode, but ensures that keysym is the primary
1566 * symbol on the keycode returned. Returns zero otherwise.
1567 */
1568 static int keysymToPrimaryKeycode(long sym) {
1569 awtLock();
1570 try {
1571 int code = XlibWrapper.XKeysymToKeycode(getDisplay(), sym);
1572 if (code == 0) {
1573 return 0;
1574 }
1575 long primary = XlibWrapper.XKeycodeToKeysym(getDisplay(), code, 0);
1576 if (sym != primary) {
1577 return 0;
1578 }
1579 return code;
1580 } finally {
1581 awtUnlock();
1582 }
1583 }
1584 static boolean getModifierState( int jkc ) {
1585 int iKeyMask = 0;
1586 long ks = XKeysym.javaKeycode2Keysym( jkc );
1587 int kc = XlibWrapper.XKeysymToKeycode(getDisplay(), ks);
1588 if (kc == 0) {
1589 return false;
1590 }
1591 awtLock();
1592 try {
1593 XModifierKeymap modmap = new XModifierKeymap(
1594 XlibWrapper.XGetModifierMapping(getDisplay()));
1595
1596 int nkeys = modmap.get_max_keypermod();
1597
1598 long map_ptr = modmap.get_modifiermap();
1599 for( int k = 0; k < 8; k++ ) {
1600 for (int i = 0; i < nkeys; ++i) {
1601 int keycode = Native.getUByte(map_ptr, k * nkeys + i);
1602 if (keycode == 0) {
1603 continue; // ignore zero keycode
1604 }
1605 if (kc == keycode) {
1606 iKeyMask = 1 << k;
1607 break;
1608 }
1609 }
1610 if( iKeyMask != 0 ) {
1611 break;
1612 }
1613 }
1614 XlibWrapper.XFreeModifiermap(modmap.pData);
1615 if (iKeyMask == 0 ) {
1616 return false;
1617 }
1618 // Now we know to which modifier is assigned the keycode
1619 // correspondent to the keysym correspondent to the java
1620 // keycode. We are going to check a state of this modifier.
1621 // If a modifier is a weird one, we cannot help it.
1622 long window = 0;
1623 try{
1624 // get any application window
1625 window = ((Long)(winMap.firstKey())).longValue();
1626 }catch(NoSuchElementException nex) {
1627 // get root window
1628 window = getDefaultRootWindow();
1629 }
1630 boolean res = XlibWrapper.XQueryPointer(getDisplay(), window,
1631 XlibWrapper.larg1, //root
1632 XlibWrapper.larg2, //child
1633 XlibWrapper.larg3, //root_x
1634 XlibWrapper.larg4, //root_y
1635 XlibWrapper.larg5, //child_x
1636 XlibWrapper.larg6, //child_y
1637 XlibWrapper.larg7);//mask
1638 int mask = Native.getInt(XlibWrapper.larg7);
1639 return ((mask & iKeyMask) != 0);
1640 } finally {
1641 awtUnlock();
1642 }
1643 }
1644
1645 /* Assign meaning - alt, meta, etc. - to X modifiers mod1 ... mod5.
1646 * Only consider primary symbols on keycodes attached to modifiers.
1647 */
1648 static void setupModifierMap() {
1649 final int metaL = keysymToPrimaryKeycode(XKeySymConstants.XK_Meta_L);
1650 final int metaR = keysymToPrimaryKeycode(XKeySymConstants.XK_Meta_R);
1651 final int altL = keysymToPrimaryKeycode(XKeySymConstants.XK_Alt_L);
1652 final int altR = keysymToPrimaryKeycode(XKeySymConstants.XK_Alt_R);
1653 final int numLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Num_Lock);
1654 final int modeSwitch = keysymToPrimaryKeycode(XKeySymConstants.XK_Mode_switch);
1655 final int shiftLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Shift_Lock);
1656 final int capsLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Caps_Lock);
1657
1658 final int modmask[] = { ShiftMask, LockMask, ControlMask, Mod1Mask,
1659 Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
1660
1661 log.fine("In setupModifierMap");
1662 awtLock();
1663 try {
2067 backingStoreType = XConstants.NotUseful;
2068
2069 if (backingStoreLog.isLoggable(Level.CONFIG)) {
2070 backingStoreLog.config("Backing store is not available on the screen " +
2071 i + ", backingStore=NotUseful");
2072 }
2073
2074 return;
2075 }
2076 }
2077 } finally {
2078 awtUnlock();
2079 }
2080 }
2081
2082 /**
2083 * One of XConstants: NotUseful, WhenMapped or Always.
2084 */
2085 private static int backingStoreType;
2086
2087 static final int XSUN_KP_BEHAVIOR = 1;
2088 static final int XORG_KP_BEHAVIOR = 2;
2089 static final int IS_SUN_KEYBOARD = 1;
2090 static final int IS_NONSUN_KEYBOARD = 2;
2091 static final int IS_KANA_KEYBOARD = 1;
2092 static final int IS_NONKANA_KEYBOARD = 2;
2093
2094
2095 static int awt_IsXsunKPBehavior = 0;
2096 static boolean awt_UseXKB = false;
2097 static boolean awt_UseXKB_Calls = false;
2098 static int awt_XKBBaseEventCode = 0;
2099 static int awt_XKBEffectiveGroup = 0; // so far, I don't use it leaving all calculations
2100 // to XkbTranslateKeyCode
2101 static long awt_XKBDescPtr = 0;
2102
2103 /**
2104 * Check for Xsun convention regarding numpad keys.
2105 * Xsun and some other servers (i.e. derived from Xsun)
2106 * under certain conditions process numpad keys unlike Xorg.
2107 */
2108 static boolean isXsunKPBehavior() {
2109 awtLock();
2110 try {
2111 if( awt_IsXsunKPBehavior == 0 ) {
2112 if( XlibWrapper.IsXsunKPBehavior(getDisplay()) ) {
2113 awt_IsXsunKPBehavior = XSUN_KP_BEHAVIOR;
2114 }else{
2115 awt_IsXsunKPBehavior = XORG_KP_BEHAVIOR;
2116 }
2117 }
2118 return awt_IsXsunKPBehavior == XSUN_KP_BEHAVIOR ? true : false;
2119 } finally {
2120 awtUnlock();
2121 }
2122 }
2123
2124 static int sunOrNotKeyboard = 0;
2125 static int kanaOrNotKeyboard = 0;
2126 static void resetKeyboardSniffer() {
2127 sunOrNotKeyboard = 0;
2128 kanaOrNotKeyboard = 0;
2129 }
2130 static boolean isSunKeyboard() {
2131 if( sunOrNotKeyboard == 0 ) {
2132 if( XlibWrapper.IsSunKeyboard( getDisplay() )) {
2133 sunOrNotKeyboard = IS_SUN_KEYBOARD;
2134 }else{
2135 sunOrNotKeyboard = IS_NONSUN_KEYBOARD;
2136 }
2137 }
2138 return (sunOrNotKeyboard == IS_SUN_KEYBOARD);
2139 }
2140 static boolean isKanaKeyboard() {
2141 if( kanaOrNotKeyboard == 0 ) {
2142 if( XlibWrapper.IsKanaKeyboard( getDisplay() )) {
2143 kanaOrNotKeyboard = IS_KANA_KEYBOARD;
2144 }else{
2145 kanaOrNotKeyboard = IS_NONKANA_KEYBOARD;
2146 }
2147 }
2148 return (kanaOrNotKeyboard == IS_KANA_KEYBOARD);
2149 }
2150 static boolean isXKBenabled() {
2151 awtLock();
2152 try {
2153 return awt_UseXKB;
2154 } finally {
2155 awtUnlock();
2156 }
2157 }
2158
2159 /**
2160 Query XKEYBOARD extension.
2161 If possible, initialize xkb library.
2162 */
2163 static boolean tryXKB() {
2164 awtLock();
2165 try {
2166 String name = "XKEYBOARD";
2167 // First, if there is extension at all.
2168 awt_UseXKB = XlibWrapper.XQueryExtension( getDisplay(), name, XlibWrapper.larg1, XlibWrapper.larg2, XlibWrapper.larg3);
2169 if( awt_UseXKB ) {
2170 // There is a keyboard extension. Check if a client library is compatible.
2171 // If not, don't use xkb calls.
2172 // In this case we still may be Xkb-capable application.
2173 awt_UseXKB_Calls = XlibWrapper.XkbLibraryVersion( XlibWrapper.larg1, XlibWrapper.larg2);
2174 if( awt_UseXKB_Calls ) {
2175 awt_UseXKB_Calls = XlibWrapper.XkbQueryExtension( getDisplay(), XlibWrapper.larg1, XlibWrapper.larg2,
2176 XlibWrapper.larg3, XlibWrapper.larg4, XlibWrapper.larg5);
2177 if( awt_UseXKB_Calls ) {
2178 awt_XKBBaseEventCode = Native.getInt(XlibWrapper.larg2);
2179 XlibWrapper.XkbSelectEvents (getDisplay(),
2180 XConstants.XkbUseCoreKbd,
2181 XConstants.XkbNewKeyboardNotifyMask |
2182 XConstants.XkbMapNotifyMask ,//|
2183 //XConstants.XkbStateNotifyMask,
2184 XConstants.XkbNewKeyboardNotifyMask |
2185 XConstants.XkbMapNotifyMask );//|
2186 //XConstants.XkbStateNotifyMask);
2187
2188 XlibWrapper.XkbSelectEventDetails(getDisplay(), XConstants.XkbUseCoreKbd,
2189 XConstants.XkbStateNotify,
2190 XConstants.XkbGroupStateMask,
2191 XConstants.XkbGroupStateMask);
2192 //XXX ? XkbGroupLockMask last, XkbAllStateComponentsMask before last?
2193 awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
2194 XConstants.XkbKeyTypesMask |
2195 XConstants.XkbKeySymsMask |
2196 XConstants.XkbModifierMapMask |
2197 XConstants.XkbVirtualModsMask,
2198 XConstants.XkbUseCoreKbd);
2199 }
2200 }
2201 }
2202 return awt_UseXKB;
2203 } finally {
2204 awtUnlock();
2205 }
2206 }
2207 static boolean canUseXKBCalls() {
2208 awtLock();
2209 try {
2210 return awt_UseXKB_Calls;
2211 } finally {
2212 awtUnlock();
2213 }
2214 }
2215 static int getXKBEffectiveGroup() {
2216 awtLock();
2217 try {
2218 return awt_XKBEffectiveGroup;
2219 } finally {
2220 awtUnlock();
2221 }
2222 }
2223 static int getXKBBaseEventCode() {
2224 awtLock();
2225 try {
2226 return awt_XKBBaseEventCode;
2227 } finally {
2228 awtUnlock();
2229 }
2230 }
2231 static long getXKBKbdDesc() {
2232 awtLock();
2233 try {
2234 return awt_XKBDescPtr;
2235 } finally {
2236 awtUnlock();
2237 }
2238 }
2239 void freeXKB() {
2240 awtLock();
2241 try {
2242 if (awt_UseXKB_Calls && awt_XKBDescPtr != 0) {
2243 XlibWrapper.XkbFreeKeyboard(awt_XKBDescPtr, 0xFF, true);
2244 }
2245 } finally {
2246 awtUnlock();
2247 }
2248 }
2249 private void processXkbChanges(XEvent ev) {
2250 // mapping change --> refresh kbd map
2251 // state change --> get a new effective group; do I really need it
2252 // or that should be left for XkbTranslateKeyCode?
2253 XkbEvent xke = new XkbEvent( ev.getPData() );
2254 int xkb_type = xke.get_any().get_xkb_type();
2255 switch( xkb_type ) {
2256 case XConstants.XkbNewKeyboardNotify :
2257 if( awt_XKBDescPtr != 0 ) {
2258 freeXKB();
2259 }
2260 awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
2261 XConstants.XkbKeyTypesMask |
2262 XConstants.XkbKeySymsMask |
2263 XConstants.XkbModifierMapMask |
2264 XConstants.XkbVirtualModsMask,
2265 XConstants.XkbUseCoreKbd);
2266 //System.out.println("XkbNewKeyboard:"+(xke.get_new_kbd()));
2267 break;
2268 case XConstants.XkbMapNotify :
2269 //TODO: provide a simple unit test.
2270 XlibWrapper.XkbGetUpdatedMap(getDisplay(),
2271 XConstants.XkbKeyTypesMask |
2272 XConstants.XkbKeySymsMask |
2273 XConstants.XkbModifierMapMask |
2274 XConstants.XkbVirtualModsMask,
2275 awt_XKBDescPtr);
2276 //System.out.println("XkbMap:"+(xke.get_map()));
2277 break;
2278 case XConstants.XkbStateNotify :
2279 // May use it later e.g. to obtain an effective group etc.
2280 //System.out.println("XkbState:"+(xke.get_state()));
2281 break;
2282 default:
2283 //System.out.println("XkbEvent of xkb_type "+xkb_type);
2284 break;
2285 }
2286 }
2287
2288 private static long eventNumber;
2289 public static long getEventNumber() {
2290 awtLock();
2291 try {
2292 return eventNumber;
2293 } finally {
2294 awtUnlock();
2295 }
2296 }
2297
2298 private static XEventDispatcher oops_waiter;
2299 private static boolean oops_updated;
2300 private static boolean oops_failed;
2301 private XAtom oops;
2302 private static final long WORKAROUND_SLEEP = 100;
2303
2304 /**
2305 * @inheritDoc
2306 */
2326 }
2327
2328 }
2329 }
2330 };
2331 }
2332
2333 if (oops == null) {
2334 oops = XAtom.get("OOPS");
2335 }
2336
2337 awtLock();
2338 try {
2339 addEventDispatcher(win.getWindow(), oops_waiter);
2340
2341 oops_updated = false;
2342 oops_failed = false;
2343 // Wait for selection notify for oops on win
2344 long event_number = getEventNumber();
2345 XAtom atom = XAtom.get("WM_S0");
2346 if (eventLog.isLoggable(Level.FINER)) {
2347 eventLog.log(Level.FINER, "WM_S0 selection owner {0}",
2348 new Object[] {XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom())});
2349 }
2350 XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(),
2351 XAtom.get("VERSION").getAtom(), oops.getAtom(),
2352 win.getWindow(), XlibWrapper.CurrentTime);
2353 XSync();
2354
2355
2356 eventLog.finer("Requested OOPS");
2357
2358 long start = System.currentTimeMillis();
2359 while (!oops_updated && !oops_failed) {
2360 try {
2361 awtLockWait(timeout);
2362 } catch (InterruptedException e) {
2363 throw new RuntimeException(e);
2364 }
2365 // This "while" is a protection from spurious
2366 // wake-ups. However, we shouldn't wait for too long
2367 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {
2368 throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
2369 }
2370 }
2371 if (oops_failed && getEventNumber() - event_number == 1) {
2372 // If selection update failed we can simply wait some time
2373 // hoping some events will arrive
2374 awtUnlock();
2375 if (eventLog.isLoggable(Level.FINEST)) {
2376 eventLog.log(Level.FINEST, "Emergency sleep");
2377 }
2378 try {
2379 Thread.sleep(WORKAROUND_SLEEP);
2380 } catch (InterruptedException ie) {
2381 throw new RuntimeException(ie);
2382 } finally {
2383 awtLock();
2384 }
2385 }
2386 return getEventNumber() - event_number > 2;
2387 } finally {
2388 removeEventDispatcher(win.getWindow(), oops_waiter);
2389 if (eventLog.isLoggable(Level.FINER)) {
2390 eventLog.log(Level.FINER, "Exiting syncNativeQueue");
2391 }
2392 awtUnlock();
2393 }
2394 }
2395 public void grab(Window w) {
2396 if (w.getPeer() != null) {
2397 ((XWindowPeer)w.getPeer()).setGrab(true);
2398 }
2399 }
2400
2401 public void ungrab(Window w) {
2402 if (w.getPeer() != null) {
2403 ((XWindowPeer)w.getPeer()).setGrab(false);
2404 }
2405 }
2406 /**
2407 * Returns if the java.awt.Desktop class is supported on the current
2408 * desktop.
2409 * <p>
2410 * The methods of java.awt.Desktop class are supported on the Gnome desktop.
2411 * Check if the running desktop is Gnome by checking the window manager.
|