فهرست منبع

Cleanup of XKB detection code.

Camilla Berglund 11 سال پیش
والد
کامیت
d95b1b33e5
3فایلهای تغییر یافته به همراه45 افزوده شده و 24 حذف شده
  1. 14 24
      src/x11_init.c
  2. 1 0
      src/x11_platform.h
  3. 30 0
      src/x11_window.c

+ 14 - 24
src/x11_init.c

@@ -40,14 +40,12 @@
 static int translateKey(int keyCode)
 {
     int keySym;
-    int keysyms_per_keycode_return;
-    KeySym *keysyms;
 
     // Valid key code range is  [8,255], according to the XLib manual
     if (keyCode < 8 || keyCode > 255)
         return GLFW_KEY_UNKNOWN;
 
-    if(_glfw.x11.xkb.available)
+    if (_glfw.x11.xkb.available)
     {
         // Try secondary keysym, for numeric keypad keys
         // Note: This way we always force "NumLock = ON", which is intentional
@@ -80,13 +78,12 @@ static int translateKey(int keyCode)
     }
     else
     {
-        keysyms =
-        XGetKeyboardMapping(_glfw.x11.display,
-                            keyCode,
-                            1,
-                            &keysyms_per_keycode_return);
-        keySym = keysyms[0];
-        XFree(keysyms);
+        int dummy;
+        KeySym* keySyms;
+
+        keySyms = XGetKeyboardMapping(_glfw.x11.display, keyCode, 1, &dummy);
+        keySym = keySyms[0];
+        XFree(keySyms);
     }
 
     switch (keySym)
@@ -233,8 +230,7 @@ static int translateKey(int keyCode)
 //
 static void updateKeyCodeLUT(void)
 {
-    int keyCode;
-    int keyCodeGLFW, i;
+    int i, keyCode, keyCodeGLFW;
     char name[XkbKeyNameLength + 1];
     XkbDescPtr descr;
 
@@ -242,7 +238,7 @@ static void updateKeyCodeLUT(void)
     for (keyCode = 0;  keyCode < 256;  keyCode++)
         _glfw.x11.keyCodeLUT[keyCode] = GLFW_KEY_UNKNOWN;
 
-    if(_glfw.x11.xkb.available)
+    if (_glfw.x11.xkb.available)
     {
         // Use XKB to determine physical key locations independently of the current
         // keyboard layout
@@ -451,8 +447,6 @@ static void detectEWMH(void)
 //
 static GLboolean initExtensions(void)
 {
-    Bool supported;
-
     // Find or create window manager atoms
     _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display,
                                          "WM_PROTOCOLS",
@@ -524,18 +518,14 @@ static GLboolean initExtensions(void)
                           &_glfw.x11.xkb.versionMajor,
                           &_glfw.x11.xkb.versionMinor);
 
-    if(_glfw.x11.xkb.available)
+    if (_glfw.x11.xkb.available)
     {
-        if (!XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
-        {
-            // X11: Failed to set detectable key repeat
-            _glfw.x11.xkb.available = GL_FALSE;
-        }
+        Bool supported;
 
-        if (!supported)
+        if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
         {
-            // X11: Detectable key repeat is not supported
-            _glfw.x11.xkb.available = GL_FALSE;
+            if (supported)
+                _glfw.x11.xkb.detectable = GL_TRUE;
         }
     }
 

+ 1 - 0
src/x11_platform.h

@@ -176,6 +176,7 @@ typedef struct _GLFWlibraryX11
 
     struct {
         GLboolean   available;
+        GLboolean   detectable;
         int         majorOpcode;
         int         eventBase;
         int         errorBase;

+ 30 - 0
src/x11_window.c

@@ -615,6 +615,36 @@ static void processEvent(XEvent *event)
             const int key = translateKey(event->xkey.keycode);
             const int mods = translateState(event->xkey.state);
 
+            if (!_glfw.x11.xkb.detectable)
+            {
+                // XKB detectable key repeat is not supported on this server
+                // For key repeats we will get KeyRelease/KeyPress pairs with
+                // similar or identical time stamps.  User selected key repeat
+                // filtering is handled in _glfwInputKey/_glfwInputChar.
+                if (XEventsQueued(_glfw.x11.display, QueuedAfterReading))
+                {
+                    XEvent nextEvent;
+                    XPeekEvent(_glfw.x11.display, &nextEvent);
+
+                    if (nextEvent.type == KeyPress &&
+                        nextEvent.xkey.window == event->xkey.window &&
+                        nextEvent.xkey.keycode == event->xkey.keycode)
+                    {
+                        // This last check is a hack to work around key repeats
+                        // leaking through due to some sort of time drift
+                        // Toshiyuki Takahashi can press a button 16 times per
+                        // second so it's fairly safe to assume that no human is
+                        // pressing the key 50 times per second (value is ms)
+                        if ((nextEvent.xkey.time - event->xkey.time) < 20)
+                        {
+                            // This is a server-generated key repeat event
+                            // Do not report anything for this event
+                            break;
+                        }
+                    }
+                }
+            }
+
             _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods);
             break;
         }