1 /++
2  + Authors: Avaxar <avaxar@nekkl.org>
3  + Copyright: Copyright © 2023, Avaxar
4  + License: $(LINK2 https://mit-license.org, MIT License)
5  +/
6 
7 module dsdl2.keyboard;
8 @safe:
9 
10 import bindbc.sdl;
11 import dsdl2.sdl;
12 import dsdl2.rect;
13 import dsdl2.window;
14 
15 import std.bitmanip : bitfields;
16 import std.format : format;
17 
18 /++
19  + Wraps `SDL_GetKeyboardFocus` which gets the keyboard-focused window
20  +
21  + This function is marked as `@system` due to the potential of referencing invalid memory.
22  +
23  + Returns: `dsdl2.Window` proxy of the window with the keyboard focus; `null` if no window is focused
24  +/
25 Window getKeyboardFocusedWindow() @system {
26     SDL_Window* sdlWindow = SDL_GetKeyboardFocus();
27     if (sdlWindow is null) {
28         return null;
29     }
30 
31     return new Window(sdlWindow, false);
32 }
33 
34 /++
35  + Wraps `SDL_GetKeyboardState` which gets the current key states of the keyboard
36  +
37  + Returns: `bool` array of whether the keys are pressed or not as indexed by `dsdl2.Scancode`
38  +/
39 const(bool[]) getKeyboardState() @trusted {
40     int numKeys = void;
41     ubyte* ptr = SDL_GetKeyboardState(&numKeys);
42     return (cast(bool*) ptr)[0 .. numKeys];
43 }
44 
45 /++
46  + Wraps `SDL_GetModState` which gets the current modifier key states
47  +
48  + Returns: `dsdl2.Keymod` containing whether the modifier keys are pressed or not
49  +/
50 Keymod getModState() @trusted {
51     return Keymod(SDL_GetModState());
52 }
53 
54 /++
55  + Wraps `SDL_GetScancodeFromKey` which gets the `dsdl2.Scancode` from a `dsdl2.Keycode`
56  +
57  + Params:
58  +   keycode = the `dsdl2.Keycode` enumeration
59  + Returns: `dsdl2.Scancode` equivalent
60  +/
61 Scancode keycodeToScancode(Keycode keycode) @trusted {
62     return cast(Scancode) SDL_GetScancodeFromKey(keycode);
63 }
64 
65 /++
66  + Wraps `SDL_GetKeyFromScancode` which gets the `dsdl2.Keycode` from a `dsdl2.Scancode`
67  +
68  + Params:
69  +   scancode = the `dsdl2.Scancode` enumeration
70  + Returns: `dsdl2.Keycode` equivalent
71  +/
72 Keycode scancodeToKeycode(Scancode scancode) @trusted {
73     return cast(Keycode) SDL_GetKeyFromScancode(scancode);
74 }
75 
76 /++
77  + Wraps `SDL_StartTextInput` which starts text input, invoking the IME if available
78  +/
79 void startTextInput() @trusted {
80     SDL_StartTextInput();
81 }
82 
83 /++
84  + Wraps `SDL_IsTextInputActive` which checks whether text input is active
85  +/
86 bool isTextInputActive() @trusted {
87     return SDL_IsTextInputActive() == SDL_TRUE;
88 }
89 
90 /++
91  + Wraps `SDL_StopTextInput` which stops text input, closing the IME if invoked prior
92  +/
93 void stopTextInput() @trusted {
94     SDL_StopTextInput();
95 }
96 
97 /++
98  + Wraps `SDL_HasScreenKeyboardSupport` which checks whether screen keyboard is supported
99  +/
100 bool hasScreenKeyboardSupport() @trusted {
101     return SDL_HasScreenKeyboardSupport() == SDL_TRUE;
102 }
103 
104 /++
105  + Wraps `SDL_SetTextInputRect` which sets the text input rectangle
106  +/
107 void setTextInputRect(Rect rect) @trusted {
108     SDL_SetTextInputRect(&rect.sdlRect);
109 }
110 
111 static if (sdlSupport >= SDLSupport.v2_0_22) {
112     /++
113      + Wraps `SDL_ClearComposition` (from SDL 2.0.22) which clears any composition in the text input
114      +/
115     void clearComposition() @trusted
116     in {
117         assert(getVersion() >= Version(2, 0, 22));
118     }
119     do {
120         SDL_ClearComposition();
121     }
122 
123     /++
124      + Wraps `SDL_IsTextInputShown` (from SDL 2.0.22) which checks whether the text input IME is shown
125      +
126      + Returns: `true` if the IME is shown, otherwise `false`
127      +/
128     bool isTextInputShown() @trusted
129     in {
130         assert(getVersion() >= Version(2, 0, 22));
131     }
132     do {
133         return SDL_IsTextInputShown() == SDL_TRUE;
134     }
135 }
136 
137 static if (sdlSupport >= SDLSupport.v2_24) {
138     /++
139      + Wraps `SDL_ResetKeyboard` (from SDL 2.24) which resets the entire keyboard state
140      +/
141     void resetKeyboard() @trusted
142     in {
143         assert(getVersion() >= Version(2, 24));
144     }
145     do {
146         SDL_ResetKeyboard();
147     }
148 }
149 
150 /++
151  + D struct that wraps `SDL_Keymod` containing modifier key states
152  +/
153 struct Keymod {
154     mixin(bitfields!(
155             bool, "lShift", 1,
156             bool, "rShift", 1,
157             bool, "lCtrl", 1,
158             bool, "rCtrl", 1,
159             bool, "lAlt", 1,
160             bool, "rAlt", 1,
161             bool, "lGUI", 1,
162             bool, "rGUI", 1,
163             bool, "num", 1,
164             bool, "caps", 1,
165             bool, "mode", 1,
166             bool, "scroll", 1,
167             ubyte, "", 4));
168 
169     this() @disable;
170 
171     /++
172      + Constructs a `dsdl2.Keymod` from a vanilla `SDL_Keymod` from bindbc-sdl
173      +
174      + Params:
175      +   sdlKeymod = the `SDL_Keymod` flag
176      +/
177     this(SDL_Keymod sdlKeymod) {
178         this.lShift = (sdlKeymod & KMOD_LSHIFT) != 0;
179         this.rShift = (sdlKeymod & KMOD_RSHIFT) != 0;
180         this.lCtrl = (sdlKeymod & KMOD_LCTRL) != 0;
181         this.rCtrl = (sdlKeymod & KMOD_RCTRL) != 0;
182         this.lAlt = (sdlKeymod & KMOD_LALT) != 0;
183         this.rAlt = (sdlKeymod & KMOD_RALT) != 0;
184         this.lGUI = (sdlKeymod & KMOD_LGUI) != 0;
185         this.rGUI = (sdlKeymod & KMOD_RGUI) != 0;
186         this.num = (sdlKeymod & KMOD_NUM) != 0;
187         this.caps = (sdlKeymod & KMOD_CAPS) != 0;
188         this.mode = (sdlKeymod & KMOD_MODE) != 0;
189         this.scroll = (sdlKeymod & KMOD_SCROLL) != 0;
190     }
191 
192     /++
193      + Constructs a `dsdl2.Keymod` by providing the flags
194      +
195      + Params:
196      +   base = base `SDL_Keymod` to assign (Put `0` for none)
197      +   lShift = whether the left shift key is pressed
198      +   rShift = whether the right shift key is pressed
199      +   lCtrl = whether the left ctrl key is pressed
200      +   rCtrl = whether the right ctrl key is pressed
201      +   lAlt = whether the left alt key is pressed
202      +   rAlt = whether the right alt key is pressed
203      +   lGUI = whether the left GUI/"Windows" key is pressed
204      +   rGUI = whether the right GUI/"Windows" key is pressed
205      +   num = whether num lock is toggled
206      +   caps = whether caps lock is toggled
207      +   mode = whether the AltGr keys are toggled
208      +   scroll = whether scroll lock is toggled
209      +/
210     this(SDL_Keymod base, bool lShift = false, bool rShift = false, bool lCtrl = false, bool rCtrl = false,
211         bool lAlt = false, bool rAlt = false, bool lGUI = false, bool rGUI = false, bool num = false,
212         bool caps = false, bool mode = false, bool scroll = false) {
213         this(base);
214         this.lShift = lShift;
215         this.rShift = rShift;
216         this.lCtrl = lCtrl;
217         this.rCtrl = rCtrl;
218         this.lAlt = lAlt;
219         this.rAlt = rAlt;
220         this.lGUI = lGUI;
221         this.rGUI = rGUI;
222         this.num = num;
223         this.caps = caps;
224         this.mode = mode;
225         this.scroll = scroll;
226     }
227 
228     /++
229      + Formats the `dsdl2.Keymod` into its construction representation:
230      + `"dsdl2.Keymod(<sdlKeymod>, <lShift>, <rShift>, <lCtrl>, <rCtrl>, <lAlt>, <rAlt>, <lGUI>, <rGUI>, <num>, <caps>, <mode>, <scroll>)"`
231      +
232      + Returns: the formatted `string`
233      +/
234     string toString() const {
235         return "dsdl2.Keymod(%d, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)".format(this.sdlKeymod,
236             this.lShift, this.rShift, this.lCtrl, this.rCtrl, this.lAlt, this.rAlt, this.lGUI, this.rGUI,
237             this.num, this.caps, this.mode, this.scroll);
238     }
239 
240     /++
241      + Gets the internal `SDL_Keymod` representation
242      +
243      + Returns: `SDL_Keymod` with the appropriate bitflags toggled
244      +/
245     SDL_Keymod sdlKeymod() const @property {
246         return (this.lShift ? KMOD_LSHIFT : 0)
247             | (this.rShift ? KMOD_RSHIFT : 0)
248             | (this.lCtrl ? KMOD_LCTRL : 0)
249             | (this.rCtrl ? KMOD_RCTRL : 0)
250             | (this.lAlt ? KMOD_LALT : 0)
251             | (this.rAlt ? KMOD_RALT : 0)
252             | (this.lGUI ? KMOD_LGUI : 0)
253             | (this.rGUI ? KMOD_RGUI : 0)
254             | (this.num ? KMOD_NUM : 0)
255             | (this.caps ? KMOD_CAPS : 0)
256             | (this.mode ? KMOD_MODE : 0)
257             | (this.scroll ? KMOD_SCROLL : 0);
258     }
259 
260     /++
261      + Checks whether either of the shift keys is pressed
262      +
263      + Returns: `lShift || rShift`
264      +/
265     bool shift() const @property {
266         return this.lShift || this.rShift;
267     }
268 
269     /++
270      + Checks whether either of the ctrl keys is pressed
271      +
272      + Returns: `lCtrl || rCtrl`
273      +/
274     bool ctrl() const @property {
275         return this.lCtrl || this.rCtrl;
276     }
277 
278     /++
279      + Checks whether either of the alt keys is pressed
280      +
281      + Returns: `lAlt || rAlt`
282      +/
283     bool alt() const @property {
284         return this.lAlt || this.rAlt;
285     }
286 
287     /++
288      + Checks whether either of the GUI/"Windows" keys is pressed
289      +
290      + Returns: `lGUI || rGUI`
291      +/
292     bool gui() const @property {
293         return this.lGUI || this.rGUI;
294     }
295 }
296 
297 /++
298  + D enum that wraps `SDL_Scancode` defining keyboard scancodes
299  +/
300 enum Scancode {
301     /++
302      + Wraps `SDL_SCANCODE_*` enumeration constants
303      +/
304     n0 = SDL_SCANCODE_0,
305     n1 = SDL_SCANCODE_1, /// ditto
306     n2 = SDL_SCANCODE_2, /// ditto
307     n3 = SDL_SCANCODE_3, /// ditto
308     n4 = SDL_SCANCODE_4, /// ditto
309     n5 = SDL_SCANCODE_5, /// ditto
310     n6 = SDL_SCANCODE_6, /// ditto
311     n7 = SDL_SCANCODE_7, /// ditto
312     n8 = SDL_SCANCODE_8, /// ditto
313     n9 = SDL_SCANCODE_9, /// ditto
314     a = SDL_SCANCODE_A, /// ditto
315     acBack = SDL_SCANCODE_AC_BACK, /// ditto
316     acBookmarks = SDL_SCANCODE_AC_BOOKMARKS, /// ditto
317     acForward = SDL_SCANCODE_AC_FORWARD, /// ditto
318     acHome = SDL_SCANCODE_AC_HOME, /// ditto
319     acRefresh = SDL_SCANCODE_AC_REFRESH, /// ditto
320     acSearch = SDL_SCANCODE_AC_SEARCH, /// ditto
321     acStop = SDL_SCANCODE_AC_STOP, /// ditto
322     again = SDL_SCANCODE_AGAIN, /// ditto
323     altErase = SDL_SCANCODE_ALTERASE, /// ditto
324     apostrophe = SDL_SCANCODE_APOSTROPHE, /// ditto
325     application = SDL_SCANCODE_APPLICATION, /// ditto
326     audioMute = SDL_SCANCODE_AUDIOMUTE, /// ditto
327     audioNext = SDL_SCANCODE_AUDIONEXT, /// ditto
328     audioPlay = SDL_SCANCODE_AUDIOPLAY, /// ditto
329     audioPrev = SDL_SCANCODE_AUDIOPREV, /// ditto
330     audioStop = SDL_SCANCODE_AUDIOSTOP, /// ditto
331     b = SDL_SCANCODE_B, /// ditto
332     backslash = SDL_SCANCODE_BACKSLASH, /// ditto
333     backspace = SDL_SCANCODE_BACKSPACE, /// ditto
334     brightnessDown = SDL_SCANCODE_BRIGHTNESSDOWN, /// ditto
335     brightnessUp = SDL_SCANCODE_BRIGHTNESSUP, /// ditto
336     c = SDL_SCANCODE_C, /// ditto
337     calculator = SDL_SCANCODE_CALCULATOR, /// ditto
338     cancel = SDL_SCANCODE_CANCEL, /// ditto
339     capsLock = SDL_SCANCODE_CAPSLOCK, /// ditto
340     clear = SDL_SCANCODE_CLEAR, /// ditto
341     clearAgain = SDL_SCANCODE_CLEARAGAIN, /// ditto
342     comma = SDL_SCANCODE_COMMA, /// ditto
343     computer = SDL_SCANCODE_COMPUTER, /// ditto
344     copy = SDL_SCANCODE_COPY, /// ditto
345     crSel = SDL_SCANCODE_CRSEL, /// ditto
346     currencySubUnit = SDL_SCANCODE_CURRENCYSUBUNIT, /// ditto
347     currencyUnit = SDL_SCANCODE_CURRENCYUNIT, /// ditto
348     cut = SDL_SCANCODE_CUT, /// ditto
349     d = SDL_SCANCODE_D, /// ditto
350     decimalSeparator = SDL_SCANCODE_DECIMALSEPARATOR, /// ditto
351     delete_ = SDL_SCANCODE_DELETE, /// ditto
352     displaySwitch = SDL_SCANCODE_DISPLAYSWITCH, /// ditto
353     down = SDL_SCANCODE_DOWN, /// ditto
354     e = SDL_SCANCODE_E, /// ditto
355     eject = SDL_SCANCODE_EJECT, /// ditto
356     end = SDL_SCANCODE_END, /// ditto
357     equals = SDL_SCANCODE_EQUALS, /// ditto
358     escape = SDL_SCANCODE_ESCAPE, /// ditto
359     execute = SDL_SCANCODE_EXECUTE, /// ditto
360     exSel = SDL_SCANCODE_EXSEL, /// ditto
361     f = SDL_SCANCODE_F, /// ditto
362     f1 = SDL_SCANCODE_F1, /// ditto
363     f10 = SDL_SCANCODE_F10, /// ditto
364     f11 = SDL_SCANCODE_F11, /// ditto
365     f12 = SDL_SCANCODE_F12, /// ditto
366     f13 = SDL_SCANCODE_F13, /// ditto
367     f14 = SDL_SCANCODE_F14, /// ditto
368     f15 = SDL_SCANCODE_F15, /// ditto
369     f16 = SDL_SCANCODE_F16, /// ditto
370     f17 = SDL_SCANCODE_F17, /// ditto
371     f18 = SDL_SCANCODE_F18, /// ditto
372     f19 = SDL_SCANCODE_F19, /// ditto
373     f2 = SDL_SCANCODE_F2, /// ditto
374     f20 = SDL_SCANCODE_F20, /// ditto
375     f21 = SDL_SCANCODE_F21, /// ditto
376     f22 = SDL_SCANCODE_F22, /// ditto
377     f23 = SDL_SCANCODE_F23, /// ditto
378     f24 = SDL_SCANCODE_F24, /// ditto
379     f3 = SDL_SCANCODE_F3, /// ditto
380     f4 = SDL_SCANCODE_F4, /// ditto
381     f5 = SDL_SCANCODE_F5, /// ditto
382     f6 = SDL_SCANCODE_F6, /// ditto
383     f7 = SDL_SCANCODE_F7, /// ditto
384     f8 = SDL_SCANCODE_F8, /// ditto
385     f9 = SDL_SCANCODE_F9, /// ditto
386     find = SDL_SCANCODE_FIND, /// ditto
387     g = SDL_SCANCODE_G, /// ditto
388     grave = SDL_SCANCODE_GRAVE, /// ditto
389     h = SDL_SCANCODE_H, /// ditto
390     help = SDL_SCANCODE_HELP, /// ditto
391     home = SDL_SCANCODE_HOME, /// ditto
392     i = SDL_SCANCODE_I, /// ditto
393     insert = SDL_SCANCODE_INSERT, /// ditto
394     j = SDL_SCANCODE_J, /// ditto
395     k = SDL_SCANCODE_K, /// ditto
396     kbdIllumDown = SDL_SCANCODE_KBDILLUMDOWN, /// ditto
397     kbdIllumToggle = SDL_SCANCODE_KBDILLUMTOGGLE, /// ditto
398     kbdIllumUp = SDL_SCANCODE_KBDILLUMUP, /// ditto
399     kp0 = SDL_SCANCODE_KP_0, /// ditto
400     kp00 = SDL_SCANCODE_KP_00, /// ditto
401     kp000 = SDL_SCANCODE_KP_000, /// ditto
402     kp1 = SDL_SCANCODE_KP_1, /// ditto
403     kp2 = SDL_SCANCODE_KP_2, /// ditto
404     kp3 = SDL_SCANCODE_KP_3, /// ditto
405     kp4 = SDL_SCANCODE_KP_4, /// ditto
406     kp5 = SDL_SCANCODE_KP_5, /// ditto
407     kp6 = SDL_SCANCODE_KP_6, /// ditto
408     kp7 = SDL_SCANCODE_KP_7, /// ditto
409     kp8 = SDL_SCANCODE_KP_8, /// ditto
410     kp9 = SDL_SCANCODE_KP_9, /// ditto
411     kpA = SDL_SCANCODE_KP_A, /// ditto
412     kpAmpersand = SDL_SCANCODE_KP_AMPERSAND, /// ditto
413     kpAt = SDL_SCANCODE_KP_AT, /// ditto
414     kpB = SDL_SCANCODE_KP_B, /// ditto
415     kpBackspace = SDL_SCANCODE_KP_BACKSPACE, /// ditto
416     kpBinary = SDL_SCANCODE_KP_BINARY, /// ditto
417     kpC = SDL_SCANCODE_KP_C, /// ditto
418     kpClear = SDL_SCANCODE_KP_CLEAR, /// ditto
419     kpClearEntry = SDL_SCANCODE_KP_CLEARENTRY, /// ditto
420     kpColon = SDL_SCANCODE_KP_COLON, /// ditto
421     kpComma = SDL_SCANCODE_KP_COMMA, /// ditto
422     kpD = SDL_SCANCODE_KP_D, /// ditto
423     kpDblAmpersand = SDL_SCANCODE_KP_DBLAMPERSAND, /// ditto
424     kpDblVerticalBar = SDL_SCANCODE_KP_DBLVERTICALBAR, /// ditto
425     kpDecimal = SDL_SCANCODE_KP_DECIMAL, /// ditto
426     kpDivide = SDL_SCANCODE_KP_DIVIDE, /// ditto
427     kpE = SDL_SCANCODE_KP_E, /// ditto
428     kpEnter = SDL_SCANCODE_KP_ENTER, /// ditto
429     kpEquals = SDL_SCANCODE_KP_EQUALS, /// ditto
430     kpEqualsAS400 = SDL_SCANCODE_KP_EQUALSAS400, /// ditto
431     kpExclam = SDL_SCANCODE_KP_EXCLAM, /// ditto
432     kpF = SDL_SCANCODE_KP_F, /// ditto
433     kpGreater = SDL_SCANCODE_KP_GREATER, /// ditto
434     kpHash = SDL_SCANCODE_KP_HASH, /// ditto
435     kpHexadecimal = SDL_SCANCODE_KP_HEXADECIMAL, /// ditto
436     kpLeftBrace = SDL_SCANCODE_KP_LEFTBRACE, /// ditto
437     kpLeftParen = SDL_SCANCODE_KP_LEFTPAREN, /// ditto
438     kpLess = SDL_SCANCODE_KP_LESS, /// ditto
439     kpMemAdd = SDL_SCANCODE_KP_MEMADD, /// ditto
440     kpMemClear = SDL_SCANCODE_KP_MEMCLEAR, /// ditto
441     kpMemDivide = SDL_SCANCODE_KP_MEMDIVIDE, /// ditto
442     kpMemMultiply = SDL_SCANCODE_KP_MEMMULTIPLY, /// ditto
443     kpMemRecall = SDL_SCANCODE_KP_MEMRECALL, /// ditto
444     kpMemStore = SDL_SCANCODE_KP_MEMSTORE, /// ditto
445     kpMemSubtract = SDL_SCANCODE_KP_MEMSUBTRACT, /// ditto
446     kpMinus = SDL_SCANCODE_KP_MINUS, /// ditto
447     kpMultiply = SDL_SCANCODE_KP_MULTIPLY, /// ditto
448     kpOctal = SDL_SCANCODE_KP_OCTAL, /// ditto
449     kpPercent = SDL_SCANCODE_KP_PERCENT, /// ditto
450     kpPeriod = SDL_SCANCODE_KP_PERIOD, /// ditto
451     kpPlus = SDL_SCANCODE_KP_PLUS, /// ditto
452     kpPlusMinus = SDL_SCANCODE_KP_PLUSMINUS, /// ditto
453     kpPower = SDL_SCANCODE_KP_POWER, /// ditto
454     kpRightBrace = SDL_SCANCODE_KP_RIGHTBRACE, /// ditto
455     kpRightParen = SDL_SCANCODE_KP_RIGHTPAREN, /// ditto
456     kpSpace = SDL_SCANCODE_KP_SPACE, /// ditto
457     kpTab = SDL_SCANCODE_KP_TAB, /// ditto
458     kpVerticalBar = SDL_SCANCODE_KP_VERTICALBAR, /// ditto
459     kpXOR = SDL_SCANCODE_KP_XOR, /// ditto
460     l = SDL_SCANCODE_L, /// ditto
461     lAlt = SDL_SCANCODE_LALT, /// ditto
462     lCtrl = SDL_SCANCODE_LCTRL, /// ditto
463     left = SDL_SCANCODE_LEFT, /// ditto
464     leftBracket = SDL_SCANCODE_LEFTBRACKET, /// ditto
465     lGUI = SDL_SCANCODE_LGUI, /// ditto
466     lShift = SDL_SCANCODE_LSHIFT, /// ditto
467     m = SDL_SCANCODE_M, /// ditto
468     mail = SDL_SCANCODE_MAIL, /// ditto
469     mediaSelect = SDL_SCANCODE_MEDIASELECT, /// ditto
470     menu = SDL_SCANCODE_MENU, /// ditto
471     minus = SDL_SCANCODE_MINUS, /// ditto
472     mode = SDL_SCANCODE_MODE, /// ditto
473     mute = SDL_SCANCODE_MUTE, /// ditto
474     n = SDL_SCANCODE_N, /// ditto
475     numLockClear = SDL_SCANCODE_NUMLOCKCLEAR, /// ditto
476     o = SDL_SCANCODE_O, /// ditto
477     oper = SDL_SCANCODE_OPER, /// ditto
478     out_ = SDL_SCANCODE_OUT, /// ditto
479     p = SDL_SCANCODE_P, /// ditto
480     pageDown = SDL_SCANCODE_PAGEDOWN, /// ditto
481     pageUp = SDL_SCANCODE_PAGEUP, /// ditto
482     paste = SDL_SCANCODE_PASTE, /// ditto
483     pause = SDL_SCANCODE_PAUSE, /// ditto
484     period = SDL_SCANCODE_PERIOD, /// ditto
485     power = SDL_SCANCODE_POWER, /// ditto
486     printScreen = SDL_SCANCODE_PRINTSCREEN, /// ditto
487     prior = SDL_SCANCODE_PRIOR, /// ditto
488     q = SDL_SCANCODE_Q, /// ditto
489     r = SDL_SCANCODE_R, /// ditto
490     rAlt = SDL_SCANCODE_RALT, /// ditto
491     rCtrl = SDL_SCANCODE_RCTRL, /// ditto
492     return1 = SDL_SCANCODE_RETURN, /// ditto
493     return2 = SDL_SCANCODE_RETURN2, /// ditto
494     rGUI = SDL_SCANCODE_RGUI, /// ditto
495     right = SDL_SCANCODE_RIGHT, /// ditto
496     rightBracket = SDL_SCANCODE_RIGHTBRACKET, /// ditto
497     rShift = SDL_SCANCODE_RSHIFT, /// ditto
498     s = SDL_SCANCODE_S, /// ditto
499     scrollLock = SDL_SCANCODE_SCROLLLOCK, /// ditto
500     select = SDL_SCANCODE_SELECT, /// ditto
501     semicolon = SDL_SCANCODE_SEMICOLON, /// ditto
502     separator = SDL_SCANCODE_SEPARATOR, /// ditto
503     slash = SDL_SCANCODE_SLASH, /// ditto
504     sleep = SDL_SCANCODE_SLEEP, /// ditto
505     space = SDL_SCANCODE_SPACE, /// ditto
506     stop = SDL_SCANCODE_STOP, /// ditto
507     sysReq = SDL_SCANCODE_SYSREQ, /// ditto
508     t = SDL_SCANCODE_T, /// ditto
509     tab = SDL_SCANCODE_TAB, /// ditto
510     thousandsSeparator = SDL_SCANCODE_THOUSANDSSEPARATOR, /// ditto
511     u = SDL_SCANCODE_U, /// ditto
512     undo = SDL_SCANCODE_UNDO, /// ditto
513     unknown = SDL_SCANCODE_UNKNOWN, /// ditto
514     up = SDL_SCANCODE_UP, /// ditto
515     v = SDL_SCANCODE_V, /// ditto
516     volumeDown = SDL_SCANCODE_VOLUMEDOWN, /// ditto
517     volumeUp = SDL_SCANCODE_VOLUMEUP, /// ditto
518     w = SDL_SCANCODE_W, /// ditto
519     www = SDL_SCANCODE_WWW, /// ditto
520     x = SDL_SCANCODE_X, /// ditto
521     y = SDL_SCANCODE_Y, /// ditto
522     z = SDL_SCANCODE_Z, /// ditto
523     international1 = SDL_SCANCODE_INTERNATIONAL1, /// ditto
524     international2 = SDL_SCANCODE_INTERNATIONAL2, /// ditto
525     international3 = SDL_SCANCODE_INTERNATIONAL3, /// ditto
526     international4 = SDL_SCANCODE_INTERNATIONAL4, /// ditto
527     international5 = SDL_SCANCODE_INTERNATIONAL5, /// ditto
528     international6 = SDL_SCANCODE_INTERNATIONAL6, /// ditto
529     international7 = SDL_SCANCODE_INTERNATIONAL7, /// ditto
530     international8 = SDL_SCANCODE_INTERNATIONAL8, /// ditto
531     international9 = SDL_SCANCODE_INTERNATIONAL9, /// ditto
532     lang1 = SDL_SCANCODE_LANG1, /// ditto
533     lang2 = SDL_SCANCODE_LANG2, /// ditto
534     lang3 = SDL_SCANCODE_LANG3, /// ditto
535     lang4 = SDL_SCANCODE_LANG4, /// ditto
536     lang5 = SDL_SCANCODE_LANG5, /// ditto
537     lang6 = SDL_SCANCODE_LANG6, /// ditto
538     lang7 = SDL_SCANCODE_LANG7, /// ditto
539     lang8 = SDL_SCANCODE_LANG8, /// ditto
540     lang9 = SDL_SCANCODE_LANG9, /// ditto
541     nonUSBackslash = SDL_SCANCODE_NONUSBACKSLASH, /// ditto
542     nonUSHash = SDL_SCANCODE_NONUSHASH /// ditto
543 }
544 
545 /++
546  + D enum that wraps `SDL_Keycode` defining virtual keys
547  +/
548 enum Keycode {
549     /++
550      + Wraps `SDLK_*` enumeration constants
551      +/
552     n0 = SDLK_0,
553     n1 = SDLK_1, /// ditto
554     n2 = SDLK_2, /// ditto
555     n3 = SDLK_3, /// ditto
556     n4 = SDLK_4, /// ditto
557     n5 = SDLK_5, /// ditto
558     n6 = SDLK_6, /// ditto
559     n7 = SDLK_7, /// ditto
560     n8 = SDLK_8, /// ditto
561     n9 = SDLK_9, /// ditto
562     a = SDLK_a, /// ditto
563     acBack = SDLK_AC_BACK, /// ditto
564     acBookmarks = SDLK_AC_BOOKMARKS, /// ditto
565     acForward = SDLK_AC_FORWARD, /// ditto
566     acHome = SDLK_AC_HOME, /// ditto
567     acRefresh = SDLK_AC_REFRESH, /// ditto
568     acSearch = SDLK_AC_SEARCH, /// ditto
569     acStop = SDLK_AC_STOP, /// ditto
570     again = SDLK_AGAIN, /// ditto
571     altErase = SDLK_ALTERASE, /// ditto
572     quote = SDLK_QUOTE, /// ditto
573     application = SDLK_APPLICATION, /// ditto
574     audioMute = SDLK_AUDIOMUTE, /// ditto
575     audioNext = SDLK_AUDIONEXT, /// ditto
576     audioPlay = SDLK_AUDIOPLAY, /// ditto
577     audioPrev = SDLK_AUDIOPREV, /// ditto
578     audioStop = SDLK_AUDIOSTOP, /// ditto
579     b = SDLK_b, /// ditto
580     backslash = SDLK_BACKSLASH, /// ditto
581     backspace = SDLK_BACKSPACE, /// ditto
582     brightnessDown = SDLK_BRIGHTNESSDOWN, /// ditto
583     brightnessUp = SDLK_BRIGHTNESSUP, /// ditto
584     c = SDLK_c, /// ditto
585     calculator = SDLK_CALCULATOR, /// ditto
586     cancel = SDLK_CANCEL, /// ditto
587     capsLock = SDLK_CAPSLOCK, /// ditto
588     clear = SDLK_CLEAR, /// ditto
589     clearAgain = SDLK_CLEARAGAIN, /// ditto
590     comma = SDLK_COMMA, /// ditto
591     computer = SDLK_COMPUTER, /// ditto
592     copy = SDLK_COPY, /// ditto
593     crSel = SDLK_CRSEL, /// ditto
594     currencySubUnit = SDLK_CURRENCYSUBUNIT, /// ditto
595     currencyUnit = SDLK_CURRENCYUNIT, /// ditto
596     cut = SDLK_CUT, /// ditto
597     d = SDLK_d, /// ditto
598     decimalSeparator = SDLK_DECIMALSEPARATOR, /// ditto
599     delete_ = SDLK_DELETE, /// ditto
600     displaySwitch = SDLK_DISPLAYSWITCH, /// ditto
601     down = SDLK_DOWN, /// ditto
602     e = SDLK_e, /// ditto
603     eject = SDLK_EJECT, /// ditto
604     end = SDLK_END, /// ditto
605     equals = SDLK_EQUALS, /// ditto
606     escape = SDLK_ESCAPE, /// ditto
607     execute = SDLK_EXECUTE, /// ditto
608     exSel = SDLK_EXSEL, /// ditto
609     f = SDLK_f, /// ditto
610     f1 = SDLK_F1, /// ditto
611     f10 = SDLK_F10, /// ditto
612     f11 = SDLK_F11, /// ditto
613     f12 = SDLK_F12, /// ditto
614     f13 = SDLK_F13, /// ditto
615     f14 = SDLK_F14, /// ditto
616     f15 = SDLK_F15, /// ditto
617     f16 = SDLK_F16, /// ditto
618     f17 = SDLK_F17, /// ditto
619     f18 = SDLK_F18, /// ditto
620     f19 = SDLK_F19, /// ditto
621     f2 = SDLK_F2, /// ditto
622     f20 = SDLK_F20, /// ditto
623     f21 = SDLK_F21, /// ditto
624     f22 = SDLK_F22, /// ditto
625     f23 = SDLK_F23, /// ditto
626     f24 = SDLK_F24, /// ditto
627     f3 = SDLK_F3, /// ditto
628     f4 = SDLK_F4, /// ditto
629     f5 = SDLK_F5, /// ditto
630     f6 = SDLK_F6, /// ditto
631     f7 = SDLK_F7, /// ditto
632     f8 = SDLK_F8, /// ditto
633     f9 = SDLK_F9, /// ditto
634     find = SDLK_FIND, /// ditto
635     g = SDLK_g, /// ditto
636     backquote = SDLK_BACKQUOTE, /// ditto
637     h = SDLK_h, /// ditto
638     help = SDLK_HELP, /// ditto
639     home = SDLK_HOME, /// ditto
640     i = SDLK_i, /// ditto
641     insert = SDLK_INSERT, /// ditto
642     j = SDLK_j, /// ditto
643     k = SDLK_k, /// ditto
644     kbdIllumDown = SDLK_KBDILLUMDOWN, /// ditto
645     kbdIllumToggle = SDLK_KBDILLUMTOGGLE, /// ditto
646     kbdIllumUp = SDLK_KBDILLUMUP, /// ditto
647     kp0 = SDLK_KP_0, /// ditto
648     kp00 = SDLK_KP_00, /// ditto
649     kp000 = SDLK_KP_000, /// ditto
650     kp1 = SDLK_KP_1, /// ditto
651     kp2 = SDLK_KP_2, /// ditto
652     kp3 = SDLK_KP_3, /// ditto
653     kp4 = SDLK_KP_4, /// ditto
654     kp5 = SDLK_KP_5, /// ditto
655     kp6 = SDLK_KP_6, /// ditto
656     kp7 = SDLK_KP_7, /// ditto
657     kp8 = SDLK_KP_8, /// ditto
658     kp9 = SDLK_KP_9, /// ditto
659     kpA = SDLK_KP_A, /// ditto
660     kpAmpersand = SDLK_KP_AMPERSAND, /// ditto
661     kpAt = SDLK_KP_AT, /// ditto
662     kpB = SDLK_KP_B, /// ditto
663     kpBackspace = SDLK_KP_BACKSPACE, /// ditto
664     kpBinary = SDLK_KP_BINARY, /// ditto
665     kpC = SDLK_KP_C, /// ditto
666     kpClear = SDLK_KP_CLEAR, /// ditto
667     kpClearEntry = SDLK_KP_CLEARENTRY, /// ditto
668     kpColon = SDLK_KP_COLON, /// ditto
669     kpComma = SDLK_KP_COMMA, /// ditto
670     kpD = SDLK_KP_D, /// ditto
671     kpDblAmpersand = SDLK_KP_DBLAMPERSAND, /// ditto
672     kpDblVerticalBar = SDLK_KP_DBLVERTICALBAR, /// ditto
673     kpDecimal = SDLK_KP_DECIMAL, /// ditto
674     kpDivide = SDLK_KP_DIVIDE, /// ditto
675     kpE = SDLK_KP_E, /// ditto
676     kpEnter = SDLK_KP_ENTER, /// ditto
677     kpEquals = SDLK_KP_EQUALS, /// ditto
678     kpEqualsAS400 = SDLK_KP_EQUALSAS400, /// ditto
679     kpExclam = SDLK_KP_EXCLAM, /// ditto
680     kpF = SDLK_KP_F, /// ditto
681     kpGreater = SDLK_KP_GREATER, /// ditto
682     kpHash = SDLK_KP_HASH, /// ditto
683     kpHexadecimal = SDLK_KP_HEXADECIMAL, /// ditto
684     kpLeftBrace = SDLK_KP_LEFTBRACE, /// ditto
685     kpLeftParen = SDLK_KP_LEFTPAREN, /// ditto
686     kpLess = SDLK_KP_LESS, /// ditto
687     kpMemAdd = SDLK_KP_MEMADD, /// ditto
688     kpMemClear = SDLK_KP_MEMCLEAR, /// ditto
689     kpMemDivide = SDLK_KP_MEMDIVIDE, /// ditto
690     kpMemMultiply = SDLK_KP_MEMMULTIPLY, /// ditto
691     kpMemRecall = SDLK_KP_MEMRECALL, /// ditto
692     kpMemStore = SDLK_KP_MEMSTORE, /// ditto
693     kpMemSubtract = SDLK_KP_MEMSUBTRACT, /// ditto
694     kpMinus = SDLK_KP_MINUS, /// ditto
695     kpMultiply = SDLK_KP_MULTIPLY, /// ditto
696     kpOctal = SDLK_KP_OCTAL, /// ditto
697     kpPercent = SDLK_KP_PERCENT, /// ditto
698     kpPeriod = SDLK_KP_PERIOD, /// ditto
699     kpPlus = SDLK_KP_PLUS, /// ditto
700     kpPlusMinus = SDLK_KP_PLUSMINUS, /// ditto
701     kpPower = SDLK_KP_POWER, /// ditto
702     kpRightBrace = SDLK_KP_RIGHTBRACE, /// ditto
703     kpRightParen = SDLK_KP_RIGHTPAREN, /// ditto
704     kpSpace = SDLK_KP_SPACE, /// ditto
705     kpTab = SDLK_KP_TAB, /// ditto
706     kpVerticalBar = SDLK_KP_VERTICALBAR, /// ditto
707     kpXOR = SDLK_KP_XOR, /// ditto
708     l = SDLK_l, /// ditto
709     lAlt = SDLK_LALT, /// ditto
710     lCtrl = SDLK_LCTRL, /// ditto
711     left = SDLK_LEFT, /// ditto
712     leftBracket = SDLK_LEFTBRACKET, /// ditto
713     lGUI = SDLK_LGUI, /// ditto
714     lShift = SDLK_LSHIFT, /// ditto
715     m = SDLK_m, /// ditto
716     mail = SDLK_MAIL, /// ditto
717     mediaSelect = SDLK_MEDIASELECT, /// ditto
718     menu = SDLK_MENU, /// ditto
719     minus = SDLK_MINUS, /// ditto
720     mode = SDLK_MODE, /// ditto
721     mute = SDLK_MUTE, /// ditto
722     n = SDLK_n, /// ditto
723     numLockClear = SDLK_NUMLOCKCLEAR, /// ditto
724     o = SDLK_o, /// ditto
725     oper = SDLK_OPER, /// ditto
726     out_ = SDLK_OUT, /// ditto
727     p = SDLK_p, /// ditto
728     pageDown = SDLK_PAGEDOWN, /// ditto
729     pageUp = SDLK_PAGEUP, /// ditto
730     paste = SDLK_PASTE, /// ditto
731     pause = SDLK_PAUSE, /// ditto
732     period = SDLK_PERIOD, /// ditto
733     power = SDLK_POWER, /// ditto
734     printScreen = SDLK_PRINTSCREEN, /// ditto
735     prior = SDLK_PRIOR, /// ditto
736     q = SDLK_q, /// ditto
737     r = SDLK_r, /// ditto
738     rAlt = SDLK_RALT, /// ditto
739     rCtrl = SDLK_RCTRL, /// ditto
740     return1 = SDLK_RETURN, /// ditto
741     return2 = SDLK_RETURN2, /// ditto
742     rGUI = SDLK_RGUI, /// ditto
743     right = SDLK_RIGHT, /// ditto
744     rightBracket = SDLK_RIGHTBRACKET, /// ditto
745     rShift = SDLK_RSHIFT, /// ditto
746     s = SDLK_s, /// ditto
747     scrollLock = SDLK_SCROLLLOCK, /// ditto
748     select = SDLK_SELECT, /// ditto
749     semicolon = SDLK_SEMICOLON, /// ditto
750     separator = SDLK_SEPARATOR, /// ditto
751     slash = SDLK_SLASH, /// ditto
752     sleep = SDLK_SLEEP, /// ditto
753     space = SDLK_SPACE, /// ditto
754     stop = SDLK_STOP, /// ditto
755     sysReq = SDLK_SYSREQ, /// ditto
756     t = SDLK_t, /// ditto
757     tab = SDLK_TAB, /// ditto
758     thousandsSeparator = SDLK_THOUSANDSSEPARATOR, /// ditto
759     u = SDLK_u, /// ditto
760     undo = SDLK_UNDO, /// ditto
761     unknown = SDLK_UNKNOWN, /// ditto
762     up = SDLK_UP, /// ditto
763     v = SDLK_v, /// ditto
764     volumeDown = SDLK_VOLUMEDOWN, /// ditto
765     volumeUp = SDLK_VOLUMEUP, /// ditto
766     w = SDLK_w, /// ditto
767     www = SDLK_WWW, /// ditto
768     x = SDLK_x, /// ditto
769     y = SDLK_y, /// ditto
770     z = SDLK_z, /// ditto
771     ampersand = SDLK_AMPERSAND, /// ditto
772     asterisk = SDLK_ASTERISK, /// ditto
773     at = SDLK_AT, /// ditto
774     caret = SDLK_CARET, /// ditto
775     colon = SDLK_COLON, /// ditto
776     dollar = SDLK_DOLLAR, /// ditto
777     exclaim = SDLK_EXCLAIM, /// ditto
778     greater = SDLK_GREATER, /// ditto
779     hash = SDLK_HASH, /// ditto
780     leftParen = SDLK_LEFTPAREN, /// ditto
781     less = SDLK_LESS, /// ditto
782     percent = SDLK_PERCENT, /// ditto
783     plus = SDLK_PLUS, /// ditto
784     question = SDLK_QUESTION, /// ditto
785     quoteDbl = SDLK_QUOTEDBL, /// ditto
786     rightParen = SDLK_RIGHTPAREN, /// ditto
787     underscore = SDLK_UNDERSCORE /// ditto
788 }