105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 2004 Harold L Hunt II All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of Harold L Hunt II 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from Harold L Hunt II. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Harold L Hunt II 2905b261ecSmrg */ 3005b261ecSmrg 3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3205b261ecSmrg#include <xwin-config.h> 3305b261ecSmrg#endif 3405b261ecSmrg#include "win.h" 3505b261ecSmrg 369ace9065Smrgstatic HHOOK g_hhookKeyboardLL = NULL; 3705b261ecSmrg 3805b261ecSmrg/* 3905b261ecSmrg * Function prototypes 4005b261ecSmrg */ 4105b261ecSmrg 4205b261ecSmrgstatic LRESULT CALLBACK 4335c4bbdfSmrgwinKeyboardMessageHookLL(int iCode, WPARAM wParam, LPARAM lParam); 4405b261ecSmrg 4505b261ecSmrg#ifndef LLKHF_EXTENDED 4635c4bbdfSmrg#define LLKHF_EXTENDED 0x00000001 4705b261ecSmrg#endif 4805b261ecSmrg#ifndef LLKHF_UP 4935c4bbdfSmrg#define LLKHF_UP 0x00000080 5005b261ecSmrg#endif 5105b261ecSmrg 5205b261ecSmrg/* 5305b261ecSmrg * KeyboardMessageHook 5405b261ecSmrg */ 5505b261ecSmrg 5605b261ecSmrgstatic LRESULT CALLBACK 5735c4bbdfSmrgwinKeyboardMessageHookLL(int iCode, WPARAM wParam, LPARAM lParam) 5805b261ecSmrg{ 5935c4bbdfSmrg BOOL fPassKeystroke = FALSE; 6035c4bbdfSmrg BOOL fPassAltTab = TRUE; 6135c4bbdfSmrg PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; 6235c4bbdfSmrg HWND hwnd = GetActiveWindow(); 6335c4bbdfSmrg 6435c4bbdfSmrg WindowPtr pWin = NULL; 6535c4bbdfSmrg winPrivWinPtr pWinPriv = NULL; 6635c4bbdfSmrg winPrivScreenPtr pScreenPriv = NULL; 6735c4bbdfSmrg winScreenInfo *pScreenInfo = NULL; 6835c4bbdfSmrg 6935c4bbdfSmrg /* Check if the Windows window property for our X window pointer is valid */ 7035c4bbdfSmrg if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) { 7135c4bbdfSmrg /* Get a pointer to our window privates */ 7235c4bbdfSmrg pWinPriv = winGetWindowPriv(pWin); 7335c4bbdfSmrg 7435c4bbdfSmrg /* Get pointers to our screen privates and screen info */ 7535c4bbdfSmrg pScreenPriv = pWinPriv->pScreenPriv; 7635c4bbdfSmrg pScreenInfo = pScreenPriv->pScreenInfo; 7735c4bbdfSmrg 7835c4bbdfSmrg if (pScreenInfo->fMultiWindow) 7935c4bbdfSmrg fPassAltTab = FALSE; 8005b261ecSmrg } 8105b261ecSmrg 8235c4bbdfSmrg /* Pass keystrokes on to our main message loop */ 8335c4bbdfSmrg if (iCode == HC_ACTION) { 8435c4bbdfSmrg winDebug("winKeyboardMessageHook: vkCode: %08x scanCode: %08x\n", 8535c4bbdfSmrg (unsigned int)p->vkCode, (unsigned int)p->scanCode); 8635c4bbdfSmrg 8735c4bbdfSmrg switch (wParam) { 8835c4bbdfSmrg case WM_KEYDOWN: 8935c4bbdfSmrg case WM_SYSKEYDOWN: 9035c4bbdfSmrg case WM_KEYUP: 9135c4bbdfSmrg case WM_SYSKEYUP: 9235c4bbdfSmrg fPassKeystroke = 9335c4bbdfSmrg (fPassAltTab && 9435c4bbdfSmrg (p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) 9535c4bbdfSmrg || (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN); 9635c4bbdfSmrg break; 9735c4bbdfSmrg } 9805b261ecSmrg } 9905b261ecSmrg 10035c4bbdfSmrg /* 10135c4bbdfSmrg * Pass message on to our main message loop. 10235c4bbdfSmrg * We process this immediately with SendMessage so that the keystroke 10335c4bbdfSmrg * appears in, hopefully, the correct order. 10435c4bbdfSmrg */ 10535c4bbdfSmrg if (fPassKeystroke) { 10635c4bbdfSmrg LPARAM lParamKey = 0x0; 10735c4bbdfSmrg 10835c4bbdfSmrg /* Construct the lParam from KBDLLHOOKSTRUCT */ 10935c4bbdfSmrg lParamKey = lParamKey | (0x0000FFFF & 0x00000001); /* Repeat count */ 11035c4bbdfSmrg lParamKey = lParamKey | (0x00FF0000 & (p->scanCode << 16)); 11135c4bbdfSmrg lParamKey = lParamKey 11235c4bbdfSmrg | (0x01000000 & ((p->flags & LLKHF_EXTENDED) << 23)); 11335c4bbdfSmrg lParamKey = lParamKey 11435c4bbdfSmrg | (0x20000000 & ((p->flags & LLKHF_ALTDOWN) << 24)); 11535c4bbdfSmrg lParamKey = lParamKey | (0x80000000 & ((p->flags & LLKHF_UP) << 24)); 11635c4bbdfSmrg 11735c4bbdfSmrg /* Send message to our main window that has the keyboard focus */ 11835c4bbdfSmrg PostMessage(hwnd, (UINT) wParam, (WPARAM) p->vkCode, lParamKey); 11935c4bbdfSmrg 12035c4bbdfSmrg return 1; 12105b261ecSmrg } 12205b261ecSmrg 12335c4bbdfSmrg /* Call next hook */ 12435c4bbdfSmrg return CallNextHookEx(NULL, iCode, wParam, lParam); 12505b261ecSmrg} 12605b261ecSmrg 12705b261ecSmrg/* 12805b261ecSmrg * Attempt to install the keyboard hook, return FALSE if it was not installed 12905b261ecSmrg */ 13005b261ecSmrg 13105b261ecSmrgBool 13235c4bbdfSmrgwinInstallKeyboardHookLL(void) 13305b261ecSmrg{ 13435c4bbdfSmrg /* Install the hook only once */ 13535c4bbdfSmrg if (!g_hhookKeyboardLL) 13635c4bbdfSmrg g_hhookKeyboardLL = SetWindowsHookEx(WH_KEYBOARD_LL, 13735c4bbdfSmrg winKeyboardMessageHookLL, 13835c4bbdfSmrg g_hInstance, 0); 13905b261ecSmrg 14035c4bbdfSmrg return TRUE; 14105b261ecSmrg} 14205b261ecSmrg 14305b261ecSmrg/* 14405b261ecSmrg * Remove the keyboard hook if it is installed 14505b261ecSmrg */ 14605b261ecSmrg 14705b261ecSmrgvoid 14835c4bbdfSmrgwinRemoveKeyboardHookLL(void) 14905b261ecSmrg{ 15035c4bbdfSmrg if (g_hhookKeyboardLL) 15135c4bbdfSmrg UnhookWindowsHookEx(g_hhookKeyboardLL); 15235c4bbdfSmrg g_hhookKeyboardLL = NULL; 15305b261ecSmrg} 154