SDL
2.0
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
SDL_keyboard.c
Go to the documentation of this file.
1
/*
2
Simple DirectMedia Layer
3
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
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
#include "../SDL_internal.h"
22
23
/* General keyboard handling code for SDL */
24
25
#include "
SDL_timer.h
"
26
#include "
SDL_events.h
"
27
#include "
SDL_events_c.h
"
28
#include "
SDL_assert.h
"
29
#include "../video/SDL_sysvideo.h"
30
31
32
/* #define DEBUG_KEYBOARD */
33
34
/* Global keyboard information */
35
36
typedef
struct
SDL_Keyboard
SDL_Keyboard
;
37
38
struct
SDL_Keyboard
39
{
40
/* Data common to all keyboards */
41
SDL_Window
*
focus
;
42
Uint16
modstate
;
43
Uint8
keystate
[
SDL_NUM_SCANCODES
];
44
SDL_Keycode
keymap
[
SDL_NUM_SCANCODES
];
45
};
46
47
static
SDL_Keyboard
SDL_keyboard
;
48
49
static
const
SDL_Keycode
SDL_default_keymap
[
SDL_NUM_SCANCODES
] = {
50
0, 0, 0, 0,
51
'a'
,
52
'b'
,
53
'c'
,
54
'd'
,
55
'e'
,
56
'f'
,
57
'g'
,
58
'h'
,
59
'i'
,
60
'j'
,
61
'k'
,
62
'l'
,
63
'm'
,
64
'n'
,
65
'o'
,
66
'p'
,
67
'q'
,
68
'r'
,
69
's'
,
70
't'
,
71
'u'
,
72
'v'
,
73
'w'
,
74
'x'
,
75
'y'
,
76
'z'
,
77
'1'
,
78
'2'
,
79
'3'
,
80
'4'
,
81
'5'
,
82
'6'
,
83
'7'
,
84
'8'
,
85
'9'
,
86
'0'
,
87
SDLK_RETURN
,
88
SDLK_ESCAPE
,
89
SDLK_BACKSPACE
,
90
SDLK_TAB
,
91
SDLK_SPACE
,
92
'-'
,
93
'='
,
94
'['
,
95
']'
,
96
'\\'
,
97
'#'
,
98
';'
,
99
'\''
,
100
'`'
,
101
','
,
102
'.'
,
103
'/'
,
104
SDLK_CAPSLOCK
,
105
SDLK_F1
,
106
SDLK_F2
,
107
SDLK_F3
,
108
SDLK_F4
,
109
SDLK_F5
,
110
SDLK_F6
,
111
SDLK_F7
,
112
SDLK_F8
,
113
SDLK_F9
,
114
SDLK_F10
,
115
SDLK_F11
,
116
SDLK_F12
,
117
SDLK_PRINTSCREEN
,
118
SDLK_SCROLLLOCK
,
119
SDLK_PAUSE
,
120
SDLK_INSERT
,
121
SDLK_HOME
,
122
SDLK_PAGEUP
,
123
SDLK_DELETE
,
124
SDLK_END
,
125
SDLK_PAGEDOWN
,
126
SDLK_RIGHT
,
127
SDLK_LEFT
,
128
SDLK_DOWN
,
129
SDLK_UP
,
130
SDLK_NUMLOCKCLEAR
,
131
SDLK_KP_DIVIDE
,
132
SDLK_KP_MULTIPLY
,
133
SDLK_KP_MINUS
,
134
SDLK_KP_PLUS
,
135
SDLK_KP_ENTER
,
136
SDLK_KP_1
,
137
SDLK_KP_2
,
138
SDLK_KP_3
,
139
SDLK_KP_4
,
140
SDLK_KP_5
,
141
SDLK_KP_6
,
142
SDLK_KP_7
,
143
SDLK_KP_8
,
144
SDLK_KP_9
,
145
SDLK_KP_0
,
146
SDLK_KP_PERIOD
,
147
0,
148
SDLK_APPLICATION
,
149
SDLK_POWER
,
150
SDLK_KP_EQUALS
,
151
SDLK_F13
,
152
SDLK_F14
,
153
SDLK_F15
,
154
SDLK_F16
,
155
SDLK_F17
,
156
SDLK_F18
,
157
SDLK_F19
,
158
SDLK_F20
,
159
SDLK_F21
,
160
SDLK_F22
,
161
SDLK_F23
,
162
SDLK_F24
,
163
SDLK_EXECUTE
,
164
SDLK_HELP
,
165
SDLK_MENU
,
166
SDLK_SELECT
,
167
SDLK_STOP
,
168
SDLK_AGAIN
,
169
SDLK_UNDO
,
170
SDLK_CUT
,
171
SDLK_COPY
,
172
SDLK_PASTE
,
173
SDLK_FIND
,
174
SDLK_MUTE
,
175
SDLK_VOLUMEUP
,
176
SDLK_VOLUMEDOWN
,
177
0, 0, 0,
178
SDLK_KP_COMMA
,
179
SDLK_KP_EQUALSAS400
,
180
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181
SDLK_ALTERASE
,
182
SDLK_SYSREQ
,
183
SDLK_CANCEL
,
184
SDLK_CLEAR
,
185
SDLK_PRIOR
,
186
SDLK_RETURN2
,
187
SDLK_SEPARATOR
,
188
SDLK_OUT
,
189
SDLK_OPER
,
190
SDLK_CLEARAGAIN
,
191
SDLK_CRSEL
,
192
SDLK_EXSEL
,
193
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194
SDLK_KP_00
,
195
SDLK_KP_000
,
196
SDLK_THOUSANDSSEPARATOR
,
197
SDLK_DECIMALSEPARATOR
,
198
SDLK_CURRENCYUNIT
,
199
SDLK_CURRENCYSUBUNIT
,
200
SDLK_KP_LEFTPAREN
,
201
SDLK_KP_RIGHTPAREN
,
202
SDLK_KP_LEFTBRACE
,
203
SDLK_KP_RIGHTBRACE
,
204
SDLK_KP_TAB
,
205
SDLK_KP_BACKSPACE
,
206
SDLK_KP_A
,
207
SDLK_KP_B
,
208
SDLK_KP_C
,
209
SDLK_KP_D
,
210
SDLK_KP_E
,
211
SDLK_KP_F
,
212
SDLK_KP_XOR
,
213
SDLK_KP_POWER
,
214
SDLK_KP_PERCENT
,
215
SDLK_KP_LESS
,
216
SDLK_KP_GREATER
,
217
SDLK_KP_AMPERSAND
,
218
SDLK_KP_DBLAMPERSAND
,
219
SDLK_KP_VERTICALBAR
,
220
SDLK_KP_DBLVERTICALBAR
,
221
SDLK_KP_COLON
,
222
SDLK_KP_HASH
,
223
SDLK_KP_SPACE
,
224
SDLK_KP_AT
,
225
SDLK_KP_EXCLAM
,
226
SDLK_KP_MEMSTORE
,
227
SDLK_KP_MEMRECALL
,
228
SDLK_KP_MEMCLEAR
,
229
SDLK_KP_MEMADD
,
230
SDLK_KP_MEMSUBTRACT
,
231
SDLK_KP_MEMMULTIPLY
,
232
SDLK_KP_MEMDIVIDE
,
233
SDLK_KP_PLUSMINUS
,
234
SDLK_KP_CLEAR
,
235
SDLK_KP_CLEARENTRY
,
236
SDLK_KP_BINARY
,
237
SDLK_KP_OCTAL
,
238
SDLK_KP_DECIMAL
,
239
SDLK_KP_HEXADECIMAL
,
240
0, 0,
241
SDLK_LCTRL
,
242
SDLK_LSHIFT
,
243
SDLK_LALT
,
244
SDLK_LGUI
,
245
SDLK_RCTRL
,
246
SDLK_RSHIFT
,
247
SDLK_RALT
,
248
SDLK_RGUI
,
249
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250
SDLK_MODE
,
251
SDLK_AUDIONEXT
,
252
SDLK_AUDIOPREV
,
253
SDLK_AUDIOSTOP
,
254
SDLK_AUDIOPLAY
,
255
SDLK_AUDIOMUTE
,
256
SDLK_MEDIASELECT
,
257
SDLK_WWW
,
258
SDLK_MAIL
,
259
SDLK_CALCULATOR
,
260
SDLK_COMPUTER
,
261
SDLK_AC_SEARCH
,
262
SDLK_AC_HOME
,
263
SDLK_AC_BACK
,
264
SDLK_AC_FORWARD
,
265
SDLK_AC_STOP
,
266
SDLK_AC_REFRESH
,
267
SDLK_AC_BOOKMARKS
,
268
SDLK_BRIGHTNESSDOWN
,
269
SDLK_BRIGHTNESSUP
,
270
SDLK_DISPLAYSWITCH
,
271
SDLK_KBDILLUMTOGGLE
,
272
SDLK_KBDILLUMDOWN
,
273
SDLK_KBDILLUMUP
,
274
SDLK_EJECT
,
275
SDLK_SLEEP
,
276
SDLK_APP1
,
277
SDLK_APP2
,
278
SDLK_AUDIOREWIND
,
279
SDLK_AUDIOFASTFORWARD
,
280
};
281
282
static
const
char
*
SDL_scancode_names
[
SDL_NUM_SCANCODES
] = {
283
NULL
,
NULL
,
NULL
,
NULL
,
284
"A"
,
285
"B"
,
286
"C"
,
287
"D"
,
288
"E"
,
289
"F"
,
290
"G"
,
291
"H"
,
292
"I"
,
293
"J"
,
294
"K"
,
295
"L"
,
296
"M"
,
297
"N"
,
298
"O"
,
299
"P"
,
300
"Q"
,
301
"R"
,
302
"S"
,
303
"T"
,
304
"U"
,
305
"V"
,
306
"W"
,
307
"X"
,
308
"Y"
,
309
"Z"
,
310
"1"
,
311
"2"
,
312
"3"
,
313
"4"
,
314
"5"
,
315
"6"
,
316
"7"
,
317
"8"
,
318
"9"
,
319
"0"
,
320
"Return"
,
321
"Escape"
,
322
"Backspace"
,
323
"Tab"
,
324
"Space"
,
325
"-"
,
326
"="
,
327
"["
,
328
"]"
,
329
"\\"
,
330
"#"
,
331
";"
,
332
"'"
,
333
"`"
,
334
","
,
335
"."
,
336
"/"
,
337
"CapsLock"
,
338
"F1"
,
339
"F2"
,
340
"F3"
,
341
"F4"
,
342
"F5"
,
343
"F6"
,
344
"F7"
,
345
"F8"
,
346
"F9"
,
347
"F10"
,
348
"F11"
,
349
"F12"
,
350
"PrintScreen"
,
351
"ScrollLock"
,
352
"Pause"
,
353
"Insert"
,
354
"Home"
,
355
"PageUp"
,
356
"Delete"
,
357
"End"
,
358
"PageDown"
,
359
"Right"
,
360
"Left"
,
361
"Down"
,
362
"Up"
,
363
"Numlock"
,
364
"Keypad /"
,
365
"Keypad *"
,
366
"Keypad -"
,
367
"Keypad +"
,
368
"Keypad Enter"
,
369
"Keypad 1"
,
370
"Keypad 2"
,
371
"Keypad 3"
,
372
"Keypad 4"
,
373
"Keypad 5"
,
374
"Keypad 6"
,
375
"Keypad 7"
,
376
"Keypad 8"
,
377
"Keypad 9"
,
378
"Keypad 0"
,
379
"Keypad ."
,
380
NULL
,
381
"Application"
,
382
"Power"
,
383
"Keypad ="
,
384
"F13"
,
385
"F14"
,
386
"F15"
,
387
"F16"
,
388
"F17"
,
389
"F18"
,
390
"F19"
,
391
"F20"
,
392
"F21"
,
393
"F22"
,
394
"F23"
,
395
"F24"
,
396
"Execute"
,
397
"Help"
,
398
"Menu"
,
399
"Select"
,
400
"Stop"
,
401
"Again"
,
402
"Undo"
,
403
"Cut"
,
404
"Copy"
,
405
"Paste"
,
406
"Find"
,
407
"Mute"
,
408
"VolumeUp"
,
409
"VolumeDown"
,
410
NULL
,
NULL
,
NULL
,
411
"Keypad ,"
,
412
"Keypad = (AS400)"
,
413
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
414
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
415
"AltErase"
,
416
"SysReq"
,
417
"Cancel"
,
418
"Clear"
,
419
"Prior"
,
420
"Return"
,
421
"Separator"
,
422
"Out"
,
423
"Oper"
,
424
"Clear / Again"
,
425
"CrSel"
,
426
"ExSel"
,
427
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
428
"Keypad 00"
,
429
"Keypad 000"
,
430
"ThousandsSeparator"
,
431
"DecimalSeparator"
,
432
"CurrencyUnit"
,
433
"CurrencySubUnit"
,
434
"Keypad ("
,
435
"Keypad )"
,
436
"Keypad {"
,
437
"Keypad }"
,
438
"Keypad Tab"
,
439
"Keypad Backspace"
,
440
"Keypad A"
,
441
"Keypad B"
,
442
"Keypad C"
,
443
"Keypad D"
,
444
"Keypad E"
,
445
"Keypad F"
,
446
"Keypad XOR"
,
447
"Keypad ^"
,
448
"Keypad %"
,
449
"Keypad <"
,
450
"Keypad >"
,
451
"Keypad &"
,
452
"Keypad &&"
,
453
"Keypad |"
,
454
"Keypad ||"
,
455
"Keypad :"
,
456
"Keypad #"
,
457
"Keypad Space"
,
458
"Keypad @"
,
459
"Keypad !"
,
460
"Keypad MemStore"
,
461
"Keypad MemRecall"
,
462
"Keypad MemClear"
,
463
"Keypad MemAdd"
,
464
"Keypad MemSubtract"
,
465
"Keypad MemMultiply"
,
466
"Keypad MemDivide"
,
467
"Keypad +/-"
,
468
"Keypad Clear"
,
469
"Keypad ClearEntry"
,
470
"Keypad Binary"
,
471
"Keypad Octal"
,
472
"Keypad Decimal"
,
473
"Keypad Hexadecimal"
,
474
NULL
,
NULL
,
475
"Left Ctrl"
,
476
"Left Shift"
,
477
"Left Alt"
,
478
"Left GUI"
,
479
"Right Ctrl"
,
480
"Right Shift"
,
481
"Right Alt"
,
482
"Right GUI"
,
483
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
484
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
485
NULL
,
486
"ModeSwitch"
,
487
"AudioNext"
,
488
"AudioPrev"
,
489
"AudioStop"
,
490
"AudioPlay"
,
491
"AudioMute"
,
492
"MediaSelect"
,
493
"WWW"
,
494
"Mail"
,
495
"Calculator"
,
496
"Computer"
,
497
"AC Search"
,
498
"AC Home"
,
499
"AC Back"
,
500
"AC Forward"
,
501
"AC Stop"
,
502
"AC Refresh"
,
503
"AC Bookmarks"
,
504
"BrightnessDown"
,
505
"BrightnessUp"
,
506
"DisplaySwitch"
,
507
"KBDIllumToggle"
,
508
"KBDIllumDown"
,
509
"KBDIllumUp"
,
510
"Eject"
,
511
"Sleep"
,
512
"App1"
,
513
"App2"
,
514
"AudioRewind"
,
515
"AudioFastForward"
,
516
};
517
518
/* Taken from SDL_iconv() */
519
char
*
520
SDL_UCS4ToUTF8
(
Uint32
ch,
char
*
dst
)
521
{
522
Uint8
*
p
= (
Uint8
*) dst;
523
if
(ch <= 0x7F) {
524
*p = (
Uint8
) ch;
525
++
dst
;
526
}
else
if
(ch <= 0x7FF) {
527
p[0] = 0xC0 | (
Uint8
) ((ch >> 6) & 0x1F);
528
p[1] = 0x80 | (
Uint8
) (ch & 0x3F);
529
dst += 2;
530
}
else
if
(ch <= 0xFFFF) {
531
p[0] = 0xE0 | (
Uint8
) ((ch >> 12) & 0x0F);
532
p[1] = 0x80 | (
Uint8
) ((ch >> 6) & 0x3F);
533
p[2] = 0x80 | (
Uint8
) (ch & 0x3F);
534
dst += 3;
535
}
else
if
(ch <= 0x1FFFFF) {
536
p[0] = 0xF0 | (
Uint8
) ((ch >> 18) & 0x07);
537
p[1] = 0x80 | (
Uint8
) ((ch >> 12) & 0x3F);
538
p[2] = 0x80 | (
Uint8
) ((ch >> 6) & 0x3F);
539
p[3] = 0x80 | (
Uint8
) (ch & 0x3F);
540
dst += 4;
541
}
else
if
(ch <= 0x3FFFFFF) {
542
p[0] = 0xF8 | (
Uint8
) ((ch >> 24) & 0x03);
543
p[1] = 0x80 | (
Uint8
) ((ch >> 18) & 0x3F);
544
p[2] = 0x80 | (
Uint8
) ((ch >> 12) & 0x3F);
545
p[3] = 0x80 | (
Uint8
) ((ch >> 6) & 0x3F);
546
p[4] = 0x80 | (
Uint8
) (ch & 0x3F);
547
dst += 5;
548
}
else
{
549
p[0] = 0xFC | (
Uint8
) ((ch >> 30) & 0x01);
550
p[1] = 0x80 | (
Uint8
) ((ch >> 24) & 0x3F);
551
p[2] = 0x80 | (
Uint8
) ((ch >> 18) & 0x3F);
552
p[3] = 0x80 | (
Uint8
) ((ch >> 12) & 0x3F);
553
p[4] = 0x80 | (
Uint8
) ((ch >> 6) & 0x3F);
554
p[5] = 0x80 | (
Uint8
) (ch & 0x3F);
555
dst += 6;
556
}
557
return
dst
;
558
}
559
560
/* Public functions */
561
int
562
SDL_KeyboardInit
(
void
)
563
{
564
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
565
566
/* Set the default keymap */
567
SDL_memcpy
(keyboard->
keymap
,
SDL_default_keymap
,
sizeof
(
SDL_default_keymap
));
568
return
(0);
569
}
570
571
void
572
SDL_ResetKeyboard
(
void
)
573
{
574
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
575
SDL_Scancode
scancode;
576
577
#ifdef DEBUG_KEYBOARD
578
printf(
"Resetting keyboard\n"
);
579
#endif
580
for
(scancode = (
SDL_Scancode
) 0; scancode <
SDL_NUM_SCANCODES
; ++scancode) {
581
if
(keyboard->
keystate
[scancode] ==
SDL_PRESSED
) {
582
SDL_SendKeyboardKey
(
SDL_RELEASED
, scancode);
583
}
584
}
585
}
586
587
void
588
SDL_GetDefaultKeymap
(
SDL_Keycode
* keymap)
589
{
590
SDL_memcpy
(keymap,
SDL_default_keymap
,
sizeof
(
SDL_default_keymap
));
591
}
592
593
void
594
SDL_SetKeymap
(
int
start
,
SDL_Keycode
* keys,
int
length
)
595
{
596
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
597
SDL_Scancode
scancode;
598
599
if
(
start < 0 || start + length >
SDL_NUM_SCANCODES
) {
600
return
;
601
}
602
603
SDL_memcpy
(&keyboard->
keymap
[start], keys,
sizeof
(*keys) * length);
604
605
/* The number key scancodes always map to the number key keycodes.
606
* On AZERTY layouts these technically are symbols, but users (and games)
607
* always think of them and view them in UI as number keys.
608
*/
609
keyboard->
keymap
[
SDL_SCANCODE_0
] =
SDLK_0
;
610
for
(scancode =
SDL_SCANCODE_1
; scancode <=
SDL_SCANCODE_9
; ++scancode) {
611
keyboard->
keymap
[scancode] =
SDLK_1
+ (scancode -
SDL_SCANCODE_1
);
612
}
613
}
614
615
void
616
SDL_SetScancodeName
(
SDL_Scancode
scancode,
const
char
*
name
)
617
{
618
SDL_scancode_names
[scancode] =
name
;
619
}
620
621
SDL_Window
*
622
SDL_GetKeyboardFocus
(
void
)
623
{
624
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
625
626
return
keyboard->
focus
;
627
}
628
629
void
630
SDL_SetKeyboardFocus
(
SDL_Window
*
window
)
631
{
632
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
633
634
if
(keyboard->
focus
&& !window) {
635
/* We won't get anymore keyboard messages, so reset keyboard state */
636
SDL_ResetKeyboard
();
637
}
638
639
/* See if the current window has lost focus */
640
if
(keyboard->
focus
&& keyboard->
focus
!= window) {
641
642
/* new window shouldn't think it has mouse captured. */
643
SDL_assert
(!window || !(window->
flags
&
SDL_WINDOW_MOUSE_CAPTURE
));
644
645
/* old window must lose an existing mouse capture. */
646
if
(keyboard->
focus
->
flags
&
SDL_WINDOW_MOUSE_CAPTURE
) {
647
SDL_CaptureMouse
(
SDL_FALSE
);
/* drop the capture. */
648
SDL_assert
(!(keyboard->
focus
->
flags
&
SDL_WINDOW_MOUSE_CAPTURE
));
649
}
650
651
SDL_SendWindowEvent
(keyboard->
focus
,
SDL_WINDOWEVENT_FOCUS_LOST
,
652
0, 0);
653
654
/* Ensures IME compositions are committed */
655
if
(
SDL_EventState
(
SDL_TEXTINPUT
,
SDL_QUERY
)) {
656
SDL_VideoDevice
*video =
SDL_GetVideoDevice
();
657
if
(video && video->
StopTextInput
) {
658
video->
StopTextInput
(video);
659
}
660
}
661
}
662
663
keyboard->
focus
=
window
;
664
665
if
(keyboard->
focus
) {
666
SDL_SendWindowEvent
(keyboard->
focus
,
SDL_WINDOWEVENT_FOCUS_GAINED
,
667
0, 0);
668
669
if
(
SDL_EventState
(
SDL_TEXTINPUT
,
SDL_QUERY
)) {
670
SDL_VideoDevice
*video =
SDL_GetVideoDevice
();
671
if
(video && video->
StartTextInput
) {
672
video->
StartTextInput
(video);
673
}
674
}
675
}
676
}
677
678
int
679
SDL_SendKeyboardKey
(
Uint8
state
,
SDL_Scancode
scancode)
680
{
681
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
682
int
posted;
683
SDL_Keymod
modifier;
684
SDL_Keycode
keycode;
685
Uint32
type
;
686
Uint8
repeat;
687
688
if
(!scancode) {
689
return
0;
690
}
691
#ifdef DEBUG_KEYBOARD
692
printf(
"The '%s' key has been %s\n"
,
SDL_GetScancodeName
(scancode),
693
state ==
SDL_PRESSED
?
"pressed"
:
"released"
);
694
#endif
695
696
/* Figure out what type of event this is */
697
switch
(state) {
698
case
SDL_PRESSED
:
699
type =
SDL_KEYDOWN
;
700
break
;
701
case
SDL_RELEASED
:
702
type =
SDL_KEYUP
;
703
break
;
704
default
:
705
/* Invalid state -- bail */
706
return
0;
707
}
708
709
/* Drop events that don't change state */
710
repeat = (state && keyboard->
keystate
[scancode]);
711
if
(keyboard->
keystate
[scancode] == state && !repeat) {
712
#if 0
713
printf(
"Keyboard event didn't change state - dropped!\n"
);
714
#endif
715
return
0;
716
}
717
718
/* Update internal keyboard state */
719
keyboard->
keystate
[scancode] =
state
;
720
721
keycode = keyboard->
keymap
[scancode];
722
723
/* Update modifiers state if applicable */
724
switch
(keycode) {
725
case
SDLK_LCTRL
:
726
modifier =
KMOD_LCTRL
;
727
break
;
728
case
SDLK_RCTRL
:
729
modifier =
KMOD_RCTRL
;
730
break
;
731
case
SDLK_LSHIFT
:
732
modifier =
KMOD_LSHIFT
;
733
break
;
734
case
SDLK_RSHIFT
:
735
modifier =
KMOD_RSHIFT
;
736
break
;
737
case
SDLK_LALT
:
738
modifier =
KMOD_LALT
;
739
break
;
740
case
SDLK_RALT
:
741
modifier =
KMOD_RALT
;
742
break
;
743
case
SDLK_LGUI
:
744
modifier =
KMOD_LGUI
;
745
break
;
746
case
SDLK_RGUI
:
747
modifier =
KMOD_RGUI
;
748
break
;
749
case
SDLK_MODE
:
750
modifier =
KMOD_MODE
;
751
break
;
752
default
:
753
modifier =
KMOD_NONE
;
754
break
;
755
}
756
if
(
SDL_KEYDOWN
== type) {
757
switch
(keycode) {
758
case
SDLK_NUMLOCKCLEAR
:
759
keyboard->
modstate
^=
KMOD_NUM
;
760
break
;
761
case
SDLK_CAPSLOCK
:
762
keyboard->
modstate
^=
KMOD_CAPS
;
763
break
;
764
default
:
765
keyboard->
modstate
|= modifier;
766
break
;
767
}
768
}
else
{
769
keyboard->
modstate
&= ~modifier;
770
}
771
772
/* Post the event, if desired */
773
posted = 0;
774
if
(
SDL_GetEventState
(type) ==
SDL_ENABLE
) {
775
SDL_Event
event
;
776
event
.key.type =
type
;
777
event
.key.state =
state
;
778
event
.key.repeat = repeat;
779
event
.key.keysym.scancode = scancode;
780
event
.key.keysym.sym = keycode;
781
event
.key.keysym.mod = keyboard->
modstate
;
782
event
.key.windowID = keyboard->
focus
? keyboard->
focus
->
id
: 0;
783
posted = (
SDL_PushEvent
(&event) > 0);
784
}
785
return
(posted);
786
}
787
788
int
789
SDL_SendKeyboardText
(
const
char
*
text
)
790
{
791
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
792
int
posted;
793
794
/* Don't post text events for unprintable characters */
795
if
((
unsigned
char
)*text <
' '
|| *text == 127) {
796
return
0;
797
}
798
799
/* Post the event, if desired */
800
posted = 0;
801
if
(
SDL_GetEventState
(
SDL_TEXTINPUT
) ==
SDL_ENABLE
) {
802
SDL_Event
event
;
803
event
.text.type =
SDL_TEXTINPUT
;
804
event
.text.windowID = keyboard->
focus
? keyboard->
focus
->
id
: 0;
805
SDL_utf8strlcpy
(event.
text
.
text
, text,
SDL_arraysize
(event.
text
.
text
));
806
posted = (
SDL_PushEvent
(&event) > 0);
807
}
808
return
(posted);
809
}
810
811
int
812
SDL_SendEditingText
(
const
char
*
text
,
int
start
,
int
length
)
813
{
814
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
815
int
posted;
816
817
/* Post the event, if desired */
818
posted = 0;
819
if
(
SDL_GetEventState
(
SDL_TEXTEDITING
) ==
SDL_ENABLE
) {
820
SDL_Event
event
;
821
event
.edit.type =
SDL_TEXTEDITING
;
822
event
.edit.windowID = keyboard->
focus
? keyboard->
focus
->
id
: 0;
823
event
.edit.start =
start
;
824
event
.edit.length =
length
;
825
SDL_utf8strlcpy
(event.
edit
.
text
, text,
SDL_arraysize
(event.
edit
.
text
));
826
posted = (
SDL_PushEvent
(&event) > 0);
827
}
828
return
(posted);
829
}
830
831
void
832
SDL_KeyboardQuit
(
void
)
833
{
834
}
835
836
const
Uint8
*
837
SDL_GetKeyboardState
(
int
*numkeys)
838
{
839
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
840
841
if
(numkeys != (
int
*) 0) {
842
*numkeys =
SDL_NUM_SCANCODES
;
843
}
844
return
keyboard->
keystate
;
845
}
846
847
SDL_Keymod
848
SDL_GetModState
(
void
)
849
{
850
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
851
852
return
(
SDL_Keymod
) keyboard->
modstate
;
853
}
854
855
void
856
SDL_SetModState
(
SDL_Keymod
modstate)
857
{
858
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
859
860
keyboard->
modstate
= modstate;
861
}
862
863
/* Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. */
864
void
865
SDL_ToggleModState
(
const
SDL_Keymod
modstate,
const
SDL_bool
toggle)
866
{
867
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
868
if
(toggle) {
869
keyboard->
modstate
|= modstate;
870
}
else
{
871
keyboard->
modstate
&= ~modstate;
872
}
873
}
874
875
876
SDL_Keycode
877
SDL_GetKeyFromScancode
(
SDL_Scancode
scancode)
878
{
879
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
880
881
if
(((
int
)scancode) < ((
int
)
SDL_SCANCODE_UNKNOWN
) || scancode >=
SDL_NUM_SCANCODES
) {
882
SDL_InvalidParamError
(
"scancode"
);
883
return
0;
884
}
885
886
return
keyboard->
keymap
[scancode];
887
}
888
889
SDL_Scancode
890
SDL_GetScancodeFromKey
(
SDL_Keycode
key
)
891
{
892
SDL_Keyboard
*keyboard = &
SDL_keyboard
;
893
SDL_Scancode
scancode;
894
895
for
(scancode =
SDL_SCANCODE_UNKNOWN
; scancode <
SDL_NUM_SCANCODES
;
896
++scancode) {
897
if
(keyboard->
keymap
[scancode] == key) {
898
return
scancode;
899
}
900
}
901
return
SDL_SCANCODE_UNKNOWN
;
902
}
903
904
const
char
*
905
SDL_GetScancodeName
(
SDL_Scancode
scancode)
906
{
907
const
char
*
name
;
908
if
(((
int
)scancode) < ((
int
)
SDL_SCANCODE_UNKNOWN
) || scancode >=
SDL_NUM_SCANCODES
) {
909
SDL_InvalidParamError
(
"scancode"
);
910
return
""
;
911
}
912
913
name =
SDL_scancode_names
[scancode];
914
if
(name)
915
return
name
;
916
else
917
return
""
;
918
}
919
920
SDL_Scancode
SDL_GetScancodeFromName
(
const
char
*
name
)
921
{
922
int
i
;
923
924
if
(!name || !*name) {
925
SDL_InvalidParamError
(
"name"
);
926
return
SDL_SCANCODE_UNKNOWN
;
927
}
928
929
for
(i = 0; i <
SDL_arraysize
(
SDL_scancode_names
); ++
i
) {
930
if
(!
SDL_scancode_names
[i]) {
931
continue
;
932
}
933
if
(
SDL_strcasecmp
(name,
SDL_scancode_names
[i]) == 0) {
934
return
(
SDL_Scancode
)
i
;
935
}
936
}
937
938
SDL_InvalidParamError
(
"name"
);
939
return
SDL_SCANCODE_UNKNOWN
;
940
}
941
942
const
char
*
943
SDL_GetKeyName
(
SDL_Keycode
key
)
944
{
945
static
char
name
[8];
946
char
*
end
;
947
948
if
(key &
SDLK_SCANCODE_MASK
) {
949
return
950
SDL_GetScancodeName
((
SDL_Scancode
) (key & ~SDLK_SCANCODE_MASK));
951
}
952
953
switch
(key) {
954
case
SDLK_RETURN
:
955
return
SDL_GetScancodeName
(
SDL_SCANCODE_RETURN
);
956
case
SDLK_ESCAPE
:
957
return
SDL_GetScancodeName
(
SDL_SCANCODE_ESCAPE
);
958
case
SDLK_BACKSPACE
:
959
return
SDL_GetScancodeName
(
SDL_SCANCODE_BACKSPACE
);
960
case
SDLK_TAB
:
961
return
SDL_GetScancodeName
(
SDL_SCANCODE_TAB
);
962
case
SDLK_SPACE
:
963
return
SDL_GetScancodeName
(
SDL_SCANCODE_SPACE
);
964
case
SDLK_DELETE
:
965
return
SDL_GetScancodeName
(
SDL_SCANCODE_DELETE
);
966
default
:
967
/* Unaccented letter keys on latin keyboards are normally
968
labeled in upper case (and probably on others like Greek or
969
Cyrillic too, so if you happen to know for sure, please
970
adapt this). */
971
if
(key >=
'a'
&& key <=
'z'
) {
972
key -= 32;
973
}
974
975
end =
SDL_UCS4ToUTF8
((
Uint32
) key, name);
976
*end =
'\0'
;
977
return
name
;
978
}
979
}
980
981
SDL_Keycode
982
SDL_GetKeyFromName
(
const
char
*
name
)
983
{
984
SDL_Keycode
key
;
985
986
/* Check input */
987
if
(name ==
NULL
) {
988
return
SDLK_UNKNOWN
;
989
}
990
991
/* If it's a single UTF-8 character, then that's the keycode itself */
992
key = *(
const
unsigned
char
*)name;
993
if
(key >= 0xF0) {
994
if
(
SDL_strlen
(name) == 4) {
995
int
i
= 0;
996
key = (
Uint16
)(name[i]&0x07) << 18;
997
key |= (
Uint16
)(name[++i]&0x3F) << 12;
998
key |= (
Uint16
)(name[++i]&0x3F) << 6;
999
key |= (
Uint16
)(name[++i]&0x3F);
1000
return
key
;
1001
}
1002
return
SDLK_UNKNOWN
;
1003
}
else
if
(key >= 0xE0) {
1004
if
(
SDL_strlen
(name) == 3) {
1005
int
i
= 0;
1006
key = (
Uint16
)(name[i]&0x0F) << 12;
1007
key |= (
Uint16
)(name[++i]&0x3F) << 6;
1008
key |= (
Uint16
)(name[++i]&0x3F);
1009
return
key
;
1010
}
1011
return
SDLK_UNKNOWN
;
1012
}
else
if
(key >= 0xC0) {
1013
if
(
SDL_strlen
(name) == 2) {
1014
int
i
= 0;
1015
key = (
Uint16
)(name[i]&0x1F) << 6;
1016
key |= (
Uint16
)(name[++i]&0x3F);
1017
return
key
;
1018
}
1019
return
SDLK_UNKNOWN
;
1020
}
else
{
1021
if
(
SDL_strlen
(name) == 1) {
1022
if
(key >=
'A'
&& key <=
'Z'
) {
1023
key += 32;
1024
}
1025
return
key
;
1026
}
1027
1028
/* Get the scancode for this name, and the associated keycode */
1029
return
SDL_default_keymap
[
SDL_GetScancodeFromName
(name)];
1030
}
1031
}
1032
1033
/* vi: set ts=4 sw=4 expandtab: */
src
events
SDL_keyboard.c
Generated on Sun Jun 26 2022 23:07:11 for SDL by
1.8.1.2