From 4c7a9b29e5ee7f5add8fc4ac99d36a873246d912 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 15 Sep 2025 04:41:23 +1000 Subject: [PATCH] add modifier keys --- platform.d | 239 +++++++++++++++++++++++++++++------------------------ 1 file changed, 132 insertions(+), 107 deletions(-) diff --git a/platform.d b/platform.d index a7fbc1e..8670258 100644 --- a/platform.d +++ b/platform.d @@ -45,11 +45,23 @@ enum Input LeftClick, MiddleClick, RightClick, }; -alias KBI = Input; +enum Modifier : u32 +{ + None = 0x00, + LeftShift = 0x01, + RightShift = 0x02, + LeftCtrl = 0x04, + RightCtrl = 0x08, + LeftAlt = 0x10, + RightAlt = 0x20, +} + +alias MD = Modifier; struct InputEvent { Input key; + Modifier md; bool pressed; i32 x; i32 y; @@ -308,13 +320,14 @@ ResetInputs(Inputs* inputs) } void -Push(Inputs* inputs, Input input, i32 x, i32 y, bool pressed) +Push(Inputs* inputs, Input input, i32 x, i32 y, bool pressed, Modifier md) { DNode!(InputEvent)* node = Alloc!(DNode!(InputEvent))(&inputs.arena); node.value.key = input; node.value.pressed = pressed; node.value.x = x; node.value.y = y; + node.value.md = md; DLLPushFront(&inputs.list, node, null); } @@ -347,6 +360,7 @@ struct PlatformWindow i32 mouse_prev_y; bool locked_cursor; bool close; + Modifier modifier; SysThread thread; MessageQueue msg_queue; @@ -687,11 +701,21 @@ HandleEvents(void* window_ptr) bool pressed = e.response_type == XCB_KEY_PRESS; xcb_keycode_t code = keyboard_event.detail; KeySym key_sym = XkbKeycodeToKeysym(w.display, cast(KeyCode)code, 0, 0); - KBI input = ConvertInput(key_sym); + Input input = ConvertInput(key_sym); - if (input != KBI.None) + enum modifiers = [Input.LeftShift, Input.RightShift, Input.LeftCtrl, Input.RightCtrl, Input.LeftAlt, Input.RightAlt]; + + static foreach(md; modifiers) { - Push(inputs, input, keyboard_event.event_x, keyboard_event.event_y, pressed); + if (input == md) + { + w.modifier = cast(Modifier)(pressed ? (w.modifier | md) : (w.modifier & ~md)); + } + } + + if (input != Input.None) + { + Push(inputs, input, keyboard_event.event_x, keyboard_event.event_y, pressed, w.modifier); } } break; case XCB_BUTTON_PRESS: @@ -711,7 +735,7 @@ HandleEvents(void* window_ptr) if (input != Input.None) { - Push(inputs, input, mouse_event.event_x, mouse_event.event_y, pressed); + Push(inputs, input, mouse_event.event_x, mouse_event.event_y, pressed, w.modifier); } } break; case XCB_MOTION_NOTIFY: @@ -797,135 +821,135 @@ ConvertInput(u64 x_key) { switch (x_key) { - case XK_BackSpace: return KBI.Backspace; - case XK_Return: return KBI.Enter; - case XK_Tab: return KBI.Tab; - case XK_Pause: return KBI.Pause; - case XK_Caps_Lock: return KBI.CapsLock; - case XK_Escape: return KBI.Esc; - case XK_space: return KBI.Space; - case XK_Prior: return KBI.PageUp; - case XK_Next: return KBI.PageDown; - case XK_End: return KBI.End; - case XK_Home: return KBI.Home; - case XK_Left: return KBI.Left; - case XK_Up: return KBI.Up; - case XK_Right: return KBI.Right; - case XK_Down: return KBI.Down; - case XK_Print: return KBI.PrintScreen; - case XK_Insert: return KBI.Insert; - case XK_Delete: return KBI.Delete; + case XK_BackSpace: return Input.Backspace; + case XK_Return: return Input.Enter; + case XK_Tab: return Input.Tab; + case XK_Pause: return Input.Pause; + case XK_Caps_Lock: return Input.CapsLock; + case XK_Escape: return Input.Esc; + case XK_space: return Input.Space; + case XK_Prior: return Input.PageUp; + case XK_Next: return Input.PageDown; + case XK_End: return Input.End; + case XK_Home: return Input.Home; + case XK_Left: return Input.Left; + case XK_Up: return Input.Up; + case XK_Right: return Input.Right; + case XK_Down: return Input.Down; + case XK_Print: return Input.PrintScreen; + case XK_Insert: return Input.Insert; + case XK_Delete: return Input.Delete; case XK_Meta_L: - case XK_Super_L: return KBI.LeftSuper; + case XK_Super_L: return Input.LeftSuper; case XK_Meta_R: - case XK_Super_R: return KBI.RightSuper; - case XK_KP_0: return KBI.Num0; - case XK_KP_1: return KBI.Num1; - case XK_KP_2: return KBI.Num2; - case XK_KP_3: return KBI.Num3; - case XK_KP_4: return KBI.Num4; - case XK_KP_5: return KBI.Num5; - case XK_KP_6: return KBI.Num6; - case XK_KP_7: return KBI.Num7; - case XK_KP_8: return KBI.Num8; - case XK_KP_9: return KBI.Num9; - case XK_multiply: return KBI.NumStar; - case XK_KP_Subtract: return KBI.NumMinus; - case XK_KP_Decimal: return KBI.NumPeriod; - case XK_KP_Divide: return KBI.NumSlash; - case XK_KP_Add: return KBI.NumPlus; - case XK_F1: return KBI.F1; - case XK_F2: return KBI.F2; - case XK_F3: return KBI.F3; - case XK_F4: return KBI.F4; - case XK_F5: return KBI.F5; - case XK_F6: return KBI.F6; - case XK_F7: return KBI.F7; - case XK_F8: return KBI.F8; - case XK_F9: return KBI.F9; - case XK_F10: return KBI.F10; - case XK_F11: return KBI.F11; - case XK_F12: return KBI.F12; - case XK_Num_Lock: return KBI.NumLock; - case XK_Scroll_Lock: return KBI.ScrollLock; - case XK_Shift_L: return KBI.LeftShift; - case XK_Shift_R: return KBI.RightShift; - case XK_Control_L: return KBI.LeftCtrl; - case XK_Control_R: return KBI.RightCtrl; - case XK_Alt_L: return KBI.LeftAlt; - case XK_Alt_R: return KBI.RightAlt; - case XK_semicolon: return KBI.Semicolon; - case XK_bracketleft: return KBI.LeftBrace; - case XK_bracketright: return KBI.RightBrace; - case XK_plus: return KBI.Plus; - case XK_comma: return KBI.Comma; - case XK_minus: return KBI.Minus; - case XK_backslash: return KBI.BackSlash; - case XK_slash: return KBI.ForwardSlash; - case XK_grave: return KBI.Tilde; - case XK_0: return KBI.Zero; - case XK_1: return KBI.One; - case XK_2: return KBI.Two; - case XK_3: return KBI.Three; - case XK_4: return KBI.Four; - case XK_5: return KBI.Five; - case XK_6: return KBI.Six; - case XK_7: return KBI.Seven; - case XK_8: return KBI.Eight; - case XK_9: return KBI.Nine; + case XK_Super_R: return Input.RightSuper; + case XK_KP_0: return Input.Num0; + case XK_KP_1: return Input.Num1; + case XK_KP_2: return Input.Num2; + case XK_KP_3: return Input.Num3; + case XK_KP_4: return Input.Num4; + case XK_KP_5: return Input.Num5; + case XK_KP_6: return Input.Num6; + case XK_KP_7: return Input.Num7; + case XK_KP_8: return Input.Num8; + case XK_KP_9: return Input.Num9; + case XK_multiply: return Input.NumStar; + case XK_KP_Subtract: return Input.NumMinus; + case XK_KP_Decimal: return Input.NumPeriod; + case XK_KP_Divide: return Input.NumSlash; + case XK_KP_Add: return Input.NumPlus; + case XK_F1: return Input.F1; + case XK_F2: return Input.F2; + case XK_F3: return Input.F3; + case XK_F4: return Input.F4; + case XK_F5: return Input.F5; + case XK_F6: return Input.F6; + case XK_F7: return Input.F7; + case XK_F8: return Input.F8; + case XK_F9: return Input.F9; + case XK_F10: return Input.F10; + case XK_F11: return Input.F11; + case XK_F12: return Input.F12; + case XK_Num_Lock: return Input.NumLock; + case XK_Scroll_Lock: return Input.ScrollLock; + case XK_Shift_L: return Input.LeftShift; + case XK_Shift_R: return Input.RightShift; + case XK_Control_L: return Input.LeftCtrl; + case XK_Control_R: return Input.RightCtrl; + case XK_Alt_L: return Input.LeftAlt; + case XK_Alt_R: return Input.RightAlt; + case XK_semicolon: return Input.Semicolon; + case XK_bracketleft: return Input.LeftBrace; + case XK_bracketright: return Input.RightBrace; + case XK_plus: return Input.Plus; + case XK_comma: return Input.Comma; + case XK_minus: return Input.Minus; + case XK_backslash: return Input.BackSlash; + case XK_slash: return Input.ForwardSlash; + case XK_grave: return Input.Tilde; + case XK_0: return Input.Zero; + case XK_1: return Input.One; + case XK_2: return Input.Two; + case XK_3: return Input.Three; + case XK_4: return Input.Four; + case XK_5: return Input.Five; + case XK_6: return Input.Six; + case XK_7: return Input.Seven; + case XK_8: return Input.Eight; + case XK_9: return Input.Nine; case XK_a: - case XK_A: return KBI.A; + case XK_A: return Input.A; case XK_b: - case XK_B: return KBI.B; + case XK_B: return Input.B; case XK_c: - case XK_C: return KBI.C; + case XK_C: return Input.C; case XK_d: - case XK_D: return KBI.D; + case XK_D: return Input.D; case XK_e: - case XK_E: return KBI.E; + case XK_E: return Input.E; case XK_f: - case XK_F: return KBI.F; + case XK_F: return Input.F; case XK_g: - case XK_G: return KBI.G; + case XK_G: return Input.G; case XK_h: - case XK_H: return KBI.H; + case XK_H: return Input.H; case XK_i: - case XK_I: return KBI.I; + case XK_I: return Input.I; case XK_j: - case XK_J: return KBI.J; + case XK_J: return Input.J; case XK_k: - case XK_K: return KBI.K; + case XK_K: return Input.K; case XK_l: - case XK_L: return KBI.L; + case XK_L: return Input.L; case XK_m: - case XK_M: return KBI.M; + case XK_M: return Input.M; case XK_n: - case XK_N: return KBI.N; + case XK_N: return Input.N; case XK_o: - case XK_O: return KBI.O; + case XK_O: return Input.O; case XK_p: - case XK_P: return KBI.P; + case XK_P: return Input.P; case XK_q: - case XK_Q: return KBI.Q; + case XK_Q: return Input.Q; case XK_r: - case XK_R: return KBI.R; + case XK_R: return Input.R; case XK_s: - case XK_S: return KBI.S; + case XK_S: return Input.S; case XK_t: - case XK_T: return KBI.T; + case XK_T: return Input.T; case XK_u: - case XK_U: return KBI.U; + case XK_U: return Input.U; case XK_v: - case XK_V: return KBI.V; + case XK_V: return Input.V; case XK_w: - case XK_W: return KBI.W; + case XK_W: return Input.W; case XK_x: - case XK_X: return KBI.X; + case XK_X: return Input.X; case XK_y: - case XK_Y: return KBI.Y; + case XK_Y: return Input.Y; case XK_z: - case XK_Z: return KBI.Z; - default: return KBI.None; + case XK_Z: return Input.Z; + default: return Input.None; } } @@ -1266,3 +1290,4 @@ Kill() } } +