Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | *Copyright (C) 2004 Harold L Hunt II All Rights Reserved. | |
3 | * | |
4 | *Permission is hereby granted, free of charge, to any person obtaining | |
5 | * a copy of this software and associated documentation files (the | |
6 | *"Software"), to deal in the Software without restriction, including | |
7 | *without limitation the rights to use, copy, modify, merge, publish, | |
8 | *distribute, sublicense, and/or sell copies of the Software, and to | |
9 | *permit persons to whom the Software is furnished to do so, subject to | |
10 | *the following conditions: | |
11 | * | |
12 | *The above copyright notice and this permission notice shall be | |
13 | *included in all copies or substantial portions of the Software. | |
14 | * | |
15 | *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
16 | *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
17 | *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
18 | *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR | |
19 | *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
20 | *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
21 | *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
22 | * | |
23 | *Except as contained in this notice, the name of Harold L Hunt II | |
24 | *shall not be used in advertising or otherwise to promote the sale, use | |
25 | *or other dealings in this Software without prior written authorization | |
26 | *from Harold L Hunt II. | |
27 | * | |
28 | * Authors: Harold L Hunt II | |
29 | */ | |
30 | ||
31 | #ifdef HAVE_XWIN_CONFIG_H | |
32 | #include <xwin-config.h> | |
33 | #endif | |
34 | #include "win.h" | |
35 | ||
36 | static HHOOK g_hhookKeyboardLL = NULL; | |
37 | ||
38 | /* | |
39 | * Function prototypes | |
40 | */ | |
41 | ||
42 | static LRESULT CALLBACK | |
43 | winKeyboardMessageHookLL(int iCode, WPARAM wParam, LPARAM lParam); | |
44 | ||
45 | #ifndef LLKHF_EXTENDED | |
46 | #define LLKHF_EXTENDED 0x00000001 | |
47 | #endif | |
48 | #ifndef LLKHF_UP | |
49 | #define LLKHF_UP 0x00000080 | |
50 | #endif | |
51 | ||
52 | /* | |
53 | * KeyboardMessageHook | |
54 | */ | |
55 | ||
56 | static LRESULT CALLBACK | |
57 | winKeyboardMessageHookLL(int iCode, WPARAM wParam, LPARAM lParam) | |
58 | { | |
59 | BOOL fPassKeystroke = FALSE; | |
60 | BOOL fPassAltTab = TRUE; | |
61 | PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; | |
62 | HWND hwnd = GetActiveWindow(); | |
63 | ||
64 | #ifdef XWIN_MULTIWINDOW | |
65 | WindowPtr pWin = NULL; | |
66 | winPrivWinPtr pWinPriv = NULL; | |
67 | winPrivScreenPtr pScreenPriv = NULL; | |
68 | winScreenInfo *pScreenInfo = NULL; | |
69 | ||
70 | /* Check if the Windows window property for our X window pointer is valid */ | |
71 | if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) { | |
72 | /* Get a pointer to our window privates */ | |
73 | pWinPriv = winGetWindowPriv(pWin); | |
74 | ||
75 | /* Get pointers to our screen privates and screen info */ | |
76 | pScreenPriv = pWinPriv->pScreenPriv; | |
77 | pScreenInfo = pScreenPriv->pScreenInfo; | |
78 | ||
79 | if (pScreenInfo->fMultiWindow) | |
80 | fPassAltTab = FALSE; | |
81 | } | |
82 | #endif | |
83 | ||
84 | /* Pass keystrokes on to our main message loop */ | |
85 | if (iCode == HC_ACTION) { | |
86 | winDebug("winKeyboardMessageHook: vkCode: %08x scanCode: %08x\n", | |
87 | p->vkCode, p->scanCode); | |
88 | ||
89 | switch (wParam) { | |
90 | case WM_KEYDOWN: | |
91 | case WM_SYSKEYDOWN: | |
92 | case WM_KEYUP: | |
93 | case WM_SYSKEYUP: | |
94 | fPassKeystroke = | |
95 | (fPassAltTab && | |
96 | (p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) | |
97 | || (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN); | |
98 | break; | |
99 | } | |
100 | } | |
101 | ||
102 | /* | |
103 | * Pass message on to our main message loop. | |
104 | * We process this immediately with SendMessage so that the keystroke | |
105 | * appears in, hopefully, the correct order. | |
106 | */ | |
107 | if (fPassKeystroke) { | |
108 | LPARAM lParamKey = 0x0; | |
109 | ||
110 | /* Construct the lParam from KBDLLHOOKSTRUCT */ | |
111 | lParamKey = lParamKey | (0x0000FFFF & 0x00000001); /* Repeat count */ | |
112 | lParamKey = lParamKey | (0x00FF0000 & (p->scanCode << 16)); | |
113 | lParamKey = lParamKey | |
114 | | (0x01000000 & ((p->flags & LLKHF_EXTENDED) << 23)); | |
115 | lParamKey = lParamKey | |
116 | | (0x20000000 & ((p->flags & LLKHF_ALTDOWN) << 24)); | |
117 | lParamKey = lParamKey | (0x80000000 & ((p->flags & LLKHF_UP) << 24)); | |
118 | ||
119 | /* Send message to our main window that has the keyboard focus */ | |
120 | PostMessage(hwnd, (UINT) wParam, (WPARAM) p->vkCode, lParamKey); | |
121 | ||
122 | return 1; | |
123 | } | |
124 | ||
125 | /* Call next hook */ | |
126 | return CallNextHookEx(NULL, iCode, wParam, lParam); | |
127 | } | |
128 | ||
129 | /* | |
130 | * Attempt to install the keyboard hook, return FALSE if it was not installed | |
131 | */ | |
132 | ||
133 | Bool | |
134 | winInstallKeyboardHookLL(void) | |
135 | { | |
136 | /* Install the hook only once */ | |
137 | if (!g_hhookKeyboardLL) | |
138 | g_hhookKeyboardLL = SetWindowsHookEx(WH_KEYBOARD_LL, | |
139 | winKeyboardMessageHookLL, | |
140 | g_hInstance, 0); | |
141 | ||
142 | return TRUE; | |
143 | } | |
144 | ||
145 | /* | |
146 | * Remove the keyboard hook if it is installed | |
147 | */ | |
148 | ||
149 | void | |
150 | winRemoveKeyboardHookLL(void) | |
151 | { | |
152 | if (g_hhookKeyboardLL) | |
153 | UnhookWindowsHookEx(g_hhookKeyboardLL); | |
154 | g_hhookKeyboardLL = NULL; | |
155 | } |