jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
changeset 1970 7718bf3a85ad
parent 1969 07500c30ab46
parent 1968 1a8fe25104ef
child 2650 44d88464a573
child 2451 597df8e1d786
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Oct 08 12:50:17 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Oct 08 13:01:40 2008 +0400
@@ -27,6 +27,7 @@
 import java.awt.*;
 import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
+import java.awt.event.KeyEvent;
 import java.awt.datatransfer.Clipboard;
 import java.awt.dnd.DragSource;
 import java.awt.dnd.DragGestureListener;
@@ -78,6 +79,25 @@
     // Dynamic Layout Resize client code setting
     protected static boolean dynamicLayoutSetting = false;
 
+    //Is it allowed to generate events assigned to extra mouse buttons.
+    //Set to true by default.
+    private static boolean areExtraMouseButtonsEnabled = true;
+
+    /**
+     * Number of buttons.
+     * By default it's taken from the system. If system value does not
+     * fit into int type range, use our own MAX_BUTTONS_SUPPORT value.
+     */
+    private static int numberOfButtons = 0;
+
+    /* XFree standard mention 24 buttons as maximum:
+     * http://www.xfree86.org/current/mouse.4.html
+     * We workaround systems supporting more than 24 buttons.
+     * Otherwise, we have to use long type values as masks
+     * which leads to API change.
+     */
+    private static int MAX_BUTTONS_SUPPORT = 24;
+
     /**
      * True when the x settings have been loaded.
      */
@@ -101,6 +121,11 @@
     static int awt_multiclick_time;
     static boolean securityWarningEnabled;
 
+    // WeakSet should be used here, but there is no such class
+    // in JDK (at least in JDK6 and earlier versions)
+    private WeakHashMap<Window, Boolean> overrideRedirectWindows =
+        new WeakHashMap<Window, Boolean>();
+
     private static int screenWidth = -1, screenHeight = -1; // Dimensions of default screen
     static long awt_defaultFg; // Pixel
     private static XMouseInfoPeer xPeer;
@@ -272,6 +297,9 @@
 
             arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
                 XCursorFontConstants.XC_arrow);
+            areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
+            //set system property if not yet assigned
+            System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
         } finally {
             awtUnlock();
         }
@@ -1079,6 +1107,19 @@
     public Map mapInputMethodHighlight(InputMethodHighlight highlight)     {
         return XInputMethod.mapInputMethodHighlight(highlight);
     }
+    @Override
+    public boolean getLockingKeyState(int key) {
+        if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
+               key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
+            throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
+        }
+        awtLock();
+        try {
+            return getModifierState( key );
+        } finally {
+            awtUnlock();
+        }
+    }
 
     public  Clipboard getSystemClipboard() {
         SecurityManager security = System.getSecurityManager();
@@ -1250,6 +1291,19 @@
         }
     }
 
+    @Override
+    public void setOverrideRedirect(Window target) {
+        synchronized (overrideRedirectWindows) {
+            overrideRedirectWindows.put(target, true);
+        }
+    }
+
+    public boolean isOverrideRedirect(Window target) {
+        synchronized (overrideRedirectWindows) {
+            return overrideRedirectWindows.containsKey(target);
+        }
+    }
+
     static void dumpPeers() {
         if (log.isLoggable(Level.FINE)) {
             log.fine("Mapped windows:");
@@ -1367,10 +1421,15 @@
         }
     }
 
-    private int getNumMouseButtons() {
+    public static int getNumMouseButtons() {
         awtLock();
         try {
-            return XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), 0, 0);
+            if (numberOfButtons == 0) {
+                numberOfButtons = Math.min(
+                    XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), 0, 0),
+                    MAX_BUTTONS_SUPPORT);
+            }
+            return numberOfButtons;
         } finally {
             awtUnlock();
         }
@@ -1526,6 +1585,66 @@
             awtUnlock();
         }
     }
+    static boolean getModifierState( int jkc ) {
+        int iKeyMask = 0;
+        long ks = XKeysym.javaKeycode2Keysym( jkc );
+        int  kc = XlibWrapper.XKeysymToKeycode(getDisplay(), ks);
+        if (kc == 0) {
+            return false;
+        }
+        awtLock();
+        try {
+            XModifierKeymap modmap = new XModifierKeymap(
+                 XlibWrapper.XGetModifierMapping(getDisplay()));
+
+            int nkeys = modmap.get_max_keypermod();
+
+            long map_ptr = modmap.get_modifiermap();
+            for( int k = 0; k < 8; k++ ) {
+                for (int i = 0; i < nkeys; ++i) {
+                    int keycode = Native.getUByte(map_ptr, k * nkeys + i);
+                    if (keycode == 0) {
+                        continue; // ignore zero keycode
+                    }
+                    if (kc == keycode) {
+                        iKeyMask = 1 << k;
+                        break;
+                    }
+                }
+                if( iKeyMask != 0 ) {
+                    break;
+                }
+            }
+            XlibWrapper.XFreeModifiermap(modmap.pData);
+            if (iKeyMask == 0 ) {
+                return false;
+            }
+            // Now we know to which modifier is assigned the keycode
+            // correspondent to the keysym correspondent to the java
+            // keycode. We are going to check a state of this modifier.
+            // If a modifier is a weird one, we cannot help it.
+            long window = 0;
+            try{
+                // get any application window
+                window = ((Long)(winMap.firstKey())).longValue();
+            }catch(NoSuchElementException nex) {
+                // get root window
+                window = getDefaultRootWindow();
+            }
+            boolean res = XlibWrapper.XQueryPointer(getDisplay(), window,
+                                            XlibWrapper.larg1, //root
+                                            XlibWrapper.larg2, //child
+                                            XlibWrapper.larg3, //root_x
+                                            XlibWrapper.larg4, //root_y
+                                            XlibWrapper.larg5, //child_x
+                                            XlibWrapper.larg6, //child_y
+                                            XlibWrapper.larg7);//mask
+            int mask = Native.getInt(XlibWrapper.larg7);
+            return ((mask & iKeyMask) != 0);
+        } finally {
+            awtUnlock();
+        }
+    }
 
     /* Assign meaning - alt, meta, etc. - to X modifiers mod1 ... mod5.
      * Only consider primary symbols on keycodes attached to modifiers.
@@ -2150,4 +2269,8 @@
     }
 
     public static native void setNoisyXErrorHandler();
+
+    public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+        return areExtraMouseButtonsEnabled;
+    }
 }