Cleanup of XKB detection code.

This commit is contained in:
Camilla Berglund 2014-05-18 12:24:29 +02:00
parent b889aa7841
commit d95b1b33e5
3 changed files with 45 additions and 24 deletions

View File

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

View File

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

View File

@ -615,6 +615,36 @@ static void processEvent(XEvent *event)
const int key = translateKey(event->xkey.keycode); const int key = translateKey(event->xkey.keycode);
const int mods = translateState(event->xkey.state); 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); _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods);
break; break;
} }