< prev index next >

src/solaris/native/sun/xawt/XlibWrapper.c

Print this page
rev 1565 : 5100701: Toolkit.getLockingKeyState() does not work on XToolkit, but works on Motif
Summary: Does not work on Motif but works on XToolkit now; implemented using XQueryPointer.
Reviewed-by: anthony
rev 1566 : 6680988: KeyEvent is still missing VK values for many keyboards
Summary: 2 new methods and some fields added to KeyEvent, plus hash of constants introduced
Reviewed-by: art
rev 1568 : 6711676: Numpad keys trigger more than one KeyEvent.
Summary: Introduce a new sniffer based on server keymap.
Reviewed-by: art
rev 1569 : 5099725: AWT doesn't seem to handle MappingNotify events under X11.
5036807: Pressing action keys "STOP/AGAIN/COMPOSE" generates keycode of F11/F12 keys.
4787377: VK_STOP key on Solaris generates wrong Key Code
Summary: Added an event processing lumped with similar native code for similar bugs.
Reviewed-by: art

@@ -31,10 +31,11 @@
 #include <X11/Xatom.h>
 #include <X11/extensions/Xdbe.h>
 #include <X11/extensions/shape.h>
 #include <string.h>
 #include <stdlib.h>
+#include <X11/Sunkeysym.h>
 
 #include <jni.h>
 #include <jni_util.h>
 #include <jlong.h>
 #include <sizecalc.h>

@@ -43,10 +44,11 @@
 #include <jvm.h>
 
 #include <Region.h>
 #include "utility/rect.h"
 
+#include <X11/XKBlib.h>
 #if defined(DEBUG) || defined(INTERNAL_BUILD)
 static jmethodID lockIsHeldMID = NULL;
 
 static void
 CheckHaveAWTLock(JNIEnv *env)

@@ -448,10 +450,83 @@
 {
     AWT_CHECK_HAVE_LOCK();
     XSelectInput((Display *) jlong_to_ptr(display), (Window) window, mask);
 }
 
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEvents
+(JNIEnv *env, jclass clazz, jlong display, jlong device, jlong bits_to_change, jlong values_for_bits)
+{
+    AWT_CHECK_HAVE_LOCK();
+    XkbSelectEvents((Display *) jlong_to_ptr(display), (unsigned int)device,
+                   (unsigned long)bits_to_change,
+                   (unsigned long)values_for_bits);
+}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEventDetails
+(JNIEnv *env, jclass clazz, jlong display, jlong device, jlong event_type, jlong bits_to_change, jlong values_for_bits)
+{
+    AWT_CHECK_HAVE_LOCK();
+    XkbSelectEventDetails((Display *) jlong_to_ptr(display), (unsigned int)device,
+                   (unsigned int) event_type,
+                   (unsigned long)bits_to_change,
+                   (unsigned long)values_for_bits);
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbQueryExtension
+(JNIEnv *env, jclass clazz, jlong display, jlong opcode_rtrn, jlong event_rtrn,
+              jlong error_rtrn, jlong major_in_out, jlong minor_in_out)
+{
+    AWT_CHECK_HAVE_LOCK();
+    return XkbQueryExtension( (Display *) jlong_to_ptr(display),
+                       (int *) jlong_to_ptr(opcode_rtrn),
+                       (int *) jlong_to_ptr(event_rtrn),
+                       (int *) jlong_to_ptr(error_rtrn),
+                       (int *) jlong_to_ptr(major_in_out),
+                       (int *) jlong_to_ptr(minor_in_out));
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion
+(JNIEnv *env, jclass clazz, jlong lib_major_in_out, jlong lib_minor_in_out)
+{
+    AWT_CHECK_HAVE_LOCK();
+    *((int *)lib_major_in_out) =  XkbMajorVersion;
+    *((int *)lib_minor_in_out) =  XkbMinorVersion;
+    return  XkbLibraryVersion((int *)jlong_to_ptr(lib_major_in_out), (int *)jlong_to_ptr(lib_minor_in_out));
+}
+
+JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetMap
+(JNIEnv *env, jclass clazz, jlong display, jlong which, jlong device_spec)
+{
+    AWT_CHECK_HAVE_LOCK();
+    return (jlong) XkbGetMap( (Display *) jlong_to_ptr(display),
+                              (unsigned int) which,
+                              (unsigned int) device_spec);
+}
+JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap
+(JNIEnv *env, jclass clazz, jlong display, jlong which, jlong xkb)
+{
+    AWT_CHECK_HAVE_LOCK();
+    return (jlong) XkbGetUpdatedMap( (Display *) jlong_to_ptr(display),
+                              (unsigned int) which,
+                              (XkbDescPtr) jlong_to_ptr(xkb));
+}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard
+(JNIEnv *env, jclass clazz, jlong xkb, jlong which, jboolean free_all)
+{
+    AWT_CHECK_HAVE_LOCK();
+    XkbFreeKeyboard(jlong_to_ptr(xkb), (unsigned int)which, free_all);
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode
+(JNIEnv *env, jclass clazz, jlong xkb, jint keycode, jlong mods, jlong mods_rtrn, jlong keysym_rtrn)
+{
+    Bool b;
+    b = XkbTranslateKeyCode((XkbDescPtr)xkb, (unsigned int)keycode, (unsigned int)mods,
+                              (unsigned int *)jlong_to_ptr(mods_rtrn),
+                               (KeySym *)jlong_to_ptr(keysym_rtrn));
+    //printf("native,  input: keycode:0x%0X; mods:0x%0X\n", keycode, mods);
+    //printf("native, output:  keysym:0x%0X; mods:0x%0X\n", *(unsigned int *)jlong_to_ptr(keysym_rtrn), *(unsigned int *)jlong_to_ptr(mods_rtrn));
+    return b;
+}
+
+
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    XNextEvent
  * Signature: (JJ)V
  */

@@ -1106,10 +1181,84 @@
 (JNIEnv *env, jclass clazz, jlong display)
 {
     AWT_CHECK_HAVE_LOCK();
     return VendorRelease((Display*)jlong_to_ptr(display));
 }
+/*
+ * Class:     sun_awt_X11_XlibWrapper
+ * Method:    IsXsunKPBehavior
+ * Signature: (J)Z;
+ */
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior
+(JNIEnv *env, jclass clazz, jlong display)
+{
+    // Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
+    // Otherwise, it is [1] or sometimes [0].
+    // This sniffer first tries to determine what is a keycode for XK_KP_7
+    // using XKeysymToKeycode;
+    // second, in which place in the keysymarray is XK_KP_7
+    // using XKeycodeToKeysym.
+    int kc7;
+    AWT_CHECK_HAVE_LOCK();
+    kc7 = XKeysymToKeycode((Display*)jlong_to_ptr(display), XK_KP_7);
+    if( !kc7 ) {
+        // keycode is not defined. Why, it's a reduced keyboard perhaps:
+        // report arbitrarily false.
+        return JNI_FALSE;
+    } else {
+        long ks2 = XKeycodeToKeysym((Display*)jlong_to_ptr(display), kc7, 2);
+        if( ks2 == XK_KP_7 ) {
+            //XXX If some Xorg server would put XK_KP_7 in keysymarray[2] as well,
+            //XXX for yet unknown to me reason, the sniffer would lie.
+            return JNI_TRUE;
+        }else{
+            return JNI_FALSE;
+        }
+    }
+}
+
+
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsSunKeyboard
+(JNIEnv *env, jclass clazz, jlong display)
+{
+    int xx;
+    AWT_CHECK_HAVE_LOCK();
+    xx = XKeysymToKeycode((Display*)jlong_to_ptr(display), SunXK_F37);
+    return (!xx) ? JNI_FALSE : JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsKanaKeyboard
+(JNIEnv *env, jclass clazz, jlong display)
+{
+    int xx;
+    AWT_CHECK_HAVE_LOCK();
+    static jboolean result = JNI_FALSE;
+
+    int32_t minKeyCode, maxKeyCode, keySymsPerKeyCode;
+    KeySym *keySyms, *keySymsStart, keySym;
+    int32_t i;
+    int32_t kanaCount = 0;
+
+    // There's no direct way to determine whether the keyboard has
+    // a kana lock key. From available keyboard mapping tables, it looks
+    // like only keyboards with the kana lock key can produce keysyms
+    // for kana characters. So, as an indirect test, we check for those.
+    XDisplayKeycodes((Display*)jlong_to_ptr(display), &minKeyCode, &maxKeyCode);
+    keySyms = XGetKeyboardMapping((Display*)jlong_to_ptr(display), minKeyCode, maxKeyCode - minKeyCode + 1, &keySymsPerKeyCode);
+    keySymsStart = keySyms;
+    for (i = 0; i < (maxKeyCode - minKeyCode + 1) * keySymsPerKeyCode; i++) {
+        keySym = *keySyms++;
+        if ((keySym & 0xff00) == 0x0400) {
+            kanaCount++;
+        }
+    }
+    XFree(keySymsStart);
+
+    // use a (somewhat arbitrary) minimum so we don't get confused by a stray function key
+    result = kanaCount > 10;
+    return result ? JNI_TRUE : JNI_FALSE;
+}
 
 JavaVM* jvm = NULL;
 static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) {
     if (jvm != NULL) {
         JNIEnv * env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

@@ -1154,10 +1303,11 @@
 (JNIEnv *env, jclass clazz, jlong handler, jlong display, jlong event_ptr)
 {
     return (*(XErrorHandler)jlong_to_ptr(handler))((Display*) jlong_to_ptr(display), (XErrorEvent*) jlong_to_ptr(event_ptr));
 }
 
+
 /*
  * Class:     sun_awt_X11_XlibWrapper
  * Method:    PrintXErrorEvent
  * Signature: (JJ)V
  */

@@ -1678,20 +1828,60 @@
   (JNIEnv *env, jclass clazz, jlong display, jlong swap_info, jint num_windows)
 {
     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,
                                               jlong display, jint keycode,
                                               jint index) {
     AWT_CHECK_HAVE_LOCK();
     return XKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (int)index);
 }
 
 JNIEXPORT jint JNICALL
+Java_sun_awt_X11_XlibWrapper_XkbGetEffectiveGroup(JNIEnv *env, jclass clazz,
+                                              jlong display) {
+    XkbStateRec sr;
+    AWT_CHECK_HAVE_LOCK();
+    memset(&sr, 0, sizeof(XkbStateRec));
+    XkbGetState((Display*) jlong_to_ptr(display), XkbUseCoreKbd, &sr);
+//    printf("-------------------------------------VVVV\n");
+//    printf("                 group:0x%0X\n",sr.group);
+//    printf("            base_group:0x%0X\n",sr.base_group);
+//    printf("         latched_group:0x%0X\n",sr.latched_group);
+//    printf("          locked_group:0x%0X\n",sr.locked_group);
+//    printf("                  mods:0x%0X\n",sr.mods);
+//    printf("             base_mods:0x%0X\n",sr.base_mods);
+//    printf("          latched_mods:0x%0X\n",sr.latched_mods);
+//    printf("           locked_mods:0x%0X\n",sr.locked_mods);
+//    printf("          compat_state:0x%0X\n",sr.compat_state);
+//    printf("             grab_mods:0x%0X\n",sr.grab_mods);
+//    printf("      compat_grab_mods:0x%0X\n",sr.compat_grab_mods);
+//    printf("           lookup_mods:0x%0X\n",sr.lookup_mods);
+//    printf("    compat_lookup_mods:0x%0X\n",sr.compat_lookup_mods);
+//    printf("           ptr_buttons:0x%0X\n",sr.ptr_buttons);
+//    printf("-------------------------------------^^^^\n");
+    return (jint)(sr.group);
+}
+JNIEXPORT jlong JNICALL
+Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym(JNIEnv *env, jclass clazz,
+                                              jlong display, jint keycode,
+                                              jint group, jint level) {
+    AWT_CHECK_HAVE_LOCK();
+    return XkbKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (unsigned int)group, (unsigned int)level);
+}
+
+JNIEXPORT jint JNICALL
 Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode(JNIEnv *env, jclass clazz,
                                               jlong display, jlong keysym) {
     AWT_CHECK_HAVE_LOCK();
     return XKeysymToKeycode((Display*) jlong_to_ptr(display), (KeySym)keysym);
 }

@@ -1707,10 +1897,21 @@
 Java_sun_awt_X11_XlibWrapper_XFreeModifiermap(JNIEnv *env, jclass clazz,
                                               jlong keymap) {
     AWT_CHECK_HAVE_LOCK();
     XFreeModifiermap((XModifierKeymap*) jlong_to_ptr(keymap));
 }
+/*
+ * Class:     sun_awt_X11_XlibWrapper
+ * Method:    XRefreshKeyboardMapping
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping
+(JNIEnv *env, jclass clazz, jlong event_ptr)
+{
+    AWT_CHECK_HAVE_LOCK();
+    XRefreshKeyboardMapping((XMappingEvent*) jlong_to_ptr(event_ptr));
+}
 
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab(JNIEnv *env, jclass clazz,
                                                       jlong display, jint mask,
                                                       jlong cursor, jlong time) {
< prev index next >