1 /*
2     DSDL
3     Copyright (C) 2025 Inochi2D Project <luna@foxgirls.gay>
4 
5     This software is provided 'as-is', without any express or implied
6     warranty.  In no event will the authors be held liable for any damages
7     arising from the use of this software.
8 
9     Permission is granted to anyone to use this software for any purpose,
10     including commercial applications, and to alter it and redistribute it
11     freely, subject to the following restrictions:
12 
13     1. The origin of this software must not be misrepresented; you must not
14         claim that you wrote the original software. If you use this software
15         in a product, an acknowledgment in the product documentation would be
16         appreciated but is not required.
17     2. Altered source versions must be plainly marked as such, and must not be
18         misrepresented as being the original software.
19     3. This notice may not be removed or altered from any source distribution.
20 
21     ==========================================================================
22 
23     Simple DirectMedia Layer
24     Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
25 
26     This software is provided 'as-is', without any express or implied
27     warranty.  In no event will the authors be held liable for any damages
28     arising from the use of this software.
29 
30     Permission is granted to anyone to use this software for any purpose,
31     including commercial applications, and to alter it and redistribute it
32     freely, subject to the following restrictions:
33 
34     1. The origin of this software must not be misrepresented; you must not
35         claim that you wrote the original software. If you use this software
36         in a product, an acknowledgment in the product documentation would be
37         appreciated but is not required.
38     2. Altered source versions must be plainly marked as such, and must not be
39         misrepresented as being the original software.
40     3. This notice may not be removed or altered from any source distribution.
41 */
42 
43 /**
44     SDL Keyboard Handling
45 
46     See_Also:
47         $(LINK2 https://wiki.libsdl.org/SDL3/CategoryKeyboard, SDL3 Keyboard Documentation)
48     
49     Copyright: © 2025 Inochi2D Project, © 1997-2025 Sam Lantinga
50     License: Subject to the terms of the Zlib License, as written in the LICENSE file.
51     Authors: 
52         Luna Nielsen
53 */
54 module sdl.keyboard;
55 import sdl.video;
56 import sdl.properties;
57 import sdl.rect;
58 import sdl.stdc;
59 
60 // These are more or less integral to keyboard use.
61 public import sdl.keycode;
62 public import sdl.scancode;
63 
64 extern (C) nothrow @nogc:
65 
66 /**
67     This is a unique ID for a keyboard for the time it is connected to the
68     system, and is never reused for the lifetime of the application.
69 
70     If the keyboard is disconnected and reconnected, it will get a new ID.
71 
72     The value 0 is an invalid ID.
73 */
74 alias SDL_KeyboardID = Uint32;
75 
76 /**
77     Return whether a keyboard is currently connected.
78 
79     Returns:
80         true if a keyboard is connected, false otherwise.
81 
82     Threadsafety:
83         This function should only be called on the main thread.
84 
85     See_Also:
86         $(D SDL_GetKeyboards)
87 */
88 extern bool SDL_HasKeyboard();
89 
90 /**
91     Get a list of currently connected keyboards.
92 
93     Note that this will include any device or virtual driver that includes
94     keyboard functionality, including some mice, KVM switches, motherboard
95     power buttons, etc. You should wait for input from a device before you
96     consider it actively in use.
97 
98     Params:
99         count = a pointer filled in with the number of keyboards returned, may
100                 be NULL.
101     
102     Returns:
103         a 0 terminated array of keyboards instance IDs or NULL on failure;
104         call SDL_GetError() for more information. This should be freed
105         with SDL_free() when it is no longer needed.
106 
107     Threadsafety:
108         This function should only be called on the main thread.
109 
110     See_Also:
111         $(D SDL_GetKeyboardNameForID)
112         $(D SDL_HasKeyboard)
113 */
114 extern SDL_KeyboardID* SDL_GetKeyboards(int* count);
115 
116 /**
117     Get the name of a keyboard.
118 
119     This function returns "" if the keyboard doesn't have a name.
120 
121     Params:
122         instance_id = the keyboard instance ID.
123 
124     Returns:
125         the name of the selected keyboard or NULL on failure; call
126         SDL_GetError() for more information.
127 
128     Threadsafety:
129         This function should only be called on the main thread.
130 
131     See_Also:
132         $(D SDL_GetKeyboards)
133 */
134 extern const(char)* SDL_GetKeyboardNameForID(SDL_KeyboardID instance_id);
135 
136 /**
137     Query the window which currently has keyboard focus.
138 
139     Returns:
140         the window with keyboard focus.
141 
142     Threadsafety:
143         This function should only be called on the main thread.
144 */
145 extern SDL_Window* SDL_GetKeyboardFocus();
146 
147 /**
148     Get a snapshot of the current state of the keyboard.
149 
150     The pointer returned is a pointer to an internal SDL array. It will be
151     valid for the whole lifetime of the application and should not be freed by
152     the caller.
153 
154     A array element with a value of true means that the key is pressed and a
155     value of false means that it is not. Indexes into this array are obtained
156     by using SDL_Scancode values.
157 
158     Use SDL_PumpEvents() to update the state array.
159 
160     This function gives you the current state after all events have been
161     processed, so if a key or button has been pressed and released before you
162     process events, then the pressed state will never show up in the
163     SDL_GetKeyboardState() calls.
164 
165     Note: This function doesn't take into account whether shift has been
166     pressed or not.
167 
168     Params:
169         numkeys = if non-NULL, receives the length of the returned array.
170     
171     Returns:
172         a pointer to an array of key states.
173 
174     Threadsafety:
175         It is safe to call this function from any thread.
176 
177     See_Also:
178         $(D SDL_PumpEvents)
179         $(D SDL_ResetKeyboard)
180 */
181 extern const(bool)* SDL_GetKeyboardState(int* numkeys);
182 
183 /**
184     Clear the state of the keyboard.
185 
186     This function will generate key up events for all pressed keys.
187 
188     Threadsafety:
189         This function should only be called on the main thread.
190 
191     See_Also:
192         $(D SDL_GetKeyboardState)
193 */
194 extern void SDL_ResetKeyboard();
195 
196 /**
197     Get the current key modifier state for the keyboard.
198 
199     Returns:
200         an OR'd combination of the modifier keys for the keyboard. See
201         SDL_Keymod for details.
202 
203     Threadsafty:
204         It is safe to call this function from any thread.
205 
206     See_Also:
207         $(D SDL_GetKeyboardState)
208         $(D SDL_SetModState)
209 */
210 extern SDL_Keymod SDL_GetModState();
211 
212 /**
213     Set the current key modifier state for the keyboard.
214 
215     The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose
216     modifier key states on your application. Simply pass your desired modifier
217     states into `modstate`. This value may be a bitwise, OR'd combination of
218     SDL_Keymod values.
219 
220     This does not change the keyboard state, only the key modifier flags that
221     SDL reports.
222 
223     Params:
224         modstate = the desired SDL_Keymod for the keyboard.
225 
226     Threadsafety:
227         It is safe to call this function from any thread.
228 
229     See_Also:
230         $(D SDL_GetModState)
231 */
232 extern void SDL_SetModState(SDL_Keymod modstate);
233 
234 /**
235     Get the key code corresponding to the given scancode according to the
236     current keyboard layout.
237 
238     If you want to get the keycode as it would be delivered in key events,
239     including options specified in SDL_HINT_KEYCODE_OPTIONS, then you should
240     pass `key_event` as true. Otherwise this function simply translates the
241     scancode based on the given modifier state.
242 
243     Params:
244         scancode =  the desired SDL_Scancode to query.
245         modstate =  the modifier state to use when translating the scancode to
246                     a keycode.
247         key_event = true if the keycode will be used in key events.
248     
249     Returns:
250         The SDL_Keycode that corresponds to the given SDL_Scancode.
251 
252     Threadsafety:
253         This function is not thread safe.
254 
255     See_Also:
256         $(D SDL_GetKeyName)
257         $(D SDL_GetScancodeFromKey)
258 */
259 extern SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate, bool key_event);
260 
261 /**
262     Get the scancode corresponding to the given key code according to the
263     current keyboard layout.
264 
265     Note that there may be multiple scancode+modifier states that can generate
266     this keycode, this will just return the first one found.
267 
268     Params:
269         key =       the desired SDL_Keycode to query.
270         modstate =  a pointer to the modifier state that would be used when the
271                     scancode generates this key, may be NULL.
272     
273     Returns:
274         The SDL_Scancode that corresponds to the given SDL_Keycode.
275 
276     Threadsafety:
277         This function is not thread safe.
278 
279     See_Also:
280         $(D SDL_GetKeyFromScancode)
281         $(D SDL_GetScancodeName)
282 */
283 extern SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key, SDL_Keymod* modstate);
284 
285 /**
286     Set a human-readable name for a scancode.
287 
288     Params:
289         scancode =  the desired SDL_Scancode.
290         name =      the name to use for the scancode, encoded as UTF-8. The string
291                     is not copied, so the pointer given to this function must stay
292                     valid while SDL is being used.
293     
294     Returns:
295         true on success or false on failure; call SDL_GetError() for more
296         information.
297 
298     Threadsafety:
299         This function is not thread safe.
300 
301     See_Also:
302         $(D SDL_GetScancodeName)
303 */
304 extern bool SDL_SetScancodeName(SDL_Scancode scancode, const(char)* name);
305 
306 /**
307     Get a human-readable name for a scancode.
308 
309     **Warning**: The returned name is by design not stable across platforms,
310     e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left
311     Windows" under Microsoft Windows, and some scancodes like
312     `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even
313     scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and
314     `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore
315     unsuitable for creating a stable cross-platform two-way mapping between
316     strings and scancodes.
317 
318     Params:
319         scancode =  the desired SDL_Scancode to query.
320     
321     Returns:
322         a pointer to the name for the scancode. If the scancode doesn't
323         have a name this function returns an empty string ("").
324 
325     Threadsafety:
326         This function is not thread safe.
327 
328     See_Also:
329         $(D SDL_GetScancodeFromKey)
330         $(D SDL_GetScancodeFromName)
331         $(D SDL_SetScancodeName)
332 */
333 extern const(char)* SDL_GetScancodeName(SDL_Scancode scancode);
334 
335 /**
336     Get a scancode from a human-readable name.
337 
338     Params:
339         name = the human-readable scancode name.
340     
341     Returns:
342         The SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't
343         recognized; call SDL_GetError() for more information.
344 
345     Threadsafety:
346         This function is not thread safe.
347 
348     See_Also:
349         $(D SDL_GetKeyFromName)
350         $(D SDL_GetScancodeFromKey)
351         $(D SDL_GetScancodeName)
352 */
353 extern SDL_Scancode SDL_GetScancodeFromName(const(char)* name);
354 
355 /**
356     Get a human-readable name for a key.
357 
358     If the key doesn't have a name, this function returns an empty string ("").
359 
360     Letters will be presented in their uppercase form, if applicable.
361 
362     Params:
363         key = the desired SDL_Keycode to query.
364     
365     Returns:
366         a UTF-8 encoded string of the key name.
367 
368     Threadsafety:
369         This function is not thread safe.
370 
371     See_Also:
372         $(D SDL_GetKeyFromName)
373         $(D SDL_GetKeyFromScancode)
374         $(D SDL_GetScancodeFromKey)
375 */
376 extern const(char)* SDL_GetKeyName(SDL_Keycode key);
377 
378 /**
379     Get a key code from a human-readable name.
380 
381     Params:
382         name = the human-readable key name.
383     
384     Returns:
385         key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call
386         SDL_GetError() for more information.
387 
388     Threadsafety:
389         This function is not thread safe.
390 
391     See_Also:
392         $(D SDL_GetKeyFromScancode)
393         $(D SDL_GetKeyName)
394         $(D SDL_GetScancodeFromName)
395 */
396 extern SDL_Keycode SDL_GetKeyFromName(const(char)* name);
397 
398 /**
399     Start accepting Unicode text input events in a window.
400 
401     This function will enable text input (SDL_EVENT_TEXT_INPUT and
402     SDL_EVENT_TEXT_EDITING events) in the specified window. Please use this
403     function paired with SDL_StopTextInput().
404 
405     Text input events are not received by default.
406 
407     On some platforms using this function shows the screen keyboard and/or
408     activates an IME, which can prevent some key press events from being passed
409     through.
410 
411     Params:
412         window = the window to enable text input.
413     
414     Returns:
415         true on success or false on failure; call SDL_GetError() for more
416         information.
417 
418     Threadsafety:
419         This function should only be called on the main thread.
420 
421     See_Also:
422         $(D SDL_SetTextInputArea)
423         $(D SDL_StartTextInputWithProperties)
424         $(D SDL_StopTextInput)
425         $(D SDL_TextInputActive)
426 */
427 extern bool SDL_StartTextInput(SDL_Window* window);
428 
429 /**
430     Text input type.
431 
432     These are the valid values for SDL_PROP_TEXTINPUT_TYPE_NUMBER. Not every
433     value is valid on every platform, but where a value isn't supported, a
434     reasonable fallback will be used.
435 
436     See_Also:
437         $(D SDL_StartTextInputWithProperties)
438 */
439 enum SDL_TextInputType {
440 
441     /**
442         The input is text
443     */
444     SDL_TEXTINPUT_TYPE_TEXT,
445 
446     /**
447         The input is a person's name
448     */
449     SDL_TEXTINPUT_TYPE_TEXT_NAME,
450 
451     /**
452         The input is an e-mail address
453     */
454     SDL_TEXTINPUT_TYPE_TEXT_EMAIL,
455 
456     /**
457         The input is a username
458     */
459     SDL_TEXTINPUT_TYPE_TEXT_USERNAME,
460 
461     /**
462         The input is a secure password that is hidden
463     */
464     SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN,
465 
466     /**
467         The input is a secure password that is visible
468     */
469     SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE,
470 
471     /**
472         The input is a number
473     */
474     SDL_TEXTINPUT_TYPE_NUMBER,
475 
476     /**
477         The input is a secure PIN that is hidden
478     */
479     SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN,
480 
481     /**
482         The input is a secure PIN that is visible
483     */
484     SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE
485 }
486 
487 /**
488     Auto capitalization type.
489 
490     These are the valid values for SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER.
491     Not every value is valid on every platform, but where a value isn't
492     supported, a reasonable fallback will be used.
493 
494     See_Also:
495     $(D SDL_StartTextInputWithProperties)
496 */
497 enum SDL_Capitalization {
498 
499     /**
500         No auto-capitalization will be done
501     */
502     SDL_CAPITALIZE_NONE,
503 
504     /**
505         The first letter of sentences will be capitalized
506     */
507     SDL_CAPITALIZE_SENTENCES,
508 
509     /**
510         The first letter of words will be capitalized
511     */
512     SDL_CAPITALIZE_WORDS,
513 
514     /**
515         All letters will be capitalized
516     */
517     SDL_CAPITALIZE_LETTERS
518 }
519 
520 /**
521     Start accepting Unicode text input events in a window, with properties
522     describing the input.
523 
524     This function will enable text input (SDL_EVENT_TEXT_INPUT and
525     SDL_EVENT_TEXT_EDITING events) in the specified window. Please use this
526     function paired with SDL_StopTextInput().
527 
528     Text input events are not received by default.
529 
530     On some platforms using this function shows the screen keyboard and/or
531     activates an IME, which can prevent some key press events from being passed
532     through.
533 
534     These are the supported properties:
535 
536     -   `SDL_PROP_TEXTINPUT_TYPE_NUMBER` - an SDL_TextInputType value that
537         describes text being input, defaults to SDL_TEXTINPUT_TYPE_TEXT.
538     -   `SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER` - an SDL_Capitalization value
539         that describes how text should be capitalized, defaults to
540         SDL_CAPITALIZE_SENTENCES for normal text entry, SDL_CAPITALIZE_WORDS for
541         SDL_TEXTINPUT_TYPE_TEXT_NAME, and SDL_CAPITALIZE_NONE for e-mail
542         addresses, usernames, and passwords.
543     -   `SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN` - true to enable auto completion
544         and auto correction, defaults to true.
545     -   `SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN` - true if multiple lines of text
546         are allowed. This defaults to true if SDL_HINT_RETURN_KEY_HIDES_IME is
547         "0" or is not set, and defaults to false if SDL_HINT_RETURN_KEY_HIDES_IME
548         is "1".
549 
550     On Android you can directly specify the input type:
551 
552     -   `SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER` - the text input type to
553         use, overriding other properties. This is documented at
554         https://developer.android.com/reference/android/text/InputType
555 
556     Params:
557         window =    the window to enable text input.
558         props =     the properties to use.
559     
560     Returns:
561         true on success or false on failure; call SDL_GetError() for more
562         information.
563 
564     Threadsafety:
565         This function should only be called on the main thread.
566 
567     See_Also:
568         $(D SDL_SetTextInputArea)
569         $(D SDL_StartTextInput)
570         $(D SDL_StopTextInput)
571         $(D SDL_TextInputActive)
572 */
573 extern bool SDL_StartTextInputWithProperties(SDL_Window* window, SDL_PropertiesID props);
574 
575 enum SDL_PROP_TEXTINPUT_TYPE_NUMBER = "SDL.textinput.type";
576 enum SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER = "SDL.textinput.capitalization";
577 enum SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN = "SDL.textinput.autocorrect";
578 enum SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN = "SDL.textinput.multiline";
579 enum SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER = "SDL.textinput.android.inputtype";
580 
581 /**
582     Check whether or not Unicode text input events are enabled for a window.
583 
584     Params:
585         window = the window to check.
586     
587     Returns:
588         true if text input events are enabled else false.
589 
590     Threadsafety:
591         This function should only be called on the main thread.
592 
593     See_Also:
594         $(D SDL_StartTextInput)
595 */
596 extern bool SDL_TextInputActive(SDL_Window* window);
597 
598 /**
599     Stop receiving any text input events in a window.
600 
601     If SDL_StartTextInput() showed the screen keyboard, this function will hide
602     it.
603 
604     Params:
605         window = the window to disable text input.
606     
607     Returns:
608         true on success or false on failure; call SDL_GetError() for more
609         information.
610 
611     Threadsafety:
612         This function should only be called on the main thread.
613 
614     See_Also:
615         $(D SDL_StartTextInput)
616 */
617 extern bool SDL_StopTextInput(SDL_Window* window);
618 
619 /**
620     Dismiss the composition window/IME without disabling the subsystem.
621 
622     Params:
623         window = the window to affect.
624     
625     Returns:
626         true on success or false on failure; call SDL_GetError() for more
627         information.
628 
629     Threadsafety:
630         This function should only be called on the main thread.
631 
632     See_Also:
633         $(D SDL_StartTextInput)
634         $(D SDL_StopTextInput)
635 */
636 extern bool SDL_ClearComposition(SDL_Window* window);
637 
638 /**
639     Set the area used to type Unicode text input.
640 
641     Native input methods may place a window with word suggestions near the
642     cursor, without covering the text being entered.
643 
644     Params:
645         window =    the window for which to set the text input area.
646         rect =      the SDL_Rect representing the text input area, in window
647                     coordinates, or NULL to clear it.
648         cursor =    the offset of the current cursor location relative to
649                     `rect->x`, in window coordinates.
650     
651     Returns:
652         true on success or false on failure; call SDL_GetError() for more
653         information.
654 
655     Threadsafety:
656         This function should only be called on the main thread.
657 
658     See_Also:
659         $(D SDL_GetTextInputArea)
660         $(D SDL_StartTextInput)
661 */
662 extern bool SDL_SetTextInputArea(SDL_Window* window, const SDL_Rect* rect, int cursor);
663 
664 /**
665     Get the area used to type Unicode text input.
666 
667     This returns the values previously set by SDL_SetTextInputArea().
668 
669     Params:
670         window =    the window for which to query the text input area.
671         rect =      a pointer to an SDL_Rect filled in with the text input area,
672                     may be NULL.
673         cursor =    a pointer to the offset of the current cursor location
674                     relative to `rect->x`, may be NULL.
675     
676     Returns:
677         true on success or false on failure; call SDL_GetError() for more
678         information.
679 
680     Threadsafety:
681         This function should only be called on the main thread.
682 
683     See_Also:
684         $(D SDL_SetTextInputArea)
685 */
686 extern bool SDL_GetTextInputArea(SDL_Window* window, SDL_Rect* rect, int* cursor);
687 
688 /**
689     Check whether the platform has screen keyboard support.
690 
691     Returns:
692         true if the platform has some screen keyboard support or false if
693         not.
694 
695     Threadsafety:
696         This function should only be called on the main thread.
697 
698     See_Also:
699         $(D SDL_StartTextInput)
700         $(D SDL_ScreenKeyboardShown)
701 */
702 extern bool SDL_HasScreenKeyboardSupport();
703 
704 /**
705     Check whether the screen keyboard is shown for given window.
706 
707     Params:
708         window = the window for which screen keyboard should be queried.
709     
710     Returns:
711         true if screen keyboard is shown or false if not.
712 
713     Threadsafety:
714         This function should only be called on the main thread.
715 
716     See_Also:
717         $(D SDL_HasScreenKeyboardSupport)
718 */
719 extern bool SDL_ScreenKeyboardShown(SDL_Window* window);