From 3a03b70319d432b76695d84b4342d1f441ea08b1 Mon Sep 17 00:00:00 2001 From: Darkvater Date: Wed, 15 Nov 2006 19:35:52 +0000 Subject: [PATCH] (svn r7153) -Fix [FS#279]: Some keyboard events possibly lost under high CPU load, handle keyboard input in place instead of global variables magic. (KUDr) --- variables.h | 1 - video/cocoa_v.m | 5 +++-- video/sdl_v.c | 3 +-- video/win32_v.c | 12 +++++++----- window.c | 22 +++++++++++++++------- window.h | 1 + 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/variables.h b/variables.h index 3e949390d6..5237030456 100644 --- a/variables.h +++ b/variables.h @@ -282,7 +282,6 @@ VARDEF int32 _additional_cash_required; VARDEF uint32 _decode_parameters[20]; -VARDEF uint32 _pressed_key; // Low 8 bits = ASCII, High 16 bits = keycode VARDEF bool _ctrl_pressed; // Is Ctrl pressed? VARDEF bool _shift_pressed; // Is Shift pressed? VARDEF byte _dirkeys; // 1 = left, 2 = up, 4 = right, 8 = down diff --git a/video/cocoa_v.m b/video/cocoa_v.m index e55e40b14b..e10e87dc24 100644 --- a/video/cocoa_v.m +++ b/video/cocoa_v.m @@ -347,8 +347,9 @@ static void QZ_KeyEvent(unsigned short keycode, unsigned short unicode, BOOL dow } if (down) { - _pressed_key = QZ_MapKey(keycode) | unicode; - DEBUG(driver, 2)("cocoa_v: QZ_KeyEvent: %x (%x), down, mapping: %x", keycode, unicode, _pressed_key); + uint32 pressed_key = QZ_MapKey(keycode) | unicode; + HandleKeypress(pressed_key); + DEBUG(driver, 2)("cocoa_v: QZ_KeyEvent: %x (%x), down, mapping: %x", keycode, unicode, pressed_key); } else { DEBUG(driver, 2)("cocoa_v: QZ_KeyEvent: %x (%x), up", keycode, unicode); } diff --git a/video/sdl_v.c b/video/sdl_v.c index d9ddc62197..b0630b27da 100644 --- a/video/sdl_v.c +++ b/video/sdl_v.c @@ -380,9 +380,8 @@ static int PollEvent(void) (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) { ToggleFullScreen(!_fullscreen); } else { - _pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym); + HandleKeypress(ConvertSdlKeyIntoMy(&ev.key.keysym)); } - break; case SDL_VIDEORESIZE: { diff --git a/video/win32_v.c b/video/win32_v.c index f6ecf069c6..747b6ef818 100644 --- a/video/win32_v.c +++ b/video/win32_v.c @@ -346,23 +346,25 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP WORD w = 0; byte ks[256]; uint scancode; + uint32 pressed_key; GetKeyboardState(ks); if (ToAscii(wParam, 0, ks, &w, 0) == 0) { w = 0; // no translation was possible } - _pressed_key = w | MapWindowsKey(wParam) << 16; + pressed_key = w | MapWindowsKey(wParam) << 16; scancode = GB(lParam, 16, 8); - if (scancode == 41) _pressed_key = w | WKC_BACKQUOTE << 16; + if (scancode == 41) pressed_key = w | WKC_BACKQUOTE << 16; - if ((_pressed_key >> 16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) { + if ((pressed_key >> 16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) { _double_size ^= 1; _wnd.double_size = _double_size; ClientSizeChanged(_wnd.width, _wnd.height); MarkWholeScreenDirty(); } + HandleKeypress(pressed_key); break; } @@ -377,11 +379,11 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP return 0; // do nothing case VK_F10: /* F10, ignore activation of menu */ - _pressed_key = MapWindowsKey(wParam) << 16; + HandleKeypress(MapWindowsKey(wParam) << 16); return 0; default: /* ALT in combination with something else */ - _pressed_key = MapWindowsKey(wParam) << 16; + HandleKeypress(MapWindowsKey(wParam) << 16); break; } break; diff --git a/window.c b/window.c index 4f2a238f42..b2e91990b3 100644 --- a/window.c +++ b/window.c @@ -1397,7 +1397,10 @@ void SendWindowMessageClass(WindowClass wnd_class, uint msg, uint wparam, uint l } } -static void HandleKeypress(uint32 key) +/** Handle keyboard input. + * @param key Lower 8 bits contain the ASCII character, the higher + * 16 bits the keycode */ +void HandleKeypress(uint32 key) { Window *w; WindowEvent e; @@ -1406,6 +1409,17 @@ static void HandleKeypress(uint32 key) * to thein this main toolbar. */ bool query_open = false; + /* + * During the generation of the world, there might be + * another thread that is currently building for example + * a road. To not interfere with those tasks, we should + * NOT change the _current_player here. + * + * This is not necessary either, as the only events that + * can be handled are the 'close application' events + */ + if (!IsGeneratingWorld()) _current_player = _local_player; + // Setup event e.event = WE_KEYPRESS; e.we.keypress.ascii = key & 0xFF; @@ -1564,12 +1578,6 @@ void InputLoop(void) */ if (!IsGeneratingWorld()) _current_player = _local_player; - // Handle pressed keys - if (_pressed_key != 0) { - HandleKeypress(_pressed_key); - _pressed_key = 0; - } - // Mouse event? click = 0; if (_left_button_down && !_left_button_clicked) { diff --git a/window.h b/window.h index a110f35472..bf85dcff4a 100644 --- a/window.h +++ b/window.h @@ -801,6 +801,7 @@ void UnInitWindowSystem(void); void ResetWindowSystem(void); int GetMenuItemIndex(const Window *w, int x, int y); void InputLoop(void); +void HandleKeypress(uint32 key); void UpdateWindows(void); void InvalidateWidget(const Window *w, byte widget_index); void InvalidateThisWindowData(Window *w);