Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
492 lines (432 loc) · 12.4 KB

SDL_keyboard.c

File metadata and controls

492 lines (432 loc) · 12.4 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Feb 1, 2006
Feb 1, 2006
3
Copyright (C) 1997-2006 Sam Lantinga
Apr 26, 2001
Apr 26, 2001
4
5
This library is free software; you can redistribute it and/or
Feb 1, 2006
Feb 1, 2006
6
modify it under the terms of the GNU Lesser General Public
Apr 26, 2001
Apr 26, 2001
7
License as published by the Free Software Foundation; either
Feb 1, 2006
Feb 1, 2006
8
version 2.1 of the License, or (at your option) any later version.
Apr 26, 2001
Apr 26, 2001
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Feb 1, 2006
Feb 1, 2006
13
Lesser General Public License for more details.
Apr 26, 2001
Apr 26, 2001
14
Feb 1, 2006
Feb 1, 2006
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Apr 26, 2001
Apr 26, 2001
18
19
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Apr 26, 2001
Apr 26, 2001
21
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
Apr 26, 2001
Apr 26, 2001
23
24
25
26
/* General keyboard handling code for SDL */
#include "SDL_timer.h"
Feb 10, 2006
Feb 10, 2006
27
#include "SDL_events.h"
Apr 26, 2001
Apr 26, 2001
28
29
#include "SDL_events_c.h"
#include "SDL_sysevents.h"
Aug 19, 2007
Aug 19, 2007
30
#include "SDL_keynames.h"
Apr 26, 2001
Apr 26, 2001
31
32
Jul 10, 2006
Jul 10, 2006
33
/* Global keyboard information */
Apr 26, 2001
Apr 26, 2001
34
int SDL_TranslateUNICODE = 0;
Jul 10, 2006
Jul 10, 2006
35
36
37
static int SDL_num_keyboards;
static int SDL_current_keyboard;
static SDL_Keyboard **SDL_keyboards;
Apr 26, 2001
Apr 26, 2001
38
Jul 10, 2006
Jul 10, 2006
39
40
41
42
43
44
45
46
47
/* Public functions */
int
SDL_KeyboardInit(void)
{
/* Set default mode of UNICODE translation */
SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION);
return (0);
}
Apr 26, 2001
Apr 26, 2001
48
Jul 10, 2006
Jul 10, 2006
49
50
51
52
53
54
55
56
SDL_Keyboard *
SDL_GetKeyboard(int index)
{
if (index < 0 || index >= SDL_num_keyboards) {
return NULL;
}
return SDL_keyboards[index];
}
Apr 26, 2001
Apr 26, 2001
57
Jul 10, 2006
Jul 10, 2006
58
59
int
SDL_AddKeyboard(const SDL_Keyboard * keyboard, int index)
Apr 26, 2001
Apr 26, 2001
60
{
Jul 10, 2006
Jul 10, 2006
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
SDL_Keyboard **keyboards;
/* Add the keyboard to the list of keyboards */
if (index < 0 || index >= SDL_num_keyboards || SDL_keyboards[index]) {
keyboards =
(SDL_Keyboard **) SDL_realloc(SDL_keyboards,
(SDL_num_keyboards +
1) * sizeof(*keyboards));
if (!keyboards) {
SDL_OutOfMemory();
return -1;
}
SDL_keyboards = keyboards;
index = SDL_num_keyboards++;
}
SDL_keyboards[index] =
(SDL_Keyboard *) SDL_malloc(sizeof(*SDL_keyboards[index]));
if (!SDL_keyboards[index]) {
SDL_OutOfMemory();
return -1;
}
*SDL_keyboards[index] = *keyboard;
return index;
Apr 26, 2001
Apr 26, 2001
86
}
Jul 10, 2006
Jul 10, 2006
87
88
89
void
SDL_DelKeyboard(int index)
Aug 21, 2005
Aug 21, 2005
90
{
Jul 10, 2006
Jul 10, 2006
91
92
93
94
95
96
97
98
99
100
101
102
SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
if (!keyboard) {
return;
}
if (keyboard->FreeKeyboard) {
keyboard->FreeKeyboard(keyboard);
}
SDL_free(keyboard);
SDL_keyboards[index] = NULL;
Aug 21, 2005
Aug 21, 2005
103
}
Apr 26, 2001
Apr 26, 2001
104
Jul 10, 2006
Jul 10, 2006
105
106
void
SDL_ResetKeyboard(int index)
Apr 26, 2001
Apr 26, 2001
107
{
Jul 10, 2006
Jul 10, 2006
108
SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
Aug 19, 2007
Aug 19, 2007
109
int key;
Jul 10, 2006
Jul 10, 2006
110
111
112
113
114
115
116
if (!keyboard) {
return;
}
for (key = SDLK_FIRST; key < SDLK_LAST; ++key) {
if (keyboard->keystate[key] == SDL_PRESSED) {
Aug 19, 2007
Aug 19, 2007
117
118
SDL_SendKeyboardKey(index, SDL_RELEASED, 0,
key | SDL_KEY_CAN_BE_PHYSICAL_BIT);
Jul 10, 2006
Jul 10, 2006
119
120
}
}
Apr 26, 2001
Apr 26, 2001
121
122
}
Jul 10, 2006
Jul 10, 2006
123
124
void
SDL_KeyboardQuit(void)
Apr 26, 2001
Apr 26, 2001
125
{
Jul 10, 2006
Jul 10, 2006
126
127
128
129
130
131
132
133
134
135
136
137
138
int i;
for (i = 0; i < SDL_num_keyboards; ++i) {
SDL_DelKeyboard(i);
}
SDL_num_keyboards = 0;
SDL_current_keyboard = 0;
if (SDL_keyboards) {
SDL_free(SDL_keyboards);
SDL_keyboards = NULL;
}
}
Apr 26, 2001
Apr 26, 2001
139
Jul 10, 2006
Jul 10, 2006
140
141
142
143
int
SDL_GetNumKeyboards(void)
{
return SDL_num_keyboards;
Apr 26, 2001
Apr 26, 2001
144
145
}
Jul 10, 2006
Jul 10, 2006
146
147
int
SDL_SelectKeyboard(int index)
Apr 26, 2001
Apr 26, 2001
148
{
Jul 10, 2006
Jul 10, 2006
149
150
151
152
if (index >= 0 && index < SDL_num_keyboards) {
SDL_current_keyboard = index;
}
return SDL_current_keyboard;
Apr 26, 2001
Apr 26, 2001
153
}
Jul 10, 2006
Jul 10, 2006
154
155
156
int
SDL_EnableUNICODE(int enable)
Apr 26, 2001
Apr 26, 2001
157
{
Jul 10, 2006
Jul 10, 2006
158
159
160
161
162
163
164
int old_mode;
old_mode = SDL_TranslateUNICODE;
if (enable >= 0) {
SDL_TranslateUNICODE = enable;
}
return (old_mode);
Apr 26, 2001
Apr 26, 2001
165
}
Jul 10, 2006
Jul 10, 2006
166
167
168
Uint8 *
SDL_GetKeyState(int *numkeys)
Apr 26, 2001
Apr 26, 2001
169
{
Jul 10, 2006
Jul 10, 2006
170
171
172
173
174
175
176
177
178
179
SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
if (numkeys != (int *) 0) {
*numkeys = SDLK_LAST;
}
if (!keyboard) {
return NULL;
}
return keyboard->keystate;
Apr 26, 2001
Apr 26, 2001
180
181
}
Jul 10, 2006
Jul 10, 2006
182
183
SDLMod
SDL_GetModState(void)
Apr 26, 2001
Apr 26, 2001
184
{
Jul 10, 2006
Jul 10, 2006
185
186
187
188
189
190
SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
if (!keyboard) {
return KMOD_NONE;
}
return keyboard->modstate;
Apr 26, 2001
Apr 26, 2001
191
192
}
Jul 10, 2006
Jul 10, 2006
193
194
void
SDL_SetModState(SDLMod modstate)
Apr 26, 2001
Apr 26, 2001
195
{
Jul 10, 2006
Jul 10, 2006
196
SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
Apr 26, 2001
Apr 26, 2001
197
Jul 10, 2006
Jul 10, 2006
198
199
200
201
202
203
if (!keyboard) {
return;
}
keyboard->modstate = modstate;
}
Aug 19, 2007
Aug 19, 2007
204
205
206
207
208
209
210
211
212
213
214
215
SDLKey
SDL_GetLayoutKey(SDLKey physicalKey)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (_this && _this->GetLayoutKey) {
return _this->GetLayoutKey(_this, physicalKey)
| (physicalKey & SDL_KEY_KEYPAD_BIT);
} else {
return physicalKey;
}
}
Jul 10, 2006
Jul 10, 2006
216
const char *
Aug 19, 2007
Aug 19, 2007
217
SDL_GetKeyName(SDLKey layoutKey)
Jul 10, 2006
Jul 10, 2006
218
{
Aug 19, 2007
Aug 19, 2007
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
const char *keyname = NULL;
if ((layoutKey & SDL_KEY_LAYOUT_SPECIAL_BIT) != 0) {
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (_this && _this->GetSpecialKeyName) {
keyname = _this->GetSpecialKeyName(_this, layoutKey);
}
} else if ((layoutKey & SDL_KEY_CAN_BE_PHYSICAL_BIT) == 0) {
/* SDLK_INDEX(layoutKey) is the unicode code point of the character generated by the key */
static char buffer[9]; /* 6 (maximal UTF-8 char length) + 2 ([] for keypad) + 1 (null teminator) */
char *bufferPtr = &buffer[1];
SDL_iconv_t cd;
size_t inbytesleft = 4, outbytesleft = 8;
Uint32 codepoint = SDLK_INDEX(layoutKey);
const char *codepointPtr = (const char *) &codepoint;
/* Unaccented letter keys on latin keyboards are normally labeled in upper case (and probably on others like Greek or Cyrillic too, so if you happen to know for sure, please adapt this). */
if (codepoint >= 'a' && codepoint <= 'z') {
codepoint -= 32;
}
Jul 10, 2006
Jul 10, 2006
239
Aug 19, 2007
Aug 19, 2007
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
cd = SDL_iconv_open("UTF-8", "UCS-4");
if (cd == (SDL_iconv_t) (-1))
return "";
SDL_iconv(cd, &codepointPtr, &inbytesleft, &bufferPtr, &outbytesleft);
SDL_iconv_close(cd);
*bufferPtr = '\0';
if ((layoutKey & SDL_KEY_KEYPAD_BIT) != 0) {
buffer[0] = '[';
*bufferPtr++ = ']';
*bufferPtr = '\0';
keyname = buffer;
} else {
keyname = &buffer[1];
}
Jul 10, 2006
Jul 10, 2006
255
} else {
Aug 19, 2007
Aug 19, 2007
256
257
258
259
/* SDLK_INDEX(layoutKey) is a physical key number */
if (SDLK_INDEX(layoutKey) < SDL_arraysize(SDL_keynames)) {
keyname = SDL_keynames[SDLK_INDEX(layoutKey)];
}
Jul 10, 2006
Jul 10, 2006
260
}
Aug 19, 2007
Aug 19, 2007
261
Jul 10, 2006
Jul 10, 2006
262
if (keyname == NULL) {
Aug 19, 2007
Aug 19, 2007
263
keyname = SDL_keynames[SDLK_INDEX(SDLK_UNKNOWN)];
Jul 10, 2006
Jul 10, 2006
264
}
Aug 19, 2007
Aug 19, 2007
265
Jul 10, 2006
Jul 10, 2006
266
267
268
return keyname;
}
Aug 19, 2007
Aug 19, 2007
269
270
271
272
273
274
275
276
277
void
SDL_SetKeyName(SDLKey physicalKey, const char *name)
{
physicalKey = SDLK_INDEX(physicalKey);
if (physicalKey < SDL_arraysize(SDL_keynames)) {
SDL_keynames[physicalKey] = name;
}
}
Jul 10, 2006
Jul 10, 2006
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
void
SDL_SetKeyboardFocus(int index, SDL_WindowID windowID)
{
SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
int i;
SDL_bool focus;
if (!keyboard || (keyboard->focus == windowID)) {
return;
}
/* See if the current window has lost focus */
if (keyboard->focus) {
focus = SDL_FALSE;
for (i = 0; i < SDL_num_keyboards; ++i) {
SDL_Keyboard *check;
if (i != index) {
check = SDL_GetKeyboard(i);
if (check && check->focus == keyboard->focus) {
focus = SDL_TRUE;
break;
}
}
}
if (!focus) {
SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST,
0, 0);
}
}
keyboard->focus = windowID;
if (keyboard->focus) {
focus = SDL_FALSE;
for (i = 0; i < SDL_num_keyboards; ++i) {
SDL_Keyboard *check;
if (i != index) {
check = SDL_GetKeyboard(i);
if (check && check->focus == keyboard->focus) {
focus = SDL_TRUE;
break;
}
}
}
if (!focus) {
SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED,
0, 0);
}
}
}
Apr 26, 2001
Apr 26, 2001
328
Jul 10, 2006
Jul 10, 2006
329
int
Aug 19, 2007
Aug 19, 2007
330
331
SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode,
SDLKey physicalKey)
Jul 10, 2006
Jul 10, 2006
332
333
{
SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
Jun 16, 2007
Jun 16, 2007
334
int posted;
Jul 10, 2006
Jul 10, 2006
335
336
337
Uint16 modstate;
Uint8 type;
Aug 19, 2007
Aug 19, 2007
338
if (!keyboard || physicalKey == SDLK_NONE) {
Jul 10, 2006
Jul 10, 2006
339
340
return 0;
}
Apr 26, 2001
Apr 26, 2001
341
#if 0
Aug 19, 2007
Aug 19, 2007
342
printf("The '%s' key has been %s\n", SDL_GetKeyName(physicalKey),
Jul 10, 2006
Jul 10, 2006
343
state == SDL_PRESSED ? "pressed" : "released");
Apr 26, 2001
Apr 26, 2001
344
#endif
Jul 10, 2006
Jul 10, 2006
345
346
if (state == SDL_PRESSED) {
modstate = keyboard->modstate;
Aug 19, 2007
Aug 19, 2007
347
switch (physicalKey) {
Jul 10, 2006
Jul 10, 2006
348
349
case SDLK_UNKNOWN:
break;
Aug 19, 2007
Aug 19, 2007
350
case SDLK_KP_NUMLOCKCLEAR:
Jul 10, 2006
Jul 10, 2006
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
keyboard->modstate ^= KMOD_NUM;
break;
case SDLK_CAPSLOCK:
keyboard->modstate ^= KMOD_CAPS;
break;
case SDLK_LCTRL:
keyboard->modstate |= KMOD_LCTRL;
break;
case SDLK_RCTRL:
keyboard->modstate |= KMOD_RCTRL;
break;
case SDLK_LSHIFT:
keyboard->modstate |= KMOD_LSHIFT;
break;
case SDLK_RSHIFT:
keyboard->modstate |= KMOD_RSHIFT;
break;
case SDLK_LALT:
keyboard->modstate |= KMOD_LALT;
break;
case SDLK_RALT:
keyboard->modstate |= KMOD_RALT;
break;
case SDLK_LMETA:
keyboard->modstate |= KMOD_LMETA;
break;
case SDLK_RMETA:
keyboard->modstate |= KMOD_RMETA;
break;
case SDLK_MODE:
keyboard->modstate |= KMOD_MODE;
break;
default:
break;
}
} else {
Aug 19, 2007
Aug 19, 2007
387
switch (physicalKey) {
Jul 10, 2006
Jul 10, 2006
388
389
case SDLK_UNKNOWN:
break;
Aug 19, 2007
Aug 19, 2007
390
case SDLK_KP_NUMLOCKCLEAR:
Jul 10, 2006
Jul 10, 2006
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
case SDLK_CAPSLOCK:
break;
case SDLK_LCTRL:
keyboard->modstate &= ~KMOD_LCTRL;
break;
case SDLK_RCTRL:
keyboard->modstate &= ~KMOD_RCTRL;
break;
case SDLK_LSHIFT:
keyboard->modstate &= ~KMOD_LSHIFT;
break;
case SDLK_RSHIFT:
keyboard->modstate &= ~KMOD_RSHIFT;
break;
case SDLK_LALT:
keyboard->modstate &= ~KMOD_LALT;
break;
case SDLK_RALT:
keyboard->modstate &= ~KMOD_RALT;
break;
case SDLK_LMETA:
keyboard->modstate &= ~KMOD_LMETA;
break;
case SDLK_RMETA:
keyboard->modstate &= ~KMOD_RMETA;
break;
case SDLK_MODE:
keyboard->modstate &= ~KMOD_MODE;
break;
default:
break;
}
modstate = keyboard->modstate;
}
/* Figure out what type of event this is */
switch (state) {
case SDL_PRESSED:
type = SDL_KEYDOWN;
break;
case SDL_RELEASED:
type = SDL_KEYUP;
break;
default:
/* Invalid state -- bail */
return 0;
}
Aug 19, 2007
Aug 19, 2007
439
if (physicalKey != SDLK_UNKNOWN) {
Jul 10, 2006
Jul 10, 2006
440
/* Drop events that don't change state */
Aug 19, 2007
Aug 19, 2007
441
if (keyboard->keystate[SDLK_INDEX(physicalKey)] == state) {
Jan 29, 2006
Jan 29, 2006
442
#if 0
Jul 10, 2006
Jul 10, 2006
443
printf("Keyboard event didn't change state - dropped!\n");
Jan 29, 2006
Jan 29, 2006
444
#endif
Jul 10, 2006
Jul 10, 2006
445
446
447
448
return 0;
}
/* Update internal keyboard state */
Aug 19, 2007
Aug 19, 2007
449
keyboard->keystate[SDLK_INDEX(physicalKey)] = state;
Jul 10, 2006
Jul 10, 2006
450
451
452
453
454
455
456
457
458
459
}
/* Post the event, if desired */
posted = 0;
if (SDL_ProcessEvents[type] == SDL_ENABLE) {
SDL_Event event;
event.key.type = type;
event.key.which = (Uint8) index;
event.key.state = state;
event.key.keysym.scancode = scancode;
Aug 19, 2007
Aug 19, 2007
460
event.key.keysym.sym = physicalKey;
Jul 10, 2006
Jul 10, 2006
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
event.key.keysym.mod = modstate;
event.key.keysym.unicode = 0;
event.key.windowID = keyboard->focus;
posted = (SDL_PushEvent(&event) > 0);
}
return (posted);
}
int
SDL_SendKeyboardText(int index, const char *text)
{
SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
int posted;
if (!keyboard) {
return 0;
}
/* Post the event, if desired */
posted = 0;
if (SDL_ProcessEvents[SDL_TEXTINPUT] == SDL_ENABLE) {
SDL_Event event;
event.text.type = SDL_TEXTINPUT;
event.text.which = (Uint8) index;
SDL_strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
Jul 30, 2006
Jul 30, 2006
486
event.text.windowID = keyboard->focus;
Jul 10, 2006
Jul 10, 2006
487
488
489
posted = (SDL_PushEvent(&event) > 0);
}
return (posted);
Apr 26, 2001
Apr 26, 2001
490
491
}
Jul 10, 2006
Jul 10, 2006
492
/* vi: set ts=4 sw=4 expandtab: */