jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java
changeset 26353 b5e3b7fbf56d
parent 26342 3637212ae8f2
parent 26037 508779ce6619
child 28084 441853c190f4
equal deleted inserted replaced
26352:fa12363e21d6 26353:b5e3b7fbf56d
       
     1 /*
       
     2  * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 package sun.awt.X11;
       
    26 
       
    27 import java.awt.*;
       
    28 import java.awt.event.InputEvent;
       
    29 import java.awt.event.MouseEvent;
       
    30 import java.awt.event.KeyEvent;
       
    31 import java.awt.datatransfer.Clipboard;
       
    32 import java.awt.dnd.DragSource;
       
    33 import java.awt.dnd.DragGestureListener;
       
    34 import java.awt.dnd.DragGestureEvent;
       
    35 import java.awt.dnd.DragGestureRecognizer;
       
    36 import java.awt.dnd.MouseDragGestureRecognizer;
       
    37 import java.awt.dnd.InvalidDnDOperationException;
       
    38 import java.awt.dnd.peer.DragSourceContextPeer;
       
    39 import java.awt.font.TextAttribute;
       
    40 import java.awt.im.InputMethodHighlight;
       
    41 import java.awt.im.spi.InputMethodDescriptor;
       
    42 import java.awt.image.ColorModel;
       
    43 import java.awt.peer.*;
       
    44 import java.beans.PropertyChangeListener;
       
    45 import java.security.AccessController;
       
    46 import java.security.PrivilegedAction;
       
    47 import java.util.*;
       
    48 import javax.swing.LookAndFeel;
       
    49 import javax.swing.UIDefaults;
       
    50 import sun.awt.*;
       
    51 import sun.awt.datatransfer.DataTransferer;
       
    52 import sun.font.FontConfigManager;
       
    53 import sun.java2d.SunGraphicsEnvironment;
       
    54 import sun.misc.*;
       
    55 import sun.awt.util.ThreadGroupUtils;
       
    56 import sun.print.PrintJob2D;
       
    57 import sun.security.action.GetPropertyAction;
       
    58 import sun.security.action.GetBooleanAction;
       
    59 import sun.util.logging.PlatformLogger;
       
    60 
       
    61 public final class XToolkit extends UNIXToolkit implements Runnable {
       
    62     private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XToolkit");
       
    63     private static final PlatformLogger eventLog = PlatformLogger.getLogger("sun.awt.X11.event.XToolkit");
       
    64     private static final PlatformLogger timeoutTaskLog = PlatformLogger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
       
    65     private static final PlatformLogger keyEventLog = PlatformLogger.getLogger("sun.awt.X11.kye.XToolkit");
       
    66     private static final PlatformLogger backingStoreLog = PlatformLogger.getLogger("sun.awt.X11.backingStore.XToolkit");
       
    67 
       
    68     //There is 400 ms is set by default on Windows and 500 by default on KDE and GNOME.
       
    69     //We use the same hardcoded constant.
       
    70     private final static int AWT_MULTICLICK_DEFAULT_TIME = 500;
       
    71 
       
    72     static final boolean PRIMARY_LOOP = false;
       
    73     static final boolean SECONDARY_LOOP = true;
       
    74 
       
    75     private static String awtAppClassName = null;
       
    76 
       
    77     // the system clipboard - CLIPBOARD selection
       
    78     XClipboard clipboard;
       
    79     // the system selection - PRIMARY selection
       
    80     XClipboard selection;
       
    81 
       
    82     // Dynamic Layout Resize client code setting
       
    83     protected static boolean dynamicLayoutSetting = false;
       
    84 
       
    85     //Is it allowed to generate events assigned to extra mouse buttons.
       
    86     //Set to true by default.
       
    87     private static boolean areExtraMouseButtonsEnabled = true;
       
    88 
       
    89     /**
       
    90      * True when the x settings have been loaded.
       
    91      */
       
    92     private boolean loadedXSettings;
       
    93 
       
    94     /**
       
    95     * XSETTINGS for the default screen.
       
    96      * <p>
       
    97      */
       
    98     private XSettings xs;
       
    99 
       
   100     private FontConfigManager fcManager = new FontConfigManager();
       
   101 
       
   102     static int arrowCursor;
       
   103     static TreeMap<Long, XBaseWindow> winMap = new TreeMap<>();
       
   104     static HashMap<Object, Object> specialPeerMap = new HashMap<>();
       
   105     static HashMap<Long, Collection<XEventDispatcher>> winToDispatcher = new HashMap<>();
       
   106     private static long _display;
       
   107     static UIDefaults uidefaults;
       
   108     static X11GraphicsEnvironment localEnv;
       
   109     static X11GraphicsDevice device;
       
   110     static final X11GraphicsConfig config;
       
   111     static int awt_multiclick_time;
       
   112     static boolean securityWarningEnabled;
       
   113 
       
   114     private static volatile int screenWidth = -1, screenHeight = -1; // Dimensions of default screen
       
   115     static long awt_defaultFg; // Pixel
       
   116     private static XMouseInfoPeer xPeer;
       
   117 
       
   118     static {
       
   119         initSecurityWarning();
       
   120         if (GraphicsEnvironment.isHeadless()) {
       
   121             config = null;
       
   122         } else {
       
   123             localEnv = (X11GraphicsEnvironment) GraphicsEnvironment
       
   124                 .getLocalGraphicsEnvironment();
       
   125             device = (X11GraphicsDevice) localEnv.getDefaultScreenDevice();
       
   126             config = (X11GraphicsConfig) (device.getDefaultConfiguration());
       
   127             if (device != null) {
       
   128                 _display = device.getDisplay();
       
   129             }
       
   130             setupModifierMap();
       
   131             initIDs();
       
   132             setBackingStoreType();
       
   133         }
       
   134     }
       
   135 
       
   136     /*
       
   137      * Return (potentially) platform specific display timeout for the
       
   138      * tray icon
       
   139      */
       
   140     static native long getTrayIconDisplayTimeout();
       
   141 
       
   142     private native static void initIDs();
       
   143     native static void waitForEvents(long nextTaskTime);
       
   144     static Thread toolkitThread;
       
   145     static boolean isToolkitThread() {
       
   146         return Thread.currentThread() == toolkitThread;
       
   147     }
       
   148 
       
   149     static void initSecurityWarning() {
       
   150         // Enable warning only for internal builds
       
   151         String runtime = AccessController.doPrivileged(
       
   152                              new GetPropertyAction("java.runtime.version"));
       
   153         securityWarningEnabled = (runtime != null && runtime.contains("internal"));
       
   154     }
       
   155 
       
   156     static boolean isSecurityWarningEnabled() {
       
   157         return securityWarningEnabled;
       
   158     }
       
   159 
       
   160     static native void awt_output_flush();
       
   161 
       
   162     static void  awtFUnlock() {
       
   163         awtUnlock();
       
   164         awt_output_flush();
       
   165     }
       
   166 
       
   167 
       
   168     private native void nativeLoadSystemColors(int[] systemColors);
       
   169 
       
   170     static UIDefaults getUIDefaults() {
       
   171         if (uidefaults == null) {
       
   172             initUIDefaults();
       
   173         }
       
   174         return uidefaults;
       
   175     }
       
   176 
       
   177     public void loadSystemColors(int[] systemColors) {
       
   178         nativeLoadSystemColors(systemColors);
       
   179         MotifColorUtilities.loadSystemColors(systemColors);
       
   180     }
       
   181 
       
   182 
       
   183 
       
   184     static void initUIDefaults() {
       
   185         try {
       
   186             // Load Defaults from MotifLookAndFeel
       
   187 
       
   188             // This dummy load is necessary to get SystemColor initialized. !!!!!!
       
   189             Color c = SystemColor.text;
       
   190 
       
   191             LookAndFeel lnf = new XAWTLookAndFeel();
       
   192             uidefaults = lnf.getDefaults();
       
   193         }
       
   194         catch (Exception e)
       
   195         {
       
   196             e.printStackTrace();
       
   197         }
       
   198     }
       
   199 
       
   200     static Object displayLock = new Object();
       
   201 
       
   202     public static long getDisplay() {
       
   203         return _display;
       
   204     }
       
   205 
       
   206     public static long getDefaultRootWindow() {
       
   207         awtLock();
       
   208         try {
       
   209             long res = XlibWrapper.RootWindow(XToolkit.getDisplay(),
       
   210                 XlibWrapper.DefaultScreen(XToolkit.getDisplay()));
       
   211 
       
   212             if (res == 0) {
       
   213                throw new IllegalStateException("Root window must not be null");
       
   214             }
       
   215             return res;
       
   216         } finally {
       
   217             awtUnlock();
       
   218         }
       
   219     }
       
   220 
       
   221     void init() {
       
   222         awtLock();
       
   223         try {
       
   224             XlibWrapper.XSupportsLocale();
       
   225             if (XlibWrapper.XSetLocaleModifiers("") == null) {
       
   226                 log.finer("X locale modifiers are not supported, using default");
       
   227             }
       
   228             tryXKB();
       
   229 
       
   230             AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
       
   231             awt_defaultFg = defaultScreen.get_blackpixel();
       
   232 
       
   233             arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
       
   234                 XCursorFontConstants.XC_arrow);
       
   235             areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
       
   236             //set system property if not yet assigned
       
   237             System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
       
   238 
       
   239             // Detect display mode changes
       
   240             XlibWrapper.XSelectInput(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(), XConstants.StructureNotifyMask);
       
   241             XToolkit.addEventDispatcher(XToolkit.getDefaultRootWindow(), new XEventDispatcher() {
       
   242                 @Override
       
   243                 public void dispatchEvent(XEvent ev) {
       
   244                     if (ev.get_type() == XConstants.ConfigureNotify) {
       
   245                         awtUnlock();
       
   246                         try {
       
   247                             ((X11GraphicsEnvironment)GraphicsEnvironment.
       
   248                              getLocalGraphicsEnvironment()).
       
   249                                 displayChanged();
       
   250                         } finally {
       
   251                             awtLock();
       
   252                         }
       
   253                     }
       
   254                 }
       
   255             });
       
   256         } finally {
       
   257             awtUnlock();
       
   258         }
       
   259         PrivilegedAction<Void> a = () -> {
       
   260             Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
       
   261                     public void run() {
       
   262                         XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
       
   263                         if (peer != null) {
       
   264                             peer.dispose();
       
   265                         }
       
   266                         if (xs != null) {
       
   267                             ((XAWTXSettings)xs).dispose();
       
   268                         }
       
   269                         freeXKB();
       
   270                         if (log.isLoggable(PlatformLogger.Level.FINE)) {
       
   271                             dumpPeers();
       
   272                         }
       
   273                     }
       
   274                 };
       
   275             shutdownThread.setContextClassLoader(null);
       
   276             Runtime.getRuntime().addShutdownHook(shutdownThread);
       
   277             return null;
       
   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 
       
   290     static native String getEnv(String key);
       
   291 
       
   292 
       
   293     static String getAWTAppClassName() {
       
   294         return awtAppClassName;
       
   295     }
       
   296 
       
   297     public XToolkit() {
       
   298         super();
       
   299         if (PerformanceLogger.loggingEnabled()) {
       
   300             PerformanceLogger.setTime("XToolkit construction");
       
   301         }
       
   302 
       
   303         if (!GraphicsEnvironment.isHeadless()) {
       
   304             String mainClassName = null;
       
   305 
       
   306             StackTraceElement trace[] = (new Throwable()).getStackTrace();
       
   307             int bottom = trace.length - 1;
       
   308             if (bottom >= 0) {
       
   309                 mainClassName = trace[bottom].getClassName();
       
   310             }
       
   311             if (mainClassName == null || mainClassName.equals("")) {
       
   312                 mainClassName = "AWT";
       
   313             }
       
   314             awtAppClassName = getCorrectXIDString(mainClassName);
       
   315 
       
   316             init();
       
   317             XWM.init();
       
   318 
       
   319             toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
       
   320                 Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
       
   321                 thread.setContextClassLoader(null);
       
   322                 thread.setPriority(Thread.NORM_PRIORITY + 1);
       
   323                 thread.setDaemon(true);
       
   324                 return thread;
       
   325             });
       
   326             toolkitThread.start();
       
   327         }
       
   328     }
       
   329 
       
   330     public ButtonPeer createButton(Button target) {
       
   331         ButtonPeer peer = new XButtonPeer(target);
       
   332         targetCreatedPeer(target, peer);
       
   333         return peer;
       
   334     }
       
   335 
       
   336     public FramePeer createLightweightFrame(LightweightFrame target) {
       
   337         FramePeer peer = new XLightweightFramePeer(target);
       
   338         targetCreatedPeer(target, peer);
       
   339         return peer;
       
   340     }
       
   341 
       
   342     public FramePeer createFrame(Frame target) {
       
   343         FramePeer peer = new XFramePeer(target);
       
   344         targetCreatedPeer(target, peer);
       
   345         return peer;
       
   346     }
       
   347 
       
   348     static void addToWinMap(long window, XBaseWindow xwin)
       
   349     {
       
   350         synchronized(winMap) {
       
   351             winMap.put(Long.valueOf(window),xwin);
       
   352         }
       
   353     }
       
   354 
       
   355     static void removeFromWinMap(long window, XBaseWindow xwin) {
       
   356         synchronized(winMap) {
       
   357             winMap.remove(Long.valueOf(window));
       
   358         }
       
   359     }
       
   360     static XBaseWindow windowToXWindow(long window) {
       
   361         synchronized(winMap) {
       
   362             return winMap.get(Long.valueOf(window));
       
   363         }
       
   364     }
       
   365 
       
   366     static void addEventDispatcher(long window, XEventDispatcher dispatcher) {
       
   367         synchronized(winToDispatcher) {
       
   368             Long key = Long.valueOf(window);
       
   369             Collection<XEventDispatcher> dispatchers = winToDispatcher.get(key);
       
   370             if (dispatchers == null) {
       
   371                 dispatchers = new Vector<>();
       
   372                 winToDispatcher.put(key, dispatchers);
       
   373             }
       
   374             dispatchers.add(dispatcher);
       
   375         }
       
   376     }
       
   377     static void removeEventDispatcher(long window, XEventDispatcher dispatcher) {
       
   378         synchronized(winToDispatcher) {
       
   379             Long key = Long.valueOf(window);
       
   380             Collection<XEventDispatcher> dispatchers = winToDispatcher.get(key);
       
   381             if (dispatchers != null) {
       
   382                 dispatchers.remove(dispatcher);
       
   383             }
       
   384         }
       
   385     }
       
   386 
       
   387     private Point lastCursorPos;
       
   388 
       
   389     /**
       
   390      * Returns whether there is last remembered cursor position.  The
       
   391      * position is remembered from X mouse events on our peers.  The
       
   392      * position is stored in <code>p</code>.
       
   393      * @return true, if there is remembered last cursor position,
       
   394      * false otherwise
       
   395      */
       
   396     boolean getLastCursorPos(Point p) {
       
   397         awtLock();
       
   398         try {
       
   399             if (lastCursorPos == null) {
       
   400                 return false;
       
   401             }
       
   402             p.setLocation(lastCursorPos);
       
   403             return true;
       
   404         } finally {
       
   405             awtUnlock();
       
   406         }
       
   407     }
       
   408 
       
   409     private void processGlobalMotionEvent(XEvent e) {
       
   410         // Only our windows guaranteely generate MotionNotify, so we
       
   411         // should track enter/leave, to catch the moment when to
       
   412         // switch to XQueryPointer
       
   413         if (e.get_type() == XConstants.MotionNotify) {
       
   414             XMotionEvent ev = e.get_xmotion();
       
   415             awtLock();
       
   416             try {
       
   417                 if (lastCursorPos == null) {
       
   418                     lastCursorPos = new Point(ev.get_x_root(), ev.get_y_root());
       
   419                 } else {
       
   420                     lastCursorPos.setLocation(ev.get_x_root(), ev.get_y_root());
       
   421                 }
       
   422             } finally {
       
   423                 awtUnlock();
       
   424             }
       
   425         } else if (e.get_type() == XConstants.LeaveNotify) {
       
   426             // Leave from our window
       
   427             awtLock();
       
   428             try {
       
   429                 lastCursorPos = null;
       
   430             } finally {
       
   431                 awtUnlock();
       
   432             }
       
   433         } else if (e.get_type() == XConstants.EnterNotify) {
       
   434             // Entrance into our window
       
   435             XCrossingEvent ev = e.get_xcrossing();
       
   436             awtLock();
       
   437             try {
       
   438                 if (lastCursorPos == null) {
       
   439                     lastCursorPos = new Point(ev.get_x_root(), ev.get_y_root());
       
   440                 } else {
       
   441                     lastCursorPos.setLocation(ev.get_x_root(), ev.get_y_root());
       
   442                 }
       
   443             } finally {
       
   444                 awtUnlock();
       
   445             }
       
   446         }
       
   447     }
       
   448 
       
   449     public interface XEventListener {
       
   450         public void eventProcessed(XEvent e);
       
   451     }
       
   452 
       
   453     private Collection<XEventListener> listeners = new LinkedList<XEventListener>();
       
   454 
       
   455     public void addXEventListener(XEventListener listener) {
       
   456         synchronized (listeners) {
       
   457             listeners.add(listener);
       
   458         }
       
   459     }
       
   460 
       
   461     private void notifyListeners(XEvent xev) {
       
   462         synchronized (listeners) {
       
   463             if (listeners.size() == 0) return;
       
   464 
       
   465             XEvent copy = xev.clone();
       
   466             try {
       
   467                 for (XEventListener listener : listeners) {
       
   468                     listener.eventProcessed(copy);
       
   469                 }
       
   470             } finally {
       
   471                 copy.dispose();
       
   472             }
       
   473         }
       
   474     }
       
   475 
       
   476     private void dispatchEvent(XEvent ev) {
       
   477         final XAnyEvent xany = ev.get_xany();
       
   478 
       
   479         if (windowToXWindow(xany.get_window()) != null &&
       
   480              (ev.get_type() == XConstants.MotionNotify || ev.get_type() == XConstants.EnterNotify || ev.get_type() == XConstants.LeaveNotify))
       
   481         {
       
   482             processGlobalMotionEvent(ev);
       
   483         }
       
   484 
       
   485         if( ev.get_type() == XConstants.MappingNotify ) {
       
   486             // The 'window' field in this event is unused.
       
   487             // This application itself does nothing to initiate such an event
       
   488             // (no calls of XChangeKeyboardMapping etc.).
       
   489             // SunRay server sends this event to the application once on every
       
   490             // keyboard (not just layout) change which means, quite seldom.
       
   491             XlibWrapper.XRefreshKeyboardMapping(ev.pData);
       
   492             resetKeyboardSniffer();
       
   493             setupModifierMap();
       
   494         }
       
   495         XBaseWindow.dispatchToWindow(ev);
       
   496 
       
   497         Collection<XEventDispatcher> dispatchers = null;
       
   498         synchronized(winToDispatcher) {
       
   499             Long key = Long.valueOf(xany.get_window());
       
   500             dispatchers = winToDispatcher.get(key);
       
   501             if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
       
   502                 dispatchers = new Vector<>(dispatchers);
       
   503             }
       
   504         }
       
   505         if (dispatchers != null) {
       
   506             Iterator<XEventDispatcher> iter = dispatchers.iterator();
       
   507             while (iter.hasNext()) {
       
   508                 XEventDispatcher disp = iter.next();
       
   509                 disp.dispatchEvent(ev);
       
   510             }
       
   511         }
       
   512         notifyListeners(ev);
       
   513     }
       
   514 
       
   515     static void processException(Throwable thr) {
       
   516         if (log.isLoggable(PlatformLogger.Level.WARNING)) {
       
   517             log.warning("Exception on Toolkit thread", thr);
       
   518         }
       
   519     }
       
   520 
       
   521     static native void awt_toolkit_init();
       
   522 
       
   523     public void run() {
       
   524         awt_toolkit_init();
       
   525         run(PRIMARY_LOOP);
       
   526     }
       
   527 
       
   528     public void run(boolean loop)
       
   529     {
       
   530         XEvent ev = new XEvent();
       
   531         while(true) {
       
   532             // Fix for 6829923: we should gracefully handle toolkit thread interruption
       
   533             if (Thread.currentThread().isInterrupted()) {
       
   534                 // We expect interruption from the AppContext.dispose() method only.
       
   535                 // If the thread is interrupted from another place, let's skip it
       
   536                 // for compatibility reasons. Probably some time later we'll remove
       
   537                 // the check for AppContext.isDisposed() and will unconditionally
       
   538                 // break the loop here.
       
   539                 if (AppContext.getAppContext().isDisposed()) {
       
   540                     break;
       
   541                 }
       
   542             }
       
   543             awtLock();
       
   544             try {
       
   545                 if (loop == SECONDARY_LOOP) {
       
   546                     // In the secondary loop we may have already acquired awt_lock
       
   547                     // several times, so waitForEvents() might be unable to release
       
   548                     // the awt_lock and this causes lock up.
       
   549                     // For now, we just avoid waitForEvents in the secondary loop.
       
   550                     if (!XlibWrapper.XNextSecondaryLoopEvent(getDisplay(),ev.pData)) {
       
   551                         break;
       
   552                     }
       
   553                 } else {
       
   554                     callTimeoutTasks();
       
   555                     // If no events are queued, waitForEvents() causes calls to
       
   556                     // awtUnlock(), awtJNI_ThreadYield, poll, awtLock(),
       
   557                     // so it spends most of its time in poll, without holding the lock.
       
   558                     while ((XlibWrapper.XEventsQueued(getDisplay(), XConstants.QueuedAfterReading) == 0) &&
       
   559                            (XlibWrapper.XEventsQueued(getDisplay(), XConstants.QueuedAfterFlush) == 0)) {
       
   560                         callTimeoutTasks();
       
   561                         waitForEvents(getNextTaskTime());
       
   562                     }
       
   563                     XlibWrapper.XNextEvent(getDisplay(),ev.pData);
       
   564                 }
       
   565 
       
   566                 if (ev.get_type() != XConstants.NoExpose) {
       
   567                     eventNumber++;
       
   568                 }
       
   569                 if (awt_UseXKB_Calls && ev.get_type() ==  awt_XKBBaseEventCode) {
       
   570                     processXkbChanges(ev);
       
   571                 }
       
   572 
       
   573                 if (XDropTargetEventProcessor.processEvent(ev) ||
       
   574                     XDragSourceContextPeer.processEvent(ev)) {
       
   575                     continue;
       
   576                 }
       
   577 
       
   578                 if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
       
   579                     eventLog.finer("{0}", ev);
       
   580                 }
       
   581 
       
   582                 // Check if input method consumes the event
       
   583                 long w = 0;
       
   584                 if (windowToXWindow(ev.get_xany().get_window()) != null) {
       
   585                     Component owner =
       
   586                         XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
       
   587                     if (owner != null) {
       
   588                         XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
       
   589                         if (ownerWindow != null) {
       
   590                             w = ownerWindow.getContentWindow();
       
   591                         }
       
   592                     }
       
   593                 }
       
   594                 if( keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) {
       
   595                     keyEventLog.fine("before XFilterEvent:"+ev);
       
   596                 }
       
   597                 if (XlibWrapper.XFilterEvent(ev.getPData(), w)) {
       
   598                     continue;
       
   599                 }
       
   600                 if( keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) {
       
   601                     keyEventLog.fine("after XFilterEvent:"+ev); // IS THIS CORRECT?
       
   602                 }
       
   603 
       
   604                 dispatchEvent(ev);
       
   605             } catch (ThreadDeath td) {
       
   606                 XBaseWindow.ungrabInput();
       
   607                 return;
       
   608             } catch (Throwable thr) {
       
   609                 XBaseWindow.ungrabInput();
       
   610                 processException(thr);
       
   611             } finally {
       
   612                 awtUnlock();
       
   613             }
       
   614         }
       
   615     }
       
   616 
       
   617     static {
       
   618         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
       
   619         if (ge instanceof SunGraphicsEnvironment) {
       
   620             ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
       
   621                 new DisplayChangedListener() {
       
   622                     @Override
       
   623                     public void displayChanged() {
       
   624                         // 7045370: Reset the cached values
       
   625                         XToolkit.screenWidth = -1;
       
   626                         XToolkit.screenHeight = -1;
       
   627                     }
       
   628 
       
   629                     @Override
       
   630                     public void paletteChanged() {}
       
   631             });
       
   632         }
       
   633     }
       
   634 
       
   635     private static void initScreenSize() {
       
   636         if (screenWidth == -1 || screenHeight == -1) {
       
   637             awtLock();
       
   638             try {
       
   639                 XWindowAttributes pattr = new XWindowAttributes();
       
   640                 try {
       
   641                     XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(), pattr.pData);
       
   642                     screenWidth  = pattr.get_width();
       
   643                     screenHeight = pattr.get_height();
       
   644                 } finally {
       
   645                     pattr.dispose();
       
   646                 }
       
   647             } finally {
       
   648                 awtUnlock();
       
   649             }
       
   650         }
       
   651     }
       
   652 
       
   653     static int getDefaultScreenWidth() {
       
   654         initScreenSize();
       
   655         return screenWidth;
       
   656     }
       
   657 
       
   658     static int getDefaultScreenHeight() {
       
   659         initScreenSize();
       
   660         return screenHeight;
       
   661     }
       
   662 
       
   663     protected int getScreenWidth() {
       
   664         return getDefaultScreenWidth();
       
   665     }
       
   666 
       
   667     protected int getScreenHeight() {
       
   668         return getDefaultScreenHeight();
       
   669     }
       
   670 
       
   671     private static Rectangle getWorkArea(long root)
       
   672     {
       
   673         XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA");
       
   674 
       
   675         long native_ptr = Native.allocateLongArray(4);
       
   676         try
       
   677         {
       
   678             boolean workareaPresent = XA_NET_WORKAREA.getAtomData(root,
       
   679                 XAtom.XA_CARDINAL, native_ptr, 4);
       
   680             if (workareaPresent)
       
   681             {
       
   682                 int rootX = (int)Native.getLong(native_ptr, 0);
       
   683                 int rootY = (int)Native.getLong(native_ptr, 1);
       
   684                 int rootWidth = (int)Native.getLong(native_ptr, 2);
       
   685                 int rootHeight = (int)Native.getLong(native_ptr, 3);
       
   686 
       
   687                 return new Rectangle(rootX, rootY, rootWidth, rootHeight);
       
   688             }
       
   689         }
       
   690         finally
       
   691         {
       
   692             XlibWrapper.unsafe.freeMemory(native_ptr);
       
   693         }
       
   694 
       
   695         return null;
       
   696     }
       
   697 
       
   698     /*
       
   699      * If we're running in non-Xinerama environment and the current
       
   700      * window manager supports _NET protocol then the screen insets
       
   701      * are calculated using _NET_WM_WORKAREA property of the root
       
   702      * window.
       
   703      * Otherwise, i. e. if Xinerama is on or _NET_WM_WORKAREA is
       
   704      * not set, we try to calculate the insets ourselves using
       
   705      * getScreenInsetsManually method.
       
   706      */
       
   707     public Insets getScreenInsets(GraphicsConfiguration gc)
       
   708     {
       
   709         XNETProtocol netProto = XWM.getWM().getNETProtocol();
       
   710         if ((netProto == null) || !netProto.active())
       
   711         {
       
   712             return super.getScreenInsets(gc);
       
   713         }
       
   714 
       
   715         XToolkit.awtLock();
       
   716         try
       
   717         {
       
   718             X11GraphicsConfig x11gc = (X11GraphicsConfig)gc;
       
   719             X11GraphicsDevice x11gd = (X11GraphicsDevice)x11gc.getDevice();
       
   720             long root = XlibUtil.getRootWindow(x11gd.getScreen());
       
   721             Rectangle rootBounds = XlibUtil.getWindowGeometry(root);
       
   722 
       
   723             X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
       
   724                 GraphicsEnvironment.getLocalGraphicsEnvironment();
       
   725             if (!x11ge.runningXinerama())
       
   726             {
       
   727                 Rectangle workArea = XToolkit.getWorkArea(root);
       
   728                 if (workArea != null)
       
   729                 {
       
   730                     return new Insets(workArea.y,
       
   731                                       workArea.x,
       
   732                                       rootBounds.height - workArea.height - workArea.y,
       
   733                                       rootBounds.width - workArea.width - workArea.x);
       
   734                 }
       
   735             }
       
   736 
       
   737             return getScreenInsetsManually(root, rootBounds, gc.getBounds());
       
   738         }
       
   739         finally
       
   740         {
       
   741             XToolkit.awtUnlock();
       
   742         }
       
   743     }
       
   744 
       
   745     /*
       
   746      * Manual calculation of screen insets: get all the windows with
       
   747      * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
       
   748      * hints' values to screen insets.
       
   749      *
       
   750      * This method should be called under XToolkit.awtLock()
       
   751      */
       
   752     private Insets getScreenInsetsManually(long root, Rectangle rootBounds, Rectangle screenBounds)
       
   753     {
       
   754         /*
       
   755          * During the manual calculation of screen insets we iterate
       
   756          * all the X windows hierarchy starting from root window. This
       
   757          * constant is the max level inspected in this hierarchy.
       
   758          * 3 is a heuristic value: I suppose any the toolbar-like
       
   759          * window is a child of either root or desktop window.
       
   760          */
       
   761         final int MAX_NESTED_LEVEL = 3;
       
   762 
       
   763         XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
       
   764         XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
       
   765 
       
   766         Insets insets = new Insets(0, 0, 0, 0);
       
   767 
       
   768         java.util.List<Object> search = new LinkedList<>();
       
   769         search.add(root);
       
   770         search.add(0);
       
   771         while (!search.isEmpty())
       
   772         {
       
   773             long window = (Long)search.remove(0);
       
   774             int windowLevel = (Integer)search.remove(0);
       
   775 
       
   776             /*
       
   777              * Note that most of the modern window managers unmap
       
   778              * application window if it is iconified. Thus, any
       
   779              * _NET_WM_STRUT[_PARTIAL] hints for iconified windows
       
   780              * are not included to the screen insets.
       
   781              */
       
   782             if (XlibUtil.getWindowMapState(window) == XConstants.IsUnmapped)
       
   783             {
       
   784                 continue;
       
   785             }
       
   786 
       
   787             long native_ptr = Native.allocateLongArray(4);
       
   788             try
       
   789             {
       
   790                 // first, check if _NET_WM_STRUT or _NET_WM_STRUT_PARTIAL are present
       
   791                 // if both are set on the window, _NET_WM_STRUT_PARTIAL is used (see _NET spec)
       
   792                 boolean strutPresent = XA_NET_WM_STRUT_PARTIAL.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
       
   793                 if (!strutPresent)
       
   794                 {
       
   795                     strutPresent = XA_NET_WM_STRUT.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
       
   796                 }
       
   797                 if (strutPresent)
       
   798                 {
       
   799                     // second, verify that window is located on the proper screen
       
   800                     Rectangle windowBounds = XlibUtil.getWindowGeometry(window);
       
   801                     if (windowLevel > 1)
       
   802                     {
       
   803                         windowBounds = XlibUtil.translateCoordinates(window, root, windowBounds);
       
   804                     }
       
   805                     // if _NET_WM_STRUT_PARTIAL is present, we should use its values to detect
       
   806                     // if the struts area intersects with screenBounds, however some window
       
   807                     // managers don't set this hint correctly, so we just get intersection with windowBounds
       
   808                     if (windowBounds != null && windowBounds.intersects(screenBounds))
       
   809                     {
       
   810                         int left = (int)Native.getLong(native_ptr, 0);
       
   811                         int right = (int)Native.getLong(native_ptr, 1);
       
   812                         int top = (int)Native.getLong(native_ptr, 2);
       
   813                         int bottom = (int)Native.getLong(native_ptr, 3);
       
   814 
       
   815                         /*
       
   816                          * struts could be relative to root window bounds, so
       
   817                          * make them relative to the screen bounds in this case
       
   818                          */
       
   819                         left = rootBounds.x + left > screenBounds.x ?
       
   820                                 rootBounds.x + left - screenBounds.x : 0;
       
   821                         right = rootBounds.x + rootBounds.width - right <
       
   822                                 screenBounds.x + screenBounds.width ?
       
   823                                 screenBounds.x + screenBounds.width -
       
   824                                 (rootBounds.x + rootBounds.width - right) : 0;
       
   825                         top = rootBounds.y + top > screenBounds.y ?
       
   826                                 rootBounds.y + top - screenBounds.y : 0;
       
   827                         bottom = rootBounds.y + rootBounds.height - bottom <
       
   828                                 screenBounds.y + screenBounds.height ?
       
   829                                 screenBounds.y + screenBounds.height -
       
   830                                 (rootBounds.y + rootBounds.height - bottom) : 0;
       
   831 
       
   832                         insets.left = Math.max(left, insets.left);
       
   833                         insets.right = Math.max(right, insets.right);
       
   834                         insets.top = Math.max(top, insets.top);
       
   835                         insets.bottom = Math.max(bottom, insets.bottom);
       
   836                     }
       
   837                 }
       
   838             }
       
   839             finally
       
   840             {
       
   841                 XlibWrapper.unsafe.freeMemory(native_ptr);
       
   842             }
       
   843 
       
   844             if (windowLevel < MAX_NESTED_LEVEL)
       
   845             {
       
   846                 Set<Long> children = XlibUtil.getChildWindows(window);
       
   847                 for (long child : children)
       
   848                 {
       
   849                     search.add(child);
       
   850                     search.add(windowLevel + 1);
       
   851                 }
       
   852             }
       
   853         }
       
   854 
       
   855         return insets;
       
   856     }
       
   857 
       
   858     /*
       
   859      * The current implementation of disabling background erasing for
       
   860      * canvases is that we don't set any native background color
       
   861      * (with XSetWindowBackground) for the canvas window. However,
       
   862      * this color is set in the peer constructor - see
       
   863      * XWindow.postInit() for details. That's why this method from
       
   864      * SunToolkit is not overridden in XToolkit: it's too late to
       
   865      * disable background erasing :(
       
   866      */
       
   867     /*
       
   868     @Override
       
   869     public void disableBackgroundErase(Canvas canvas) {
       
   870         XCanvasPeer peer = (XCanvasPeer)canvas.getPeer();
       
   871         if (peer == null) {
       
   872             throw new IllegalStateException("Canvas must have a valid peer");
       
   873         }
       
   874         peer.disableBackgroundErase();
       
   875     }
       
   876     */
       
   877 
       
   878     // Need this for XMenuItemPeer.
       
   879     protected static Object targetToPeer(Object target) {
       
   880         Object p=null;
       
   881         if (target != null && !GraphicsEnvironment.isHeadless()) {
       
   882             p = specialPeerMap.get(target);
       
   883         }
       
   884         if (p != null) return p;
       
   885         else
       
   886             return SunToolkit.targetToPeer(target);
       
   887     }
       
   888 
       
   889     // Need this for XMenuItemPeer.
       
   890     protected static void targetDisposedPeer(Object target, Object peer) {
       
   891         SunToolkit.targetDisposedPeer(target, peer);
       
   892     }
       
   893 
       
   894     public RobotPeer createRobot(Robot target, GraphicsDevice screen) {
       
   895         return new XRobotPeer(screen.getDefaultConfiguration());
       
   896     }
       
   897 
       
   898 
       
   899   /*
       
   900      * On X, support for dynamic layout on resizing is governed by the
       
   901      * window manager.  If the window manager supports it, it happens
       
   902      * automatically.  The setter method for this property is
       
   903      * irrelevant on X.
       
   904      */
       
   905     public void setDynamicLayout(boolean b) {
       
   906         dynamicLayoutSetting = b;
       
   907     }
       
   908 
       
   909     protected boolean isDynamicLayoutSet() {
       
   910         return dynamicLayoutSetting;
       
   911     }
       
   912 
       
   913     /* Called from isDynamicLayoutActive() and from
       
   914      * lazilyLoadDynamicLayoutSupportedProperty()
       
   915      */
       
   916     protected boolean isDynamicLayoutSupported() {
       
   917         return XWM.getWM().supportsDynamicLayout();
       
   918     }
       
   919 
       
   920     public boolean isDynamicLayoutActive() {
       
   921         return isDynamicLayoutSupported();
       
   922     }
       
   923 
       
   924 
       
   925     public FontPeer getFontPeer(String name, int style){
       
   926         return new XFontPeer(name, style);
       
   927     }
       
   928 
       
   929     public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
       
   930         final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
       
   931         if (f != null) {
       
   932             return f.createDragSourceContextPeer(dge);
       
   933         }
       
   934 
       
   935         return XDragSourceContextPeer.createDragSourceContextPeer(dge);
       
   936     }
       
   937 
       
   938     @SuppressWarnings("unchecked")
       
   939     public <T extends DragGestureRecognizer> T
       
   940     createDragGestureRecognizer(Class<T> recognizerClass,
       
   941                     DragSource ds,
       
   942                     Component c,
       
   943                     int srcActions,
       
   944                     DragGestureListener dgl)
       
   945     {
       
   946         final LightweightFrame f = SunToolkit.getLightweightFrame(c);
       
   947         if (f != null) {
       
   948             return f.createDragGestureRecognizer(recognizerClass, ds, c, srcActions, dgl);
       
   949         }
       
   950 
       
   951         if (MouseDragGestureRecognizer.class.equals(recognizerClass))
       
   952             return (T)new XMouseDragGestureRecognizer(ds, c, srcActions, dgl);
       
   953         else
       
   954             return null;
       
   955     }
       
   956 
       
   957     public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) {
       
   958         XCheckboxMenuItemPeer peer = new XCheckboxMenuItemPeer(target);
       
   959         //vb157120: looks like we don't need to map menu items
       
   960         //in new menus implementation
       
   961         //targetCreatedPeer(target, peer);
       
   962         return peer;
       
   963     }
       
   964 
       
   965     public MenuItemPeer createMenuItem(MenuItem target) {
       
   966         XMenuItemPeer peer = new XMenuItemPeer(target);
       
   967         //vb157120: looks like we don't need to map menu items
       
   968         //in new menus implementation
       
   969         //targetCreatedPeer(target, peer);
       
   970         return peer;
       
   971     }
       
   972 
       
   973     public TextFieldPeer createTextField(TextField target) {
       
   974         TextFieldPeer  peer = new XTextFieldPeer(target);
       
   975         targetCreatedPeer(target, peer);
       
   976         return peer;
       
   977     }
       
   978 
       
   979     public LabelPeer createLabel(Label target) {
       
   980         LabelPeer  peer = new XLabelPeer(target);
       
   981         targetCreatedPeer(target, peer);
       
   982         return peer;
       
   983     }
       
   984 
       
   985     public ListPeer createList(java.awt.List target) {
       
   986         ListPeer peer = new XListPeer(target);
       
   987         targetCreatedPeer(target, peer);
       
   988         return peer;
       
   989     }
       
   990 
       
   991     public CheckboxPeer createCheckbox(Checkbox target) {
       
   992         CheckboxPeer peer = new XCheckboxPeer(target);
       
   993         targetCreatedPeer(target, peer);
       
   994         return peer;
       
   995     }
       
   996 
       
   997     public ScrollbarPeer createScrollbar(Scrollbar target) {
       
   998         XScrollbarPeer peer = new XScrollbarPeer(target);
       
   999         targetCreatedPeer(target, peer);
       
  1000         return peer;
       
  1001     }
       
  1002 
       
  1003     public ScrollPanePeer createScrollPane(ScrollPane target) {
       
  1004         XScrollPanePeer peer = new XScrollPanePeer(target);
       
  1005         targetCreatedPeer(target, peer);
       
  1006         return peer;
       
  1007     }
       
  1008 
       
  1009     public TextAreaPeer createTextArea(TextArea target) {
       
  1010         TextAreaPeer peer = new XTextAreaPeer(target);
       
  1011         targetCreatedPeer(target, peer);
       
  1012         return peer;
       
  1013     }
       
  1014 
       
  1015     public ChoicePeer createChoice(Choice target) {
       
  1016         XChoicePeer peer = new XChoicePeer(target);
       
  1017         targetCreatedPeer(target, peer);
       
  1018         return peer;
       
  1019     }
       
  1020 
       
  1021     public CanvasPeer createCanvas(Canvas target) {
       
  1022         XCanvasPeer peer = (isXEmbedServerRequested() ? new XEmbedCanvasPeer(target) : new XCanvasPeer(target));
       
  1023         targetCreatedPeer(target, peer);
       
  1024         return peer;
       
  1025     }
       
  1026 
       
  1027     public PanelPeer createPanel(Panel target) {
       
  1028         PanelPeer peer = new XPanelPeer(target);
       
  1029         targetCreatedPeer(target, peer);
       
  1030         return peer;
       
  1031     }
       
  1032 
       
  1033     public WindowPeer createWindow(Window target) {
       
  1034         WindowPeer peer = new XWindowPeer(target);
       
  1035         targetCreatedPeer(target, peer);
       
  1036         return peer;
       
  1037     }
       
  1038 
       
  1039     public DialogPeer createDialog(Dialog target) {
       
  1040         DialogPeer peer = new XDialogPeer(target);
       
  1041         targetCreatedPeer(target, peer);
       
  1042         return peer;
       
  1043     }
       
  1044 
       
  1045     private static Boolean sunAwtDisableGtkFileDialogs = null;
       
  1046 
       
  1047     /**
       
  1048      * Returns the value of "sun.awt.disableGtkFileDialogs" property. Default
       
  1049      * value is {@code false}.
       
  1050      */
       
  1051     public synchronized static boolean getSunAwtDisableGtkFileDialogs() {
       
  1052         if (sunAwtDisableGtkFileDialogs == null) {
       
  1053             sunAwtDisableGtkFileDialogs = AccessController.doPrivileged(
       
  1054                                               new GetBooleanAction("sun.awt.disableGtkFileDialogs"));
       
  1055         }
       
  1056         return sunAwtDisableGtkFileDialogs.booleanValue();
       
  1057     }
       
  1058 
       
  1059     public FileDialogPeer createFileDialog(FileDialog target) {
       
  1060         FileDialogPeer peer = null;
       
  1061         // The current GtkFileChooser is available from GTK+ 2.4
       
  1062         if (!getSunAwtDisableGtkFileDialogs() && checkGtkVersion(2, 4, 0)) {
       
  1063             peer = new GtkFileDialogPeer(target);
       
  1064         } else {
       
  1065             peer = new XFileDialogPeer(target);
       
  1066         }
       
  1067         targetCreatedPeer(target, peer);
       
  1068         return peer;
       
  1069     }
       
  1070 
       
  1071     public MenuBarPeer createMenuBar(MenuBar target) {
       
  1072         XMenuBarPeer peer = new XMenuBarPeer(target);
       
  1073         targetCreatedPeer(target, peer);
       
  1074         return peer;
       
  1075     }
       
  1076 
       
  1077     public MenuPeer createMenu(Menu target) {
       
  1078         XMenuPeer peer = new XMenuPeer(target);
       
  1079         //vb157120: looks like we don't need to map menu items
       
  1080         //in new menus implementation
       
  1081         //targetCreatedPeer(target, peer);
       
  1082         return peer;
       
  1083     }
       
  1084 
       
  1085     public PopupMenuPeer createPopupMenu(PopupMenu target) {
       
  1086         XPopupMenuPeer peer = new XPopupMenuPeer(target);
       
  1087         targetCreatedPeer(target, peer);
       
  1088         return peer;
       
  1089     }
       
  1090 
       
  1091     public synchronized MouseInfoPeer getMouseInfoPeer() {
       
  1092         if (xPeer == null) {
       
  1093             xPeer = new XMouseInfoPeer();
       
  1094         }
       
  1095         return xPeer;
       
  1096     }
       
  1097 
       
  1098     public XEmbeddedFramePeer createEmbeddedFrame(XEmbeddedFrame target)
       
  1099     {
       
  1100         XEmbeddedFramePeer peer = new XEmbeddedFramePeer(target);
       
  1101         targetCreatedPeer(target, peer);
       
  1102         return peer;
       
  1103     }
       
  1104 
       
  1105     XEmbedChildProxyPeer createEmbedProxy(XEmbedChildProxy target) {
       
  1106         XEmbedChildProxyPeer peer = new XEmbedChildProxyPeer(target);
       
  1107         targetCreatedPeer(target, peer);
       
  1108         return peer;
       
  1109     }
       
  1110 
       
  1111     public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() throws HeadlessException {
       
  1112         return XKeyboardFocusManagerPeer.getInstance();
       
  1113     }
       
  1114 
       
  1115     /**
       
  1116      * Returns a new custom cursor.
       
  1117      */
       
  1118     public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
       
  1119       throws IndexOutOfBoundsException {
       
  1120         return new XCustomCursor(cursor, hotSpot, name);
       
  1121     }
       
  1122 
       
  1123     public TrayIconPeer createTrayIcon(TrayIcon target)
       
  1124       throws HeadlessException, AWTException
       
  1125     {
       
  1126         TrayIconPeer peer = new XTrayIconPeer(target);
       
  1127         targetCreatedPeer(target, peer);
       
  1128         return peer;
       
  1129     }
       
  1130 
       
  1131     public SystemTrayPeer createSystemTray(SystemTray target) throws HeadlessException {
       
  1132         SystemTrayPeer peer = new XSystemTrayPeer(target);
       
  1133         return peer;
       
  1134     }
       
  1135 
       
  1136     public boolean isTraySupported() {
       
  1137         XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
       
  1138         if (peer != null) {
       
  1139             return peer.isAvailable();
       
  1140         }
       
  1141         return false;
       
  1142     }
       
  1143 
       
  1144     @Override
       
  1145     public DataTransferer getDataTransferer() {
       
  1146         return XDataTransferer.getInstanceImpl();
       
  1147     }
       
  1148 
       
  1149     /**
       
  1150      * Returns the supported cursor size
       
  1151      */
       
  1152     public Dimension getBestCursorSize(int preferredWidth, int preferredHeight) {
       
  1153         return XCustomCursor.getBestCursorSize(
       
  1154                                                java.lang.Math.max(1,preferredWidth), java.lang.Math.max(1,preferredHeight));
       
  1155     }
       
  1156 
       
  1157 
       
  1158     public int getMaximumCursorColors() {
       
  1159         return 2;  // Black and white.
       
  1160     }
       
  1161 
       
  1162     public Map<TextAttribute, ?> mapInputMethodHighlight( InputMethodHighlight highlight) {
       
  1163         return XInputMethod.mapInputMethodHighlight(highlight);
       
  1164     }
       
  1165     @Override
       
  1166     public boolean getLockingKeyState(int key) {
       
  1167         if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
       
  1168                key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
       
  1169             throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
       
  1170         }
       
  1171         awtLock();
       
  1172         try {
       
  1173             return getModifierState( key );
       
  1174         } finally {
       
  1175             awtUnlock();
       
  1176         }
       
  1177     }
       
  1178 
       
  1179     public  Clipboard getSystemClipboard() {
       
  1180         SecurityManager security = System.getSecurityManager();
       
  1181         if (security != null) {
       
  1182             security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION);
       
  1183         }
       
  1184         synchronized (this) {
       
  1185             if (clipboard == null) {
       
  1186                 clipboard = new XClipboard("System", "CLIPBOARD");
       
  1187             }
       
  1188         }
       
  1189         return clipboard;
       
  1190     }
       
  1191 
       
  1192     public Clipboard getSystemSelection() {
       
  1193         SecurityManager security = System.getSecurityManager();
       
  1194         if (security != null) {
       
  1195             security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION);
       
  1196         }
       
  1197         synchronized (this) {
       
  1198             if (selection == null) {
       
  1199                 selection = new XClipboard("Selection", "PRIMARY");
       
  1200             }
       
  1201         }
       
  1202         return selection;
       
  1203     }
       
  1204 
       
  1205     public void beep() {
       
  1206         awtLock();
       
  1207         try {
       
  1208             XlibWrapper.XBell(getDisplay(), 0);
       
  1209             XlibWrapper.XFlush(getDisplay());
       
  1210         } finally {
       
  1211             awtUnlock();
       
  1212         }
       
  1213     }
       
  1214 
       
  1215     public PrintJob getPrintJob(final Frame frame, final String doctitle,
       
  1216                                 final Properties props) {
       
  1217 
       
  1218         if (frame == null) {
       
  1219             throw new NullPointerException("frame must not be null");
       
  1220         }
       
  1221 
       
  1222         PrintJob2D printJob = new PrintJob2D(frame, doctitle, props);
       
  1223 
       
  1224         if (printJob.printDialog() == false) {
       
  1225             printJob = null;
       
  1226         }
       
  1227         return printJob;
       
  1228     }
       
  1229 
       
  1230     public PrintJob getPrintJob(final Frame frame, final String doctitle,
       
  1231                 final JobAttributes jobAttributes,
       
  1232                 final PageAttributes pageAttributes)
       
  1233     {
       
  1234         if (frame == null) {
       
  1235             throw new NullPointerException("frame must not be null");
       
  1236         }
       
  1237 
       
  1238         PrintJob2D printJob = new PrintJob2D(frame, doctitle,
       
  1239                                              jobAttributes, pageAttributes);
       
  1240 
       
  1241         if (printJob.printDialog() == false) {
       
  1242             printJob = null;
       
  1243         }
       
  1244 
       
  1245         return printJob;
       
  1246     }
       
  1247 
       
  1248     static void XSync() {
       
  1249         awtLock();
       
  1250         try {
       
  1251             XlibWrapper.XSync(getDisplay(),0);
       
  1252         } finally {
       
  1253             awtUnlock();
       
  1254         }
       
  1255     }
       
  1256 
       
  1257     public int getScreenResolution() {
       
  1258         long display = getDisplay();
       
  1259         awtLock();
       
  1260         try {
       
  1261             return (int) ((XlibWrapper.DisplayWidth(display,
       
  1262                 XlibWrapper.DefaultScreen(display)) * 25.4) /
       
  1263                     XlibWrapper.DisplayWidthMM(display,
       
  1264                 XlibWrapper.DefaultScreen(display)));
       
  1265         } finally {
       
  1266             awtUnlock();
       
  1267         }
       
  1268     }
       
  1269 
       
  1270     static native long getDefaultXColormap();
       
  1271     static native long getDefaultScreenData();
       
  1272 
       
  1273     static ColorModel screenmodel;
       
  1274 
       
  1275     static ColorModel getStaticColorModel() {
       
  1276         if (screenmodel == null) {
       
  1277             screenmodel = config.getColorModel ();
       
  1278         }
       
  1279         return screenmodel;
       
  1280     }
       
  1281 
       
  1282     public ColorModel getColorModel() {
       
  1283         return getStaticColorModel();
       
  1284     }
       
  1285 
       
  1286     /**
       
  1287      * Returns a new input method adapter descriptor for native input methods.
       
  1288      */
       
  1289     public InputMethodDescriptor getInputMethodAdapterDescriptor() throws AWTException {
       
  1290         return new XInputMethodDescriptor();
       
  1291     }
       
  1292 
       
  1293     /**
       
  1294      * Returns whether enableInputMethods should be set to true for peered
       
  1295      * TextComponent instances on this platform. True by default.
       
  1296      */
       
  1297     @Override
       
  1298     public boolean enableInputMethodsForTextComponent() {
       
  1299         return true;
       
  1300     }
       
  1301 
       
  1302     static int getMultiClickTime() {
       
  1303         if (awt_multiclick_time == 0) {
       
  1304             initializeMultiClickTime();
       
  1305         }
       
  1306         return awt_multiclick_time;
       
  1307     }
       
  1308     static void initializeMultiClickTime() {
       
  1309         awtLock();
       
  1310         try {
       
  1311             try {
       
  1312                 String multiclick_time_query = XlibWrapper.XGetDefault(XToolkit.getDisplay(), "*", "multiClickTime");
       
  1313                 if (multiclick_time_query != null) {
       
  1314                     awt_multiclick_time = (int)Long.parseLong(multiclick_time_query);
       
  1315                 } else {
       
  1316                     multiclick_time_query = XlibWrapper.XGetDefault(XToolkit.getDisplay(),
       
  1317                                                                     "OpenWindows", "MultiClickTimeout");
       
  1318                     if (multiclick_time_query != null) {
       
  1319                         /* Note: OpenWindows.MultiClickTimeout is in tenths of
       
  1320                            a second, so we need to multiply by 100 to convert to
       
  1321                            milliseconds */
       
  1322                         awt_multiclick_time = (int)Long.parseLong(multiclick_time_query) * 100;
       
  1323                     } else {
       
  1324                         awt_multiclick_time = AWT_MULTICLICK_DEFAULT_TIME;
       
  1325                     }
       
  1326                 }
       
  1327             } catch (NumberFormatException nf) {
       
  1328                 awt_multiclick_time = AWT_MULTICLICK_DEFAULT_TIME;
       
  1329             } catch (NullPointerException npe) {
       
  1330                 awt_multiclick_time = AWT_MULTICLICK_DEFAULT_TIME;
       
  1331             }
       
  1332         } finally {
       
  1333             awtUnlock();
       
  1334         }
       
  1335         if (awt_multiclick_time == 0) {
       
  1336             awt_multiclick_time = AWT_MULTICLICK_DEFAULT_TIME;
       
  1337         }
       
  1338     }
       
  1339 
       
  1340     public boolean isFrameStateSupported(int state)
       
  1341       throws HeadlessException
       
  1342     {
       
  1343         if (state == Frame.NORMAL || state == Frame.ICONIFIED) {
       
  1344             return true;
       
  1345         } else {
       
  1346             return XWM.getWM().supportsExtendedState(state);
       
  1347         }
       
  1348     }
       
  1349 
       
  1350     static void dumpPeers() {
       
  1351         if (log.isLoggable(PlatformLogger.Level.FINE)) {
       
  1352             log.fine("Mapped windows:");
       
  1353             winMap.forEach((k, v) -> {
       
  1354                 log.fine(k + "->" + v);
       
  1355                 if (v instanceof XComponentPeer) {
       
  1356                     Component target = (Component)((XComponentPeer)v).getTarget();
       
  1357                     log.fine("\ttarget: " + target);
       
  1358                 }
       
  1359             });
       
  1360 
       
  1361             SunToolkit.dumpPeers(log);
       
  1362 
       
  1363             log.fine("Mapped special peers:");
       
  1364             specialPeerMap.forEach((k, v) -> {
       
  1365                 log.fine(k + "->" + v);
       
  1366             });
       
  1367 
       
  1368             log.fine("Mapped dispatchers:");
       
  1369             winToDispatcher.forEach((k, v) -> {
       
  1370                 log.fine(k + "->" + v);
       
  1371             });
       
  1372         }
       
  1373     }
       
  1374 
       
  1375     /* Protected with awt_lock. */
       
  1376     private static boolean initialized;
       
  1377     private static boolean timeStampUpdated;
       
  1378     private static long timeStamp;
       
  1379 
       
  1380     private static final XEventDispatcher timeFetcher =
       
  1381     new XEventDispatcher() {
       
  1382             public void dispatchEvent(XEvent ev) {
       
  1383                 switch (ev.get_type()) {
       
  1384                   case XConstants.PropertyNotify:
       
  1385                       XPropertyEvent xpe = ev.get_xproperty();
       
  1386 
       
  1387                       awtLock();
       
  1388                       try {
       
  1389                           timeStamp = xpe.get_time();
       
  1390                           timeStampUpdated = true;
       
  1391                           awtLockNotifyAll();
       
  1392                       } finally {
       
  1393                           awtUnlock();
       
  1394                       }
       
  1395 
       
  1396                       break;
       
  1397                 }
       
  1398             }
       
  1399         };
       
  1400 
       
  1401     private static XAtom _XA_JAVA_TIME_PROPERTY_ATOM;
       
  1402 
       
  1403     static long getCurrentServerTime() {
       
  1404         awtLock();
       
  1405         try {
       
  1406             try {
       
  1407                 if (!initialized) {
       
  1408                     XToolkit.addEventDispatcher(XBaseWindow.getXAWTRootWindow().getWindow(),
       
  1409                                                 timeFetcher);
       
  1410                     _XA_JAVA_TIME_PROPERTY_ATOM = XAtom.get("_SUNW_JAVA_AWT_TIME");
       
  1411                     initialized = true;
       
  1412                 }
       
  1413                 timeStampUpdated = false;
       
  1414                 XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
       
  1415                                             XBaseWindow.getXAWTRootWindow().getWindow(),
       
  1416                                             _XA_JAVA_TIME_PROPERTY_ATOM.getAtom(), XAtom.XA_ATOM, 32,
       
  1417                                             XConstants.PropModeAppend,
       
  1418                                             0, 0);
       
  1419                 XlibWrapper.XFlush(XToolkit.getDisplay());
       
  1420 
       
  1421                 if (isToolkitThread()) {
       
  1422                     XEvent event = new XEvent();
       
  1423                     try {
       
  1424                         XlibWrapper.XWindowEvent(XToolkit.getDisplay(),
       
  1425                                                  XBaseWindow.getXAWTRootWindow().getWindow(),
       
  1426                                                  XConstants.PropertyChangeMask,
       
  1427                                                  event.pData);
       
  1428                         timeFetcher.dispatchEvent(event);
       
  1429                     }
       
  1430                     finally {
       
  1431                         event.dispose();
       
  1432                     }
       
  1433                 }
       
  1434                 else {
       
  1435                     while (!timeStampUpdated) {
       
  1436                         awtLockWait();
       
  1437                     }
       
  1438                 }
       
  1439             } catch (InterruptedException ie) {
       
  1440             // Note: the returned timeStamp can be incorrect in this case.
       
  1441                 if (log.isLoggable(PlatformLogger.Level.FINE)) {
       
  1442                     log.fine("Catched exception, timeStamp may not be correct (ie = " + ie + ")");
       
  1443                 }
       
  1444             }
       
  1445         } finally {
       
  1446             awtUnlock();
       
  1447         }
       
  1448         return timeStamp;
       
  1449     }
       
  1450     protected void initializeDesktopProperties() {
       
  1451         desktopProperties.put("DnD.Autoscroll.initialDelay",
       
  1452                               Integer.valueOf(50));
       
  1453         desktopProperties.put("DnD.Autoscroll.interval",
       
  1454                               Integer.valueOf(50));
       
  1455         desktopProperties.put("DnD.Autoscroll.cursorHysteresis",
       
  1456                               Integer.valueOf(5));
       
  1457         desktopProperties.put("Shell.shellFolderManager",
       
  1458                               "sun.awt.shell.ShellFolderManager");
       
  1459         // Don't want to call getMultiClickTime() if we are headless
       
  1460         if (!GraphicsEnvironment.isHeadless()) {
       
  1461             desktopProperties.put("awt.multiClickInterval",
       
  1462                                   Integer.valueOf(getMultiClickTime()));
       
  1463             desktopProperties.put("awt.mouse.numButtons",
       
  1464                                   Integer.valueOf(getNumberOfButtons()));
       
  1465         }
       
  1466     }
       
  1467 
       
  1468     /**
       
  1469      * This method runs through the XPointer and XExtendedPointer array.
       
  1470      * XExtendedPointer has priority because on some systems XPointer
       
  1471      * (which is assigned to the virtual pointer) reports the maximum
       
  1472      * capabilities of the mouse pointer (i.e. 32 physical buttons).
       
  1473      */
       
  1474     private native int getNumberOfButtonsImpl();
       
  1475 
       
  1476     @Override
       
  1477     public int getNumberOfButtons(){
       
  1478         awtLock();
       
  1479         try {
       
  1480             if (numberOfButtons == 0) {
       
  1481                 numberOfButtons = getNumberOfButtonsImpl();
       
  1482                 numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
       
  1483                 //4th and 5th buttons are for wheel and shouldn't be reported as buttons.
       
  1484                 //If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
       
  1485                 //If we have 3 physical buttons and a wheel, we report 3 buttons.
       
  1486                 //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
       
  1487                 if (numberOfButtons >=5) {
       
  1488                     numberOfButtons -= 2;
       
  1489                 } else if (numberOfButtons == 4 || numberOfButtons ==5){
       
  1490                     numberOfButtons = 3;
       
  1491                 }
       
  1492             }
       
  1493             //Assume don't have to re-query the number again and again.
       
  1494             return numberOfButtons;
       
  1495         } finally {
       
  1496             awtUnlock();
       
  1497         }
       
  1498     }
       
  1499 
       
  1500     static int getNumberOfButtonsForMask() {
       
  1501         return Math.min(XConstants.MAX_BUTTONS, ((SunToolkit) (Toolkit.getDefaultToolkit())).getNumberOfButtons());
       
  1502     }
       
  1503 
       
  1504     private final static String prefix  = "DnD.Cursor.";
       
  1505     private final static String postfix = ".32x32";
       
  1506     private static final String dndPrefix  = "DnD.";
       
  1507 
       
  1508     protected Object lazilyLoadDesktopProperty(String name) {
       
  1509         if (name.startsWith(prefix)) {
       
  1510             String cursorName = name.substring(prefix.length(), name.length()) + postfix;
       
  1511 
       
  1512             try {
       
  1513                 return Cursor.getSystemCustomCursor(cursorName);
       
  1514             } catch (AWTException awte) {
       
  1515                 throw new RuntimeException("cannot load system cursor: " + cursorName, awte);
       
  1516             }
       
  1517         }
       
  1518 
       
  1519         if (name.equals("awt.dynamicLayoutSupported")) {
       
  1520             return  Boolean.valueOf(isDynamicLayoutSupported());
       
  1521         }
       
  1522 
       
  1523         if (initXSettingsIfNeeded(name)) {
       
  1524             return desktopProperties.get(name);
       
  1525         }
       
  1526 
       
  1527         return super.lazilyLoadDesktopProperty(name);
       
  1528     }
       
  1529 
       
  1530     public synchronized void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
       
  1531         if (name == null) {
       
  1532             // See JavaDoc for the Toolkit.addPropertyChangeListener() method
       
  1533             return;
       
  1534         }
       
  1535         initXSettingsIfNeeded(name);
       
  1536         super.addPropertyChangeListener(name, pcl);
       
  1537     }
       
  1538 
       
  1539     /**
       
  1540      * Initializes XAWTXSettings if a property for a given property name is provided by
       
  1541      * XSettings and they are not initialized yet.
       
  1542      *
       
  1543      * @return true if the method has initialized XAWTXSettings.
       
  1544      */
       
  1545     private boolean initXSettingsIfNeeded(final String propName) {
       
  1546         if (!loadedXSettings &&
       
  1547             (propName.startsWith("gnome.") ||
       
  1548              propName.equals(SunToolkit.DESKTOPFONTHINTS) ||
       
  1549              propName.startsWith(dndPrefix)))
       
  1550         {
       
  1551             loadedXSettings = true;
       
  1552             if (!GraphicsEnvironment.isHeadless()) {
       
  1553                 loadXSettings();
       
  1554                 /* If no desktop font hint could be retrieved, check for
       
  1555                  * KDE running KWin and retrieve settings from fontconfig.
       
  1556                  * If that isn't found let SunToolkit will see if there's a
       
  1557                  * system property set by a user.
       
  1558                  */
       
  1559                 if (desktopProperties.get(SunToolkit.DESKTOPFONTHINTS) == null) {
       
  1560                     if (XWM.isKDE2()) {
       
  1561                         Object hint = FontConfigManager.getFontConfigAAHint();
       
  1562                         if (hint != null) {
       
  1563                             /* set the fontconfig/KDE property so that
       
  1564                              * getDesktopHints() below will see it
       
  1565                              * and set the public property.
       
  1566                              */
       
  1567                             desktopProperties.put(UNIXToolkit.FONTCONFIGAAHINT,
       
  1568                                                   hint);
       
  1569                         }
       
  1570                     }
       
  1571                     desktopProperties.put(SunToolkit.DESKTOPFONTHINTS,
       
  1572                                           SunToolkit.getDesktopFontHints());
       
  1573                 }
       
  1574 
       
  1575                 return true;
       
  1576             }
       
  1577         }
       
  1578         return false;
       
  1579     }
       
  1580 
       
  1581     private void loadXSettings() {
       
  1582        xs = new XAWTXSettings();
       
  1583     }
       
  1584 
       
  1585     /**
       
  1586      * Callback from the native side indicating some, or all, of the
       
  1587      * desktop properties have changed and need to be reloaded.
       
  1588      * <code>data</code> is the byte array directly from the x server and
       
  1589      * may be in little endian format.
       
  1590      * <p>
       
  1591      * NB: This could be called from any thread if triggered by
       
  1592      * <code>loadXSettings</code>.  It is called from the System EDT
       
  1593      * if triggered by an XSETTINGS change.
       
  1594      */
       
  1595     void parseXSettings(int screen_XXX_ignored,Map<String, Object> updatedSettings) {
       
  1596 
       
  1597         if (updatedSettings == null || updatedSettings.isEmpty()) {
       
  1598             return;
       
  1599         }
       
  1600 
       
  1601         Iterator<Map.Entry<String, Object>> i = updatedSettings.entrySet().iterator();
       
  1602         while (i.hasNext()) {
       
  1603             Map.Entry<String, Object> e = i.next();
       
  1604             String name = e.getKey();
       
  1605 
       
  1606             name = "gnome." + name;
       
  1607             setDesktopProperty(name, e.getValue());
       
  1608             if (log.isLoggable(PlatformLogger.Level.FINE)) {
       
  1609                 log.fine("name = " + name + " value = " + e.getValue());
       
  1610             }
       
  1611 
       
  1612             // XXX: we probably want to do something smarter.  In
       
  1613             // particular, "Net" properties are of interest to the
       
  1614             // "core" AWT itself.  E.g.
       
  1615             //
       
  1616             // Net/DndDragThreshold -> ???
       
  1617             // Net/DoubleClickTime  -> awt.multiClickInterval
       
  1618         }
       
  1619 
       
  1620         setDesktopProperty(SunToolkit.DESKTOPFONTHINTS,
       
  1621                            SunToolkit.getDesktopFontHints());
       
  1622 
       
  1623         Integer dragThreshold = null;
       
  1624         synchronized (this) {
       
  1625             dragThreshold = (Integer)desktopProperties.get("gnome.Net/DndDragThreshold");
       
  1626         }
       
  1627         if (dragThreshold != null) {
       
  1628             setDesktopProperty("DnD.gestureMotionThreshold", dragThreshold);
       
  1629         }
       
  1630 
       
  1631     }
       
  1632 
       
  1633 
       
  1634 
       
  1635     static int altMask;
       
  1636     static int metaMask;
       
  1637     static int numLockMask;
       
  1638     static int modeSwitchMask;
       
  1639     static int modLockIsShiftLock;
       
  1640 
       
  1641     /* Like XKeysymToKeycode, but ensures that keysym is the primary
       
  1642     * symbol on the keycode returned.  Returns zero otherwise.
       
  1643     */
       
  1644     static int keysymToPrimaryKeycode(long sym) {
       
  1645         awtLock();
       
  1646         try {
       
  1647             int code = XlibWrapper.XKeysymToKeycode(getDisplay(), sym);
       
  1648             if (code == 0) {
       
  1649                 return 0;
       
  1650             }
       
  1651             long primary = XlibWrapper.XKeycodeToKeysym(getDisplay(), code, 0);
       
  1652             if (sym != primary) {
       
  1653                 return 0;
       
  1654             }
       
  1655             return code;
       
  1656         } finally {
       
  1657             awtUnlock();
       
  1658         }
       
  1659     }
       
  1660     static boolean getModifierState( int jkc ) {
       
  1661         int iKeyMask = 0;
       
  1662         long ks = XKeysym.javaKeycode2Keysym( jkc );
       
  1663         int  kc = XlibWrapper.XKeysymToKeycode(getDisplay(), ks);
       
  1664         if (kc == 0) {
       
  1665             return false;
       
  1666         }
       
  1667         awtLock();
       
  1668         try {
       
  1669             XModifierKeymap modmap = new XModifierKeymap(
       
  1670                  XlibWrapper.XGetModifierMapping(getDisplay()));
       
  1671 
       
  1672             int nkeys = modmap.get_max_keypermod();
       
  1673 
       
  1674             long map_ptr = modmap.get_modifiermap();
       
  1675             for( int k = 0; k < 8; k++ ) {
       
  1676                 for (int i = 0; i < nkeys; ++i) {
       
  1677                     int keycode = Native.getUByte(map_ptr, k * nkeys + i);
       
  1678                     if (keycode == 0) {
       
  1679                         continue; // ignore zero keycode
       
  1680                     }
       
  1681                     if (kc == keycode) {
       
  1682                         iKeyMask = 1 << k;
       
  1683                         break;
       
  1684                     }
       
  1685                 }
       
  1686                 if( iKeyMask != 0 ) {
       
  1687                     break;
       
  1688                 }
       
  1689             }
       
  1690             XlibWrapper.XFreeModifiermap(modmap.pData);
       
  1691             if (iKeyMask == 0 ) {
       
  1692                 return false;
       
  1693             }
       
  1694             // Now we know to which modifier is assigned the keycode
       
  1695             // correspondent to the keysym correspondent to the java
       
  1696             // keycode. We are going to check a state of this modifier.
       
  1697             // If a modifier is a weird one, we cannot help it.
       
  1698             long window = 0;
       
  1699             try{
       
  1700                 // get any application window
       
  1701                 window = winMap.firstKey().longValue();
       
  1702             }catch(NoSuchElementException nex) {
       
  1703                 // get root window
       
  1704                 window = getDefaultRootWindow();
       
  1705             }
       
  1706             boolean res = XlibWrapper.XQueryPointer(getDisplay(), window,
       
  1707                                             XlibWrapper.larg1, //root
       
  1708                                             XlibWrapper.larg2, //child
       
  1709                                             XlibWrapper.larg3, //root_x
       
  1710                                             XlibWrapper.larg4, //root_y
       
  1711                                             XlibWrapper.larg5, //child_x
       
  1712                                             XlibWrapper.larg6, //child_y
       
  1713                                             XlibWrapper.larg7);//mask
       
  1714             int mask = Native.getInt(XlibWrapper.larg7);
       
  1715             return ((mask & iKeyMask) != 0);
       
  1716         } finally {
       
  1717             awtUnlock();
       
  1718         }
       
  1719     }
       
  1720 
       
  1721     /* Assign meaning - alt, meta, etc. - to X modifiers mod1 ... mod5.
       
  1722      * Only consider primary symbols on keycodes attached to modifiers.
       
  1723      */
       
  1724     static void setupModifierMap() {
       
  1725         final int metaL = keysymToPrimaryKeycode(XKeySymConstants.XK_Meta_L);
       
  1726         final int metaR = keysymToPrimaryKeycode(XKeySymConstants.XK_Meta_R);
       
  1727         final int altL = keysymToPrimaryKeycode(XKeySymConstants.XK_Alt_L);
       
  1728         final int altR = keysymToPrimaryKeycode(XKeySymConstants.XK_Alt_R);
       
  1729         final int numLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Num_Lock);
       
  1730         final int modeSwitch = keysymToPrimaryKeycode(XKeySymConstants.XK_Mode_switch);
       
  1731         final int shiftLock = keysymToPrimaryKeycode(XKeySymConstants.XK_Shift_Lock);
       
  1732         final int capsLock  = keysymToPrimaryKeycode(XKeySymConstants.XK_Caps_Lock);
       
  1733 
       
  1734         final int modmask[] = { XConstants.ShiftMask, XConstants.LockMask, XConstants.ControlMask, XConstants.Mod1Mask,
       
  1735             XConstants.Mod2Mask, XConstants.Mod3Mask, XConstants.Mod4Mask, XConstants.Mod5Mask };
       
  1736 
       
  1737         log.fine("In setupModifierMap");
       
  1738         awtLock();
       
  1739         try {
       
  1740             XModifierKeymap modmap = new XModifierKeymap(
       
  1741                  XlibWrapper.XGetModifierMapping(getDisplay()));
       
  1742 
       
  1743             int nkeys = modmap.get_max_keypermod();
       
  1744 
       
  1745             long map_ptr = modmap.get_modifiermap();
       
  1746 
       
  1747             for (int modn = XConstants.Mod1MapIndex;
       
  1748                  modn <= XConstants.Mod5MapIndex;
       
  1749                  ++modn)
       
  1750             {
       
  1751                 for (int i = 0; i < nkeys; ++i) {
       
  1752                     /* for each keycode attached to this modifier */
       
  1753                     int keycode = Native.getUByte(map_ptr, modn * nkeys + i);
       
  1754 
       
  1755                     if (keycode == 0) {
       
  1756                         break;
       
  1757                     }
       
  1758                     if (metaMask == 0 &&
       
  1759                         (keycode == metaL || keycode == metaR))
       
  1760                     {
       
  1761                         metaMask = modmask[modn];
       
  1762                         break;
       
  1763                     }
       
  1764                     if (altMask == 0 && (keycode == altL || keycode == altR)) {
       
  1765                         altMask = modmask[modn];
       
  1766                         break;
       
  1767                     }
       
  1768                     if (numLockMask == 0 && keycode == numLock) {
       
  1769                         numLockMask = modmask[modn];
       
  1770                         break;
       
  1771                     }
       
  1772                     if (modeSwitchMask == 0 && keycode == modeSwitch) {
       
  1773                         modeSwitchMask = modmask[modn];
       
  1774                         break;
       
  1775                     }
       
  1776                     continue;
       
  1777                 }
       
  1778             }
       
  1779             modLockIsShiftLock = 0;
       
  1780             for (int j = 0; j < nkeys; ++j) {
       
  1781                 int keycode = Native.getUByte(map_ptr, XConstants.LockMapIndex * nkeys + j);
       
  1782                 if (keycode == 0) {
       
  1783                     break;
       
  1784                 }
       
  1785                 if (keycode == shiftLock) {
       
  1786                     modLockIsShiftLock = 1;
       
  1787                     break;
       
  1788                 }
       
  1789                 if (keycode == capsLock) {
       
  1790                     break;
       
  1791                 }
       
  1792             }
       
  1793             XlibWrapper.XFreeModifiermap(modmap.pData);
       
  1794         } finally {
       
  1795             awtUnlock();
       
  1796         }
       
  1797         if (log.isLoggable(PlatformLogger.Level.FINE)) {
       
  1798             log.fine("metaMask = " + metaMask);
       
  1799             log.fine("altMask = " + altMask);
       
  1800             log.fine("numLockMask = " + numLockMask);
       
  1801             log.fine("modeSwitchMask = " + modeSwitchMask);
       
  1802             log.fine("modLockIsShiftLock = " + modLockIsShiftLock);
       
  1803         }
       
  1804     }
       
  1805 
       
  1806 
       
  1807     private static SortedMap<Long, java.util.List<Runnable>> timeoutTasks;
       
  1808 
       
  1809     /**
       
  1810      * Removed the task from the list of waiting-to-be called tasks.
       
  1811      * If the task has been scheduled several times removes only first one.
       
  1812      */
       
  1813     static void remove(Runnable task) {
       
  1814         if (task == null) {
       
  1815             throw new NullPointerException("task is null");
       
  1816         }
       
  1817         awtLock();
       
  1818         try {
       
  1819             if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
       
  1820                 timeoutTaskLog.finer("Removing task " + task);
       
  1821             }
       
  1822             if (timeoutTasks == null) {
       
  1823                 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
       
  1824                     timeoutTaskLog.finer("Task is not scheduled");
       
  1825                 }
       
  1826                 return;
       
  1827             }
       
  1828             Collection<java.util.List<Runnable>> values = timeoutTasks.values();
       
  1829             Iterator<java.util.List<Runnable>> iter = values.iterator();
       
  1830             while (iter.hasNext()) {
       
  1831                 java.util.List<Runnable> list = iter.next();
       
  1832                 boolean removed = false;
       
  1833                 if (list.contains(task)) {
       
  1834                     list.remove(task);
       
  1835                     if (list.isEmpty()) {
       
  1836                         iter.remove();
       
  1837                     }
       
  1838                     break;
       
  1839                 }
       
  1840             }
       
  1841         } finally {
       
  1842             awtUnlock();
       
  1843         }
       
  1844     }
       
  1845 
       
  1846     static native void wakeup_poll();
       
  1847 
       
  1848     /**
       
  1849      * Registers a Runnable which <code>run()</code> method will be called
       
  1850      * once on the toolkit thread when a specified interval of time elapses.
       
  1851      *
       
  1852      * @param task a Runnable which <code>run</code> method will be called
       
  1853      *        on the toolkit thread when <code>interval</code> milliseconds
       
  1854      *        elapse
       
  1855      * @param interval an interal in milliseconds
       
  1856      *
       
  1857      * @throws NullPointerException if <code>task</code> is <code>null</code>
       
  1858      * @throws IllegalArgumentException if <code>interval</code> is not positive
       
  1859      */
       
  1860     static void schedule(Runnable task, long interval) {
       
  1861         if (task == null) {
       
  1862             throw new NullPointerException("task is null");
       
  1863         }
       
  1864         if (interval <= 0) {
       
  1865             throw new IllegalArgumentException("interval " + interval + " is not positive");
       
  1866         }
       
  1867 
       
  1868         awtLock();
       
  1869         try {
       
  1870             if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
       
  1871                 timeoutTaskLog.finer("XToolkit.schedule(): current time={0}" +
       
  1872                                      ";  interval={1}" +
       
  1873                                      ";  task being added={2}" + ";  tasks before addition={3}",
       
  1874                                      Long.valueOf(System.currentTimeMillis()), Long.valueOf(interval), task, timeoutTasks);
       
  1875             }
       
  1876 
       
  1877             if (timeoutTasks == null) {
       
  1878                 timeoutTasks = new TreeMap<>();
       
  1879             }
       
  1880 
       
  1881             Long time = Long.valueOf(System.currentTimeMillis() + interval);
       
  1882             java.util.List<Runnable> tasks = timeoutTasks.get(time);
       
  1883             if (tasks == null) {
       
  1884                 tasks = new ArrayList<>(1);
       
  1885                 timeoutTasks.put(time, tasks);
       
  1886             }
       
  1887             tasks.add(task);
       
  1888 
       
  1889 
       
  1890             if (timeoutTasks.get(timeoutTasks.firstKey()) == tasks && tasks.size() == 1) {
       
  1891                 // Added task became first task - poll won't know
       
  1892                 // about it so we need to wake it up
       
  1893                 wakeup_poll();
       
  1894             }
       
  1895         }  finally {
       
  1896             awtUnlock();
       
  1897         }
       
  1898     }
       
  1899 
       
  1900     private long getNextTaskTime() {
       
  1901         awtLock();
       
  1902         try {
       
  1903             if (timeoutTasks == null || timeoutTasks.isEmpty()) {
       
  1904                 return -1L;
       
  1905             }
       
  1906             return timeoutTasks.firstKey();
       
  1907         } finally {
       
  1908             awtUnlock();
       
  1909         }
       
  1910     }
       
  1911 
       
  1912     /**
       
  1913      * Executes mature timeout tasks registered with schedule().
       
  1914      * Called from run() under awtLock.
       
  1915      */
       
  1916     private static void callTimeoutTasks() {
       
  1917         if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
       
  1918             timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" +
       
  1919                                  ";  tasks={1}", Long.valueOf(System.currentTimeMillis()), timeoutTasks);
       
  1920         }
       
  1921 
       
  1922         if (timeoutTasks == null || timeoutTasks.isEmpty()) {
       
  1923             return;
       
  1924         }
       
  1925 
       
  1926         Long currentTime = Long.valueOf(System.currentTimeMillis());
       
  1927         Long time = timeoutTasks.firstKey();
       
  1928 
       
  1929         while (time.compareTo(currentTime) <= 0) {
       
  1930             java.util.List<Runnable> tasks = timeoutTasks.remove(time);
       
  1931 
       
  1932             for (Iterator<Runnable> iter = tasks.iterator(); iter.hasNext();) {
       
  1933                 Runnable task = iter.next();
       
  1934 
       
  1935                 if (timeoutTaskLog.isLoggable(PlatformLogger.Level.FINER)) {
       
  1936                     timeoutTaskLog.finer("XToolkit.callTimeoutTasks(): current time={0}" +
       
  1937                                          ";  about to run task={1}", Long.valueOf(currentTime), task);
       
  1938                 }
       
  1939 
       
  1940                 try {
       
  1941                     task.run();
       
  1942                 } catch (ThreadDeath td) {
       
  1943                     throw td;
       
  1944                 } catch (Throwable thr) {
       
  1945                     processException(thr);
       
  1946                 }
       
  1947             }
       
  1948 
       
  1949             if (timeoutTasks.isEmpty()) {
       
  1950                 break;
       
  1951             }
       
  1952             time = timeoutTasks.firstKey();
       
  1953         }
       
  1954     }
       
  1955 
       
  1956     static long getAwtDefaultFg() {
       
  1957         return awt_defaultFg;
       
  1958     }
       
  1959 
       
  1960     static boolean isLeftMouseButton(MouseEvent me) {
       
  1961         switch (me.getID()) {
       
  1962           case MouseEvent.MOUSE_PRESSED:
       
  1963           case MouseEvent.MOUSE_RELEASED:
       
  1964               return (me.getButton() == MouseEvent.BUTTON1);
       
  1965           case MouseEvent.MOUSE_ENTERED:
       
  1966           case MouseEvent.MOUSE_EXITED:
       
  1967           case MouseEvent.MOUSE_CLICKED:
       
  1968           case MouseEvent.MOUSE_DRAGGED:
       
  1969               return ((me.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0);
       
  1970         }
       
  1971         return false;
       
  1972     }
       
  1973 
       
  1974     static boolean isRightMouseButton(MouseEvent me) {
       
  1975         int numButtons = ((Integer)getDefaultToolkit().getDesktopProperty("awt.mouse.numButtons")).intValue();
       
  1976         switch (me.getID()) {
       
  1977           case MouseEvent.MOUSE_PRESSED:
       
  1978           case MouseEvent.MOUSE_RELEASED:
       
  1979               return ((numButtons == 2 && me.getButton() == MouseEvent.BUTTON2) ||
       
  1980                        (numButtons > 2 && me.getButton() == MouseEvent.BUTTON3));
       
  1981           case MouseEvent.MOUSE_ENTERED:
       
  1982           case MouseEvent.MOUSE_EXITED:
       
  1983           case MouseEvent.MOUSE_CLICKED:
       
  1984           case MouseEvent.MOUSE_DRAGGED:
       
  1985               return ((numButtons == 2 && (me.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) != 0) ||
       
  1986                       (numButtons > 2 && (me.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0));
       
  1987         }
       
  1988         return false;
       
  1989     }
       
  1990 
       
  1991     static long reset_time_utc;
       
  1992     static final long WRAP_TIME_MILLIS = 0x00000000FFFFFFFFL;
       
  1993 
       
  1994     /*
       
  1995      * This function converts between the X server time (number of milliseconds
       
  1996      * since the last server reset) and the UTC time for the 'when' field of an
       
  1997      * InputEvent (or another event type with a timestamp).
       
  1998      */
       
  1999     static long nowMillisUTC_offset(long server_offset) {
       
  2000         // ported from awt_util.c
       
  2001         /*
       
  2002          * Because Time is of type 'unsigned long', it is possible that Time will
       
  2003          * never wrap when using 64-bit Xlib. However, if a 64-bit client
       
  2004          * connects to a 32-bit server, I suspect the values will still wrap. So
       
  2005          * we should not attempt to remove the wrap checking even if _LP64 is
       
  2006          * true.
       
  2007          */
       
  2008 
       
  2009         long current_time_utc = System.currentTimeMillis();
       
  2010         if (log.isLoggable(PlatformLogger.Level.FINER)) {
       
  2011             log.finer("reset_time=" + reset_time_utc + ", current_time=" + current_time_utc
       
  2012                       + ", server_offset=" + server_offset + ", wrap_time=" + WRAP_TIME_MILLIS);
       
  2013         }
       
  2014 
       
  2015         if ((current_time_utc - reset_time_utc) > WRAP_TIME_MILLIS) {
       
  2016             reset_time_utc = System.currentTimeMillis() - getCurrentServerTime();
       
  2017         }
       
  2018 
       
  2019         if (log.isLoggable(PlatformLogger.Level.FINER)) {
       
  2020             log.finer("result = " + (reset_time_utc + server_offset));
       
  2021         }
       
  2022         return reset_time_utc + server_offset;
       
  2023     }
       
  2024 
       
  2025     /**
       
  2026      * @see sun.awt.SunToolkit#needsXEmbedImpl
       
  2027      */
       
  2028     protected boolean needsXEmbedImpl() {
       
  2029         // XToolkit implements supports for XEmbed-client protocol and
       
  2030         // requires the supports from the embedding host for it to work.
       
  2031         return true;
       
  2032     }
       
  2033 
       
  2034     public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
       
  2035         return (modalityType == null) ||
       
  2036                (modalityType == Dialog.ModalityType.MODELESS) ||
       
  2037                (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
       
  2038                (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
       
  2039                (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
       
  2040     }
       
  2041 
       
  2042     public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
       
  2043         return (exclusionType == null) ||
       
  2044                (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) ||
       
  2045                (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) ||
       
  2046                (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
       
  2047     }
       
  2048 
       
  2049     static EventQueue getEventQueue(Object target) {
       
  2050         AppContext appContext = targetToAppContext(target);
       
  2051         if (appContext != null) {
       
  2052             return (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
       
  2053         }
       
  2054         return null;
       
  2055     }
       
  2056 
       
  2057     static void removeSourceEvents(EventQueue queue,
       
  2058                                    Object source,
       
  2059                                    boolean removeAllEvents) {
       
  2060         AWTAccessor.getEventQueueAccessor()
       
  2061             .removeSourceEvents(queue, source, removeAllEvents);
       
  2062     }
       
  2063 
       
  2064     public boolean isAlwaysOnTopSupported() {
       
  2065         for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) {
       
  2066             if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
       
  2067                 return true;
       
  2068             }
       
  2069         }
       
  2070         return false;
       
  2071     }
       
  2072 
       
  2073     public boolean useBufferPerWindow() {
       
  2074         return XToolkit.getBackingStoreType() == XConstants.NotUseful;
       
  2075     }
       
  2076 
       
  2077     /**
       
  2078      * Returns one of XConstants: NotUseful, WhenMapped or Always.
       
  2079      * If backing store is not available on at least one screen, or
       
  2080      * java2d uses DGA(which conflicts with backing store) on at least one screen,
       
  2081      * or the string system property "sun.awt.backingStore" is neither "Always"
       
  2082      * nor "WhenMapped", then the method returns XConstants.NotUseful.
       
  2083      * Otherwise, if the system property "sun.awt.backingStore" is "WhenMapped",
       
  2084      * then the method returns XConstants.WhenMapped.
       
  2085      * Otherwise (i.e., if the system property "sun.awt.backingStore" is "Always"),
       
  2086      * the method returns XConstants.Always.
       
  2087      */
       
  2088     static int getBackingStoreType() {
       
  2089         return backingStoreType;
       
  2090     }
       
  2091 
       
  2092     private static void setBackingStoreType() {
       
  2093         String prop = AccessController.doPrivileged(
       
  2094                 new sun.security.action.GetPropertyAction("sun.awt.backingStore"));
       
  2095 
       
  2096         if (prop == null) {
       
  2097             backingStoreType = XConstants.NotUseful;
       
  2098             if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
       
  2099                 backingStoreLog.config("The system property sun.awt.backingStore is not set" +
       
  2100                                        ", by default backingStore=NotUseful");
       
  2101             }
       
  2102             return;
       
  2103         }
       
  2104 
       
  2105         if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
       
  2106             backingStoreLog.config("The system property sun.awt.backingStore is " + prop);
       
  2107         }
       
  2108         prop = prop.toLowerCase();
       
  2109         if (prop.equals("always")) {
       
  2110             backingStoreType = XConstants.Always;
       
  2111         } else if (prop.equals("whenmapped")) {
       
  2112             backingStoreType = XConstants.WhenMapped;
       
  2113         } else {
       
  2114             backingStoreType = XConstants.NotUseful;
       
  2115         }
       
  2116 
       
  2117         if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
       
  2118             backingStoreLog.config("backingStore(as provided by the system property)=" +
       
  2119                                    ( backingStoreType == XConstants.NotUseful ? "NotUseful"
       
  2120                                      : backingStoreType == XConstants.WhenMapped ?
       
  2121                                      "WhenMapped" : "Always") );
       
  2122         }
       
  2123 
       
  2124         if (sun.java2d.x11.X11SurfaceData.isDgaAvailable()) {
       
  2125             backingStoreType = XConstants.NotUseful;
       
  2126 
       
  2127             if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
       
  2128                 backingStoreLog.config("DGA is available, backingStore=NotUseful");
       
  2129             }
       
  2130 
       
  2131             return;
       
  2132         }
       
  2133 
       
  2134         awtLock();
       
  2135         try {
       
  2136             int screenCount = XlibWrapper.ScreenCount(getDisplay());
       
  2137             for (int i = 0; i < screenCount; i++) {
       
  2138                 if (XlibWrapper.DoesBackingStore(XlibWrapper.ScreenOfDisplay(getDisplay(), i))
       
  2139                         == XConstants.NotUseful) {
       
  2140                     backingStoreType = XConstants.NotUseful;
       
  2141 
       
  2142                     if (backingStoreLog.isLoggable(PlatformLogger.Level.CONFIG)) {
       
  2143                         backingStoreLog.config("Backing store is not available on the screen " +
       
  2144                                                i + ", backingStore=NotUseful");
       
  2145                     }
       
  2146 
       
  2147                     return;
       
  2148                 }
       
  2149             }
       
  2150         } finally {
       
  2151             awtUnlock();
       
  2152         }
       
  2153     }
       
  2154 
       
  2155     /**
       
  2156      * One of XConstants: NotUseful, WhenMapped or Always.
       
  2157      */
       
  2158     private static int backingStoreType;
       
  2159 
       
  2160     static final int XSUN_KP_BEHAVIOR = 1;
       
  2161     static final int XORG_KP_BEHAVIOR = 2;
       
  2162     static final int    IS_SUN_KEYBOARD = 1;
       
  2163     static final int IS_NONSUN_KEYBOARD = 2;
       
  2164     static final int    IS_KANA_KEYBOARD = 1;
       
  2165     static final int IS_NONKANA_KEYBOARD = 2;
       
  2166 
       
  2167 
       
  2168     static int     awt_IsXsunKPBehavior = 0;
       
  2169     static boolean awt_UseXKB         = false;
       
  2170     static boolean awt_UseXKB_Calls   = false;
       
  2171     static int     awt_XKBBaseEventCode = 0;
       
  2172     static int     awt_XKBEffectiveGroup = 0; // so far, I don't use it leaving all calculations
       
  2173                                               // to XkbTranslateKeyCode
       
  2174     static long    awt_XKBDescPtr     = 0;
       
  2175 
       
  2176     /**
       
  2177      * Check for Xsun convention regarding numpad keys.
       
  2178      * Xsun and some other servers (i.e. derived from Xsun)
       
  2179      * under certain conditions process numpad keys unlike Xorg.
       
  2180      */
       
  2181     static boolean isXsunKPBehavior() {
       
  2182         awtLock();
       
  2183         try {
       
  2184             if( awt_IsXsunKPBehavior == 0 ) {
       
  2185                 if( XlibWrapper.IsXsunKPBehavior(getDisplay()) ) {
       
  2186                     awt_IsXsunKPBehavior = XSUN_KP_BEHAVIOR;
       
  2187                 }else{
       
  2188                     awt_IsXsunKPBehavior = XORG_KP_BEHAVIOR;
       
  2189                 }
       
  2190             }
       
  2191             return awt_IsXsunKPBehavior == XSUN_KP_BEHAVIOR ? true : false;
       
  2192         } finally {
       
  2193             awtUnlock();
       
  2194         }
       
  2195     }
       
  2196 
       
  2197     static int  sunOrNotKeyboard = 0;
       
  2198     static int kanaOrNotKeyboard = 0;
       
  2199     static void resetKeyboardSniffer() {
       
  2200         sunOrNotKeyboard  = 0;
       
  2201         kanaOrNotKeyboard = 0;
       
  2202     }
       
  2203     static boolean isSunKeyboard() {
       
  2204         if( sunOrNotKeyboard == 0 ) {
       
  2205             if( XlibWrapper.IsSunKeyboard( getDisplay() )) {
       
  2206                 sunOrNotKeyboard = IS_SUN_KEYBOARD;
       
  2207             }else{
       
  2208                 sunOrNotKeyboard = IS_NONSUN_KEYBOARD;
       
  2209             }
       
  2210         }
       
  2211         return (sunOrNotKeyboard == IS_SUN_KEYBOARD);
       
  2212     }
       
  2213     static boolean isKanaKeyboard() {
       
  2214         if( kanaOrNotKeyboard == 0 ) {
       
  2215             if( XlibWrapper.IsKanaKeyboard( getDisplay() )) {
       
  2216                 kanaOrNotKeyboard = IS_KANA_KEYBOARD;
       
  2217             }else{
       
  2218                 kanaOrNotKeyboard = IS_NONKANA_KEYBOARD;
       
  2219             }
       
  2220         }
       
  2221         return (kanaOrNotKeyboard == IS_KANA_KEYBOARD);
       
  2222     }
       
  2223     static boolean isXKBenabled() {
       
  2224         awtLock();
       
  2225         try {
       
  2226             return awt_UseXKB;
       
  2227         } finally {
       
  2228             awtUnlock();
       
  2229         }
       
  2230     }
       
  2231 
       
  2232     /**
       
  2233       Query XKEYBOARD extension.
       
  2234       If possible, initialize xkb library.
       
  2235     */
       
  2236     static boolean tryXKB() {
       
  2237         awtLock();
       
  2238         try {
       
  2239             String name = "XKEYBOARD";
       
  2240             // First, if there is extension at all.
       
  2241             awt_UseXKB = XlibWrapper.XQueryExtension( getDisplay(), name, XlibWrapper.larg1, XlibWrapper.larg2, XlibWrapper.larg3);
       
  2242             if( awt_UseXKB ) {
       
  2243                 // There is a keyboard extension. Check if a client library is compatible.
       
  2244                 // If not, don't use xkb calls.
       
  2245                 // In this case we still may be Xkb-capable application.
       
  2246                 awt_UseXKB_Calls = XlibWrapper.XkbLibraryVersion( XlibWrapper.larg1, XlibWrapper.larg2);
       
  2247                 if( awt_UseXKB_Calls ) {
       
  2248                     awt_UseXKB_Calls = XlibWrapper.XkbQueryExtension( getDisplay(),  XlibWrapper.larg1, XlibWrapper.larg2,
       
  2249                                      XlibWrapper.larg3, XlibWrapper.larg4, XlibWrapper.larg5);
       
  2250                     if( awt_UseXKB_Calls ) {
       
  2251                         awt_XKBBaseEventCode = Native.getInt(XlibWrapper.larg2);
       
  2252                         XlibWrapper.XkbSelectEvents (getDisplay(),
       
  2253                                          XConstants.XkbUseCoreKbd,
       
  2254                                          XConstants.XkbNewKeyboardNotifyMask |
       
  2255                                                  XConstants.XkbMapNotifyMask ,//|
       
  2256                                                  //XConstants.XkbStateNotifyMask,
       
  2257                                          XConstants.XkbNewKeyboardNotifyMask |
       
  2258                                                  XConstants.XkbMapNotifyMask );//|
       
  2259                                                  //XConstants.XkbStateNotifyMask);
       
  2260 
       
  2261                         XlibWrapper.XkbSelectEventDetails(getDisplay(), XConstants.XkbUseCoreKbd,
       
  2262                                                      XConstants.XkbStateNotify,
       
  2263                                                      XConstants.XkbGroupStateMask,
       
  2264                                                      XConstants.XkbGroupStateMask);
       
  2265                                                      //XXX ? XkbGroupLockMask last, XkbAllStateComponentsMask before last?
       
  2266                         awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
       
  2267                                                      XConstants.XkbKeyTypesMask    |
       
  2268                                                      XConstants.XkbKeySymsMask     |
       
  2269                                                      XConstants.XkbModifierMapMask |
       
  2270                                                      XConstants.XkbVirtualModsMask,
       
  2271                                                      XConstants.XkbUseCoreKbd);
       
  2272 
       
  2273                         XlibWrapper.XkbSetDetectableAutoRepeat(getDisplay(), true);
       
  2274                     }
       
  2275                 }
       
  2276             }
       
  2277             return awt_UseXKB;
       
  2278         } finally {
       
  2279             awtUnlock();
       
  2280         }
       
  2281     }
       
  2282     static boolean canUseXKBCalls() {
       
  2283         awtLock();
       
  2284         try {
       
  2285             return awt_UseXKB_Calls;
       
  2286         } finally {
       
  2287             awtUnlock();
       
  2288         }
       
  2289     }
       
  2290     static int getXKBEffectiveGroup() {
       
  2291         awtLock();
       
  2292         try {
       
  2293             return awt_XKBEffectiveGroup;
       
  2294         } finally {
       
  2295             awtUnlock();
       
  2296         }
       
  2297     }
       
  2298     static int getXKBBaseEventCode() {
       
  2299         awtLock();
       
  2300         try {
       
  2301             return awt_XKBBaseEventCode;
       
  2302         } finally {
       
  2303             awtUnlock();
       
  2304         }
       
  2305     }
       
  2306     static long getXKBKbdDesc() {
       
  2307         awtLock();
       
  2308         try {
       
  2309             return awt_XKBDescPtr;
       
  2310         } finally {
       
  2311             awtUnlock();
       
  2312         }
       
  2313     }
       
  2314     void freeXKB() {
       
  2315         awtLock();
       
  2316         try {
       
  2317             if (awt_UseXKB_Calls && awt_XKBDescPtr != 0) {
       
  2318                 XlibWrapper.XkbFreeKeyboard(awt_XKBDescPtr, 0xFF, true);
       
  2319                 awt_XKBDescPtr = 0;
       
  2320             }
       
  2321         } finally {
       
  2322             awtUnlock();
       
  2323         }
       
  2324     }
       
  2325     private void processXkbChanges(XEvent ev) {
       
  2326         // mapping change --> refresh kbd map
       
  2327         // state change --> get a new effective group; do I really need it
       
  2328         //  or that should be left for XkbTranslateKeyCode?
       
  2329         XkbEvent xke = new XkbEvent( ev.getPData() );
       
  2330         int xkb_type = xke.get_any().get_xkb_type();
       
  2331         switch( xkb_type ) {
       
  2332             case XConstants.XkbNewKeyboardNotify :
       
  2333                  if( awt_XKBDescPtr != 0 ) {
       
  2334                      freeXKB();
       
  2335                  }
       
  2336                  awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
       
  2337                                               XConstants.XkbKeyTypesMask    |
       
  2338                                               XConstants.XkbKeySymsMask     |
       
  2339                                               XConstants.XkbModifierMapMask |
       
  2340                                               XConstants.XkbVirtualModsMask,
       
  2341                                               XConstants.XkbUseCoreKbd);
       
  2342                  //System.out.println("XkbNewKeyboard:"+(xke.get_new_kbd()));
       
  2343                  break;
       
  2344             case XConstants.XkbMapNotify :
       
  2345                  //TODO: provide a simple unit test.
       
  2346                  XlibWrapper.XkbGetUpdatedMap(getDisplay(),
       
  2347                                               XConstants.XkbKeyTypesMask    |
       
  2348                                               XConstants.XkbKeySymsMask     |
       
  2349                                               XConstants.XkbModifierMapMask |
       
  2350                                               XConstants.XkbVirtualModsMask,
       
  2351                                               awt_XKBDescPtr);
       
  2352                  //System.out.println("XkbMap:"+(xke.get_map()));
       
  2353                  break;
       
  2354             case XConstants.XkbStateNotify :
       
  2355                  // May use it later e.g. to obtain an effective group etc.
       
  2356                  //System.out.println("XkbState:"+(xke.get_state()));
       
  2357                  break;
       
  2358             default:
       
  2359                  //System.out.println("XkbEvent of xkb_type "+xkb_type);
       
  2360                  break;
       
  2361         }
       
  2362     }
       
  2363 
       
  2364     private static long eventNumber;
       
  2365     public static long getEventNumber() {
       
  2366         awtLock();
       
  2367         try {
       
  2368             return eventNumber;
       
  2369         } finally {
       
  2370             awtUnlock();
       
  2371         }
       
  2372     }
       
  2373 
       
  2374     private static XEventDispatcher oops_waiter;
       
  2375     private static boolean oops_updated;
       
  2376     private static boolean oops_move;
       
  2377 
       
  2378     /**
       
  2379      * @inheritDoc
       
  2380      */
       
  2381     protected boolean syncNativeQueue(final long timeout) {
       
  2382         XBaseWindow win = XBaseWindow.getXAWTRootWindow();
       
  2383 
       
  2384         if (oops_waiter == null) {
       
  2385             oops_waiter = new XEventDispatcher() {
       
  2386                     public void dispatchEvent(XEvent e) {
       
  2387                         if (e.get_type() == XConstants.ConfigureNotify) {
       
  2388                             // OOPS ConfigureNotify event catched
       
  2389                             oops_updated = true;
       
  2390                             awtLockNotifyAll();
       
  2391                         }
       
  2392                     }
       
  2393                 };
       
  2394         }
       
  2395 
       
  2396         awtLock();
       
  2397         try {
       
  2398             addEventDispatcher(win.getWindow(), oops_waiter);
       
  2399 
       
  2400             oops_updated = false;
       
  2401             long event_number = getEventNumber();
       
  2402             // Generate OOPS ConfigureNotify event
       
  2403             XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), oops_move ? 0 : 1, 0);
       
  2404             // Change win position each time to avoid system optimization
       
  2405             oops_move = !oops_move;
       
  2406             XSync();
       
  2407 
       
  2408             eventLog.finer("Generated OOPS ConfigureNotify event");
       
  2409 
       
  2410             long start = System.currentTimeMillis();
       
  2411             while (!oops_updated) {
       
  2412                 try {
       
  2413                     // Wait for OOPS ConfigureNotify event
       
  2414                     awtLockWait(timeout);
       
  2415                 } catch (InterruptedException e) {
       
  2416                     throw new RuntimeException(e);
       
  2417                 }
       
  2418                 // This "while" is a protection from spurious
       
  2419                 // wake-ups.  However, we shouldn't wait for too long
       
  2420                 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {
       
  2421                     throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
       
  2422                 }
       
  2423             }
       
  2424             // Don't take into account OOPS ConfigureNotify event
       
  2425             return getEventNumber() - event_number > 1;
       
  2426         } finally {
       
  2427             removeEventDispatcher(win.getWindow(), oops_waiter);
       
  2428             eventLog.finer("Exiting syncNativeQueue");
       
  2429             awtUnlock();
       
  2430         }
       
  2431     }
       
  2432     public void grab(Window w) {
       
  2433         if (w.getPeer() != null) {
       
  2434             ((XWindowPeer)w.getPeer()).setGrab(true);
       
  2435         }
       
  2436     }
       
  2437 
       
  2438     public void ungrab(Window w) {
       
  2439         if (w.getPeer() != null) {
       
  2440            ((XWindowPeer)w.getPeer()).setGrab(false);
       
  2441         }
       
  2442     }
       
  2443     /**
       
  2444      * Returns if the java.awt.Desktop class is supported on the current
       
  2445      * desktop.
       
  2446      * <p>
       
  2447      * The methods of java.awt.Desktop class are supported on the Gnome desktop.
       
  2448      * Check if the running desktop is Gnome by checking the window manager.
       
  2449      */
       
  2450     public boolean isDesktopSupported(){
       
  2451         return XDesktopPeer.isDesktopSupported();
       
  2452     }
       
  2453 
       
  2454     public DesktopPeer createDesktopPeer(Desktop target){
       
  2455         return new XDesktopPeer();
       
  2456     }
       
  2457 
       
  2458     public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
       
  2459         return areExtraMouseButtonsEnabled;
       
  2460     }
       
  2461 
       
  2462     @Override
       
  2463     public boolean isWindowOpacitySupported() {
       
  2464         XNETProtocol net_protocol = XWM.getWM().getNETProtocol();
       
  2465 
       
  2466         if (net_protocol == null) {
       
  2467             return false;
       
  2468         }
       
  2469 
       
  2470         return net_protocol.doOpacityProtocol();
       
  2471     }
       
  2472 
       
  2473     @Override
       
  2474     public boolean isWindowShapingSupported() {
       
  2475         return XlibUtil.isShapingSupported();
       
  2476     }
       
  2477 
       
  2478     @Override
       
  2479     public boolean isWindowTranslucencySupported() {
       
  2480         //NOTE: it may not be supported. The actual check is being performed
       
  2481         //      at com.sun.awt.AWTUtilities(). In X11 we need to check
       
  2482         //      whether there's any translucency-capable GC available.
       
  2483         return true;
       
  2484     }
       
  2485 
       
  2486     @Override
       
  2487     public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
       
  2488         if (!(gc instanceof X11GraphicsConfig)) {
       
  2489             return false;
       
  2490         }
       
  2491         return ((X11GraphicsConfig)gc).isTranslucencyCapable();
       
  2492     }
       
  2493 
       
  2494     /**
       
  2495      * Returns the value of "sun.awt.disablegrab" property. Default
       
  2496      * value is {@code false}.
       
  2497      */
       
  2498     public static boolean getSunAwtDisableGrab() {
       
  2499         return AccessController.doPrivileged(new GetBooleanAction("sun.awt.disablegrab"));
       
  2500     }
       
  2501 }