comparison src/events/SDL_keyboard.c @ 2303:d87417504c75

First pass implementation of new SDL scancode concept, as discussed with Christian Walther. Currently only implemented on Mac OS X for sanity checking purposes.
author Sam Lantinga <slouken@libsdl.org>
date Tue, 05 Feb 2008 07:19:23 +0000
parents c97ad1abe05b
children fbe8ff44c519
comparison
equal deleted inserted replaced
2302:7ae1c419b626 2303:d87417504c75
25 25
26 #include "SDL_timer.h" 26 #include "SDL_timer.h"
27 #include "SDL_events.h" 27 #include "SDL_events.h"
28 #include "SDL_events_c.h" 28 #include "SDL_events_c.h"
29 #include "SDL_sysevents.h" 29 #include "SDL_sysevents.h"
30 #include "SDL_keynames.h"
31 30
32 31
33 /* Global keyboard information */ 32 /* Global keyboard information */
34 int SDL_TranslateUNICODE = 0;
35 static int SDL_num_keyboards; 33 static int SDL_num_keyboards;
36 static int SDL_current_keyboard; 34 static int SDL_current_keyboard;
37 static SDL_Keyboard **SDL_keyboards; 35 static SDL_Keyboard **SDL_keyboards;
38 36
37 static SDLKey SDL_default_keymap[SDL_NUM_SCANCODES] = {
38 0, 0, 0, 0,
39 'a',
40 'b',
41 'c',
42 'd',
43 'e',
44 'f',
45 'g',
46 'h',
47 'i',
48 'j',
49 'k',
50 'l',
51 'm',
52 'n',
53 'o',
54 'p',
55 'q',
56 'r',
57 's',
58 't',
59 'u',
60 'v',
61 'w',
62 'x',
63 'y',
64 'z',
65 '1',
66 '2',
67 '3',
68 '4',
69 '5',
70 '6',
71 '7',
72 '8',
73 '9',
74 '0',
75 SDLK_RETURN,
76 SDLK_ESCAPE,
77 SDLK_BACKSPACE,
78 SDLK_TAB,
79 SDLK_SPACE,
80 '-',
81 '=',
82 '[',
83 ']',
84 '\\',
85 '#',
86 ';',
87 '\'',
88 '`',
89 ',',
90 '.',
91 '/',
92 SDLK_CAPSLOCK,
93 SDLK_F1,
94 SDLK_F2,
95 SDLK_F3,
96 SDLK_F4,
97 SDLK_F5,
98 SDLK_F6,
99 SDLK_F7,
100 SDLK_F8,
101 SDLK_F9,
102 SDLK_F10,
103 SDLK_F11,
104 SDLK_F12,
105 SDLK_PRINTSCREEN,
106 SDLK_SCROLLLOCK,
107 SDLK_PAUSE,
108 SDLK_INSERT,
109 SDLK_HOME,
110 SDLK_PAGEUP,
111 SDLK_DELETE,
112 SDLK_END,
113 SDLK_PAGEDOWN,
114 SDLK_RIGHT,
115 SDLK_LEFT,
116 SDLK_DOWN,
117 SDLK_UP,
118 SDLK_NUMLOCKCLEAR,
119 SDLK_KP_DIVIDE,
120 SDLK_KP_MULTIPLY,
121 SDLK_KP_MINUS,
122 SDLK_KP_PLUS,
123 SDLK_KP_ENTER,
124 SDLK_KP_1,
125 SDLK_KP_2,
126 SDLK_KP_3,
127 SDLK_KP_4,
128 SDLK_KP_5,
129 SDLK_KP_6,
130 SDLK_KP_7,
131 SDLK_KP_8,
132 SDLK_KP_9,
133 SDLK_KP_0,
134 SDLK_KP_PERIOD,
135 0,
136 SDLK_APPLICATION,
137 SDLK_POWER,
138 SDLK_KP_EQUALS,
139 SDLK_F13,
140 SDLK_F14,
141 SDLK_F15,
142 SDLK_F16,
143 SDLK_F17,
144 SDLK_F18,
145 SDLK_F19,
146 SDLK_F20,
147 SDLK_F21,
148 SDLK_F22,
149 SDLK_F23,
150 SDLK_F24,
151 SDLK_EXECUTE,
152 SDLK_HELP,
153 SDLK_MENU,
154 SDLK_SELECT,
155 SDLK_STOP,
156 SDLK_AGAIN,
157 SDLK_UNDO,
158 SDLK_CUT,
159 SDLK_COPY,
160 SDLK_PASTE,
161 SDLK_FIND,
162 SDLK_MUTE,
163 SDLK_VOLUMEUP,
164 SDLK_VOLUMEDOWN,
165 0, 0, 0,
166 SDLK_KP_COMMA,
167 SDLK_KP_EQUALSAS400,
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 SDLK_ALTERASE,
170 SDLK_SYSREQ,
171 SDLK_CANCEL,
172 SDLK_CLEAR,
173 SDLK_PRIOR,
174 SDLK_RETURN2,
175 SDLK_SEPARATOR,
176 SDLK_OUT,
177 SDLK_OPER,
178 SDLK_CLEARAGAIN,
179 SDLK_CRSEL,
180 SDLK_EXSEL,
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182 SDLK_KP_00,
183 SDLK_KP_000,
184 SDLK_THOUSANDSSEPARATOR,
185 SDLK_DECIMALSEPARATOR,
186 SDLK_CURRENCYUNIT,
187 SDLK_CURRENCYSUBUNIT,
188 SDLK_KP_LEFTPAREN,
189 SDLK_KP_RIGHTPAREN,
190 SDLK_KP_LEFTBRACE,
191 SDLK_KP_RIGHTBRACE,
192 SDLK_KP_TAB,
193 SDLK_KP_BACKSPACE,
194 SDLK_KP_A,
195 SDLK_KP_B,
196 SDLK_KP_C,
197 SDLK_KP_D,
198 SDLK_KP_E,
199 SDLK_KP_F,
200 SDLK_KP_XOR,
201 SDLK_KP_POWER,
202 SDLK_KP_PERCENT,
203 SDLK_KP_LESS,
204 SDLK_KP_GREATER,
205 SDLK_KP_AMPERSAND,
206 SDLK_KP_DBLAMPERSAND,
207 SDLK_KP_VERTICALBAR,
208 SDLK_KP_DBLVERTICALBAR,
209 SDLK_KP_COLON,
210 SDLK_KP_HASH,
211 SDLK_KP_SPACE,
212 SDLK_KP_AT,
213 SDLK_KP_EXCLAM,
214 SDLK_KP_MEMSTORE,
215 SDLK_KP_MEMRECALL,
216 SDLK_KP_MEMCLEAR,
217 SDLK_KP_MEMADD,
218 SDLK_KP_MEMSUBTRACT,
219 SDLK_KP_MEMMULTIPLY,
220 SDLK_KP_MEMDIVIDE,
221 SDLK_KP_PLUSMINUS,
222 SDLK_KP_CLEAR,
223 SDLK_KP_CLEARENTRY,
224 SDLK_KP_BINARY,
225 SDLK_KP_OCTAL,
226 SDLK_KP_DECIMAL,
227 SDLK_KP_HEXADECIMAL,
228 0, 0,
229 SDLK_LCTRL,
230 SDLK_LSHIFT,
231 SDLK_LALT,
232 SDLK_LGUI,
233 SDLK_RCTRL,
234 SDLK_RSHIFT,
235 SDLK_RALT,
236 SDLK_RGUI,
237 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,
238 SDLK_MODE,
239 SDLK_AUDIONEXT,
240 SDLK_AUDIOPREV,
241 SDLK_AUDIOSTOP,
242 SDLK_AUDIOPLAY,
243 SDLK_AUDIOMUTE,
244 SDLK_MEDIASELECT,
245 SDLK_MAIL,
246 SDLK_CALCULATOR,
247 SDLK_COMPUTER,
248 SDLK_AC_SEARCH,
249 SDLK_AC_HOME,
250 SDLK_AC_BACK,
251 SDLK_AC_FORWARD,
252 SDLK_AC_STOP,
253 SDLK_AC_REFRESH,
254 SDLK_AC_BOOKMARKS,
255 SDLK_BRIGHTNESSDOWN,
256 SDLK_BRIGHTNESSUP,
257 SDLK_DISPLAYSWITCH,
258 SDLK_KBDILLUMTOGGLE,
259 SDLK_KBDILLUMDOWN,
260 SDLK_KBDILLUMUP,
261 SDLK_EJECT,
262 SDLK_SLEEP,
263 };
264
265 static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = {
266 NULL, NULL, NULL, NULL,
267 "A",
268 "B",
269 "C",
270 "D",
271 "E",
272 "F",
273 "G",
274 "H",
275 "I",
276 "J",
277 "K",
278 "L",
279 "M",
280 "N",
281 "O",
282 "P",
283 "Q",
284 "R",
285 "S",
286 "T",
287 "U",
288 "V",
289 "W",
290 "X",
291 "Y",
292 "Z",
293 "1",
294 "2",
295 "3",
296 "4",
297 "5",
298 "6",
299 "7",
300 "8",
301 "9",
302 "0",
303 "Return",
304 "Escape",
305 "Backspace",
306 "Tab",
307 "Space",
308 "-",
309 "=",
310 "[",
311 "]",
312 "\\",
313 "#",
314 ";",
315 "'",
316 "`",
317 ",",
318 ".",
319 "/",
320 "CapsLock",
321 "F1",
322 "F2",
323 "F3",
324 "F4",
325 "F5",
326 "F6",
327 "F7",
328 "F8",
329 "F9",
330 "F10",
331 "F11",
332 "F12",
333 "PrintScreen",
334 "ScrollLock",
335 "Pause",
336 "Insert",
337 "Home",
338 "PageUp",
339 "Delete",
340 "End",
341 "PageDown",
342 "Right",
343 "Left",
344 "Down",
345 "Up",
346 "Numlock",
347 "Keypad /",
348 "Keypad *",
349 "Keypad -",
350 "Keypad +",
351 "Keypad Enter",
352 "Keypad 1",
353 "Keypad 2",
354 "Keypad 3",
355 "Keypad 4",
356 "Keypad 5",
357 "Keypad 6",
358 "Keypad 7",
359 "Keypad 8",
360 "Keypad 9",
361 "Keypad 0",
362 "Keypad .",
363 NULL,
364 "Application",
365 "Power",
366 "Keypad =",
367 "F13",
368 "F14",
369 "F15",
370 "F16",
371 "F17",
372 "F18",
373 "F19",
374 "F20",
375 "F21",
376 "F22",
377 "F23",
378 "F24",
379 "Execute",
380 "Help",
381 "Menu",
382 "Select",
383 "Stop",
384 "Again",
385 "Undo",
386 "Cut",
387 "Copy",
388 "Paste",
389 "Find",
390 "Mute",
391 "VolumeUp",
392 "VolumeDown",
393 NULL, NULL, NULL,
394 "Keypad ,",
395 "Keypad = (AS400)",
396 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
397 NULL, NULL, NULL, NULL, NULL, NULL,
398 "AltErase",
399 "SysReq",
400 "Cancel",
401 "Clear",
402 "Prior",
403 "Return",
404 "Separator",
405 "Out",
406 "Oper",
407 "Clear / Again",
408 "CrSel",
409 "ExSel",
410 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
411 "Keypad 00",
412 "Keypad 000",
413 "ThousandsSeparator",
414 "DecimalSeparator",
415 "CurrencyUnit",
416 "CurrencySubUnit",
417 "Keypad (",
418 "Keypad )",
419 "Keypad {",
420 "Keypad }",
421 "Keypad Tab",
422 "Keypad Backspace",
423 "Keypad A",
424 "Keypad B",
425 "Keypad C",
426 "Keypad D",
427 "Keypad E",
428 "Keypad F",
429 "Keypad XOR",
430 "Keypad ^",
431 "Keypad %",
432 "Keypad <",
433 "Keypad >",
434 "Keypad &",
435 "Keypad &&",
436 "Keypad |",
437 "Keypad ||",
438 "Keypad :",
439 "Keypad #",
440 "Keypad Space",
441 "Keypad @",
442 "Keypad !",
443 "Keypad MemStore",
444 "Keypad MemRecall",
445 "Keypad MemClear",
446 "Keypad MemAdd",
447 "Keypad MemSubtract",
448 "Keypad MemMultiply",
449 "Keypad MemDivide",
450 "Keypad +/-",
451 "Keypad Clear",
452 "Keypad ClearEntry",
453 "Keypad Binary",
454 "Keypad Octal",
455 "Keypad Decimal",
456 "Keypad Hexadecimal",
457 NULL, NULL,
458 "Left Ctrl",
459 "Left Shift",
460 "Left Alt",
461 "Left GUI",
462 "Right Ctrl",
463 "Right Shift",
464 "Right Alt",
465 "Right GUI",
466 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
467 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
468 NULL,
469 "ModeSwitch",
470 "AudioNext",
471 "AudioPrev",
472 "AudioStop",
473 "AudioPlay",
474 "AudioMute",
475 "MediaSelect",
476 "Mail",
477 "Calculator",
478 "Computer",
479 "AC Search",
480 "AC Home",
481 "AC Back",
482 "AC Forward",
483 "AC Stop",
484 "AC Refresh",
485 "AC Bookmarks",
486 "BrightnessDown",
487 "BrightnessUp",
488 "DisplaySwitch",
489 "KBDIllumToggle",
490 "KBDIllumDown",
491 "KBDIllumUp",
492 "Eject",
493 "Sleep",
494 };
495
39 /* Taken from SDL_iconv() */ 496 /* Taken from SDL_iconv() */
40 char * 497 static char *
41 SDL_Ucs4ToUtf8(Uint32 ch, char *dst) 498 SDL_UCS4ToUTF8(Uint32 ch, char *dst)
42 { 499 {
43 Uint8 *p = (Uint8 *) dst; 500 Uint8 *p = (Uint8 *) dst;
44 if (ch <= 0x7F) { 501 if (ch <= 0x7F) {
45 *p = (Uint8) ch; 502 *p = (Uint8) ch;
46 ++dst; 503 ++dst;
80 537
81 /* Public functions */ 538 /* Public functions */
82 int 539 int
83 SDL_KeyboardInit(void) 540 SDL_KeyboardInit(void)
84 { 541 {
85 /* Set default mode of UNICODE translation */
86 SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION);
87
88 return (0); 542 return (0);
89 } 543 }
90 544
91 SDL_Keyboard * 545 SDL_Keyboard *
92 SDL_GetKeyboard(int index) 546 SDL_GetKeyboard(int index)
146 600
147 void 601 void
148 SDL_ResetKeyboard(int index) 602 SDL_ResetKeyboard(int index)
149 { 603 {
150 SDL_Keyboard *keyboard = SDL_GetKeyboard(index); 604 SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
151 int key; 605 SDL_scancode scancode;
152 606
153 if (!keyboard) { 607 if (!keyboard) {
154 return; 608 return;
155 } 609 }
156 610
157 for (key = SDLK_FIRST; key < SDLK_LAST; ++key) { 611 for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
158 if (keyboard->keystate[key] == SDL_PRESSED) { 612 if (keyboard->keystate[scancode] == SDL_PRESSED) {
159 SDL_SendKeyboardKey(index, SDL_RELEASED, 0, 613 SDL_SendKeyboardKey(index, SDL_RELEASED, scancode);
160 key | SDL_KEY_CAN_BE_PHYSICAL_BIT);
161 } 614 }
162 } 615 }
163 } 616 }
164 617
165 void 618 void
166 SDL_KeyboardQuit(void) 619 SDL_GetDefaultKeymap(SDLKey * keymap)
167 { 620 {
168 int i; 621 SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap));
169
170 for (i = 0; i < SDL_num_keyboards; ++i) {
171 SDL_DelKeyboard(i);
172 }
173 SDL_num_keyboards = 0;
174 SDL_current_keyboard = 0;
175
176 if (SDL_keyboards) {
177 SDL_free(SDL_keyboards);
178 SDL_keyboards = NULL;
179 }
180 }
181
182 int
183 SDL_GetNumKeyboards(void)
184 {
185 return SDL_num_keyboards;
186 }
187
188 int
189 SDL_SelectKeyboard(int index)
190 {
191 if (index >= 0 && index < SDL_num_keyboards) {
192 SDL_current_keyboard = index;
193 }
194 return SDL_current_keyboard;
195 }
196
197 int
198 SDL_EnableUNICODE(int enable)
199 {
200 int old_mode;
201
202 old_mode = SDL_TranslateUNICODE;
203 if (enable >= 0) {
204 SDL_TranslateUNICODE = enable;
205 }
206 return (old_mode);
207 }
208
209 Uint8 *
210 SDL_GetKeyState(int *numkeys)
211 {
212 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
213
214 if (numkeys != (int *) 0) {
215 *numkeys = SDLK_LAST;
216 }
217
218 if (!keyboard) {
219 return NULL;
220 }
221 return keyboard->keystate;
222 }
223
224 SDLMod
225 SDL_GetModState(void)
226 {
227 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
228
229 if (!keyboard) {
230 return KMOD_NONE;
231 }
232 return keyboard->modstate;
233 } 622 }
234 623
235 void 624 void
236 SDL_SetModState(SDLMod modstate) 625 SDL_SetKeymap(int index, int start, SDLKey * keys, int length)
237 { 626 {
238 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard); 627 SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
239 628
240 if (!keyboard) { 629 if (!keyboard) {
241 return; 630 return;
242 } 631 }
243 keyboard->modstate = modstate; 632
244 } 633 if (start < 0 || start + length > SDL_NUM_SCANCODES) {
245 634 return;
246 SDLKey 635 }
247 SDL_GetLayoutKey(SDLKey physicalKey) 636
248 { 637 SDL_memcpy(&keyboard->keymap[start], keys, sizeof(*keys) * length);
249 SDL_VideoDevice *_this = SDL_GetVideoDevice();
250 if (_this && _this->GetLayoutKey) {
251 return _this->GetLayoutKey(_this, physicalKey)
252 | (physicalKey & SDL_KEY_KEYPAD_BIT);
253 } else {
254 return physicalKey;
255 }
256 }
257
258 const char *
259 SDL_GetKeyName(SDLKey layoutKey)
260 {
261 const char *keyname = NULL;
262
263 if ((layoutKey & SDL_KEY_LAYOUT_SPECIAL_BIT) != 0) {
264 SDL_VideoDevice *_this = SDL_GetVideoDevice();
265 if (_this && _this->GetSpecialKeyName) {
266 keyname = _this->GetSpecialKeyName(_this, layoutKey);
267 }
268 } else if ((layoutKey & SDL_KEY_CAN_BE_PHYSICAL_BIT) == 0) {
269 /* SDLK_INDEX(layoutKey) is the unicode code point of the
270 character generated by the key */
271 static char buffer[9]; /* 6 (maximal UTF-8 char length) + 2 ([] for keypad) + 1 (null teminator) */
272 char *bufferPtr = &buffer[1];
273 Uint32 codepoint = SDLK_INDEX(layoutKey);
274
275 /* Unaccented letter keys on latin keyboards are normally
276 labeled in upper case (and probably on others like Greek or
277 Cyrillic too, so if you happen to know for sure, please
278 adapt this). */
279 if (codepoint >= 'a' && codepoint <= 'z') {
280 codepoint -= 32;
281 }
282
283 bufferPtr = SDL_Ucs4ToUtf8(codepoint, bufferPtr);
284 *bufferPtr = '\0';
285
286 if ((layoutKey & SDL_KEY_KEYPAD_BIT) != 0) {
287 buffer[0] = '[';
288 *bufferPtr++ = ']';
289 *bufferPtr = '\0';
290 keyname = buffer;
291 } else {
292 keyname = &buffer[1];
293 }
294 } else {
295 /* SDLK_INDEX(layoutKey) is a physical key number */
296 if (SDLK_INDEX(layoutKey) < SDL_arraysize(SDL_keynames)) {
297 keyname = SDL_keynames[SDLK_INDEX(layoutKey)];
298 }
299 }
300
301 if (keyname == NULL) {
302 keyname = SDL_keynames[SDLK_INDEX(SDLK_UNKNOWN)];
303 }
304
305 return keyname;
306 } 638 }
307 639
308 void 640 void
309 SDL_SetKeyName(SDLKey physicalKey, const char *name) 641 SDL_SetScancodeName(SDL_scancode scancode, const char *name)
310 { 642 {
311 physicalKey = SDLK_INDEX(physicalKey); 643 SDL_scancode_names[scancode] = name;
312 if (physicalKey < SDL_arraysize(SDL_keynames)) {
313 SDL_keynames[physicalKey] = name;
314 }
315 } 644 }
316 645
317 void 646 void
318 SDL_SetKeyboardFocus(int index, SDL_WindowID windowID) 647 SDL_SetKeyboardFocus(int index, SDL_WindowID windowID)
319 { 648 {
364 } 693 }
365 } 694 }
366 } 695 }
367 696
368 int 697 int
369 SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode, 698 SDL_SendKeyboardKey(int index, Uint8 state, SDL_scancode scancode)
370 SDLKey physicalKey)
371 { 699 {
372 SDL_Keyboard *keyboard = SDL_GetKeyboard(index); 700 SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
373 int posted; 701 int posted;
374 Uint16 modstate; 702 Uint16 modstate;
375 Uint8 type; 703 Uint8 type;
376 704
377 if (!keyboard || physicalKey == SDLK_NONE) { 705 if (!keyboard || !scancode) {
378 return 0; 706 return 0;
379 } 707 }
380 #if 0 708 #if 0
381 printf("The '%s' key has been %s\n", SDL_GetKeyName(physicalKey), 709 printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode),
382 state == SDL_PRESSED ? "pressed" : "released"); 710 state == SDL_PRESSED ? "pressed" : "released");
383 #endif 711 #endif
384 if (state == SDL_PRESSED) { 712 if (state == SDL_PRESSED) {
385 modstate = keyboard->modstate; 713 modstate = keyboard->modstate;
386 switch (physicalKey) { 714 switch (scancode) {
387 case SDLK_UNKNOWN: 715 case SDL_SCANCODE_NUMLOCKCLEAR:
388 break;
389 case SDLK_KP_NUMLOCKCLEAR:
390 keyboard->modstate ^= KMOD_NUM; 716 keyboard->modstate ^= KMOD_NUM;
391 break; 717 break;
392 case SDLK_CAPSLOCK: 718 case SDL_SCANCODE_CAPSLOCK:
393 keyboard->modstate ^= KMOD_CAPS; 719 keyboard->modstate ^= KMOD_CAPS;
394 break; 720 break;
395 case SDLK_LCTRL: 721 case SDL_SCANCODE_LCTRL:
396 keyboard->modstate |= KMOD_LCTRL; 722 keyboard->modstate |= KMOD_LCTRL;
397 break; 723 break;
398 case SDLK_RCTRL: 724 case SDL_SCANCODE_RCTRL:
399 keyboard->modstate |= KMOD_RCTRL; 725 keyboard->modstate |= KMOD_RCTRL;
400 break; 726 break;
401 case SDLK_LSHIFT: 727 case SDL_SCANCODE_LSHIFT:
402 keyboard->modstate |= KMOD_LSHIFT; 728 keyboard->modstate |= KMOD_LSHIFT;
403 break; 729 break;
404 case SDLK_RSHIFT: 730 case SDL_SCANCODE_RSHIFT:
405 keyboard->modstate |= KMOD_RSHIFT; 731 keyboard->modstate |= KMOD_RSHIFT;
406 break; 732 break;
407 case SDLK_LALT: 733 case SDL_SCANCODE_LALT:
408 keyboard->modstate |= KMOD_LALT; 734 keyboard->modstate |= KMOD_LALT;
409 break; 735 break;
410 case SDLK_RALT: 736 case SDL_SCANCODE_RALT:
411 keyboard->modstate |= KMOD_RALT; 737 keyboard->modstate |= KMOD_RALT;
412 break; 738 break;
413 case SDLK_LMETA: 739 case SDL_SCANCODE_LGUI:
414 keyboard->modstate |= KMOD_LMETA; 740 keyboard->modstate |= KMOD_LGUI;
415 break; 741 break;
416 case SDLK_RMETA: 742 case SDL_SCANCODE_RGUI:
417 keyboard->modstate |= KMOD_RMETA; 743 keyboard->modstate |= KMOD_RGUI;
418 break; 744 break;
419 case SDLK_MODE: 745 case SDL_SCANCODE_MODE:
420 keyboard->modstate |= KMOD_MODE; 746 keyboard->modstate |= KMOD_MODE;
421 break; 747 break;
422 default: 748 default:
423 break; 749 break;
424 } 750 }
425 } else { 751 } else {
426 switch (physicalKey) { 752 switch (scancode) {
427 case SDLK_UNKNOWN: 753 case SDL_SCANCODE_NUMLOCKCLEAR:
428 break; 754 case SDL_SCANCODE_CAPSLOCK:
429 case SDLK_KP_NUMLOCKCLEAR: 755 break;
430 case SDLK_CAPSLOCK: 756 case SDL_SCANCODE_LCTRL:
431 break;
432 case SDLK_LCTRL:
433 keyboard->modstate &= ~KMOD_LCTRL; 757 keyboard->modstate &= ~KMOD_LCTRL;
434 break; 758 break;
435 case SDLK_RCTRL: 759 case SDL_SCANCODE_RCTRL:
436 keyboard->modstate &= ~KMOD_RCTRL; 760 keyboard->modstate &= ~KMOD_RCTRL;
437 break; 761 break;
438 case SDLK_LSHIFT: 762 case SDL_SCANCODE_LSHIFT:
439 keyboard->modstate &= ~KMOD_LSHIFT; 763 keyboard->modstate &= ~KMOD_LSHIFT;
440 break; 764 break;
441 case SDLK_RSHIFT: 765 case SDL_SCANCODE_RSHIFT:
442 keyboard->modstate &= ~KMOD_RSHIFT; 766 keyboard->modstate &= ~KMOD_RSHIFT;
443 break; 767 break;
444 case SDLK_LALT: 768 case SDL_SCANCODE_LALT:
445 keyboard->modstate &= ~KMOD_LALT; 769 keyboard->modstate &= ~KMOD_LALT;
446 break; 770 break;
447 case SDLK_RALT: 771 case SDL_SCANCODE_RALT:
448 keyboard->modstate &= ~KMOD_RALT; 772 keyboard->modstate &= ~KMOD_RALT;
449 break; 773 break;
450 case SDLK_LMETA: 774 case SDL_SCANCODE_LGUI:
451 keyboard->modstate &= ~KMOD_LMETA; 775 keyboard->modstate &= ~KMOD_LGUI;
452 break; 776 break;
453 case SDLK_RMETA: 777 case SDL_SCANCODE_RGUI:
454 keyboard->modstate &= ~KMOD_RMETA; 778 keyboard->modstate &= ~KMOD_RGUI;
455 break; 779 break;
456 case SDLK_MODE: 780 case SDL_SCANCODE_MODE:
457 keyboard->modstate &= ~KMOD_MODE; 781 keyboard->modstate &= ~KMOD_MODE;
458 break; 782 break;
459 default: 783 default:
460 break; 784 break;
461 } 785 }
473 default: 797 default:
474 /* Invalid state -- bail */ 798 /* Invalid state -- bail */
475 return 0; 799 return 0;
476 } 800 }
477 801
478 if (physicalKey != SDLK_UNKNOWN) { 802 /* Drop events that don't change state */
479 /* Drop events that don't change state */ 803 if (keyboard->keystate[scancode] == state) {
480 if (keyboard->keystate[SDLK_INDEX(physicalKey)] == state) {
481 #if 0 804 #if 0
482 printf("Keyboard event didn't change state - dropped!\n"); 805 printf("Keyboard event didn't change state - dropped!\n");
483 #endif 806 #endif
484 return 0; 807 return 0;
485 } 808 }
486 809
487 /* Update internal keyboard state */ 810 /* Update internal keyboard state */
488 keyboard->keystate[SDLK_INDEX(physicalKey)] = state; 811 keyboard->keystate[scancode] = state;
489 }
490 812
491 /* Post the event, if desired */ 813 /* Post the event, if desired */
492 posted = 0; 814 posted = 0;
493 if (SDL_ProcessEvents[type] == SDL_ENABLE) { 815 if (SDL_ProcessEvents[type] == SDL_ENABLE) {
494 SDL_Event event; 816 SDL_Event event;
495 event.key.type = type; 817 event.key.type = type;
496 event.key.which = (Uint8) index; 818 event.key.which = (Uint8) index;
497 event.key.state = state; 819 event.key.state = state;
498 event.key.keysym.scancode = scancode; 820 event.key.keysym.scancode = scancode;
499 event.key.keysym.sym = physicalKey; 821 event.key.keysym.sym = keyboard->keymap[scancode];
500 event.key.keysym.mod = modstate; 822 event.key.keysym.mod = modstate;
501 event.key.keysym.unicode = 0; 823 event.key.keysym.unicode = 0;
502 event.key.windowID = keyboard->focus; 824 event.key.windowID = keyboard->focus;
503 posted = (SDL_PushEvent(&event) > 0); 825 posted = (SDL_PushEvent(&event) > 0);
504 } 826 }
526 posted = (SDL_PushEvent(&event) > 0); 848 posted = (SDL_PushEvent(&event) > 0);
527 } 849 }
528 return (posted); 850 return (posted);
529 } 851 }
530 852
853 void
854 SDL_KeyboardQuit(void)
855 {
856 int i;
857
858 for (i = 0; i < SDL_num_keyboards; ++i) {
859 SDL_DelKeyboard(i);
860 }
861 SDL_num_keyboards = 0;
862 SDL_current_keyboard = 0;
863
864 if (SDL_keyboards) {
865 SDL_free(SDL_keyboards);
866 SDL_keyboards = NULL;
867 }
868 }
869
870 int
871 SDL_GetNumKeyboards(void)
872 {
873 return SDL_num_keyboards;
874 }
875
876 int
877 SDL_SelectKeyboard(int index)
878 {
879 if (index >= 0 && index < SDL_num_keyboards) {
880 SDL_current_keyboard = index;
881 }
882 return SDL_current_keyboard;
883 }
884
885 Uint8 *
886 SDL_GetKeyboardState(int *numkeys)
887 {
888 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
889
890 if (numkeys != (int *) 0) {
891 *numkeys = SDL_NUM_SCANCODES;
892 }
893
894 if (!keyboard) {
895 return NULL;
896 }
897 return keyboard->keystate;
898 }
899
900 SDLMod
901 SDL_GetModState(void)
902 {
903 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
904
905 if (!keyboard) {
906 return KMOD_NONE;
907 }
908 return keyboard->modstate;
909 }
910
911 void
912 SDL_SetModState(SDLMod modstate)
913 {
914 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
915
916 if (!keyboard) {
917 return;
918 }
919 keyboard->modstate = modstate;
920 }
921
922 SDLKey
923 SDL_GetKeyFromScancode(SDL_scancode scancode)
924 {
925 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
926
927 if (!keyboard) {
928 return SDLK_UNKNOWN;
929 }
930 return keyboard->keymap[scancode];
931 }
932
933 SDL_scancode
934 SDL_GetScancodeFromKey(SDLKey key)
935 {
936 SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
937 SDL_scancode scancode;
938
939 if (!keyboard) {
940 return SDL_SCANCODE_UNKNOWN;
941 }
942
943 for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES;
944 ++scancode) {
945 if (keyboard->keymap[scancode] == key) {
946 return scancode;
947 }
948 }
949 return SDL_SCANCODE_UNKNOWN;
950 }
951
952 const char *
953 SDL_GetScancodeName(SDL_scancode scancode)
954 {
955 const char *name = SDL_scancode_names[scancode];
956
957 if (name)
958 return name;
959 else
960 return "";
961 }
962
963 const char *
964 SDL_GetKeyName(SDLKey key)
965 {
966 static char name[8];
967 char *end;
968
969 if (key & SDLK_SCANCODE_MASK) {
970 return
971 SDL_GetScancodeName((SDL_scancode) (key & ~SDLK_SCANCODE_MASK));
972 }
973
974 /* Unaccented letter keys on latin keyboards are normally
975 labeled in upper case (and probably on others like Greek or
976 Cyrillic too, so if you happen to know for sure, please
977 adapt this). */
978 if (key >= 'a' && key <= 'z') {
979 key -= 32;
980 }
981
982 end = SDL_UCS4ToUTF8((Uint32) key, name);
983 *end = '\0';
984 return name;
985 }
986
531 /* vi: set ts=4 sw=4 expandtab: */ 987 /* vi: set ts=4 sw=4 expandtab: */