commit 7b9a480
uint
·
2026-06-23 00:01:18 +0000 UTC
parent 6608b81
Add event polling, event handling, key->mauskey translations
1 files changed,
+208,
-0
+208,
-0
1@@ -1,11 +1,43 @@
2 #include <windows.h>
3+#include <windowsx.h>
4
5 #include "maus.h"
6+#include "maus_input.h"
7 #include "maus_win.h"
8
9+typedef struct {
10+ UINT vk;
11+ MausKey maus;
12+} KeyMapEntry;
13+
14 static bool fb_create(Maus* mw);
15+static void fb_destroy(Maus* mw);
16+static bool handle_event(const MSG* msg, MausEvent* ev, Maus* mw);
17+static MausKey vk_to_mauskey(UINT vk);
18+static UINT resolve_lr(UINT vk, LPARAM lparam);
19+static char translate_text(UINT vk, UINT scan);
20 static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
21
22+static const KeyMapEntry keymap[] = {
23+ { VK_BACK, MAUS_KEY_BACKSPACE }, { VK_TAB, MAUS_KEY_TAB },
24+ { VK_RETURN, MAUS_KEY_ENTER }, { VK_ESCAPE, MAUS_KEY_ESCAPE },
25+ { VK_SPACE, MAUS_KEY_SPACE }, { VK_DELETE, MAUS_KEY_DELETE },
26+ { VK_LEFT, MAUS_KEY_LEFT }, { VK_RIGHT, MAUS_KEY_RIGHT },
27+ { VK_UP, MAUS_KEY_UP }, { VK_DOWN, MAUS_KEY_DOWN },
28+ { VK_HOME, MAUS_KEY_HOME }, { VK_END, MAUS_KEY_END },
29+ { VK_PRIOR, MAUS_KEY_PAGE_UP }, { VK_NEXT, MAUS_KEY_PAGE_DOWN },
30+ { VK_INSERT, MAUS_KEY_INSERT }, { VK_CAPITAL, MAUS_KEY_CAPS_LOCK },
31+ { VK_NUMLOCK, MAUS_KEY_NUM_LOCK }, { VK_SCROLL, MAUS_KEY_SCROLL_LOCK },
32+ { VK_PAUSE, MAUS_KEY_PAUSE }, { VK_SNAPSHOT, MAUS_KEY_PRINT_SCREEN },
33+ { VK_APPS, MAUS_KEY_MENU }, { VK_LSHIFT, MAUS_KEY_SHIFT_L },
34+ { VK_RSHIFT, MAUS_KEY_SHIFT_R }, { VK_LCONTROL, MAUS_KEY_CONTROL_L },
35+ { VK_RCONTROL, MAUS_KEY_CONTROL_R }, { VK_LMENU, MAUS_KEY_ALT_L },
36+ { VK_RMENU, MAUS_KEY_ALT_R }, { VK_LWIN, MAUS_KEY_SUPER_L },
37+ { VK_RWIN, MAUS_KEY_SUPER_R }, { VK_ADD, MAUS_KEY_KP_ADD },
38+ { VK_SUBTRACT, MAUS_KEY_KP_SUBTRACT },{ VK_MULTIPLY, MAUS_KEY_KP_MULTIPLY },
39+ { VK_DIVIDE, MAUS_KEY_KP_DIVIDE }, { VK_DECIMAL, MAUS_KEY_KP_DECIMAL },
40+};
41+
42 static bool fb_create(Maus* mw)
43 {
44 MausBackend* be = &mw->backend;
45@@ -56,6 +88,157 @@ static void fb_destroy(Maus* mw)
46 mw->stride = 0;
47 }
48
49+static bool handle_event(const MSG* msg, MausEvent* ev, Maus* mw)
50+{
51+ UINT scan;
52+ UINT vk;
53+ int delta;
54+ MausMouseButton mbtype;
55+
56+ switch (msg->message) {
57+ case WM_QUIT:
58+ ev->type = MAUS_EV_CLOSE;
59+ return true;
60+
61+ case WM_MOUSEMOVE:
62+ ev->type = MAUS_EV_MOUSE_MOTION;
63+ ev->mouse.motion.x = GET_X_LPARAM(msg->lParam);
64+ ev->mouse.motion.y = GET_Y_LPARAM(msg->lParam);
65+ return true;
66+
67+ case WM_LBUTTONDOWN:
68+ ev->type = MAUS_EV_MOUSE_BUTTON;
69+ ev->mouse.button.button = MAUS_MOUSE_BUTTON_LEFT;
70+ ev->mouse.button.pressed = true;
71+ mw->mouse_buttons[MAUS_MOUSE_BUTTON_LEFT] = true;
72+ return true;
73+ case WM_LBUTTONUP:
74+ ev->type = MAUS_EV_MOUSE_BUTTON;
75+ ev->mouse.button.button = MAUS_MOUSE_BUTTON_LEFT;
76+ ev->mouse.button.pressed = false;
77+ mw->mouse_buttons[MAUS_MOUSE_BUTTON_LEFT] = false;
78+ return true;
79+
80+ case WM_RBUTTONDOWN:
81+ ev->type = MAUS_EV_MOUSE_BUTTON;
82+ ev->mouse.button.button = MAUS_MOUSE_BUTTON_RIGHT;
83+ ev->mouse.button.pressed = true;
84+ mw->mouse_buttons[MAUS_MOUSE_BUTTON_RIGHT] = true;
85+ return true;
86+ case WM_RBUTTONUP:
87+ ev->type = MAUS_EV_MOUSE_BUTTON;
88+ ev->mouse.button.button = MAUS_MOUSE_BUTTON_RIGHT;
89+ ev->mouse.button.pressed = false;
90+ mw->mouse_buttons[MAUS_MOUSE_BUTTON_RIGHT] = false;
91+ return true;
92+
93+ case WM_MBUTTONDOWN:
94+ ev->type = MAUS_EV_MOUSE_BUTTON;
95+ ev->mouse.button.button = MAUS_MOUSE_BUTTON_MIDDLE;
96+ ev->mouse.button.pressed = true;
97+ mw->mouse_buttons[MAUS_MOUSE_BUTTON_MIDDLE] = true;
98+ return true;
99+ case WM_MBUTTONUP:
100+ ev->type = MAUS_EV_MOUSE_BUTTON;
101+ ev->mouse.button.button = MAUS_MOUSE_BUTTON_MIDDLE;
102+ ev->mouse.button.pressed = false;
103+ mw->mouse_buttons[MAUS_MOUSE_BUTTON_MIDDLE] = false;
104+ return true;
105+
106+ case WM_MOUSEWHEEL:
107+ delta = GET_WHEEL_DELTA_WPARAM(msg->wParam);
108+ mbtype = (delta > 0) ? MAUS_MOUSE_BUTTON_SCROLL_UP
109+ : MAUS_MOUSE_BUTTON_SCROLL_DOWN;
110+ ev->type = MAUS_EV_MOUSE_BUTTON;
111+ ev->mouse.button.button = mbtype;
112+ ev->mouse.button.pressed = true;
113+ return true;
114+
115+ case WM_KEYDOWN:
116+ case WM_SYSKEYDOWN:
117+ scan = (UINT)((msg->lParam >> 16) & 0xFF);
118+ vk = resolve_lr((UINT)msg->wParam, msg->lParam);
119+
120+ ev->type = MAUS_EV_KEY;
121+ ev->key.code = (uint32_t)msg->wParam;
122+ ev->key.pressed = true;
123+ ev->key.key = vk_to_mauskey(vk);
124+ ev->key.text = translate_text((UINT)msg->wParam, scan);
125+
126+ if (ev->key.code < MAUS_KEYCODE_LAST)
127+ mw->key_codes[ev->key.code] = true;
128+ if (ev->key.key != MAUS_KEY_NONE)
129+ mw->key_syms[ev->key.key] = true;
130+ return true;
131+
132+ case WM_KEYUP:
133+ case WM_SYSKEYUP:
134+ vk = resolve_lr((UINT)msg->wParam, msg->lParam);
135+
136+ ev->type = MAUS_EV_KEY;
137+ ev->key.code = (uint32_t)msg->wParam;
138+ ev->key.pressed = false;
139+ ev->key.key = vk_to_mauskey(vk);
140+ ev->key.text = 0;
141+
142+ if (ev->key.code < MAUS_KEYCODE_LAST)
143+ mw->key_codes[ev->key.code] = false;
144+ if (ev->key.key != MAUS_KEY_NONE)
145+ mw->key_syms[ev->key.key] = false;
146+ return true;
147+ }
148+
149+ return false;
150+}
151+
152+static MausKey vk_to_mauskey(UINT vk)
153+{
154+ if (vk >= 'A' && vk <= 'Z')
155+ return (MausKey)(MAUS_KEY_A + (vk - 'A'));
156+ if (vk >= '0' && vk <= '9')
157+ return (MausKey)(MAUS_KEY_0 + (vk - '0'));
158+ if (vk >= VK_F1 && vk <= VK_F12)
159+ return (MausKey)(MAUS_KEY_F1 + (vk - VK_F1));
160+ if (vk >= VK_NUMPAD0 && vk <= VK_NUMPAD9)
161+ return (MausKey)(MAUS_KEY_KP_0 + (vk - VK_NUMPAD0));
162+
163+ for (size_t i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++) {
164+ if (keymap[i].vk == vk)
165+ return keymap[i].maus;
166+ }
167+
168+ return MAUS_KEY_NONE;
169+}
170+
171+static UINT resolve_lr(UINT vk, LPARAM lparam)
172+{
173+ UINT scan = (UINT)((lparam >> 16) & 0xFF);
174+ int ext = (lparam & (1 << 24)) != 0;
175+
176+ if (vk == VK_SHIFT)
177+ return MapVirtualKey(scan, MAPVK_VSC_TO_VK_EX);
178+ if (vk == VK_CONTROL)
179+ return ext ? VK_RCONTROL : VK_LCONTROL;
180+ if (vk == VK_MENU)
181+ return ext ? VK_RMENU : VK_LMENU;
182+
183+ return vk;
184+}
185+
186+static char translate_text(UINT vk, UINT scan)
187+{
188+ BYTE state[256];
189+ if (!GetKeyboardState(state))
190+ return 0;
191+
192+ WCHAR buf[4];
193+ int n = ToUnicode(vk, scan, state, buf, 4, 0);
194+ if (n == 1 && buf[0] < 0x80)
195+ return (buf[0] == '\r') ? '\n' : (char)buf[0];
196+
197+ return 0;
198+}
199+
200 static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
201 {
202 if (msg == WM_DESTROY) {
203@@ -158,12 +341,37 @@ Maus* maus_init(const char* title, int x, int y, int width, int height)
204
205 bool maus_event_poll(Maus* mw, MausEvent* ev)
206 {
207+ MSG msg;
208+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
209+ TranslateMessage(&msg);
210+ DispatchMessage(&msg);
211+ ev->type = MAUS_EV_NONE;
212+
213+ if (handle_event(&msg, ev, mw))
214+ return true;
215+ }
216
217+ return false;
218 }
219
220 void maus_event_wait(Maus* mw, MausEvent* ev)
221 {
222+ MSG msg;
223
224+ for (;;) {
225+ int r = GetMessage(&msg, NULL, 0, 0);
226+ if (r <= 0) {
227+ ev->type = MAUS_EV_CLOSE;
228+ return;
229+ }
230+
231+ TranslateMessage(&msg);
232+ DispatchMessage(&msg);
233+ ev->type = MAUS_EV_NONE;
234+
235+ if (handle_event(&msg, ev, mw))
236+ return;
237+ }
238 }
239
240 void maus_present(Maus* mw)