MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Win32/KeyMapping.cpp
Go to the documentation of this file.
1#include "KeyMapping.hpp"
2
3#ifdef MAYAFLUX_PLATFORM_WINDOWS
4
5namespace MayaFlux::Core {
6
7// ============================================================================
8// from_win32_key
9// ============================================================================
10
11IO::Keys from_win32_key(WPARAM vk) noexcept
12{
13 if (vk >= 0x30 && vk <= 0x39)
14 return static_cast<IO::Keys>(static_cast<int16_t>(vk));
15
16 if (vk >= 0x41 && vk <= 0x5A)
17 return static_cast<IO::Keys>(static_cast<int16_t>(vk));
18
19 switch (vk) {
20 case VK_SPACE:
21 return IO::Keys::Space;
22 case VK_OEM_7:
24 case VK_OEM_COMMA:
25 return IO::Keys::Comma;
26 case VK_OEM_MINUS:
27 return IO::Keys::Minus;
28 case VK_OEM_PERIOD:
29 return IO::Keys::Period;
30 case VK_OEM_2:
31 return IO::Keys::Slash;
32 case VK_OEM_1:
34 case VK_OEM_PLUS:
35 return IO::Keys::Equal;
36 case VK_OEM_4:
38 case VK_OEM_5:
40 case VK_OEM_6:
42 case VK_OEM_3:
44
45 case VK_ESCAPE:
46 return IO::Keys::Escape;
47 case VK_RETURN:
48 return IO::Keys::Enter;
49 case VK_TAB:
50 return IO::Keys::Tab;
51 case VK_BACK:
53 case VK_INSERT:
54 return IO::Keys::Insert;
55 case VK_DELETE:
56 return IO::Keys::Delete;
57
58 case VK_RIGHT:
59 return IO::Keys::Right;
60 case VK_LEFT:
61 return IO::Keys::Left;
62 case VK_DOWN:
63 return IO::Keys::Down;
64 case VK_UP:
65 return IO::Keys::Up;
66
67 case VK_PRIOR:
68 return IO::Keys::PageUp;
69 case VK_NEXT:
70 return IO::Keys::PageDown;
71 case VK_HOME:
72 return IO::Keys::Home;
73 case VK_END:
74 return IO::Keys::End;
75
76 case VK_CAPITAL:
77 return IO::Keys::CapsLock;
78 case VK_SCROLL:
80 case VK_NUMLOCK:
81 return IO::Keys::NumLock;
82 case VK_SNAPSHOT:
84 case VK_PAUSE:
85 return IO::Keys::Pause;
86
87 case VK_F1:
88 return IO::Keys::F1;
89 case VK_F2:
90 return IO::Keys::F2;
91 case VK_F3:
92 return IO::Keys::F3;
93 case VK_F4:
94 return IO::Keys::F4;
95 case VK_F5:
96 return IO::Keys::F5;
97 case VK_F6:
98 return IO::Keys::F6;
99 case VK_F7:
100 return IO::Keys::F7;
101 case VK_F8:
102 return IO::Keys::F8;
103 case VK_F9:
104 return IO::Keys::F9;
105 case VK_F10:
106 return IO::Keys::F10;
107 case VK_F11:
108 return IO::Keys::F11;
109 case VK_F12:
110 return IO::Keys::F12;
111 case VK_F13:
112 return IO::Keys::F13;
113 case VK_F14:
114 return IO::Keys::F14;
115 case VK_F15:
116 return IO::Keys::F15;
117 case VK_F16:
118 return IO::Keys::F16;
119 case VK_F17:
120 return IO::Keys::F17;
121 case VK_F18:
122 return IO::Keys::F18;
123 case VK_F19:
124 return IO::Keys::F19;
125 case VK_F20:
126 return IO::Keys::F20;
127 case VK_F21:
128 return IO::Keys::F21;
129 case VK_F22:
130 return IO::Keys::F22;
131 case VK_F23:
132 return IO::Keys::F23;
133 case VK_F24:
134 return IO::Keys::F24;
135
136 case VK_NUMPAD0:
137 return IO::Keys::KP0;
138 case VK_NUMPAD1:
139 return IO::Keys::KP1;
140 case VK_NUMPAD2:
141 return IO::Keys::KP2;
142 case VK_NUMPAD3:
143 return IO::Keys::KP3;
144 case VK_NUMPAD4:
145 return IO::Keys::KP4;
146 case VK_NUMPAD5:
147 return IO::Keys::KP5;
148 case VK_NUMPAD6:
149 return IO::Keys::KP6;
150 case VK_NUMPAD7:
151 return IO::Keys::KP7;
152 case VK_NUMPAD8:
153 return IO::Keys::KP8;
154 case VK_NUMPAD9:
155 return IO::Keys::KP9;
156 case VK_DECIMAL:
157 return IO::Keys::KPDecimal;
158 case VK_DIVIDE:
159 return IO::Keys::KPDivide;
160 case VK_MULTIPLY:
162 case VK_SUBTRACT:
164 case VK_ADD:
165 return IO::Keys::KPAdd;
166 // No Win32 VK for KPEnter distinct from VK_RETURN on most keyboards;
167 // WM_KEYDOWN with VK_RETURN and an extended-key flag is the real signal,
168 // but WndProc does not receive that distinction here. Left unmapped.
169
170 case VK_LSHIFT:
171 return IO::Keys::LShift;
172 case VK_LCONTROL:
173 return IO::Keys::LCtrl;
174 case VK_LMENU:
175 return IO::Keys::LAlt;
176 case VK_LWIN:
177 return IO::Keys::LSuper;
178 case VK_RSHIFT:
179 return IO::Keys::RShift;
180 case VK_RCONTROL:
181 return IO::Keys::RCtrl;
182 case VK_RMENU:
183 return IO::Keys::RAlt;
184 case VK_RWIN:
185 return IO::Keys::RSuper;
186 // Non-sided VK_SHIFT / VK_CONTROL / VK_MENU arrive only when the OS
187 // cannot distinguish sides; map to the left variant to match GLFW.
188 case VK_SHIFT:
189 return IO::Keys::LShift;
190 case VK_CONTROL:
191 return IO::Keys::LCtrl;
192 case VK_MENU:
193 return IO::Keys::LAlt;
194
195 case VK_APPS:
196 return IO::Keys::Menu;
197
198 default:
199 return IO::Keys::Unknown;
200 }
201}
202
203// ============================================================================
204// to_win32_key
205// ============================================================================
206
207int to_win32_key(IO::Keys key) noexcept
208{
209 using K = IO::Keys;
210
211 int k = static_cast<int>(key);
212
213 // Digits: Keys::N0=48 .. N9=57 == VK_0=0x30 .. VK_9=0x39
214 if (k >= 48 && k <= 57)
215 return k;
216
217 // Letters: Keys::A=65 .. Z=90 == VK_A=0x41 .. VK_Z=0x5A
218 if (k >= 65 && k <= 90)
219 return k;
220
221 switch (key) {
222 case K::Space:
223 return VK_SPACE;
224 case K::Apostrophe:
225 return VK_OEM_7;
226 case K::Comma:
227 return VK_OEM_COMMA;
228 case K::Minus:
229 return VK_OEM_MINUS;
230 case K::Period:
231 return VK_OEM_PERIOD;
232 case K::Slash:
233 return VK_OEM_2;
234 case K::Semicolon:
235 return VK_OEM_1;
236 case K::Equal:
237 return VK_OEM_PLUS;
238 case K::LeftBracket:
239 return VK_OEM_4;
240 case K::Backslash:
241 return VK_OEM_5;
242 case K::RightBracket:
243 return VK_OEM_6;
244 case K::GraveAccent:
245 return VK_OEM_3;
246
247 case K::Escape:
248 return VK_ESCAPE;
249 case K::Enter:
250 return VK_RETURN;
251 case K::Tab:
252 return VK_TAB;
253 case K::Backspace:
254 return VK_BACK;
255 case K::Insert:
256 return VK_INSERT;
257 case K::Delete:
258 return VK_DELETE;
259
260 case K::Right:
261 return VK_RIGHT;
262 case K::Left:
263 return VK_LEFT;
264 case K::Down:
265 return VK_DOWN;
266 case K::Up:
267 return VK_UP;
268
269 case K::PageUp:
270 return VK_PRIOR;
271 case K::PageDown:
272 return VK_NEXT;
273 case K::Home:
274 return VK_HOME;
275 case K::End:
276 return VK_END;
277
278 case K::CapsLock:
279 return VK_CAPITAL;
280 case K::ScrollLock:
281 return VK_SCROLL;
282 case K::NumLock:
283 return VK_NUMLOCK;
284 case K::PrintScreen:
285 return VK_SNAPSHOT;
286 case K::Pause:
287 return VK_PAUSE;
288
289 case K::F1:
290 return VK_F1;
291 case K::F2:
292 return VK_F2;
293 case K::F3:
294 return VK_F3;
295 case K::F4:
296 return VK_F4;
297 case K::F5:
298 return VK_F5;
299 case K::F6:
300 return VK_F6;
301 case K::F7:
302 return VK_F7;
303 case K::F8:
304 return VK_F8;
305 case K::F9:
306 return VK_F9;
307 case K::F10:
308 return VK_F10;
309 case K::F11:
310 return VK_F11;
311 case K::F12:
312 return VK_F12;
313 case K::F13:
314 return VK_F13;
315 case K::F14:
316 return VK_F14;
317 case K::F15:
318 return VK_F15;
319 case K::F16:
320 return VK_F16;
321 case K::F17:
322 return VK_F17;
323 case K::F18:
324 return VK_F18;
325 case K::F19:
326 return VK_F19;
327 case K::F20:
328 return VK_F20;
329 case K::F21:
330 return VK_F21;
331 case K::F22:
332 return VK_F22;
333 case K::F23:
334 return VK_F23;
335 case K::F24:
336 return VK_F24;
337 case K::F25:
338 return 0; // No Win32 equivalent
339
340 case K::KP0:
341 return VK_NUMPAD0;
342 case K::KP1:
343 return VK_NUMPAD1;
344 case K::KP2:
345 return VK_NUMPAD2;
346 case K::KP3:
347 return VK_NUMPAD3;
348 case K::KP4:
349 return VK_NUMPAD4;
350 case K::KP5:
351 return VK_NUMPAD5;
352 case K::KP6:
353 return VK_NUMPAD6;
354 case K::KP7:
355 return VK_NUMPAD7;
356 case K::KP8:
357 return VK_NUMPAD8;
358 case K::KP9:
359 return VK_NUMPAD9;
360 case K::KPDecimal:
361 return VK_DECIMAL;
362 case K::KPDivide:
363 return VK_DIVIDE;
364 case K::KPMultiply:
365 return VK_MULTIPLY;
366 case K::KPSubtract:
367 return VK_SUBTRACT;
368 case K::KPAdd:
369 return VK_ADD;
370 case K::KPEnter:
371 return 0; // No distinct VK; see from_win32_key note
372 case K::KPEqual:
373 return 0; // No Win32 equivalent
374
375 case K::LShift:
376 return VK_LSHIFT;
377 case K::LCtrl:
378 return VK_LCONTROL;
379 case K::LAlt:
380 return VK_LMENU;
381 case K::LSuper:
382 return VK_LWIN;
383 case K::RShift:
384 return VK_RSHIFT;
385 case K::RCtrl:
386 return VK_RCONTROL;
387 case K::RAlt:
388 return VK_RMENU;
389 case K::RSuper:
390 return VK_RWIN;
391 case K::Menu:
392 return VK_APPS;
393
394 default:
395 return 0;
396 }
397}
398
399IO::Keys from_win32_scancode(uint32_t scancode) noexcept
400{
401 if (scancode & 0x100)
402 return IO::Keys::Unknown;
403
404 switch (scancode & 0xFF) {
405 case 0x47:
406 return IO::Keys::KP7;
407 case 0x48:
408 return IO::Keys::KP8;
409 case 0x49:
410 return IO::Keys::KP9;
411 case 0x4B:
412 return IO::Keys::KP4;
413 case 0x4C:
414 return IO::Keys::KP5;
415 case 0x4D:
416 return IO::Keys::KP6;
417 case 0x4F:
418 return IO::Keys::KP1;
419 case 0x50:
420 return IO::Keys::KP2;
421 case 0x51:
422 return IO::Keys::KP3;
423 case 0x52:
424 return IO::Keys::KP0;
425 case 0x53:
426 return IO::Keys::KPDecimal;
427 default:
428 return IO::Keys::Unknown;
429 }
430}
431
432// ============================================================================
433// is_valid_win32_key
434// ============================================================================
435
436bool is_valid_win32_key(WPARAM vk) noexcept
437{
438 return from_win32_key(vk) != IO::Keys::Unknown;
439}
440
441} // namespace MayaFlux::Core
442
443#endif // MAYAFLUX_PLATFORM_WINDOWS