diff --git a/make/sun/xawt/mapfile-vers b/make/sun/xawt/mapfile-vers index 59c5577877382b205fc5ccd49cf246bf20847c13..3f6bcdeb821471bf126ab5c7981270d5a8517d6e 100644 --- a/make/sun/xawt/mapfile-vers +++ b/make/sun/xawt/mapfile-vers @@ -289,6 +289,7 @@ SUNWprivate_1.1 { Java_sun_awt_X11_XlibWrapper_XGetIconSizes; Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym; Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode; + Java_sun_awt_X11_XlibWrapper_XQueryKeymap; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab; diff --git a/src/solaris/classes/sun/awt/X11/XKeysym.java b/src/solaris/classes/sun/awt/X11/XKeysym.java index 4dae66c0183095d1e96d2ee7d8f62b19565cbde4..9ec3d1c71097cb3cff25363febe735aafa3367f3 100644 --- a/src/solaris/classes/sun/awt/X11/XKeysym.java +++ b/src/solaris/classes/sun/awt/X11/XKeysym.java @@ -63,6 +63,8 @@ public class XKeysym { // TODO: or not to do: add reverse lookup javakeycode2keysym, // for robot only it seems to me. After that, we can remove lookup table // from XWindow.c altogether. + // Another use for reverse lookup: query keyboard state, for some keys. + static Hashtable javaKeycode2KeysymHash = new Hashtable(); static long keysym_lowercase = unsafe.allocateMemory(Native.getLongSize()); static long keysym_uppercase = unsafe.allocateMemory(Native.getLongSize()); public static char convertKeysym( long ks, int state ) { @@ -196,6 +198,10 @@ public class XKeysym { Keysym2JavaKeycode jkc = getJavaKeycode( ev ); return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode(); } + static long javaKeycode2Keysym( int jkey ) { + Long ks = javaKeycode2KeysymHash.get( jkey ); + return (ks == null ? 0 : ks.longValue()); + } /** Return keysym derived from a keycode and modifiers. Usually an input method does this. However non-system input methods (e.g. Java IMs) do not. @@ -1583,6 +1589,14 @@ public class XKeysym { keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.hpXK_mute_asciitilde), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_DEAD_TILDE, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); keysym2JavaKeycodeHash.put( Long.valueOf(XConstants.NoSymbol), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN)); + + /* Reverse search of keysym by keycode. */ + + /* Add keyboard locking codes. */ + javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_CAPS_LOCK, XKeySymConstants.XK_Caps_Lock); + javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_NUM_LOCK, XKeySymConstants.XK_Num_Lock); + javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_SCROLL_LOCK, XKeySymConstants.XK_Scroll_Lock); + javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_KANA_LOCK, XKeySymConstants.XK_Kana_Lock); }; } diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java index 241fdf3f18c75a0b3ead77fa90f43045be528b90..8326fc58648ea737f146c69c39e43a2c4c4a6da6 100644 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -27,6 +27,7 @@ package sun.awt.X11; 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; @@ -1102,6 +1103,19 @@ public final class XToolkit extends UNIXToolkit implements Runnable { 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(); @@ -1569,6 +1583,66 @@ public final class XToolkit extends UNIXToolkit implements Runnable { 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. diff --git a/src/solaris/classes/sun/awt/X11/XlibWrapper.java b/src/solaris/classes/sun/awt/X11/XlibWrapper.java index 50be5f54da722ba3eb193a84000d7043b72ff93e..eb6d5e77510d005ca4a59b1374710a700f64209e 100644 --- a/src/solaris/classes/sun/awt/X11/XlibWrapper.java +++ b/src/solaris/classes/sun/awt/X11/XlibWrapper.java @@ -485,6 +485,7 @@ static native String XSetLocaleModifiers(String modifier_list); static native int XdbeEndIdiom(long display); static native int XdbeSwapBuffers(long display, long swap_info, int num_windows); + static native void XQueryKeymap(long display, long vector); static native long XKeycodeToKeysym(long display, int keycode, int index); static native int XKeysymToKeycode(long display, long keysym); diff --git a/src/solaris/classes/sun/awt/X11/keysym2ucs.h b/src/solaris/classes/sun/awt/X11/keysym2ucs.h index c5750d8d101b996d2da0f6ded7a177d2d3ce0aa0..c59ffde042a12f22bac0f0152d18da7269cee1ae 100644 --- a/src/solaris/classes/sun/awt/X11/keysym2ucs.h +++ b/src/solaris/classes/sun/awt/X11/keysym2ucs.h @@ -101,6 +101,8 @@ tojava static Hashtable uppercaseHash = new Hashtable javaKeycode2KeysymHash = new Hashtable(); tojava static long keysym_lowercase = unsafe.allocateMemory(Native.getLongSize()); tojava static long keysym_uppercase = unsafe.allocateMemory(Native.getLongSize()); tojava public static char convertKeysym( long ks, int state ) { @@ -234,6 +236,10 @@ tojava static int getJavaKeycodeOnly( XKeyEvent ev ) { tojava Keysym2JavaKeycode jkc = getJavaKeycode( ev ); tojava return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode(); tojava } +tojava static long javaKeycode2Keysym( int jkey ) { +tojava Long ks = javaKeycode2KeysymHash.get( jkey ); +tojava return (ks == null ? 0 : ks.longValue()); +tojava } tojava /** tojava Return keysym derived from a keycode and modifiers. tojava Usually an input method does this. However non-system input methods (e.g. Java IMs) do not. @@ -2634,6 +2640,14 @@ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.hpXK_mu tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.hpXK_mute_asciitilde), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_DEAD_TILDE, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); tojava tojava keysym2JavaKeycodeHash.put( Long.valueOf(XConstants.NoSymbol), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN)); +tojava +tojava /* Reverse search of keysym by keycode. */ +tojava +tojava /* Add keyboard locking codes. */ +tojava javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_CAPS_LOCK, XKeySymConstants.XK_Caps_Lock); +tojava javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_NUM_LOCK, XKeySymConstants.XK_Num_Lock); +tojava javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_SCROLL_LOCK, XKeySymConstants.XK_Scroll_Lock); +tojava javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_KANA_LOCK, XKeySymConstants.XK_Kana_Lock); tojava }; tojava tojava } diff --git a/src/solaris/native/sun/xawt/XlibWrapper.c b/src/solaris/native/sun/xawt/XlibWrapper.c index 6801dd9470106e5de758bed111d94fe7f411b82f..31525310137171c0b3f84df539698627fbfef0e6 100644 --- a/src/solaris/native/sun/xawt/XlibWrapper.c +++ b/src/solaris/native/sun/xawt/XlibWrapper.c @@ -1641,6 +1641,13 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeSwapBuffers AWT_CHECK_HAVE_LOCK(); return XdbeSwapBuffers((Display*) jlong_to_ptr(display), (XdbeSwapInfo *) jlong_to_ptr(swap_info), num_windows); } +JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XQueryKeymap +(JNIEnv *env, jclass clazz, jlong display, jlong vector) +{ + + AWT_CHECK_HAVE_LOCK(); + XQueryKeymap( (Display *) jlong_to_ptr(display), (char *) jlong_to_ptr(vector)); +} JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym(JNIEnv *env, jclass clazz,