From b878e9646ea2a6b2d435a86966e6619e2ae008c3 Mon Sep 17 00:00:00 2001 From: John Popplewell Date: Thu, 10 Jul 2008 20:57:25 +0000 Subject: [PATCH] Added code to hook low-level keyboard events on 2K/XP/Vista. The hook is only installed if in full-screen mode. Filters out the left and right Windows keys to avoid accidentally dropping out of full-screen mode. If Tux Paint is deliberately switched to the background (using ALT-TAB, say) the Windows keys function as normal until Tux Paint is the active application again. --- src/tuxpaint.c | 18 ++++++++++++++++ src/win32_print.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ src/win32_print.h | 5 +++++ 3 files changed, 76 insertions(+) diff --git a/src/tuxpaint.c b/src/tuxpaint.c index 050d5014f..2f1e65178 100644 --- a/src/tuxpaint.c +++ b/src/tuxpaint.c @@ -6842,6 +6842,14 @@ static void setup(int argc, char *argv[]) } } +#ifdef _WIN32 + if (fullscreen) + { + InstallKeyboardHook(); + SetActivationState(1); + } +#endif + setup_language(getfilename(argv[0]), &button_label_y_nudge); im_init(&im_data, get_current_language()); @@ -14812,6 +14820,10 @@ void play_slideshow(int * selected, int num_selected, char * dirname, next = 1; done = 1; } + else if (event.type == SDL_ACTIVEEVENT) + { + handle_active(&event); + } else if (event.type == SDL_KEYDOWN) { key = event.key.keysym.sym; @@ -16169,6 +16181,12 @@ static void handle_active(SDL_Event * event) SDL_Flip(screen); } } +#ifdef _WIN32 + if (event->active.state & SDL_APPINPUTFOCUS|SDL_APPACTIVE) + { + SetActivationState(event->active.gain); + } +#endif } diff --git a/src/win32_print.c b/src/win32_print.c index 39f962af6..2bdbcbe3d 100644 --- a/src/win32_print.c +++ b/src/win32_print.c @@ -589,3 +589,56 @@ char *get_temp_fname(const char *const name) return strdup(f); } +/* + * Nasty low-level hook into the keyboard. 2K/XP/Vista only. + */ + +static HHOOK g_hKeyboardHook = NULL; +static int g_bWindowActive = 0; + +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + int bEatKeystroke = 0; + KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT*)lParam; + + if (nCode < 0 || nCode != HC_ACTION) + return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam); + + switch (wParam) + { + case WM_KEYDOWN: + case WM_KEYUP: + { + bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)); + break; + } + } + + if(bEatKeystroke) + return 1; + return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam); +} + +int InstallKeyboardHook(void) +{ + if (g_hKeyboardHook) + return -1; + g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); + return g_hKeyboardHook ? 0 : -2; +} + +int RemoveKeyboardHook(void) +{ + if (!g_hKeyboardHook) + return -1; + UnhookWindowsHookEx(g_hKeyboardHook); + g_hKeyboardHook = NULL; + return 0; +} + +void SetActivationState(int state) +{ + g_bWindowActive = state; +} + + diff --git a/src/win32_print.h b/src/win32_print.h index fb3c9e136..a12054860 100644 --- a/src/win32_print.h +++ b/src/win32_print.h @@ -24,4 +24,9 @@ extern char *GetDefaultSaveDir(const char *suffix); extern char *GetSystemFontDir(void); extern char *get_temp_fname(const char *const name); +/* keyboard hooking functions */ +extern int InstallKeyboardHook(void); +extern int RemoveKeyboardHook(void); +extern void SetActivationState(int state); + #endif