diff options
author | hnOsmium0001 <[email protected]> | 2022-04-15 20:30:39 -0700 |
---|---|---|
committer | hnOsmium0001 <[email protected]> | 2022-04-15 20:30:39 -0700 |
commit | 509201784d6525fc26345e55a56ab81e4a7616b3 (patch) | |
tree | bcd68f247937324d06480b58a284b47e1c6bb2b8 /3rdparty/glfw/source/src/x11_window.c | |
parent | 989f90ebe2c37e8a517691a35d7e0d827fbe7006 (diff) |
Work on Material system
Diffstat (limited to '3rdparty/glfw/source/src/x11_window.c')
-rw-r--r-- | 3rdparty/glfw/source/src/x11_window.c | 127 |
1 files changed, 105 insertions, 22 deletions
diff --git a/3rdparty/glfw/source/src/x11_window.c b/3rdparty/glfw/source/src/x11_window.c index 490abcc..5f1441f 100644 --- a/3rdparty/glfw/source/src/x11_window.c +++ b/3rdparty/glfw/source/src/x11_window.c @@ -1218,6 +1218,12 @@ static void processEvent(XEvent *event) case XI_KeyPress: { XIDeviceEvent* de = event->xcookie.data; + if (de->deviceid != de->sourceid) + { + // This event came from a master device + break; + } + Bool repeat = de->flags & XIKeyRepeat; _GLFWwindow* window = NULL; @@ -1229,13 +1235,89 @@ static void processEvent(XEvent *event) break; } + keycode = de->detail; const int key = translateKey(de->detail); const int mods = translateXI2Mods(&de->mods); + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); // XIDeviceEvent::deviceid gives the final device in the redirection chain (which is usually the master device), // whereas XIDeviceEvent::sourceid gives the actual slave device that generated this event _GLFWkeyboard* keyboard = _glfwGetKeyboardFromDeviceIdX11(de->sourceid);// TODO(hnosm) do we need to handle XIM? - _glfwInputKey(window, keyboard, key, de->detail, repeat ? GLFW_REPEAT : GLFW_PRESS, mods); + + XKeyEvent fakeEvent; + fakeEvent.type = KeyPress; + fakeEvent.serial = de->serial; + fakeEvent.send_event = de->send_event; + fakeEvent.display = de->display; + fakeEvent.window = de->event; + fakeEvent.root = de->root; + fakeEvent.subwindow = de->child; + fakeEvent.time = de->time; + fakeEvent.x = de->event_x; + fakeEvent.y = de->event_y; + fakeEvent.x_root = de->root_x; + fakeEvent.y_root = de->root_y; + // NOTE: we assume XI2 mods and X event modifier state are thet same; this appears to be true but isn't documented anywhere + fakeEvent.state = de->mods.effective; + fakeEvent.keycode = de->detail; + fakeEvent.same_screen = 1; // TODO + + if (window->x11.ic) + { + // HACK: See processing of regular KeyPressed for details + Time diff = de->time - window->x11.keyPressTimes[keycode]; + if (diff == de->time || (diff > 0 && diff < ((Time)1 << 31))) + { + if (keycode) + _glfwInputKey(window, keyboard, key, keycode, repeat ? GLFW_REPEAT : GLFW_PRESS, mods); + + window->x11.keyPressTimes[keycode] = de->time; + } + + if (!filtered) + { + int count; + Status status; + char buffer[100]; + char* chars = buffer; + + count = Xutf8LookupString(window->x11.ic, + &fakeEvent, + buffer, sizeof(buffer) - 1, + NULL, &status); + + if (status == XBufferOverflow) + { + chars = _glfw_calloc(count + 1, 1); + count = Xutf8LookupString(window->x11.ic, + &fakeEvent, + chars, count, + NULL, &status); + } + + if (status == XLookupChars || status == XLookupBoth) + { + const char* c = chars; + chars[count] = '\0'; + while (c - chars < count) + _glfwInputChar(window, decodeUTF8(&c), mods, plain); + } + + if (chars != buffer) + _glfw_free(chars); + } + } + else + { + KeySym keysym; + XLookupString(&fakeEvent, NULL, 0, &keysym, NULL); + + _glfwInputKey(window, keyboard, key, keycode, repeat ? GLFW_REPEAT : GLFW_PRESS, mods); + + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); + if (codepoint != GLFW_INVALID_CODEPOINT) + _glfwInputChar(window, codepoint, mods, plain); + } break; } @@ -1243,6 +1325,11 @@ static void processEvent(XEvent *event) case XI_KeyRelease: { XIDeviceEvent* de = event->xcookie.data; + if (de->deviceid != de->sourceid) + { + // This event came from a master device + break; + } _GLFWwindow* window = NULL; if (XFindContext(_glfw.x11.display, @@ -1384,30 +1471,30 @@ static void processEvent(XEvent *event) case KeyPress: { + // Non-XInput2 codepath, see above for handling of those + if (!_glfwKeyboardsSupportedX11()) + break; + const int key = translateKey(keycode); const int mods = translateState(event->xkey.state); const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); if (window->x11.ic) { - // Non-XInput2 codepath, see above for handling of those - if (!_glfwKeyboardsSupportedX11()) + // HACK: Do not report the key press events duplicated by XIM + // Duplicate key releases are filtered out implicitly by + // the GLFW key repeat logic in _glfwInputKey + // A timestamp per key is used to handle simultaneous keys + // NOTE: Always allow the first event for each key through + // (the server never sends a timestamp of zero) + // NOTE: Timestamp difference is compared to handle wrap-around + Time diff = event->xkey.time - window->x11.keyPressTimes[keycode]; + if (diff == event->xkey.time || (diff > 0 && diff < ((Time)1 << 31))) { - // HACK: Do not report the key press events duplicated by XIM - // Duplicate key releases are filtered out implicitly by - // the GLFW key repeat logic in _glfwInputKey - // A timestamp per key is used to handle simultaneous keys - // NOTE: Always allow the first event for each key through - // (the server never sends a timestamp of zero) - // NOTE: Timestamp difference is compared to handle wrap-around - Time diff = event->xkey.time - window->x11.keyPressTimes[keycode]; - if (diff == event->xkey.time || (diff > 0 && diff < ((Time)1 << 31))) - { - if (keycode) - _glfwInputKey(window, NULL, key, keycode, GLFW_PRESS, mods); + if (keycode) + _glfwInputKey(window, NULL, key, keycode, GLFW_PRESS, mods); - window->x11.keyPressTimes[keycode] = event->xkey.time; - } + window->x11.keyPressTimes[keycode] = event->xkey.time; } if (!filtered) @@ -1448,11 +1535,7 @@ static void processEvent(XEvent *event) KeySym keysym; XLookupString(&event->xkey, NULL, 0, &keysym, NULL); - // Non-XInput2 codepath, see above for handling of those - if (!_glfwKeyboardsSupportedX11()) - { - _glfwInputKey(window, NULL, key, keycode, GLFW_PRESS, mods); - } + _glfwInputKey(window, NULL, key, keycode, GLFW_PRESS, mods); const uint32_t codepoint = _glfwKeySym2Unicode(keysym); if (codepoint != GLFW_INVALID_CODEPOINT) |