aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-09-12 02:23:01 +0200
committerdec05eba <dec05eba@protonmail.com>2022-09-12 02:23:01 +0200
commit14e28f6107d9e9bae81eeee8d0a22abdc256a295 (patch)
tree5cf90c7363bb5f4861712fb3f695d62afa92471c
parent82715e294cd05a1eb4baee5b5bc08ad61ca2ca6d (diff)
Fix key/button state when window loses focus (check state on call to is_**_pressed)
-rw-r--r--src/window/window.c131
1 files changed, 88 insertions, 43 deletions
diff --git a/src/window/window.c b/src/window/window.c
index b60c9e4..8acd428 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -75,8 +75,6 @@ typedef struct {
an event for all of them.
*/
x11_events_circular_buffer events;
- bool key_pressed[__MGL_NUM_KEYS__];
- bool mouse_button_pressed[__MGL_NUM_MOUSE_BUTTONS__];
} x11_context;
static void x11_context_deinit(x11_context *self);
@@ -124,14 +122,6 @@ static int x11_context_init(x11_context *self) {
x11_events_circular_buffer_init(&self->events);
- for(size_t i = 0; i < __MGL_NUM_KEYS__; ++i) {
- self->key_pressed[i] = false;
- }
-
- for(size_t i = 0; i < __MGL_NUM_MOUSE_BUTTONS__; ++i) {
- self->mouse_button_pressed[i] = false;
- }
-
return 0;
}
@@ -177,34 +167,6 @@ static bool x11_context_pop_event(x11_context *self, mgl_event *event) {
return x11_events_circular_buffer_pop(&self->events, event);
}
-/* Returns true if the state changed */
-static bool x11_context_update_key_state(x11_context *self, mgl_key key, bool key_pressed) {
- if(self->key_pressed[key] != key_pressed) {
- self->key_pressed[key] = key_pressed;
- return true;
- } else {
- return false;
- }
-}
-
-/* Returns true if the state changed */
-static bool x11_context_update_mouse_button_state(x11_context *self, mgl_mouse_button button, bool button_pressed) {
- if(self->mouse_button_pressed[button] != button_pressed) {
- self->mouse_button_pressed[button] = button_pressed;
- return true;
- } else {
- return false;
- }
-}
-
-static bool x11_context_is_key_pressed(const x11_context *self, mgl_key key) {
- return self->key_pressed[key];
-}
-
-static bool x11_context_is_mouse_button_pressed(const x11_context *self, mgl_mouse_button button) {
- return self->mouse_button_pressed[button];
-}
-
/* TODO: Use gl OML present for other platforms than nvidia? nvidia doesn't support present yet */
/* TODO: check for glx swap control extension string (GLX_EXT_swap_control, etc) */
@@ -418,6 +380,7 @@ void mgl_window_deinit(mgl_window *self) {
self->open = false;
}
+/* Returns MGL_KEY_UNKNOWN on no match */
static mgl_key x11_keysym_to_mgl_key(KeySym key_sym) {
if(key_sym >= XK_A && key_sym <= XK_Z)
return MGL_KEY_A + (key_sym - XK_A);
@@ -472,6 +435,59 @@ static mgl_key x11_keysym_to_mgl_key(KeySym key_sym) {
return MGL_KEY_UNKNOWN;
}
+/* Returns XK_VoidSymbol on no match */
+static KeySym mgl_key_to_x11_keysym(mgl_key key) {
+ if(key >= MGL_KEY_A && key <= MGL_KEY_Z)
+ return XK_A + (key - MGL_KEY_A);
+ if(key >= MGL_KEY_NUM0 && key <= MGL_KEY_NUM9)
+ return XK_0 + (key - MGL_KEY_NUM0);
+ if(key >= MGL_KEY_NUMPAD0 && key <= MGL_KEY_NUMPAD9)
+ return XK_KP_0 + (key - MGL_KEY_NUMPAD0);
+
+ /* TODO: Fill in the rest */
+ switch(key) {
+ case MGL_KEY_SPACE: return XK_space;
+ case MGL_KEY_BACKSPACE: return XK_BackSpace;
+ case MGL_KEY_TAB: return XK_Tab;
+ case MGL_KEY_ENTER: return XK_Return;
+ case MGL_KEY_ESCAPE: return XK_Escape;
+ case MGL_KEY_LCONTROL: return XK_Control_L;
+ case MGL_KEY_LSHIFT: return XK_Shift_L;
+ case MGL_KEY_LALT: return XK_Alt_L;
+ case MGL_KEY_LSYSTEM: return XK_Super_L;
+ case MGL_KEY_RCONTROL: return XK_Control_R;
+ case MGL_KEY_RSHIFT: return XK_Shift_R;
+ case MGL_KEY_RALT: return XK_Alt_R;
+ case MGL_KEY_RSYSTEM: return XK_Super_R;
+ case MGL_KEY_DELETE: return XK_Delete;
+ case MGL_KEY_HOME: return XK_Home;
+ case MGL_KEY_LEFT: return XK_Left;
+ case MGL_KEY_UP: return XK_Up;
+ case MGL_KEY_RIGHT: return XK_Right;
+ case MGL_KEY_DOWN: return XK_Down;
+ case MGL_KEY_PAGEUP: return XK_Page_Up;
+ case MGL_KEY_PAGEDOWN: return XK_Page_Down;
+ case MGL_KEY_END: return XK_End;
+ case MGL_KEY_F1: return XK_F1;
+ case MGL_KEY_F2: return XK_F2;
+ case MGL_KEY_F3: return XK_F3;
+ case MGL_KEY_F4: return XK_F4;
+ case MGL_KEY_F5: return XK_F5;
+ case MGL_KEY_F6: return XK_F6;
+ case MGL_KEY_F7: return XK_F7;
+ case MGL_KEY_F8: return XK_F8;
+ case MGL_KEY_F9: return XK_F9;
+ case MGL_KEY_F10: return XK_F10;
+ case MGL_KEY_F11: return XK_F11;
+ case MGL_KEY_F12: return XK_F12;
+ case MGL_KEY_F13: return XK_F13;
+ case MGL_KEY_F14: return XK_F14;
+ case MGL_KEY_F15: return XK_F15;
+ default: return XK_VoidSymbol;
+ }
+ return XK_VoidSymbol;
+}
+
static mgl_mouse_button x11_button_to_mgl_button(unsigned int button) {
switch(button) {
case Button1: return MGL_BUTTON_LEFT;
@@ -489,7 +505,6 @@ static void mgl_window_handle_key_event(mgl_window *self, XKeyEvent *xkey, mgl_e
event->key.control = ((xkey->state & ControlMask) != 0);
event->key.shift = ((xkey->state & ShiftMask) != 0);
event->key.system = ((xkey->state & Mod4Mask) != 0);
- x11_context_update_key_state(self->context, event->key.code, pressed);
}
static void mgl_window_handle_text_event(mgl_window *self, XEvent *xev) {
@@ -577,7 +592,6 @@ static void mgl_window_on_receive_event(mgl_window *self, XEvent *xev, mgl_event
event->mouse_button.button = x11_button_to_mgl_button(xev->xbutton.button);
event->mouse_button.x = xev->xbutton.x;
event->mouse_button.y = xev->xbutton.y;
- x11_context_update_mouse_button_state(self->context, event->mouse_button.button, true);
}
return;
}
@@ -586,7 +600,6 @@ static void mgl_window_on_receive_event(mgl_window *self, XEvent *xev, mgl_event
event->mouse_button.button = x11_button_to_mgl_button(xev->xbutton.button);
event->mouse_button.x = xev->xbutton.x;
event->mouse_button.y = xev->xbutton.y;
- x11_context_update_mouse_button_state(self->context, event->mouse_button.button, false);
return;
}
case FocusIn: {
@@ -780,16 +793,48 @@ bool mgl_window_has_focus(const mgl_window *self) {
return self->focused;
}
+/* TODO: Track keys with events instead, but somehow handle window focus lost */
bool mgl_window_is_key_pressed(const mgl_window *self, mgl_key key) {
if(key < 0 || key >= __MGL_NUM_KEYS__)
return false;
- return x11_context_is_key_pressed(self->context, key);
+
+ mgl_context *context = mgl_get_context();
+ const KeySym keysym = mgl_key_to_x11_keysym(key);
+ if(keysym == XK_VoidSymbol)
+ return false;
+
+ KeyCode keycode = XKeysymToKeycode(context->connection, keysym);
+ if(keycode == 0)
+ return false;
+
+ char keys[32];
+ XQueryKeymap(context->connection, keys);
+
+ return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
}
+/* TODO: Track keys with events instead, but somehow handle window focus lost */
bool mgl_window_is_mouse_button_pressed(const mgl_window *self, mgl_mouse_button button) {
if(button < 0 || button >= __MGL_NUM_MOUSE_BUTTONS__)
return false;
- return x11_context_is_mouse_button_pressed(self->context, button);
+
+ mgl_context *context = mgl_get_context();
+ Window root, child;
+ int root_x, root_y, win_x, win_y;
+
+ unsigned int buttons_mask = 0;
+ XQueryPointer(context->connection, DefaultRootWindow(context->connection), &root, &child, &root_x, &root_y, &win_x, &win_y, &buttons_mask);
+
+ switch(button) {
+ case MGL_BUTTON_LEFT: return buttons_mask & Button1Mask;
+ case MGL_BUTTON_MIDDLE: return buttons_mask & Button2Mask;
+ case MGL_BUTTON_RIGHT: return buttons_mask & Button3Mask;
+ case MGL_BUTTON_XBUTTON1: return false; /* Not supported by x11 */
+ case MGL_BUTTON_XBUTTON2: return false; /* Not supported by x11 */
+ default: return false;
+ }
+
+ return false;
}
void mgl_window_close(mgl_window *self) {