@@ -638,6 +638,91 @@ static uint16 conv_mouse_buttons(Uint8 const state)
638638}
639639
640640
641+ static inline bool is_numpad_key (SDL_Keycode keycode)
642+ {
643+ return
644+ keycode == SDLK_KP_1 ||
645+ keycode == SDLK_KP_2 ||
646+ keycode == SDLK_KP_3 ||
647+ keycode == SDLK_KP_4 ||
648+ keycode == SDLK_KP_5 ||
649+ keycode == SDLK_KP_6 ||
650+ keycode == SDLK_KP_7 ||
651+ keycode == SDLK_KP_8 ||
652+ keycode == SDLK_KP_9 ||
653+ keycode == SDLK_KP_0;
654+ }
655+
656+
657+ // SDL doesn't set numlock state correctly on startup. Revert to win32 function as workaround.
658+ static inline bool is_numlock_enabled ()
659+ {
660+ #ifdef _WIN32
661+ return (GetKeyState ( VK_NUMLOCK ) & 1 ) != 0 ;
662+ #else
663+ return SDL_GetModState () & KMOD_NUM;
664+ #endif
665+ }
666+
667+
668+ static inline unsigned long sdlk_to_simkey (SDL_Keycode keycode, bool keypad_emits_numbers)
669+ {
670+ switch ( keycode ) {
671+ case SDLK_BACKSPACE: return SIM_KEYCODE_BACKSPACE;
672+ case SDLK_TAB: return SIM_KEYCODE_TAB;
673+ case SDLK_RETURN: return SIM_KEYCODE_ENTER;
674+ case SDLK_ESCAPE: return SIM_KEYCODE_ESCAPE;
675+ case SDLK_AC_BACK:
676+ case SDLK_DELETE: return SIM_KEYCODE_DELETE;
677+ case SDLK_DOWN: return SIM_KEYCODE_DOWN;
678+ case SDLK_END: return SIM_KEYCODE_END;
679+ case SDLK_HOME: return SIM_KEYCODE_HOME;
680+ case SDLK_F1: return SIM_KEYCODE_F1;
681+ case SDLK_F2: return SIM_KEYCODE_F2;
682+ case SDLK_F3: return SIM_KEYCODE_F3;
683+ case SDLK_F4: return SIM_KEYCODE_F4;
684+ case SDLK_F5: return SIM_KEYCODE_F5;
685+ case SDLK_F6: return SIM_KEYCODE_F6;
686+ case SDLK_F7: return SIM_KEYCODE_F7;
687+ case SDLK_F8: return SIM_KEYCODE_F8;
688+ case SDLK_F9: return SIM_KEYCODE_F9;
689+ case SDLK_F10: return SIM_KEYCODE_F10;
690+ case SDLK_F11: return SIM_KEYCODE_F11;
691+ case SDLK_F12: return SIM_KEYCODE_F12;
692+ case SDLK_F13: return SIM_KEYCODE_F13;
693+ case SDLK_F14: return SIM_KEYCODE_F14;
694+ case SDLK_F15: return SIM_KEYCODE_F15;
695+ case SDLK_KP_0: return (keypad_emits_numbers ? ' 0' : (unsigned long )SIM_KEYCODE_NUMPAD_BASE);
696+ case SDLK_KP_1: return (keypad_emits_numbers ? ' 1' : (unsigned long )SIM_KEYCODE_DOWNLEFT);
697+ case SDLK_KP_2: return (keypad_emits_numbers ? ' 2' : (unsigned long )SIM_KEYCODE_DOWN);
698+ case SDLK_KP_3: return (keypad_emits_numbers ? ' 3' : (unsigned long )SIM_KEYCODE_DOWNRIGHT);
699+ case SDLK_KP_4: return (keypad_emits_numbers ? ' 4' : (unsigned long )SIM_KEYCODE_LEFT);
700+ case SDLK_KP_5: return (keypad_emits_numbers ? ' 5' : (unsigned long )SIM_KEYCODE_CENTER);
701+ case SDLK_KP_6: return (keypad_emits_numbers ? ' 6' : (unsigned long )SIM_KEYCODE_RIGHT);
702+ case SDLK_KP_7: return (keypad_emits_numbers ? ' 7' : (unsigned long )SIM_KEYCODE_UPLEFT);
703+ case SDLK_KP_8: return (keypad_emits_numbers ? ' 8' : (unsigned long )SIM_KEYCODE_UP);
704+ case SDLK_KP_9: return (keypad_emits_numbers ? ' 9' : (unsigned long )SIM_KEYCODE_UPRIGHT);
705+ case SDLK_KP_ENTER: return SIM_KEYCODE_ENTER;
706+ case SDLK_LEFT: return SIM_KEYCODE_LEFT;
707+ case SDLK_PAGEDOWN: return ' <' ;
708+ case SDLK_PAGEUP: return ' >' ;
709+ case SDLK_RIGHT: return SIM_KEYCODE_RIGHT;
710+ case SDLK_UP: return SIM_KEYCODE_UP;
711+ case SDLK_PAUSE: return SIM_KEYCODE_PAUSE;
712+ case SDLK_SCROLLLOCK: return SIM_KEYCODE_SCROLLLOCK;
713+ default : {
714+ // Handle CTRL-keys. SDL_TEXTINPUT event handles regular input
715+ if ( (sys_event.key_mod & SIM_KEYMOD_CTRL) && SDLK_a <= keycode && keycode <= SDLK_z ) {
716+ return keycode & 31 ;
717+ }
718+ else {
719+ return 0 ;
720+ }
721+ }
722+ }
723+ }
724+
725+
641726static void internal_GetEvents ()
642727{
643728 // Apparently Cocoa SDL posts key events that meant to be used by IM...
@@ -902,7 +987,7 @@ static void internal_GetEvents()
902987 }
903988 break ;
904989
905- case SDL_KEYDOWN: {
990+ case SDL_KEYDOWN:
906991 // Hack: when 2 byte character composition is under way, we have to leave the key processing with the IME
907992 // BUT: if not, we have to do it ourselves, or the cursor or return will not be recognised
908993 if ( composition_is_underway ) {
@@ -915,78 +1000,19 @@ static void internal_GetEvents()
9151000 }
9161001 }
9171002 }
1003+ // fallthrough
9181004
919- unsigned long code;
920- #ifdef _WIN32
921- // SDL doesn't set numlock state correctly on startup. Revert to win32 function as workaround.
922- const bool key_numlock = ((GetKeyState ( VK_NUMLOCK ) & 1 ) != 0 );
923- #else
924- const bool key_numlock = (SDL_GetModState () & KMOD_NUM);
925- #endif
926- const bool numlock = key_numlock || (env_t ::numpad_always_moves_map && !win_is_textinput ());
927- sys_event.key_mod = ModifierKeys ();
928- SDL_Keycode sym = event.key .keysym .sym ;
929- bool np = false ; // to indicate we converted a numpad key
930-
931- switch ( sym ) {
932- case SDLK_BACKSPACE: code = SIM_KEYCODE_BACKSPACE; break ;
933- case SDLK_TAB: code = SIM_KEYCODE_TAB; break ;
934- case SDLK_RETURN: code = SIM_KEYCODE_ENTER; break ;
935- case SDLK_ESCAPE: code = SIM_KEYCODE_ESCAPE; break ;
936- case SDLK_AC_BACK:
937- case SDLK_DELETE: code = SIM_KEYCODE_DELETE; break ;
938- case SDLK_DOWN: code = SIM_KEYCODE_DOWN; break ;
939- case SDLK_END: code = SIM_KEYCODE_END; break ;
940- case SDLK_HOME: code = SIM_KEYCODE_HOME; break ;
941- case SDLK_F1: code = SIM_KEYCODE_F1; break ;
942- case SDLK_F2: code = SIM_KEYCODE_F2; break ;
943- case SDLK_F3: code = SIM_KEYCODE_F3; break ;
944- case SDLK_F4: code = SIM_KEYCODE_F4; break ;
945- case SDLK_F5: code = SIM_KEYCODE_F5; break ;
946- case SDLK_F6: code = SIM_KEYCODE_F6; break ;
947- case SDLK_F7: code = SIM_KEYCODE_F7; break ;
948- case SDLK_F8: code = SIM_KEYCODE_F8; break ;
949- case SDLK_F9: code = SIM_KEYCODE_F9; break ;
950- case SDLK_F10: code = SIM_KEYCODE_F10; break ;
951- case SDLK_F11: code = SIM_KEYCODE_F11; break ;
952- case SDLK_F12: code = SIM_KEYCODE_F12; break ;
953- case SDLK_F13: code = SIM_KEYCODE_F13; break ;
954- case SDLK_F14: code = SIM_KEYCODE_F14; break ;
955- case SDLK_F15: code = SIM_KEYCODE_F15; break ;
956- case SDLK_KP_0: np = true ; code = (numlock ? ' 0' : (unsigned long )SIM_KEYCODE_NUMPAD_BASE); break ;
957- case SDLK_KP_1: np = true ; code = (numlock ? ' 1' : (unsigned long )SIM_KEYCODE_DOWNLEFT); break ;
958- case SDLK_KP_2: np = true ; code = (numlock ? ' 2' : (unsigned long )SIM_KEYCODE_DOWN); break ;
959- case SDLK_KP_3: np = true ; code = (numlock ? ' 3' : (unsigned long )SIM_KEYCODE_DOWNRIGHT); break ;
960- case SDLK_KP_4: np = true ; code = (numlock ? ' 4' : (unsigned long )SIM_KEYCODE_LEFT); break ;
961- case SDLK_KP_5: np = true ; code = (numlock ? ' 5' : (unsigned long )SIM_KEYCODE_CENTER); break ;
962- case SDLK_KP_6: np = true ; code = (numlock ? ' 6' : (unsigned long )SIM_KEYCODE_RIGHT); break ;
963- case SDLK_KP_7: np = true ; code = (numlock ? ' 7' : (unsigned long )SIM_KEYCODE_UPLEFT); break ;
964- case SDLK_KP_8: np = true ; code = (numlock ? ' 8' : (unsigned long )SIM_KEYCODE_UP); break ;
965- case SDLK_KP_9: np = true ; code = (numlock ? ' 9' : (unsigned long )SIM_KEYCODE_UPRIGHT); break ;
966- case SDLK_KP_ENTER: code = SIM_KEYCODE_ENTER; break ;
967- case SDLK_LEFT: code = SIM_KEYCODE_LEFT; break ;
968- case SDLK_PAGEDOWN: code = ' <' ; break ;
969- case SDLK_PAGEUP: code = ' >' ; break ;
970- case SDLK_RIGHT: code = SIM_KEYCODE_RIGHT; break ;
971- case SDLK_UP: code = SIM_KEYCODE_UP; break ;
972- case SDLK_PAUSE: code = SIM_KEYCODE_PAUSE; break ;
973- case SDLK_SCROLLLOCK: code = SIM_KEYCODE_SCROLLLOCK; break ;
974- default : {
975- // Handle CTRL-keys. SDL_TEXTINPUT event handles regular input
976- if ( (sys_event.key_mod & SIM_KEYMOD_CTRL) && SDLK_a <= sym && sym <= SDLK_z ) {
977- code = event.key .keysym .sym & 31 ;
978- }
979- else {
980- code = 0 ;
981- }
982- break ;
983- }
1005+ case SDL_KEYUP:
1006+ {
1007+ const bool numlock_enabled = is_numlock_enabled ();
1008+ const bool keypad_emits_numbers = numlock_enabled || (env_t ::numpad_always_moves_map && !win_is_textinput ());
1009+
1010+ ignore_previous_number = (is_numpad_key (event.key .keysym .sym ) && numlock_enabled);
1011+ sys_event.type = event.type == SDL_KEYDOWN ? SIM_KEYDOWN : SIM_KEYUP;
1012+ sys_event.code = sdlk_to_simkey (event.key .keysym .sym , keypad_emits_numbers);
1013+ sys_event.key_mod = ModifierKeys ();
9841014 }
985- ignore_previous_number = (np && key_numlock);
986- sys_event.type = SIM_KEYBOARD;
987- sys_event.code = code;
9881015 break ;
989- }
9901016
9911017 case SDL_TEXTINPUT: {
9921018 size_t in_pos = 0 ;
@@ -997,8 +1023,8 @@ static void internal_GetEvents()
9971023 ignore_previous_number = false ;
9981024 break ;
9991025 }
1000- sys_event.type = SIM_KEYBOARD ;
1001- sys_event.code = (unsigned long )uc;
1026+ sys_event.type = SIM_KEYDOWN ;
1027+ sys_event.code = (unsigned long )uc;
10021028 }
10031029 else {
10041030 // string
@@ -1036,11 +1062,6 @@ static void internal_GetEvents()
10361062 break ;
10371063 }
10381064#endif
1039- case SDL_KEYUP: {
1040- sys_event.type = SIM_KEYBOARD;
1041- sys_event.code = 0 ;
1042- break ;
1043- }
10441065 case SDL_QUIT: {
10451066 sys_event.type = SIM_SYSTEM;
10461067 sys_event.code = SYSTEM_QUIT;
0 commit comments