diff --git a/src/w32console.c b/src/w32console.c index 0936b5f37e6..2161e738252 100644 --- a/src/w32console.c +++ b/src/w32console.c @@ -822,7 +822,9 @@ initialize_w32_display (struct terminal *term, int *width, int *height) w32_initialize_display_info (build_string ("Console")); /* Set up the keyboard hook. */ - setup_w32_kbdhook (); + /* FIXME where can this be cleaned up, that is, where can we call + remove_w32_kbdhook? */ + setup_w32_kbdhook (NULL); } diff --git a/src/w32fns.c b/src/w32fns.c index 8d4bd00b91c..1f2a68c2fed 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -49,6 +49,7 @@ #define _WIN32_WINNT 0x0600 #ifdef WINDOWSNT #include #include /* for _getmbcp */ +#include /* for WTS(Un)RegisterSessionNotificationEx */ #endif /* WINDOWSNT */ #if CYGWIN @@ -204,6 +205,10 @@ DECLARE_HANDLE(HMONITOR); typedef HRESULT (WINAPI * DwmSetWindowAttribute_Proc) (HWND hwnd, DWORD dwAttribute, IN LPCVOID pvAttribute, DWORD cbAttribute); +typedef BOOL (WINAPI * WTSRegisterSessionNotification_Proc) + (HWND hwnd, DWORD dwFlags); +typedef BOOL (WINAPI * WTSUnRegisterSessionNotification_Proc) (HWND hwnd); + TrackMouseEvent_Proc track_mouse_event_fn = NULL; ImmGetCompositionString_Proc get_composition_string_fn = NULL; ImmGetContext_Proc get_ime_context_fn = NULL; @@ -2744,7 +2749,7 @@ funhook (int code, WPARAM w, LPARAM l) /* Set up the hook; can be called several times, with matching remove_w32_kbdhook calls. */ void -setup_w32_kbdhook (void) +setup_w32_kbdhook (HWND hwnd) { kbdhook.hook_count++; @@ -2800,17 +2805,35 @@ setup_w32_kbdhook (void) /* Set the hook. */ kbdhook.hook = SetWindowsHookEx (WH_KEYBOARD_LL, funhook, GetModuleHandle (NULL), 0); + if (hwnd != NULL) + { + HMODULE wtsapi32_lib = LoadLibrary ("wtsapi32.dll"); + WTSRegisterSessionNotification_Proc WTSRegisterSessionNotification_fn + = (WTSRegisterSessionNotification_Proc) + get_proc_addr (wtsapi32_lib, "WTSRegisterSessionNotification"); + if (WTSRegisterSessionNotification_fn != NULL) + WTSRegisterSessionNotification_fn (hwnd, NOTIFY_FOR_THIS_SESSION); + } } } /* Remove the hook. */ void -remove_w32_kbdhook (void) +remove_w32_kbdhook (HWND hwnd) { kbdhook.hook_count--; if (kbdhook.hook_count == 0 && w32_kbdhook_active) { UnhookWindowsHookEx (kbdhook.hook); + if (hwnd != NULL) + { + HMODULE wtsapi32_lib = GetModuleHandle ("wtsapi32.dll"); + WTSUnRegisterSessionNotification_Proc WTSUnRegisterSessionNotification_fn + = (WTSUnRegisterSessionNotification_Proc) + get_proc_addr (wtsapi32_lib, "WTSUnRegisterSessionNotification"); + if (WTSUnRegisterSessionNotification_fn != NULL) + WTSUnRegisterSessionNotification_fn (hwnd); + } kbdhook.hook = NULL; } } @@ -5301,13 +5324,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) #ifdef WINDOWSNT case WM_CREATE: - setup_w32_kbdhook (); + setup_w32_kbdhook (hwnd); goto dflt; #endif case WM_DESTROY: #ifdef WINDOWSNT - remove_w32_kbdhook (); + remove_w32_kbdhook (hwnd); #endif CoUninitialize (); return 0; diff --git a/src/w32term.h b/src/w32term.h index 29ace0b2797..374c8055ed8 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -779,8 +779,8 @@ #define FILE_NOTIFICATIONS_SIZE 16384 #ifdef WINDOWSNT /* Keyboard hooks. */ -extern void setup_w32_kbdhook (void); -extern void remove_w32_kbdhook (void); +extern void setup_w32_kbdhook (HWND); +extern void remove_w32_kbdhook (HWND); extern int check_w32_winkey_state (int); #define w32_kbdhook_active (os_subtype != OS_SUBTYPE_9X) #else