diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c index c14684c96..d55c7ade0 100644 --- a/hw/xwin/InitInput.c +++ b/hw/xwin/InitInput.c @@ -50,7 +50,7 @@ DISPATCH_PROC(winProcSetSelectionOwner); * Local global declarations */ -CARD32 g_c32LastInputEventTime = 0; +CARD32 g_c32LastInputEventTime = 0; /* diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index 40ed36f88..bd7dc83c7 100644 --- a/hw/xwin/InitOutput.c +++ b/hw/xwin/InitOutput.c @@ -245,6 +245,9 @@ ddxGiveUp (void) g_pszCommandLine = NULL; } + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); + /* Tell Windows that we want to end the app */ PostQuitMessage (0); } diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 6eef4f9bd..a453a8e48 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -967,6 +967,17 @@ void winSendKeyEvent (DWORD dwKey, Bool fDown); +/* + * winkeyhook.c + */ + +Bool +winInstallKeyboardHookLL (); + +void +winRemoveKeyboardHookLL (); + + /* * winmisc.c */ diff --git a/hw/xwin/winclipboardunicode.c b/hw/xwin/winclipboardunicode.c index 2701a7d58..48a10fdba 100644 --- a/hw/xwin/winclipboardunicode.c +++ b/hw/xwin/winclipboardunicode.c @@ -50,13 +50,13 @@ winClipboardDetectUnicodeSupport (void) switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT: - /* Engine 4 is supported on NT only */ + /* Unicode supported on NT only */ ErrorF ("DetectUnicodeSupport - Windows NT/2000/XP\n"); fReturn = TRUE; break; case VER_PLATFORM_WIN32_WINDOWS: - /* Engine 4 is supported on NT only */ + /* Unicode is not supported on non-NT */ ErrorF ("DetectUnicodeSupport - Windows 95/98/Me\n"); fReturn = FALSE; break; diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index 53ed03aa1..54d3653c9 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -59,9 +59,9 @@ int g_iLogVerbose = 4; Bool g_fLogInited = FALSE; char * g_pszCommandLine = NULL; Bool g_fUseMsg = FALSE; -#ifdef XWIN_MULTIWINDOW DWORD g_dwCurrentThreadID = 0; -#endif +Bool g_fKeyboardHookLL = TRUE; +HHOOK g_hhookKeyboardLL = NULL; /* @@ -110,9 +110,7 @@ Atom g_atomLastOwnedSelection = None; void winInitializeGlobals (void) { -#ifdef XWIN_MULTIWINDOW g_dwCurrentThreadID = GetCurrentThreadId (); -#endif #ifdef XWIN_CLIPBOARD g_fClipboardLaunched = FALSE; g_fClipboardStarted = FALSE; diff --git a/hw/xwin/winkeyhook.c b/hw/xwin/winkeyhook.c new file mode 100755 index 000000000..ce2d7ff9e --- /dev/null +++ b/hw/xwin/winkeyhook.c @@ -0,0 +1,127 @@ +/* + *Copyright (C) 2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#include "win.h" + + +/* + * References to external symbols + */ + +extern HHOOK g_hhookKeyboardLL; +extern DWORD g_dwCurrentThreadID; + + +/* + * Function prototypes + */ + +static LRESULT CALLBACK +winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam); + + +/* + * KeyboardMessageHook + */ + +static LRESULT CALLBACK +winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam) +{ + BOOL fEatKeystroke = FALSE; + PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; + + /* Swallow keystrokes only for our app */ + if (iCode == HC_ACTION) + { + switch (wParam) + { + case WM_KEYDOWN: case WM_SYSKEYDOWN: + case WM_KEYUP: case WM_SYSKEYUP: + p = (PKBDLLHOOKSTRUCT) lParam; + + fEatKeystroke = + (p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0); + break; + } + } + + return (fEatKeystroke ? 1 : CallNextHookEx (NULL, iCode, wParam, + lParam)); +} + + +/* + * Attempt to install the keyboard hook, return FALSE if it was not installed + */ + +Bool +winInstallKeyboardHookLL () +{ + OSVERSIONINFO osvi = {0}; + + /* Get operating system version information */ + osvi.dwOSVersionInfoSize = sizeof (osvi); + GetVersionEx (&osvi); + + /* Branch on platform ID */ + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + /* Low-level is supported on NT 4.0 SP3+ only */ + /* TODO: Return FALSE on NT 4.0 with no SP, SP1, or SP2 */ + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Low-level hook is not supported on non-NT */ + return FALSE; + } + + /* Install the hook only once */ + if (!g_hhookKeyboardLL) + g_hhookKeyboardLL = SetWindowsHookEx (WH_KEYBOARD_LL, + winKeyboardMessageHookLL, + g_hInstance, + 0); + + return TRUE; +} + + +/* + * Remove the keyboard hook if it is installed + */ + +void +winRemoveKeyboardHookLL () +{ + if (g_hhookKeyboardLL) + UnhookWindowsHookEx (g_hhookKeyboardLL); + g_hhookKeyboardLL = NULL; +} diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c index c4660cd97..8c64ddbe7 100755 --- a/hw/xwin/winmultiwindowwndproc.c +++ b/hw/xwin/winmultiwindowwndproc.c @@ -40,8 +40,9 @@ * External global variables */ -extern Bool g_fCursor; -extern HICON g_hiconX; +extern Bool g_fCursor; +extern HICON g_hiconX; +extern Bool g_fKeyboardHookLL; /* @@ -59,7 +60,6 @@ static UINT_PTR g_uipMousePollingTimerID = 0; #define WIN_MULTIWINDOW_SHAPE YES - /* * ConstrainSize - Taken from TWM sources - Respects hints for sizing */ @@ -626,11 +626,18 @@ winTopLevelWindowProc (HWND hwnd, UINT message, break; winRestoreModeKeyStates (); + + /* Add the keyboard hook if possible */ + if (g_fKeyboardHookLL) + g_fKeyboardHookLL = winInstallKeyboardHookLL (); return 0; case WM_KILLFOCUS: /* Pop any pressed keys since we are losing keyboard focus */ winKeybdReleaseKeys (); + + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); return 0; case WM_SYSDEADCHAR: diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index 894e96b44..7ddd94373 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -52,6 +52,7 @@ Bool g_fCursor = TRUE; extern Bool g_fClipboard; extern HWND g_hDlgDepthChange; +extern Bool g_fKeyboardHookLL; /* @@ -913,6 +914,10 @@ winWindowProc (HWND hwnd, UINT message, /* Restore the state of all mode keys */ winRestoreModeKeyStates (); + + /* Add the keyboard hook if possible */ + if (g_fKeyboardHookLL) + g_fKeyboardHookLL = winInstallKeyboardHookLL (); return 0; case WM_KILLFOCUS: @@ -921,6 +926,9 @@ winWindowProc (HWND hwnd, UINT message, /* Release any pressed keys */ winKeybdReleaseKeys (); + + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); return 0; case WM_SYSKEYDOWN: