aboutsummaryrefslogtreecommitdiff
path: root/3rdparty/glfw/source/src
diff options
context:
space:
mode:
authorhnOsmium0001 <[email protected]>2022-04-15 20:30:39 -0700
committerhnOsmium0001 <[email protected]>2022-04-15 20:30:39 -0700
commit509201784d6525fc26345e55a56ab81e4a7616b3 (patch)
treebcd68f247937324d06480b58a284b47e1c6bb2b8 /3rdparty/glfw/source/src
parent989f90ebe2c37e8a517691a35d7e0d827fbe7006 (diff)
Work on Material system
Diffstat (limited to '3rdparty/glfw/source/src')
-rw-r--r--3rdparty/glfw/source/src/x11_window.c127
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)