SDL_keyboard.c (22840B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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 36typedef struct SDL_Keyboard SDL_Keyboard; 37 38struct 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 47static SDL_Keyboard SDL_keyboard; 48 49static 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}; 277 278static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = { 279 NULL, NULL, NULL, NULL, 280 "A", 281 "B", 282 "C", 283 "D", 284 "E", 285 "F", 286 "G", 287 "H", 288 "I", 289 "J", 290 "K", 291 "L", 292 "M", 293 "N", 294 "O", 295 "P", 296 "Q", 297 "R", 298 "S", 299 "T", 300 "U", 301 "V", 302 "W", 303 "X", 304 "Y", 305 "Z", 306 "1", 307 "2", 308 "3", 309 "4", 310 "5", 311 "6", 312 "7", 313 "8", 314 "9", 315 "0", 316 "Return", 317 "Escape", 318 "Backspace", 319 "Tab", 320 "Space", 321 "-", 322 "=", 323 "[", 324 "]", 325 "\\", 326 "#", 327 ";", 328 "'", 329 "`", 330 ",", 331 ".", 332 "/", 333 "CapsLock", 334 "F1", 335 "F2", 336 "F3", 337 "F4", 338 "F5", 339 "F6", 340 "F7", 341 "F8", 342 "F9", 343 "F10", 344 "F11", 345 "F12", 346 "PrintScreen", 347 "ScrollLock", 348 "Pause", 349 "Insert", 350 "Home", 351 "PageUp", 352 "Delete", 353 "End", 354 "PageDown", 355 "Right", 356 "Left", 357 "Down", 358 "Up", 359 "Numlock", 360 "Keypad /", 361 "Keypad *", 362 "Keypad -", 363 "Keypad +", 364 "Keypad Enter", 365 "Keypad 1", 366 "Keypad 2", 367 "Keypad 3", 368 "Keypad 4", 369 "Keypad 5", 370 "Keypad 6", 371 "Keypad 7", 372 "Keypad 8", 373 "Keypad 9", 374 "Keypad 0", 375 "Keypad .", 376 NULL, 377 "Application", 378 "Power", 379 "Keypad =", 380 "F13", 381 "F14", 382 "F15", 383 "F16", 384 "F17", 385 "F18", 386 "F19", 387 "F20", 388 "F21", 389 "F22", 390 "F23", 391 "F24", 392 "Execute", 393 "Help", 394 "Menu", 395 "Select", 396 "Stop", 397 "Again", 398 "Undo", 399 "Cut", 400 "Copy", 401 "Paste", 402 "Find", 403 "Mute", 404 "VolumeUp", 405 "VolumeDown", 406 NULL, NULL, NULL, 407 "Keypad ,", 408 "Keypad = (AS400)", 409 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 410 NULL, NULL, NULL, NULL, NULL, NULL, 411 "AltErase", 412 "SysReq", 413 "Cancel", 414 "Clear", 415 "Prior", 416 "Return", 417 "Separator", 418 "Out", 419 "Oper", 420 "Clear / Again", 421 "CrSel", 422 "ExSel", 423 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 424 "Keypad 00", 425 "Keypad 000", 426 "ThousandsSeparator", 427 "DecimalSeparator", 428 "CurrencyUnit", 429 "CurrencySubUnit", 430 "Keypad (", 431 "Keypad )", 432 "Keypad {", 433 "Keypad }", 434 "Keypad Tab", 435 "Keypad Backspace", 436 "Keypad A", 437 "Keypad B", 438 "Keypad C", 439 "Keypad D", 440 "Keypad E", 441 "Keypad F", 442 "Keypad XOR", 443 "Keypad ^", 444 "Keypad %", 445 "Keypad <", 446 "Keypad >", 447 "Keypad &", 448 "Keypad &&", 449 "Keypad |", 450 "Keypad ||", 451 "Keypad :", 452 "Keypad #", 453 "Keypad Space", 454 "Keypad @", 455 "Keypad !", 456 "Keypad MemStore", 457 "Keypad MemRecall", 458 "Keypad MemClear", 459 "Keypad MemAdd", 460 "Keypad MemSubtract", 461 "Keypad MemMultiply", 462 "Keypad MemDivide", 463 "Keypad +/-", 464 "Keypad Clear", 465 "Keypad ClearEntry", 466 "Keypad Binary", 467 "Keypad Octal", 468 "Keypad Decimal", 469 "Keypad Hexadecimal", 470 NULL, NULL, 471 "Left Ctrl", 472 "Left Shift", 473 "Left Alt", 474 "Left GUI", 475 "Right Ctrl", 476 "Right Shift", 477 "Right Alt", 478 "Right GUI", 479 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 480 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 481 NULL, 482 "ModeSwitch", 483 "AudioNext", 484 "AudioPrev", 485 "AudioStop", 486 "AudioPlay", 487 "AudioMute", 488 "MediaSelect", 489 "WWW", 490 "Mail", 491 "Calculator", 492 "Computer", 493 "AC Search", 494 "AC Home", 495 "AC Back", 496 "AC Forward", 497 "AC Stop", 498 "AC Refresh", 499 "AC Bookmarks", 500 "BrightnessDown", 501 "BrightnessUp", 502 "DisplaySwitch", 503 "KBDIllumToggle", 504 "KBDIllumDown", 505 "KBDIllumUp", 506 "Eject", 507 "Sleep", 508}; 509 510/* Taken from SDL_iconv() */ 511char * 512SDL_UCS4ToUTF8(Uint32 ch, char *dst) 513{ 514 Uint8 *p = (Uint8 *) dst; 515 if (ch <= 0x7F) { 516 *p = (Uint8) ch; 517 ++dst; 518 } else if (ch <= 0x7FF) { 519 p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F); 520 p[1] = 0x80 | (Uint8) (ch & 0x3F); 521 dst += 2; 522 } else if (ch <= 0xFFFF) { 523 p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F); 524 p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); 525 p[2] = 0x80 | (Uint8) (ch & 0x3F); 526 dst += 3; 527 } else if (ch <= 0x1FFFFF) { 528 p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07); 529 p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); 530 p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); 531 p[3] = 0x80 | (Uint8) (ch & 0x3F); 532 dst += 4; 533 } else if (ch <= 0x3FFFFFF) { 534 p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03); 535 p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F); 536 p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); 537 p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); 538 p[4] = 0x80 | (Uint8) (ch & 0x3F); 539 dst += 5; 540 } else { 541 p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01); 542 p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F); 543 p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F); 544 p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); 545 p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); 546 p[5] = 0x80 | (Uint8) (ch & 0x3F); 547 dst += 6; 548 } 549 return dst; 550} 551 552/* Public functions */ 553int 554SDL_KeyboardInit(void) 555{ 556 SDL_Keyboard *keyboard = &SDL_keyboard; 557 558 /* Set the default keymap */ 559 SDL_memcpy(keyboard->keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); 560 return (0); 561} 562 563void 564SDL_ResetKeyboard(void) 565{ 566 SDL_Keyboard *keyboard = &SDL_keyboard; 567 SDL_Scancode scancode; 568 569#ifdef DEBUG_KEYBOARD 570 printf("Resetting keyboard\n"); 571#endif 572 for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) { 573 if (keyboard->keystate[scancode] == SDL_PRESSED) { 574 SDL_SendKeyboardKey(SDL_RELEASED, scancode); 575 } 576 } 577} 578 579void 580SDL_GetDefaultKeymap(SDL_Keycode * keymap) 581{ 582 SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); 583} 584 585void 586SDL_SetKeymap(int start, SDL_Keycode * keys, int length) 587{ 588 SDL_Keyboard *keyboard = &SDL_keyboard; 589 590 if (start < 0 || start + length > SDL_NUM_SCANCODES) { 591 return; 592 } 593 594 SDL_memcpy(&keyboard->keymap[start], keys, sizeof(*keys) * length); 595} 596 597void 598SDL_SetScancodeName(SDL_Scancode scancode, const char *name) 599{ 600 SDL_scancode_names[scancode] = name; 601} 602 603SDL_Window * 604SDL_GetKeyboardFocus(void) 605{ 606 SDL_Keyboard *keyboard = &SDL_keyboard; 607 608 return keyboard->focus; 609} 610 611void 612SDL_SetKeyboardFocus(SDL_Window * window) 613{ 614 SDL_Keyboard *keyboard = &SDL_keyboard; 615 616 if (keyboard->focus && !window) { 617 /* We won't get anymore keyboard messages, so reset keyboard state */ 618 SDL_ResetKeyboard(); 619 } 620 621 /* See if the current window has lost focus */ 622 if (keyboard->focus && keyboard->focus != window) { 623 624 /* new window shouldn't think it has mouse captured. */ 625 SDL_assert(!window || !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)); 626 627 /* old window must lose an existing mouse capture. */ 628 if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) { 629 SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */ 630 SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE)); 631 } 632 633 SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST, 634 0, 0); 635 636 /* Ensures IME compositions are committed */ 637 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { 638 SDL_VideoDevice *video = SDL_GetVideoDevice(); 639 if (video && video->StopTextInput) { 640 video->StopTextInput(video); 641 } 642 } 643 } 644 645 keyboard->focus = window; 646 647 if (keyboard->focus) { 648 SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED, 649 0, 0); 650 651 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { 652 SDL_VideoDevice *video = SDL_GetVideoDevice(); 653 if (video && video->StartTextInput) { 654 video->StartTextInput(video); 655 } 656 } 657 } 658} 659 660int 661SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) 662{ 663 SDL_Keyboard *keyboard = &SDL_keyboard; 664 int posted; 665 Uint16 modstate; 666 Uint32 type; 667 Uint8 repeat; 668 669 if (!scancode) { 670 return 0; 671 } 672#ifdef DEBUG_KEYBOARD 673 printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode), 674 state == SDL_PRESSED ? "pressed" : "released"); 675#endif 676 if (state == SDL_PRESSED) { 677 modstate = keyboard->modstate; 678 switch (scancode) { 679 case SDL_SCANCODE_NUMLOCKCLEAR: 680 keyboard->modstate ^= KMOD_NUM; 681 break; 682 case SDL_SCANCODE_CAPSLOCK: 683 keyboard->modstate ^= KMOD_CAPS; 684 break; 685 case SDL_SCANCODE_LCTRL: 686 keyboard->modstate |= KMOD_LCTRL; 687 break; 688 case SDL_SCANCODE_RCTRL: 689 keyboard->modstate |= KMOD_RCTRL; 690 break; 691 case SDL_SCANCODE_LSHIFT: 692 keyboard->modstate |= KMOD_LSHIFT; 693 break; 694 case SDL_SCANCODE_RSHIFT: 695 keyboard->modstate |= KMOD_RSHIFT; 696 break; 697 case SDL_SCANCODE_LALT: 698 keyboard->modstate |= KMOD_LALT; 699 break; 700 case SDL_SCANCODE_RALT: 701 keyboard->modstate |= KMOD_RALT; 702 break; 703 case SDL_SCANCODE_LGUI: 704 keyboard->modstate |= KMOD_LGUI; 705 break; 706 case SDL_SCANCODE_RGUI: 707 keyboard->modstate |= KMOD_RGUI; 708 break; 709 case SDL_SCANCODE_MODE: 710 keyboard->modstate |= KMOD_MODE; 711 break; 712 default: 713 break; 714 } 715 } else { 716 switch (scancode) { 717 case SDL_SCANCODE_NUMLOCKCLEAR: 718 case SDL_SCANCODE_CAPSLOCK: 719 break; 720 case SDL_SCANCODE_LCTRL: 721 keyboard->modstate &= ~KMOD_LCTRL; 722 break; 723 case SDL_SCANCODE_RCTRL: 724 keyboard->modstate &= ~KMOD_RCTRL; 725 break; 726 case SDL_SCANCODE_LSHIFT: 727 keyboard->modstate &= ~KMOD_LSHIFT; 728 break; 729 case SDL_SCANCODE_RSHIFT: 730 keyboard->modstate &= ~KMOD_RSHIFT; 731 break; 732 case SDL_SCANCODE_LALT: 733 keyboard->modstate &= ~KMOD_LALT; 734 break; 735 case SDL_SCANCODE_RALT: 736 keyboard->modstate &= ~KMOD_RALT; 737 break; 738 case SDL_SCANCODE_LGUI: 739 keyboard->modstate &= ~KMOD_LGUI; 740 break; 741 case SDL_SCANCODE_RGUI: 742 keyboard->modstate &= ~KMOD_RGUI; 743 break; 744 case SDL_SCANCODE_MODE: 745 keyboard->modstate &= ~KMOD_MODE; 746 break; 747 default: 748 break; 749 } 750 modstate = keyboard->modstate; 751 } 752 753 /* Figure out what type of event this is */ 754 switch (state) { 755 case SDL_PRESSED: 756 type = SDL_KEYDOWN; 757 break; 758 case SDL_RELEASED: 759 type = SDL_KEYUP; 760 break; 761 default: 762 /* Invalid state -- bail */ 763 return 0; 764 } 765 766 /* Drop events that don't change state */ 767 repeat = (state && keyboard->keystate[scancode]); 768 if (keyboard->keystate[scancode] == state && !repeat) { 769#if 0 770 printf("Keyboard event didn't change state - dropped!\n"); 771#endif 772 return 0; 773 } 774 775 /* Update internal keyboard state */ 776 keyboard->keystate[scancode] = state; 777 778 /* Post the event, if desired */ 779 posted = 0; 780 if (SDL_GetEventState(type) == SDL_ENABLE) { 781 SDL_Event event; 782 event.key.type = type; 783 event.key.state = state; 784 event.key.repeat = repeat; 785 event.key.keysym.scancode = scancode; 786 event.key.keysym.sym = keyboard->keymap[scancode]; 787 event.key.keysym.mod = modstate; 788 event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; 789 posted = (SDL_PushEvent(&event) > 0); 790 } 791 return (posted); 792} 793 794int 795SDL_SendKeyboardText(const char *text) 796{ 797 SDL_Keyboard *keyboard = &SDL_keyboard; 798 int posted; 799 800 /* Don't post text events for unprintable characters */ 801 if ((unsigned char)*text < ' ' || *text == 127) { 802 return 0; 803 } 804 805 /* Post the event, if desired */ 806 posted = 0; 807 if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { 808 SDL_Event event; 809 event.text.type = SDL_TEXTINPUT; 810 event.text.windowID = keyboard->focus ? keyboard->focus->id : 0; 811 SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text)); 812 posted = (SDL_PushEvent(&event) > 0); 813 } 814 return (posted); 815} 816 817int 818SDL_SendEditingText(const char *text, int start, int length) 819{ 820 SDL_Keyboard *keyboard = &SDL_keyboard; 821 int posted; 822 823 /* Post the event, if desired */ 824 posted = 0; 825 if (SDL_GetEventState(SDL_TEXTEDITING) == SDL_ENABLE) { 826 SDL_Event event; 827 event.edit.type = SDL_TEXTEDITING; 828 event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; 829 event.edit.start = start; 830 event.edit.length = length; 831 SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text)); 832 posted = (SDL_PushEvent(&event) > 0); 833 } 834 return (posted); 835} 836 837void 838SDL_KeyboardQuit(void) 839{ 840} 841 842const Uint8 * 843SDL_GetKeyboardState(int *numkeys) 844{ 845 SDL_Keyboard *keyboard = &SDL_keyboard; 846 847 if (numkeys != (int *) 0) { 848 *numkeys = SDL_NUM_SCANCODES; 849 } 850 return keyboard->keystate; 851} 852 853SDL_Keymod 854SDL_GetModState(void) 855{ 856 SDL_Keyboard *keyboard = &SDL_keyboard; 857 858 return keyboard->modstate; 859} 860 861void 862SDL_SetModState(SDL_Keymod modstate) 863{ 864 SDL_Keyboard *keyboard = &SDL_keyboard; 865 866 keyboard->modstate = modstate; 867} 868 869SDL_Keycode 870SDL_GetKeyFromScancode(SDL_Scancode scancode) 871{ 872 SDL_Keyboard *keyboard = &SDL_keyboard; 873 874 if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { 875 SDL_InvalidParamError("scancode"); 876 return 0; 877 } 878 879 return keyboard->keymap[scancode]; 880} 881 882SDL_Scancode 883SDL_GetScancodeFromKey(SDL_Keycode key) 884{ 885 SDL_Keyboard *keyboard = &SDL_keyboard; 886 SDL_Scancode scancode; 887 888 for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; 889 ++scancode) { 890 if (keyboard->keymap[scancode] == key) { 891 return scancode; 892 } 893 } 894 return SDL_SCANCODE_UNKNOWN; 895} 896 897const char * 898SDL_GetScancodeName(SDL_Scancode scancode) 899{ 900 const char *name; 901 if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { 902 SDL_InvalidParamError("scancode"); 903 return ""; 904 } 905 906 name = SDL_scancode_names[scancode]; 907 if (name) 908 return name; 909 else 910 return ""; 911} 912 913SDL_Scancode SDL_GetScancodeFromName(const char *name) 914{ 915 int i; 916 917 if (!name || !*name) { 918 SDL_InvalidParamError("name"); 919 return SDL_SCANCODE_UNKNOWN; 920 } 921 922 for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) { 923 if (!SDL_scancode_names[i]) { 924 continue; 925 } 926 if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) { 927 return (SDL_Scancode)i; 928 } 929 } 930 931 SDL_InvalidParamError("name"); 932 return SDL_SCANCODE_UNKNOWN; 933} 934 935const char * 936SDL_GetKeyName(SDL_Keycode key) 937{ 938 static char name[8]; 939 char *end; 940 941 if (key & SDLK_SCANCODE_MASK) { 942 return 943 SDL_GetScancodeName((SDL_Scancode) (key & ~SDLK_SCANCODE_MASK)); 944 } 945 946 switch (key) { 947 case SDLK_RETURN: 948 return SDL_GetScancodeName(SDL_SCANCODE_RETURN); 949 case SDLK_ESCAPE: 950 return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE); 951 case SDLK_BACKSPACE: 952 return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE); 953 case SDLK_TAB: 954 return SDL_GetScancodeName(SDL_SCANCODE_TAB); 955 case SDLK_SPACE: 956 return SDL_GetScancodeName(SDL_SCANCODE_SPACE); 957 case SDLK_DELETE: 958 return SDL_GetScancodeName(SDL_SCANCODE_DELETE); 959 default: 960 /* Unaccented letter keys on latin keyboards are normally 961 labeled in upper case (and probably on others like Greek or 962 Cyrillic too, so if you happen to know for sure, please 963 adapt this). */ 964 if (key >= 'a' && key <= 'z') { 965 key -= 32; 966 } 967 968 end = SDL_UCS4ToUTF8((Uint32) key, name); 969 *end = '\0'; 970 return name; 971 } 972} 973 974SDL_Keycode 975SDL_GetKeyFromName(const char *name) 976{ 977 SDL_Keycode key; 978 979 /* Check input */ 980 if (name == NULL) return SDLK_UNKNOWN; 981 982 /* If it's a single UTF-8 character, then that's the keycode itself */ 983 key = *(const unsigned char *)name; 984 if (key >= 0xF0) { 985 if (SDL_strlen(name) == 4) { 986 int i = 0; 987 key = (Uint16)(name[i]&0x07) << 18; 988 key |= (Uint16)(name[++i]&0x3F) << 12; 989 key |= (Uint16)(name[++i]&0x3F) << 6; 990 key |= (Uint16)(name[++i]&0x3F); 991 return key; 992 } 993 return SDLK_UNKNOWN; 994 } else if (key >= 0xE0) { 995 if (SDL_strlen(name) == 3) { 996 int i = 0; 997 key = (Uint16)(name[i]&0x0F) << 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 >= 0xC0) { 1004 if (SDL_strlen(name) == 2) { 1005 int i = 0; 1006 key = (Uint16)(name[i]&0x1F) << 6; 1007 key |= (Uint16)(name[++i]&0x3F); 1008 return key; 1009 } 1010 return SDLK_UNKNOWN; 1011 } else { 1012 if (SDL_strlen(name) == 1) { 1013 if (key >= 'A' && key <= 'Z') { 1014 key += 32; 1015 } 1016 return key; 1017 } 1018 1019 /* Get the scancode for this name, and the associated keycode */ 1020 return SDL_default_keymap[SDL_GetScancodeFromName(name)]; 1021 } 1022} 1023 1024/* vi: set ts=4 sw=4 expandtab: */