249 awtUnlock();
250 }
251 PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
252 public Void run() {
253 ThreadGroup mainTG = Thread.currentThread().getThreadGroup();
254 ThreadGroup parentTG = mainTG.getParent();
255 while (parentTG != null) {
256 mainTG = parentTG;
257 parentTG = mainTG.getParent();
258 }
259 Thread shutdownThread = new Thread(mainTG, "XToolkt-Shutdown-Thread") {
260 public void run() {
261 XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
262 if (peer != null) {
263 peer.dispose();
264 }
265 if (xs != null) {
266 ((XAWTXSettings)xs).dispose();
267 }
268 freeXKB();
269 if (log.isLoggable(PlatformLogger.FINE)) {
270 dumpPeers();
271 }
272 }
273 };
274 shutdownThread.setContextClassLoader(null);
275 Runtime.getRuntime().addShutdownHook(shutdownThread);
276 return null;
277 }
278 };
279 AccessController.doPrivileged(a);
280 }
281
282 static String getCorrectXIDString(String val) {
283 if (val != null) {
284 return val.replace('.', '-');
285 } else {
286 return val;
287 }
288 }
289
507
508 Collection dispatchers = null;
509 synchronized(winToDispatcher) {
510 Long key = Long.valueOf(xany.get_window());
511 dispatchers = (Collection)winToDispatcher.get(key);
512 if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
513 dispatchers = new Vector(dispatchers);
514 }
515 }
516 if (dispatchers != null) {
517 Iterator iter = dispatchers.iterator();
518 while (iter.hasNext()) {
519 XEventDispatcher disp = (XEventDispatcher)iter.next();
520 disp.dispatchEvent(ev);
521 }
522 }
523 notifyListeners(ev);
524 }
525
526 static void processException(Throwable thr) {
527 if (log.isLoggable(PlatformLogger.WARNING)) {
528 log.warning("Exception on Toolkit thread", thr);
529 }
530 }
531
532 static native void awt_toolkit_init();
533
534 public void run() {
535 awt_toolkit_init();
536 run(PRIMARY_LOOP);
537 }
538
539 public void run(boolean loop)
540 {
541 XEvent ev = new XEvent();
542 while(true) {
543 // Fix for 6829923: we should gracefully handle toolkit thread interruption
544 if (Thread.currentThread().isInterrupted()) {
545 // We expect interruption from the AppContext.dispose() method only.
546 // If the thread is interrupted from another place, let's skip it
547 // for compatibility reasons. Probably some time later we'll remove
569 while ((XlibWrapper.XEventsQueued(getDisplay(), XConstants.QueuedAfterReading) == 0) &&
570 (XlibWrapper.XEventsQueued(getDisplay(), XConstants.QueuedAfterFlush) == 0)) {
571 callTimeoutTasks();
572 waitForEvents(getNextTaskTime());
573 }
574 XlibWrapper.XNextEvent(getDisplay(),ev.pData);
575 }
576
577 if (ev.get_type() != XConstants.NoExpose) {
578 eventNumber++;
579 }
580 if (awt_UseXKB_Calls && ev.get_type() == awt_XKBBaseEventCode) {
581 processXkbChanges(ev);
582 }
583
584 if (XDropTargetEventProcessor.processEvent(ev) ||
585 XDragSourceContextPeer.processEvent(ev)) {
586 continue;
587 }
588
589 if (eventLog.isLoggable(PlatformLogger.FINER)) {
590 eventLog.finer("{0}", ev);
591 }
592
593 // Check if input method consumes the event
594 long w = 0;
595 if (windowToXWindow(ev.get_xany().get_window()) != null) {
596 Component owner =
597 XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
598 if (owner != null) {
599 XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
600 if (ownerWindow != null) {
601 w = ownerWindow.getContentWindow();
602 }
603 }
604 }
605 if( keyEventLog.isLoggable(PlatformLogger.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) {
606 keyEventLog.fine("before XFilterEvent:"+ev);
607 }
608 if (XlibWrapper.XFilterEvent(ev.getPData(), w)) {
609 continue;
610 }
611 if( keyEventLog.isLoggable(PlatformLogger.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) {
612 keyEventLog.fine("after XFilterEvent:"+ev); // IS THIS CORRECT?
613 }
614
615 dispatchEvent(ev);
616 } catch (ThreadDeath td) {
617 XBaseWindow.ungrabInput();
618 return;
619 } catch (Throwable thr) {
620 XBaseWindow.ungrabInput();
621 processException(thr);
622 } finally {
623 awtUnlock();
624 }
625 }
626 }
627
628 static {
629 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
630 if (ge instanceof SunGraphicsEnvironment) {
631 ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
1304 }
1305 } finally {
1306 awtUnlock();
1307 }
1308 if (awt_multiclick_time == 0) {
1309 awt_multiclick_time = AWT_MULTICLICK_DEFAULT_TIME;
1310 }
1311 }
1312
1313 public boolean isFrameStateSupported(int state)
1314 throws HeadlessException
1315 {
1316 if (state == Frame.NORMAL || state == Frame.ICONIFIED) {
1317 return true;
1318 } else {
1319 return XWM.getWM().supportsExtendedState(state);
1320 }
1321 }
1322
1323 static void dumpPeers() {
1324 if (log.isLoggable(PlatformLogger.FINE)) {
1325 log.fine("Mapped windows:");
1326 Iterator iter = winMap.entrySet().iterator();
1327 while (iter.hasNext()) {
1328 Map.Entry entry = (Map.Entry)iter.next();
1329 log.fine(entry.getKey() + "->" + entry.getValue());
1330 if (entry.getValue() instanceof XComponentPeer) {
1331 Component target = (Component)((XComponentPeer)entry.getValue()).getTarget();
1332 log.fine("\ttarget: " + target);
1333 }
1334 }
1335
1336 SunToolkit.dumpPeers(log);
1337
1338 log.fine("Mapped special peers:");
1339 iter = specialPeerMap.entrySet().iterator();
1340 while (iter.hasNext()) {
1341 Map.Entry entry = (Map.Entry)iter.next();
1342 log.fine(entry.getKey() + "->" + entry.getValue());
1343 }
1344
1400 if (isToolkitThread()) {
1401 XEvent event = new XEvent();
1402 try {
1403 XlibWrapper.XWindowEvent(XToolkit.getDisplay(),
1404 XBaseWindow.getXAWTRootWindow().getWindow(),
1405 XConstants.PropertyChangeMask,
1406 event.pData);
1407 timeFetcher.dispatchEvent(event);
1408 }
1409 finally {
1410 event.dispose();
1411 }
1412 }
1413 else {
1414 while (!timeStampUpdated) {
1415 awtLockWait();
1416 }
1417 }
1418 } catch (InterruptedException ie) {
1419 // Note: the returned timeStamp can be incorrect in this case.
1420 if (log.isLoggable(PlatformLogger.FINE)) {
1421 log.fine("Catched exception, timeStamp may not be correct (ie = " + ie + ")");
1422 }
1423 }
1424 } finally {
1425 awtUnlock();
1426 }
1427 return timeStamp;
1428 }
1429 protected void initializeDesktopProperties() {
1430 desktopProperties.put("DnD.Autoscroll.initialDelay",
1431 Integer.valueOf(50));
1432 desktopProperties.put("DnD.Autoscroll.interval",
1433 Integer.valueOf(50));
1434 desktopProperties.put("DnD.Autoscroll.cursorHysteresis",
1435 Integer.valueOf(5));
1436 desktopProperties.put("Shell.shellFolderManager",
1437 "sun.awt.shell.ShellFolderManager");
1438 // Don't want to call getMultiClickTime() if we are headless
1439 if (!GraphicsEnvironment.isHeadless()) {
1440 desktopProperties.put("awt.multiClickInterval",
1567 * <code>data</code> is the byte array directly from the x server and
1568 * may be in little endian format.
1569 * <p>
1570 * NB: This could be called from any thread if triggered by
1571 * <code>loadXSettings</code>. It is called from the System EDT
1572 * if triggered by an XSETTINGS change.
1573 */
1574 void parseXSettings(int screen_XXX_ignored,Map updatedSettings) {
1575
1576 if (updatedSettings == null || updatedSettings.isEmpty()) {
1577 return;
1578 }
1579
1580 Iterator i = updatedSettings.entrySet().iterator();
1581 while (i.hasNext()) {
1582 Map.Entry e = (Map.Entry)i.next();
1583 String name = (String)e.getKey();
1584
1585 name = "gnome." + name;
1586 setDesktopProperty(name, e.getValue());
1587 if (log.isLoggable(PlatformLogger.FINE)) {
1588 log.fine("name = " + name + " value = " + e.getValue());
1589 }
1590
1591 // XXX: we probably want to do something smarter. In
1592 // particular, "Net" properties are of interest to the
1593 // "core" AWT itself. E.g.
1594 //
1595 // Net/DndDragThreshold -> ???
1596 // Net/DoubleClickTime -> awt.multiClickInterval
1597 }
1598
1599 setDesktopProperty(SunToolkit.DESKTOPFONTHINTS,
1600 SunToolkit.getDesktopFontHints());
1601
1602 Integer dragThreshold = null;
1603 synchronized (this) {
1604 dragThreshold = (Integer)desktopProperties.get("gnome.Net/DndDragThreshold");
1605 }
1606 if (dragThreshold != null) {
1607 setDesktopProperty("DnD.gestureMotionThreshold", dragThreshold);
1756 }
1757 }
1758 modLockIsShiftLock = 0;
1759 for (int j = 0; j < nkeys; ++j) {
1760 int keycode = Native.getUByte(map_ptr, XConstants.LockMapIndex * nkeys + j);
1761 if (keycode == 0) {
1762 break;
1763 }
1764 if (keycode == shiftLock) {
1765 modLockIsShiftLock = 1;
1766 break;
1767 }
1768 if (keycode == capsLock) {
1769 break;
1770 }
1771 }
1772 XlibWrapper.XFreeModifiermap(modmap.pData);
1773 } finally {
1774 awtUnlock();
1775 }
1776 if (log.isLoggable(PlatformLogger.FINE)) {
1777 log.fine("metaMask = " + metaMask);
1778 log.fine("altMask = " + altMask);
1779 log.fine("numLockMask = " + numLockMask);
1780 log.fine("modeSwitchMask = " + modeSwitchMask);
1781 log.fine("modLockIsShiftLock = " + modLockIsShiftLock);
1782 }
1783 }
1784
1785
1786 private static SortedMap timeoutTasks;
1787
1788 /**
1789 * Removed the task from the list of waiting-to-be called tasks.
1790 * If the task has been scheduled several times removes only first one.
1791 */
1792 static void remove(Runnable task) {
1793 if (task == null) {
1794 throw new NullPointerException("task is null");
1795 }
1796 awtLock();
1797 try {
1798 if (timeoutTaskLog.isLoggable(PlatformLogger.FINER)) {
1799 timeoutTaskLog.finer("Removing task " + task);
1800 }
1801 if (timeoutTasks == null) {
1802 if (timeoutTaskLog.isLoggable(PlatformLogger.FINER)) {
1803 timeoutTaskLog.finer("Task is not scheduled");
1804 }
1805 return;
1806 }
1807 Collection values = timeoutTasks.values();
1808 Iterator iter = values.iterator();
1809 while (iter.hasNext()) {
1810 java.util.List list = (java.util.List)iter.next();
1811 boolean removed = false;
1812 if (list.contains(task)) {
1813 list.remove(task);
1814 if (list.isEmpty()) {
1815 iter.remove();
1816 }
1817 break;
1818 }
1819 }
1820 } finally {
1821 awtUnlock();
1822 }
1829 * once on the toolkit thread when a specified interval of time elapses.
1830 *
1831 * @param task a Runnable which <code>run</code> method will be called
1832 * on the toolkit thread when <code>interval</code> milliseconds
1833 * elapse
1834 * @param interval an interal in milliseconds
1835 *
1836 * @throws NullPointerException if <code>task</code> is <code>null</code>
1837 * @throws IllegalArgumentException if <code>interval</code> is not positive
1838 */
1839 static void schedule(Runnable task, long interval) {
1840 if (task == null) {
1841 throw new NullPointerException("task is null");
1842 }
1843 if (interval <= 0) {
1844 throw new IllegalArgumentException("interval " + interval + " is not positive");
1845 }
1846
1847 awtLock();
1848 try {
1849 if (timeoutTaskLog.isLoggable(PlatformLogger.FINER)) {
1850 timeoutTaskLog.finer("XToolkit.schedule(): current time={0}" +
1851 "; interval={1}" +
1852 "; task being added={2}" + "; tasks before addition={3}",
1853 Long.valueOf(System.currentTimeMillis()), Long.valueOf(interval), task, timeoutTasks);
1854 }
1855
1856 if (timeoutTasks == null) {
1857 timeoutTasks = new TreeMap();
1858 }
1859
1860 Long time = Long.valueOf(System.currentTimeMillis() + interval);
1861 java.util.List tasks = (java.util.List)timeoutTasks.get(time);
1862 if (tasks == null) {
1863 tasks = new ArrayList(1);
1864 timeoutTasks.put(time, tasks);
1865 }
1866 tasks.add(task);
1867
1868
1869 if (timeoutTasks.get(timeoutTasks.firstKey()) == tasks && tasks.size() == 1) {
1876 }
1877 }
1878
1879 private long getNextTaskTime() {
1880 awtLock();
1881 try {
1882 if (timeoutTasks == null || timeoutTasks.isEmpty()) {
1883 return -1L;
1884 }
1885 return (Long)timeoutTasks.firstKey();
1886 } finally {
1887 awtUnlock();
1888 }
1889 }
1890
1891 /**
1892 * Executes mature timeout tasks registered with schedule().
1893 * Called from run() under awtLock.
1894 */
1895 private static void callTimeoutTasks() {
1896 if (timeoutTaskLog.isLoggable(PlatformLogger.FINER)) {
1897 timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" +
1898 "; tasks={1}", Long.valueOf(System.currentTimeMillis()), timeoutTasks);
1899 }
1900
1901 if (timeoutTasks == null || timeoutTasks.isEmpty()) {
1902 return;
1903 }
1904
1905 Long currentTime = Long.valueOf(System.currentTimeMillis());
1906 Long time = (Long)timeoutTasks.firstKey();
1907
1908 while (time.compareTo(currentTime) <= 0) {
1909 java.util.List tasks = (java.util.List)timeoutTasks.remove(time);
1910
1911 for (Iterator iter = tasks.iterator(); iter.hasNext();) {
1912 Runnable task = (Runnable)iter.next();
1913
1914 if (timeoutTaskLog.isLoggable(PlatformLogger.FINER)) {
1915 timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" +
1916 "; about to run task={1}", Long.valueOf(currentTime), task);
1917 }
1918
1919 try {
1920 task.run();
1921 } catch (ThreadDeath td) {
1922 throw td;
1923 } catch (Throwable thr) {
1924 processException(thr);
1925 }
1926 }
1927
1928 if (timeoutTasks.isEmpty()) {
1929 break;
1930 }
1931 time = (Long)timeoutTasks.firstKey();
1932 }
1933 }
1934
1969
1970 static long reset_time_utc;
1971 static final long WRAP_TIME_MILLIS = 0x00000000FFFFFFFFL;
1972
1973 /*
1974 * This function converts between the X server time (number of milliseconds
1975 * since the last server reset) and the UTC time for the 'when' field of an
1976 * InputEvent (or another event type with a timestamp).
1977 */
1978 static long nowMillisUTC_offset(long server_offset) {
1979 // ported from awt_util.c
1980 /*
1981 * Because Time is of type 'unsigned long', it is possible that Time will
1982 * never wrap when using 64-bit Xlib. However, if a 64-bit client
1983 * connects to a 32-bit server, I suspect the values will still wrap. So
1984 * we should not attempt to remove the wrap checking even if _LP64 is
1985 * true.
1986 */
1987
1988 long current_time_utc = System.currentTimeMillis();
1989 if (log.isLoggable(PlatformLogger.FINER)) {
1990 log.finer("reset_time=" + reset_time_utc + ", current_time=" + current_time_utc
1991 + ", server_offset=" + server_offset + ", wrap_time=" + WRAP_TIME_MILLIS);
1992 }
1993
1994 if ((current_time_utc - reset_time_utc) > WRAP_TIME_MILLIS) {
1995 reset_time_utc = System.currentTimeMillis() - getCurrentServerTime();
1996 }
1997
1998 if (log.isLoggable(PlatformLogger.FINER)) {
1999 log.finer("result = " + (reset_time_utc + server_offset));
2000 }
2001 return reset_time_utc + server_offset;
2002 }
2003
2004 /**
2005 * @see sun.awt.SunToolkit#needsXEmbedImpl
2006 */
2007 protected boolean needsXEmbedImpl() {
2008 // XToolkit implements supports for XEmbed-client protocol and
2009 // requires the supports from the embedding host for it to work.
2010 return true;
2011 }
2012
2013 public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
2014 return (modalityType == null) ||
2015 (modalityType == Dialog.ModalityType.MODELESS) ||
2016 (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
2017 (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
2018 (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
2057 * Returns one of XConstants: NotUseful, WhenMapped or Always.
2058 * If backing store is not available on at least one screen, or
2059 * java2d uses DGA(which conflicts with backing store) on at least one screen,
2060 * or the string system property "sun.awt.backingStore" is neither "Always"
2061 * nor "WhenMapped", then the method returns XConstants.NotUseful.
2062 * Otherwise, if the system property "sun.awt.backingStore" is "WhenMapped",
2063 * then the method returns XConstants.WhenMapped.
2064 * Otherwise (i.e., if the system property "sun.awt.backingStore" is "Always"),
2065 * the method returns XConstants.Always.
2066 */
2067 static int getBackingStoreType() {
2068 return backingStoreType;
2069 }
2070
2071 private static void setBackingStoreType() {
2072 String prop = (String)AccessController.doPrivileged(
2073 new sun.security.action.GetPropertyAction("sun.awt.backingStore"));
2074
2075 if (prop == null) {
2076 backingStoreType = XConstants.NotUseful;
2077 if (backingStoreLog.isLoggable(PlatformLogger.CONFIG)) {
2078 backingStoreLog.config("The system property sun.awt.backingStore is not set" +
2079 ", by default backingStore=NotUseful");
2080 }
2081 return;
2082 }
2083
2084 if (backingStoreLog.isLoggable(PlatformLogger.CONFIG)) {
2085 backingStoreLog.config("The system property sun.awt.backingStore is " + prop);
2086 }
2087 prop = prop.toLowerCase();
2088 if (prop.equals("always")) {
2089 backingStoreType = XConstants.Always;
2090 } else if (prop.equals("whenmapped")) {
2091 backingStoreType = XConstants.WhenMapped;
2092 } else {
2093 backingStoreType = XConstants.NotUseful;
2094 }
2095
2096 if (backingStoreLog.isLoggable(PlatformLogger.CONFIG)) {
2097 backingStoreLog.config("backingStore(as provided by the system property)=" +
2098 ( backingStoreType == XConstants.NotUseful ? "NotUseful"
2099 : backingStoreType == XConstants.WhenMapped ?
2100 "WhenMapped" : "Always") );
2101 }
2102
2103 if (sun.java2d.x11.X11SurfaceData.isDgaAvailable()) {
2104 backingStoreType = XConstants.NotUseful;
2105
2106 if (backingStoreLog.isLoggable(PlatformLogger.CONFIG)) {
2107 backingStoreLog.config("DGA is available, backingStore=NotUseful");
2108 }
2109
2110 return;
2111 }
2112
2113 awtLock();
2114 try {
2115 int screenCount = XlibWrapper.ScreenCount(getDisplay());
2116 for (int i = 0; i < screenCount; i++) {
2117 if (XlibWrapper.DoesBackingStore(XlibWrapper.ScreenOfDisplay(getDisplay(), i))
2118 == XConstants.NotUseful) {
2119 backingStoreType = XConstants.NotUseful;
2120
2121 if (backingStoreLog.isLoggable(PlatformLogger.CONFIG)) {
2122 backingStoreLog.config("Backing store is not available on the screen " +
2123 i + ", backingStore=NotUseful");
2124 }
2125
2126 return;
2127 }
2128 }
2129 } finally {
2130 awtUnlock();
2131 }
2132 }
2133
2134 /**
2135 * One of XConstants: NotUseful, WhenMapped or Always.
2136 */
2137 private static int backingStoreType;
2138
2139 static final int XSUN_KP_BEHAVIOR = 1;
2140 static final int XORG_KP_BEHAVIOR = 2;
2141 static final int IS_SUN_KEYBOARD = 1;
2379 }
2380
2381 }
2382 }
2383 };
2384 }
2385
2386 if (oops == null) {
2387 oops = XAtom.get("OOPS");
2388 }
2389
2390 awtLock();
2391 try {
2392 addEventDispatcher(win.getWindow(), oops_waiter);
2393
2394 oops_updated = false;
2395 oops_failed = false;
2396 // Wait for selection notify for oops on win
2397 long event_number = getEventNumber();
2398 XAtom atom = XAtom.get("WM_S0");
2399 if (eventLog.isLoggable(PlatformLogger.FINER)) {
2400 eventLog.finer("WM_S0 selection owner {0}", XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom()));
2401 }
2402 XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(),
2403 XAtom.get("VERSION").getAtom(), oops.getAtom(),
2404 win.getWindow(), XConstants.CurrentTime);
2405 XSync();
2406
2407 eventLog.finer("Requested OOPS");
2408
2409 long start = System.currentTimeMillis();
2410 while (!oops_updated && !oops_failed) {
2411 try {
2412 awtLockWait(timeout);
2413 } catch (InterruptedException e) {
2414 throw new RuntimeException(e);
2415 }
2416 // This "while" is a protection from spurious
2417 // wake-ups. However, we shouldn't wait for too long
2418 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {
2419 throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
|
249 awtUnlock();
250 }
251 PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
252 public Void run() {
253 ThreadGroup mainTG = Thread.currentThread().getThreadGroup();
254 ThreadGroup parentTG = mainTG.getParent();
255 while (parentTG != null) {
256 mainTG = parentTG;
257 parentTG = mainTG.getParent();
258 }
259 Thread shutdownThread = new Thread(mainTG, "XToolkt-Shutdown-Thread") {
260 public void run() {
261 XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
262 if (peer != null) {
263 peer.dispose();
264 }
265 if (xs != null) {
266 ((XAWTXSettings)xs).dispose();
267 }
268 freeXKB();
269 if (log.isLoggable(PlatformLogger.Level.FINE)) {
270 dumpPeers();
271 }
272 }
273 };
274 shutdownThread.setContextClassLoader(null);
275 Runtime.getRuntime().addShutdownHook(shutdownThread);
276 return null;
277 }
278 };
279 AccessController.doPrivileged(a);
280 }
281
282 static String getCorrectXIDString(String val) {
283 if (val != null) {
284 return val.replace('.', '-');
285 } else {
286 return val;
287 }
288 }
289
507
508 Collection dispatchers = null;
509 synchronized(winToDispatcher) {
510 Long key = Long.valueOf(xany.get_window());
511 dispatchers = (Collection)winToDispatcher.get(key);
512 if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
513 dispatchers = new Vector(dispatchers);
514 }
515 }
516 if (dispatchers != null) {
517 Iterator iter = dispatchers.iterator();
518 while (iter.hasNext()) {
519 XEventDispatcher disp = (XEventDispatcher)iter.next();
520 disp.dispatchEvent(ev);
521 }
522 }
523 notifyListeners(ev);
524 }
525
526 static void processException(Throwable thr) {
527 if (log.isLoggable(PlatformLogger.Level.WARNING)) {
528 log.warning("Exception on Toolkit thread", thr);
529 }
530 }
531
532 static native void awt_toolkit_init();
533
534 public void run() {
535 awt_toolkit_init();
536 run(PRIMARY_LOOP);
537 }
538
539 public void run(boolean loop)
540 {
541 XEvent ev = new XEvent();
542 while(true) {
543 // Fix for 6829923: we should gracefully handle toolkit thread interruption
544 if (Thread.currentThread().isInterrupted()) {
545 // We expect interruption from the AppContext.dispose() method only.
546 // If the thread is interrupted from another place, let's skip it
547 // for compatibility reasons. Probably some time later we'll remove
569 while ((XlibWrapper.XEventsQueued(getDisplay(), XConstants.QueuedAfterReading) == 0) &&
570 (XlibWrapper.XEventsQueued(getDisplay(), XConstants.QueuedAfterFlush) == 0)) {
571 callTimeoutTasks();
572 waitForEvents(getNextTaskTime());
573 }
574 XlibWrapper.XNextEvent(getDisplay(),ev.pData);
575 }
576
577 if (ev.get_type() != XConstants.NoExpose) {
578 eventNumber++;
579 }
580 if (awt_UseXKB_Calls && ev.get_type() == awt_XKBBaseEventCode) {
581 processXkbChanges(ev);
582 }
583
584 if (XDropTargetEventProcessor.processEvent(ev) ||
585 XDragSourceContextPeer.processEvent(ev)) {
586 continue;
587 }
588
589 if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
590 eventLog.finer("{0}", ev);
591 }
592
593 // Check if input method consumes the event
594 long w = 0;
595 if (windowToXWindow(ev.get_xany().get_window()) != null) {
596 Component owner =
597 XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
598 if (owner != null) {
599 XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
600 if (ownerWindow != null) {
601 w = ownerWindow.getContentWindow();
602 }
603 }
604 }
605 if( keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) {
606 keyEventLog.fine("before XFilterEvent:"+ev);
607 }
608 if (XlibWrapper.XFilterEvent(ev.getPData(), w)) {
609 continue;
610 }
611 if( keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) {
612 keyEventLog.fine("after XFilterEvent:"+ev); // IS THIS CORRECT?
613 }
614
615 dispatchEvent(ev);
616 } catch (ThreadDeath td) {
617 XBaseWindow.ungrabInput();
618 return;
619 } catch (Throwable thr) {
620 XBaseWindow.ungrabInput();
621 processException(thr);
622 } finally {
623 awtUnlock();
624 }
625 }
626 }
627
628 static {
629 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
630 if (ge instanceof SunGraphicsEnvironment) {
631 ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
1304 }
1305 } finally {
1306 awtUnlock();
1307 }
1308 if (awt_multiclick_time == 0) {
1309 awt_multiclick_time = AWT_MULTICLICK_DEFAULT_TIME;
1310 }
1311 }
1312
1313 public boolean isFrameStateSupported(int state)
1314 throws HeadlessException
1315 {
1316 if (state == Frame.NORMAL || state == Frame.ICONIFIED) {
1317 return true;
1318 } else {
1319 return XWM.getWM().supportsExtendedState(state);
1320 }
1321 }
1322
1323 static void dumpPeers() {
1324 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1325 log.fine("Mapped windows:");
1326 Iterator iter = winMap.entrySet().iterator();
1327 while (iter.hasNext()) {
1328 Map.Entry entry = (Map.Entry)iter.next();
1329 log.fine(entry.getKey() + "->" + entry.getValue());
1330 if (entry.getValue() instanceof XComponentPeer) {
1331 Component target = (Component)((XComponentPeer)entry.getValue()).getTarget();
1332 log.fine("\ttarget: " + target);
1333 }
1334 }
1335
1336 SunToolkit.dumpPeers(log);
1337
1338 log.fine("Mapped special peers:");
1339 iter = specialPeerMap.entrySet().iterator();
1340 while (iter.hasNext()) {
1341 Map.Entry entry = (Map.Entry)iter.next();
1342 log.fine(entry.getKey() + "->" + entry.getValue());
1343 }
1344
1400 if (isToolkitThread()) {
1401 XEvent event = new XEvent();
1402 try {
1403 XlibWrapper.XWindowEvent(XToolkit.getDisplay(),
1404 XBaseWindow.getXAWTRootWindow().getWindow(),
1405 XConstants.PropertyChangeMask,
1406 event.pData);
1407 timeFetcher.dispatchEvent(event);
1408 }
1409 finally {
1410 event.dispose();
1411 }
1412 }
1413 else {
1414 while (!timeStampUpdated) {
1415 awtLockWait();
1416 }
1417 }
1418 } catch (InterruptedException ie) {
1419 // Note: the returned timeStamp can be incorrect in this case.
1420 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1421 log.fine("Catched exception, timeStamp may not be correct (ie = " + ie + ")");
1422 }
1423 }
1424 } finally {
1425 awtUnlock();
1426 }
1427 return timeStamp;
1428 }
1429 protected void initializeDesktopProperties() {
1430 desktopProperties.put("DnD.Autoscroll.initialDelay",
1431 Integer.valueOf(50));
1432 desktopProperties.put("DnD.Autoscroll.interval",
1433 Integer.valueOf(50));
1434 desktopProperties.put("DnD.Autoscroll.cursorHysteresis",
1435 Integer.valueOf(5));
1436 desktopProperties.put("Shell.shellFolderManager",
1437 "sun.awt.shell.ShellFolderManager");
1438 // Don't want to call getMultiClickTime() if we are headless
1439 if (!GraphicsEnvironment.isHeadless()) {
1440 desktopProperties.put("awt.multiClickInterval",
1567 * <code>data</code> is the byte array directly from the x server and
1568 * may be in little endian format.
1569 * <p>
1570 * NB: This could be called from any thread if triggered by
1571 * <code>loadXSettings</code>. It is called from the System EDT
1572 * if triggered by an XSETTINGS change.
1573 */
1574 void parseXSettings(int screen_XXX_ignored,Map updatedSettings) {
1575
1576 if (updatedSettings == null || updatedSettings.isEmpty()) {
1577 return;
1578 }
1579
1580 Iterator i = updatedSettings.entrySet().iterator();
1581 while (i.hasNext()) {
1582 Map.Entry e = (Map.Entry)i.next();
1583 String name = (String)e.getKey();
1584
1585 name = "gnome." + name;
1586 setDesktopProperty(name, e.getValue());
1587 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1588 log.fine("name = " + name + " value = " + e.getValue());
1589 }
1590
1591 // XXX: we probably want to do something smarter. In
1592 // particular, "Net" properties are of interest to the
1593 // "core" AWT itself. E.g.
1594 //
1595 // Net/DndDragThreshold -> ???
1596 // Net/DoubleClickTime -> awt.multiClickInterval
1597 }
1598
1599 setDesktopProperty(SunToolkit.DESKTOPFONTHINTS,
1600 SunToolkit.getDesktopFontHints());
1601
1602 Integer dragThreshold = null;
1603 synchronized (this) {
1604 dragThreshold = (Integer)desktopProperties.get("gnome.Net/DndDragThreshold");
1605 }
1606 if (dragThreshold != null) {
1607 setDesktopProperty("DnD.gestureMotionThreshold", dragThreshold);
1756 }
1757 }
1758 modLockIsShiftLock = 0;
1759 for (int j = 0; j < nkeys; ++j) {
1760 int keycode = Native.getUByte(map_ptr, XConstants.LockMapIndex * nkeys + j);
1761 if (keycode == 0) {
1762 break;
1763 }
1764 if (keycode == shiftLock) {
1765 modLockIsShiftLock = 1;
1766 break;
1767 }
1768 if (keycode == capsLock) {
1769 break;
1770 }
1771 }
1772 XlibWrapper.XFreeModifiermap(modmap.pData);
1773 } finally {
1774 awtUnlock();
1775 }
1776 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1777 log.fine("metaMask = " + metaMask);
1778 log.fine("altMask = " + altMask);
1779 log.fine("numLockMask = " + numLockMask);
1780 log.fine("modeSwitchMask = " + modeSwitchMask);
1781 log.fine("modLockIsShiftLock = " + modLockIsShiftLock);
1782 }
1783 }
1784
1785
1786 private static SortedMap timeoutTasks;
1787
1788 /**
1789 * Removed the task from the list of waiting-to-be called tasks.
1790 * If the task has been scheduled several times removes only first one.
1791 */
1792 static void remove(Runnable task) {
1793 if (task == null) {
1794 throw new NullPointerException("task is null");
1795 }
1796 awtLock();
1797 try {
1798 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
1799 timeoutTaskLog.finer("Removing task " + task);
1800 }
1801 if (timeoutTasks == null) {
1802 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
1803 timeoutTaskLog.finer("Task is not scheduled");
1804 }
1805 return;
1806 }
1807 Collection values = timeoutTasks.values();
1808 Iterator iter = values.iterator();
1809 while (iter.hasNext()) {
1810 java.util.List list = (java.util.List)iter.next();
1811 boolean removed = false;
1812 if (list.contains(task)) {
1813 list.remove(task);
1814 if (list.isEmpty()) {
1815 iter.remove();
1816 }
1817 break;
1818 }
1819 }
1820 } finally {
1821 awtUnlock();
1822 }
1829 * once on the toolkit thread when a specified interval of time elapses.
1830 *
1831 * @param task a Runnable which <code>run</code> method will be called
1832 * on the toolkit thread when <code>interval</code> milliseconds
1833 * elapse
1834 * @param interval an interal in milliseconds
1835 *
1836 * @throws NullPointerException if <code>task</code> is <code>null</code>
1837 * @throws IllegalArgumentException if <code>interval</code> is not positive
1838 */
1839 static void schedule(Runnable task, long interval) {
1840 if (task == null) {
1841 throw new NullPointerException("task is null");
1842 }
1843 if (interval <= 0) {
1844 throw new IllegalArgumentException("interval " + interval + " is not positive");
1845 }
1846
1847 awtLock();
1848 try {
1849 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
1850 timeoutTaskLog.finer("XToolkit.schedule(): current time={0}" +
1851 "; interval={1}" +
1852 "; task being added={2}" + "; tasks before addition={3}",
1853 Long.valueOf(System.currentTimeMillis()), Long.valueOf(interval), task, timeoutTasks);
1854 }
1855
1856 if (timeoutTasks == null) {
1857 timeoutTasks = new TreeMap();
1858 }
1859
1860 Long time = Long.valueOf(System.currentTimeMillis() + interval);
1861 java.util.List tasks = (java.util.List)timeoutTasks.get(time);
1862 if (tasks == null) {
1863 tasks = new ArrayList(1);
1864 timeoutTasks.put(time, tasks);
1865 }
1866 tasks.add(task);
1867
1868
1869 if (timeoutTasks.get(timeoutTasks.firstKey()) == tasks && tasks.size() == 1) {
1876 }
1877 }
1878
1879 private long getNextTaskTime() {
1880 awtLock();
1881 try {
1882 if (timeoutTasks == null || timeoutTasks.isEmpty()) {
1883 return -1L;
1884 }
1885 return (Long)timeoutTasks.firstKey();
1886 } finally {
1887 awtUnlock();
1888 }
1889 }
1890
1891 /**
1892 * Executes mature timeout tasks registered with schedule().
1893 * Called from run() under awtLock.
1894 */
1895 private static void callTimeoutTasks() {
1896 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
1897 timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" +
1898 "; tasks={1}", Long.valueOf(System.currentTimeMillis()), timeoutTasks);
1899 }
1900
1901 if (timeoutTasks == null || timeoutTasks.isEmpty()) {
1902 return;
1903 }
1904
1905 Long currentTime = Long.valueOf(System.currentTimeMillis());
1906 Long time = (Long)timeoutTasks.firstKey();
1907
1908 while (time.compareTo(currentTime) <= 0) {
1909 java.util.List tasks = (java.util.List)timeoutTasks.remove(time);
1910
1911 for (Iterator iter = tasks.iterator(); iter.hasNext();) {
1912 Runnable task = (Runnable)iter.next();
1913
1914 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
1915 timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" +
1916 "; about to run task={1}", Long.valueOf(currentTime), task);
1917 }
1918
1919 try {
1920 task.run();
1921 } catch (ThreadDeath td) {
1922 throw td;
1923 } catch (Throwable thr) {
1924 processException(thr);
1925 }
1926 }
1927
1928 if (timeoutTasks.isEmpty()) {
1929 break;
1930 }
1931 time = (Long)timeoutTasks.firstKey();
1932 }
1933 }
1934
1969
1970 static long reset_time_utc;
1971 static final long WRAP_TIME_MILLIS = 0x00000000FFFFFFFFL;
1972
1973 /*
1974 * This function converts between the X server time (number of milliseconds
1975 * since the last server reset) and the UTC time for the 'when' field of an
1976 * InputEvent (or another event type with a timestamp).
1977 */
1978 static long nowMillisUTC_offset(long server_offset) {
1979 // ported from awt_util.c
1980 /*
1981 * Because Time is of type 'unsigned long', it is possible that Time will
1982 * never wrap when using 64-bit Xlib. However, if a 64-bit client
1983 * connects to a 32-bit server, I suspect the values will still wrap. So
1984 * we should not attempt to remove the wrap checking even if _LP64 is
1985 * true.
1986 */
1987
1988 long current_time_utc = System.currentTimeMillis();
1989 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1990 log.finer("reset_time=" + reset_time_utc + ", current_time=" + current_time_utc
1991 + ", server_offset=" + server_offset + ", wrap_time=" + WRAP_TIME_MILLIS);
1992 }
1993
1994 if ((current_time_utc - reset_time_utc) > WRAP_TIME_MILLIS) {
1995 reset_time_utc = System.currentTimeMillis() - getCurrentServerTime();
1996 }
1997
1998 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1999 log.finer("result = " + (reset_time_utc + server_offset));
2000 }
2001 return reset_time_utc + server_offset;
2002 }
2003
2004 /**
2005 * @see sun.awt.SunToolkit#needsXEmbedImpl
2006 */
2007 protected boolean needsXEmbedImpl() {
2008 // XToolkit implements supports for XEmbed-client protocol and
2009 // requires the supports from the embedding host for it to work.
2010 return true;
2011 }
2012
2013 public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
2014 return (modalityType == null) ||
2015 (modalityType == Dialog.ModalityType.MODELESS) ||
2016 (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
2017 (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
2018 (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
2057 * Returns one of XConstants: NotUseful, WhenMapped or Always.
2058 * If backing store is not available on at least one screen, or
2059 * java2d uses DGA(which conflicts with backing store) on at least one screen,
2060 * or the string system property "sun.awt.backingStore" is neither "Always"
2061 * nor "WhenMapped", then the method returns XConstants.NotUseful.
2062 * Otherwise, if the system property "sun.awt.backingStore" is "WhenMapped",
2063 * then the method returns XConstants.WhenMapped.
2064 * Otherwise (i.e., if the system property "sun.awt.backingStore" is "Always"),
2065 * the method returns XConstants.Always.
2066 */
2067 static int getBackingStoreType() {
2068 return backingStoreType;
2069 }
2070
2071 private static void setBackingStoreType() {
2072 String prop = (String)AccessController.doPrivileged(
2073 new sun.security.action.GetPropertyAction("sun.awt.backingStore"));
2074
2075 if (prop == null) {
2076 backingStoreType = XConstants.NotUseful;
2077 if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
2078 backingStoreLog.config("The system property sun.awt.backingStore is not set" +
2079 ", by default backingStore=NotUseful");
2080 }
2081 return;
2082 }
2083
2084 if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
2085 backingStoreLog.config("The system property sun.awt.backingStore is " + prop);
2086 }
2087 prop = prop.toLowerCase();
2088 if (prop.equals("always")) {
2089 backingStoreType = XConstants.Always;
2090 } else if (prop.equals("whenmapped")) {
2091 backingStoreType = XConstants.WhenMapped;
2092 } else {
2093 backingStoreType = XConstants.NotUseful;
2094 }
2095
2096 if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
2097 backingStoreLog.config("backingStore(as provided by the system property)=" +
2098 ( backingStoreType == XConstants.NotUseful ? "NotUseful"
2099 : backingStoreType == XConstants.WhenMapped ?
2100 "WhenMapped" : "Always") );
2101 }
2102
2103 if (sun.java2d.x11.X11SurfaceData.isDgaAvailable()) {
2104 backingStoreType = XConstants.NotUseful;
2105
2106 if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
2107 backingStoreLog.config("DGA is available, backingStore=NotUseful");
2108 }
2109
2110 return;
2111 }
2112
2113 awtLock();
2114 try {
2115 int screenCount = XlibWrapper.ScreenCount(getDisplay());
2116 for (int i = 0; i < screenCount; i++) {
2117 if (XlibWrapper.DoesBackingStore(XlibWrapper.ScreenOfDisplay(getDisplay(), i))
2118 == XConstants.NotUseful) {
2119 backingStoreType = XConstants.NotUseful;
2120
2121 if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
2122 backingStoreLog.config("Backing store is not available on the screen " +
2123 i + ", backingStore=NotUseful");
2124 }
2125
2126 return;
2127 }
2128 }
2129 } finally {
2130 awtUnlock();
2131 }
2132 }
2133
2134 /**
2135 * One of XConstants: NotUseful, WhenMapped or Always.
2136 */
2137 private static int backingStoreType;
2138
2139 static final int XSUN_KP_BEHAVIOR = 1;
2140 static final int XORG_KP_BEHAVIOR = 2;
2141 static final int IS_SUN_KEYBOARD = 1;
2379 }
2380
2381 }
2382 }
2383 };
2384 }
2385
2386 if (oops == null) {
2387 oops = XAtom.get("OOPS");
2388 }
2389
2390 awtLock();
2391 try {
2392 addEventDispatcher(win.getWindow(), oops_waiter);
2393
2394 oops_updated = false;
2395 oops_failed = false;
2396 // Wait for selection notify for oops on win
2397 long event_number = getEventNumber();
2398 XAtom atom = XAtom.get("WM_S0");
2399 if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
2400 eventLog.finer("WM_S0 selection owner {0}", XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom()));
2401 }
2402 XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(),
2403 XAtom.get("VERSION").getAtom(), oops.getAtom(),
2404 win.getWindow(), XConstants.CurrentTime);
2405 XSync();
2406
2407 eventLog.finer("Requested OOPS");
2408
2409 long start = System.currentTimeMillis();
2410 while (!oops_updated && !oops_failed) {
2411 try {
2412 awtLockWait(timeout);
2413 } catch (InterruptedException e) {
2414 throw new RuntimeException(e);
2415 }
2416 // This "while" is a protection from spurious
2417 // wake-ups. However, we shouldn't wait for too long
2418 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {
2419 throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
|