Atlas - SDL_keyboard.c
Home / ext / SDL2 / src / events Lines: 4 | Size: 22681 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 SDLK_APP1, 277 SDLK_APP2, 278 SDLK_AUDIOREWIND, 279 SDLK_AUDIOFASTFORWARD, 280}; 281 282static 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() */ 519char * 520SDL_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 */ 561int 562SDL_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 571void 572SDL_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 587void 588SDL_GetDefaultKeymap(SDL_Keycode * keymap) 589{ 590 SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); 591} 592 593void 594SDL_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 615void 616SDL_SetScancodeName(SDL_Scancode scancode, const char *name) 617{ 618 SDL_scancode_names[scancode] = name; 619} 620 621SDL_Window * 622SDL_GetKeyboardFocus(void) 623{ 624 SDL_Keyboard *keyboard = &SDL_keyboard; 625 626 return keyboard->focus; 627} 628 629void 630SDL_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 678int 679SDL_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 788int 789SDL_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 811int 812SDL_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 831void 832SDL_KeyboardQuit(void) 833{ 834} 835 836const Uint8 * 837SDL_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 847SDL_Keymod 848SDL_GetModState(void) 849{ 850 SDL_Keyboard *keyboard = &SDL_keyboard; 851 852 return (SDL_Keymod) keyboard->modstate; 853} 854 855void 856SDL_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. */ 864void 865SDL_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 876SDL_Keycode 877SDL_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 889SDL_Scancode 890SDL_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 904const char * 905SDL_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 920SDL_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 942const char * 943SDL_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 981SDL_Keycode 982SDL_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: */ 1034[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.