Skip to content

Commit a3b2dea

Browse files
committed
CHG: Support separate key-down/key-up events
git-svn-id: svn://tron.homeunix.org/simutrans/simutrans/trunk@11858 8aca7d54-2c30-db11-9de9-000461428c89
1 parent 49a15b6 commit a3b2dea

File tree

5 files changed

+170
-133
lines changed

5 files changed

+170
-133
lines changed

src/simutrans/gui/help_frame.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,10 @@ void help_frame_t::set_helpfile(const char *filename, bool resize_frame )
353353
switch (uint16 const key = i->command_key) {
354354
case '<': c.append( "&lt;" ); break;
355355
case '>': c.append( "&gt;" ); break;
356-
case 27: c.append( translator::translate( "[ESCAPE]" ) ); break;
357-
case 127: c.append( translator::translate( "[DELETE]" ) ); break;
358-
case SIM_KEYCODE_HOME: c.append( translator::translate( "[HOME]" ) ); break;
359-
case SIM_KEYCODE_END: c.append( translator::translate( "[END]" ) ); break;
356+
case SIM_KEYCODE_ESCAPE: c.append( translator::translate( "[ESCAPE]" ) ); break;
357+
case SIM_KEYCODE_DELETE: c.append( translator::translate( "[DELETE]" ) ); break;
358+
case SIM_KEYCODE_HOME: c.append( translator::translate( "[HOME]" ) ); break;
359+
case SIM_KEYCODE_END: c.append( translator::translate( "[END]" ) ); break;
360360
case SIM_KEYCODE_SCROLLLOCK: c.append( translator::translate( "[SCROLLLOCK]" ) ); break;
361361
default:
362362
if (key <= 26) {

src/simutrans/simevent.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,16 @@ static void fill_event(event_t* const ev)
9999
case SIM_IGNORE_EVENT:
100100
break;
101101

102-
case SIM_KEYBOARD:
102+
case SIM_KEYDOWN:
103103
ev->ev_class = EVENT_KEYDOWN;
104104
ev->ev_code = sys_event.code;
105105
break;
106106

107+
case SIM_KEYUP:
108+
ev->ev_class = EVENT_KEYUP;
109+
ev->ev_code = sys_event.code;
110+
break;
111+
107112
case SIM_STRING:
108113
ev->ev_class = EVENT_STRING;
109114
ev->ev_ptr = sys_event.ptr;

src/simutrans/sys/simsys.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ enum sim_event_type_t : uint32
2929
{
3030
SIM_NOEVENT = 0,
3131
SIM_MOUSE_BUTTONS = 1,
32-
SIM_KEYBOARD = 2,
33-
SIM_MOUSE_MOVE = 3,
34-
SIM_STRING = 4,
32+
SIM_KEYDOWN = 2,
33+
SIM_KEYUP = 3,
34+
SIM_MOUSE_MOVE = 4,
35+
SIM_STRING = 5,
3536
SIM_SYSTEM = 254,
3637
SIM_IGNORE_EVENT = 255
3738
};

src/simutrans/sys/simsys_s2.cc

Lines changed: 98 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
641726
static 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;

src/simutrans/sys/simsys_w.cc

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,55 @@ static inline unsigned int ModifierKeys()
495495
}
496496

497497

498+
static inline unsigned long vkey_to_simkey(WPARAM wParam, LPARAM lParam)
499+
{
500+
sint16 code = lParam >> 16;
501+
if( code >= 0x47 && code <= 0x52 && code != 0x4A && code != 0x4e ) {
502+
if( (GetKeyState( VK_NUMLOCK ) & 1) == 0 || (env_t::numpad_always_moves_map && !win_is_textinput()) ) { // numlock off?
503+
switch( code ) {
504+
case 0x47: code = SIM_KEYCODE_UPLEFT; break;
505+
case 0x48: code = SIM_KEYCODE_UP; break;
506+
case 0x49: code = SIM_KEYCODE_UPRIGHT; break;
507+
case 0x4B: code = SIM_KEYCODE_LEFT; break;
508+
case 0x4C: code = SIM_KEYCODE_CENTER; break;
509+
case 0x4D: code = SIM_KEYCODE_RIGHT; break;
510+
case 0x4F: code = SIM_KEYCODE_DOWNLEFT; break;
511+
case 0x50: code = SIM_KEYCODE_DOWN; break;
512+
case 0x51: code = SIM_KEYCODE_DOWNRIGHT; break;
513+
case 0x52: code = SIM_KEYCODE_NUMPAD_BASE; break;
514+
}
515+
516+
if( code>=SIM_KEYCODE_NUMPAD_BASE ) {
517+
// ok found something
518+
return code;
519+
}
520+
}
521+
}
522+
523+
// do low level special stuff here
524+
switch (wParam) {
525+
case VK_SCROLL: return SIM_KEYCODE_SCROLLLOCK; break;
526+
case VK_PAUSE: return SIM_KEYCODE_PAUSE; break;
527+
case VK_LEFT: return SIM_KEYCODE_LEFT; break;
528+
case VK_RIGHT: return SIM_KEYCODE_RIGHT; break;
529+
case VK_UP: return SIM_KEYCODE_UP; break;
530+
case VK_DOWN: return SIM_KEYCODE_DOWN; break;
531+
case VK_PRIOR: return '>'; break;
532+
case VK_NEXT: return '<'; break;
533+
case VK_DELETE: return 127; break;
534+
case VK_HOME: return SIM_KEYCODE_HOME; break;
535+
case VK_END: return SIM_KEYCODE_END; break;
536+
}
537+
538+
// check for F-Keys!
539+
if (code == 0 && wParam >= VK_F1 && wParam <= VK_F15) {
540+
code = wParam - VK_F1 + SIM_KEYCODE_F1;
541+
}
542+
543+
return code;
544+
}
545+
546+
498547
/* Windows eventhandler: does most of the work */
499548
LRESULT WINAPI WindowProc(HWND this_hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
500549
{
@@ -649,56 +698,17 @@ LRESULT WINAPI WindowProc(HWND this_hwnd, UINT msg, WPARAM wParam, LPARAM lParam
649698
break;
650699
}
651700

652-
case WM_KEYDOWN: { /* originally KeyPress */
701+
/* originally KeyPress */
702+
case WM_KEYDOWN:
703+
case WM_KEYUP: {
653704
// check for not numlock!
654-
sys_event.type = SIM_KEYBOARD;
655-
sys_event.code = 0;
705+
sys_event.type = msg==WM_KEYDOWN ? SIM_KEYDOWN : SIM_KEYUP;
706+
sys_event.code = vkey_to_simkey(wParam, lParam);
656707
sys_event.key_mod = ModifierKeys();
657708

658-
sint16 code = lParam >> 16;
659-
if( code >= 0x47 && code <= 0x52 && code != 0x4A && code != 0x4e ) {
660-
if( (GetKeyState( VK_NUMLOCK ) & 1) == 0 || (env_t::numpad_always_moves_map && !win_is_textinput()) ) { // numlock off?
661-
switch( code ) {
662-
case 0x47: code = SIM_KEYCODE_UPLEFT; break;
663-
case 0x48: code = SIM_KEYCODE_UP; break;
664-
case 0x49: code = SIM_KEYCODE_UPRIGHT; break;
665-
case 0x4B: code = SIM_KEYCODE_LEFT; break;
666-
case 0x4C: code = SIM_KEYCODE_CENTER; break;
667-
case 0x4D: code = SIM_KEYCODE_RIGHT; break;
668-
case 0x4F: code = SIM_KEYCODE_DOWNLEFT; break;
669-
case 0x50: code = SIM_KEYCODE_DOWN; break;
670-
case 0x51: code = SIM_KEYCODE_DOWNRIGHT; break;
671-
case 0x52: code = SIM_KEYCODE_NUMPAD_BASE; break;
672-
}
673-
if( code>=SIM_KEYCODE_NUMPAD_BASE ) {
674-
// ok found something
675-
sys_event.code = code;
676-
break;
677-
}
678-
}
679-
}
680-
681-
// do low level special stuff here
682-
switch (wParam) {
683-
case VK_SCROLL: sys_event.code = SIM_KEYCODE_SCROLLLOCK; break;
684-
case VK_PAUSE: sys_event.code = SIM_KEYCODE_PAUSE; break;
685-
case VK_LEFT: sys_event.code = SIM_KEYCODE_LEFT; break;
686-
case VK_RIGHT: sys_event.code = SIM_KEYCODE_RIGHT; break;
687-
case VK_UP: sys_event.code = SIM_KEYCODE_UP; break;
688-
case VK_DOWN: sys_event.code = SIM_KEYCODE_DOWN; break;
689-
case VK_PRIOR: sys_event.code = '>'; break;
690-
case VK_NEXT: sys_event.code = '<'; break;
691-
case VK_DELETE: sys_event.code = 127; break;
692-
case VK_HOME: sys_event.code = SIM_KEYCODE_HOME; break;
693-
case VK_END: sys_event.code = SIM_KEYCODE_END; break;
694-
}
695-
// check for F-Keys!
696-
if (sys_event.code == 0 && wParam >= VK_F1 && wParam <= VK_F15) {
697-
sys_event.code = wParam - VK_F1 + SIM_KEYCODE_F1;
698-
//printf("WindowsEvent: Key %i, (state %i)\n", sys_event.code, sys_event.key_mod);
699-
}
700709
// some result?
701710
if (sys_event.code != 0) return 0;
711+
702712
sys_event.type = SIM_NOEVENT;
703713
sys_event.code = 0;
704714
break;
@@ -715,8 +725,8 @@ LRESULT WINAPI WindowProc(HWND this_hwnd, UINT msg, WPARAM wParam, LPARAM lParam
715725
break;
716726
}
717727
}
718-
sys_event.type = SIM_KEYBOARD;
719-
sys_event.code = wParam;
728+
sys_event.type = SIM_KEYDOWN;
729+
sys_event.code = wParam;
720730
sys_event.key_mod = ModifierKeys();
721731
break;
722732
}
@@ -812,7 +822,7 @@ LRESULT WINAPI WindowProc(HWND this_hwnd, UINT msg, WPARAM wParam, LPARAM lParam
812822
}
813823
else {
814824
// single key
815-
sys_event.type = SIM_KEYBOARD;
825+
sys_event.type = SIM_KEYDOWN;
816826
sys_event.code = u16buf[0];
817827
}
818828
sys_event.key_mod = ModifierKeys();

0 commit comments

Comments
 (0)