29
29
#include < glib.h>
30
30
#include " glass_general.h"
31
31
#include < gdk/gdkkeysyms.h>
32
+ #include < X11/XKBlib.h>
32
33
33
34
static gboolean key_initialized = FALSE ;
34
35
static GHashTable *keymap;
@@ -345,6 +346,25 @@ JNIEXPORT jint JNICALL Java_com_sun_glass_ui_gtk_GtkApplication__1getKeyCodeForC
345
346
return gdk_keyval_to_glass (keyval);
346
347
}
347
348
349
+ /*
350
+ * Function to determine whether the Xkb extention is available. This is a
351
+ * precaution against X protocol errors, although it should be available on all
352
+ * Linux systems.
353
+ */
354
+
355
+ static Bool xkbInitialized = False;
356
+ static Bool xkbAvailable = False;
357
+
358
+ static Bool isXkbAvailable (Display *display) {
359
+ if (!xkbInitialized) {
360
+ int xkbMajor = XkbMajorVersion;
361
+ int xkbMinor = XkbMinorVersion;
362
+ xkbAvailable = XkbQueryExtension (display, NULL , NULL , NULL , &xkbMajor, &xkbMinor);
363
+ xkbInitialized = True;
364
+ }
365
+ return xkbAvailable;
366
+ }
367
+
348
368
/*
349
369
* Class: com_sun_glass_ui_gtk_GtkApplication
350
370
* Method: _isKeyLocked
@@ -353,28 +373,36 @@ JNIEXPORT jint JNICALL Java_com_sun_glass_ui_gtk_GtkApplication__1getKeyCodeForC
353
373
JNIEXPORT jint JNICALL Java_com_sun_glass_ui_gtk_GtkApplication__1isKeyLocked
354
374
(JNIEnv * env, jobject obj, jint keyCode)
355
375
{
356
- #ifdef GLASS_GTK3
357
- GdkKeymap *keyMap = gdk_keymap_get_default ();
358
- gboolean lockState = FALSE ;
376
+ Display* display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
377
+ if (!isXkbAvailable (display)) {
378
+ return com_sun_glass_events_KeyEvent_KEY_LOCK_UNKNOWN;
379
+ }
380
+
381
+ Atom atom = None;
359
382
switch (keyCode) {
360
383
case com_sun_glass_events_KeyEvent_VK_CAPS_LOCK:
361
- lockState = gdk_keymap_get_caps_lock_state (keyMap );
384
+ atom = XInternAtom (display, " Caps Lock " , True );
362
385
break ;
363
386
364
387
case com_sun_glass_events_KeyEvent_VK_NUM_LOCK:
365
- lockState = gdk_keymap_get_num_lock_state (keyMap );
388
+ atom = XInternAtom (display, " Num Lock " , True );
366
389
break ;
390
+ }
367
391
368
- default :
369
- return com_sun_glass_events_KeyEvent_KEY_LOCK_UNKNOWN;
392
+ if (atom == None) {
393
+ return com_sun_glass_events_KeyEvent_KEY_LOCK_UNKNOWN;
370
394
}
371
- return lockState ? com_sun_glass_events_KeyEvent_KEY_LOCK_ON
372
- : com_sun_glass_events_KeyEvent_KEY_LOCK_OFF;
373
- #else /* GLASS_GTK3 */
374
- // Caps Lock detection is not reliable in GTK 2, and Num Lock detection is
375
- // only available in GTK 3.
395
+
396
+ Bool isLocked = False;
397
+ if (XkbGetNamedIndicator (display, atom, NULL , &isLocked, NULL , NULL )) {
398
+ if (isLocked) {
399
+ return com_sun_glass_events_KeyEvent_KEY_LOCK_ON;
400
+ } else {
401
+ return com_sun_glass_events_KeyEvent_KEY_LOCK_OFF;
402
+ }
403
+ }
404
+
376
405
return com_sun_glass_events_KeyEvent_KEY_LOCK_UNKNOWN;
377
- #endif /* GLASS_GTK3 */
378
406
}
379
407
380
408
} // extern "C"
0 commit comments