src/solaris/classes/sun/awt/X11/XToolkit.java

Print this page




 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));