--- 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;
+ }
}