1 /*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2012-2016 Symless Ltd.
4 * Copyright (C) 2003 Chris Schoeneman
5 *
6 * This package is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * found in the file LICENSE that should have accompanied this file.
9 *
10 * This package is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "platform/MSWindowsKeyState.h"
20
21 #include "platform/MSWindowsDesks.h"
22 #include "mt/Thread.h"
23 #include "arch/win32/ArchMiscWindows.h"
24 #include "base/FunctionJob.h"
25 #include "base/Log.h"
26 #include "base/String.h"
27 #include "base/IEventQueue.h"
28 #include "base/TMethodEventJob.h"
29
30 // extended mouse buttons
31 #if !defined(VK_XBUTTON1)
32 #define VK_XBUTTON1 0x05
33 #define VK_XBUTTON2 0x06
34 #endif
35
36 //
37 // MSWindowsKeyState
38 //
39
40 // map virtual keys to synergy key enumeration
41 const KeyID MSWindowsKeyState::s_virtualKey[] =
42 {
43 /* 0x000 */ { kKeyNone }, // reserved
44 /* 0x001 */ { kKeyNone }, // VK_LBUTTON
45 /* 0x002 */ { kKeyNone }, // VK_RBUTTON
46 /* 0x003 */ { kKeyNone }, // VK_CANCEL
47 /* 0x004 */ { kKeyNone }, // VK_MBUTTON
48 /* 0x005 */ { kKeyNone }, // VK_XBUTTON1
49 /* 0x006 */ { kKeyNone }, // VK_XBUTTON2
50 /* 0x007 */ { kKeyNone }, // undefined
51 /* 0x008 */ { kKeyBackSpace }, // VK_BACK
52 /* 0x009 */ { kKeyTab }, // VK_TAB
53 /* 0x00a */ { kKeyNone }, // undefined
54 /* 0x00b */ { kKeyNone }, // undefined
55 /* 0x00c */ { kKeyClear }, // VK_CLEAR
56 /* 0x00d */ { kKeyReturn }, // VK_RETURN
57 /* 0x00e */ { kKeyNone }, // undefined
58 /* 0x00f */ { kKeyNone }, // undefined
59 /* 0x010 */ { kKeyShift_L }, // VK_SHIFT
60 /* 0x011 */ { kKeyControl_L }, // VK_CONTROL
61 /* 0x012 */ { kKeyAlt_L }, // VK_MENU
62 /* 0x013 */ { kKeyPause }, // VK_PAUSE
63 /* 0x014 */ { kKeyCapsLock }, // VK_CAPITAL
64 /* 0x015 */ { kKeyKana }, // VK_HANGUL, VK_KANA
65 /* 0x016 */ { kKeyNone }, // undefined
66 /* 0x017 */ { kKeyNone }, // VK_JUNJA
67 /* 0x018 */ { kKeyNone }, // VK_FINAL
68 /* 0x019 */ { kKeyKanzi }, // VK_HANJA, VK_KANJI
69 /* 0x01a */ { kKeyNone }, // undefined
70 /* 0x01b */ { kKeyEscape }, // VK_ESCAPE
71 /* 0x01c */ { kKeyHenkan }, // VK_CONVERT
72 /* 0x01d */ { kKeyNone }, // VK_NONCONVERT
73 /* 0x01e */ { kKeyNone }, // VK_ACCEPT
74 /* 0x01f */ { kKeyNone }, // VK_MODECHANGE
75 /* 0x020 */ { kKeyNone }, // VK_SPACE
76 /* 0x021 */ { kKeyKP_PageUp }, // VK_PRIOR
77 /* 0x022 */ { kKeyKP_PageDown },// VK_NEXT
78 /* 0x023 */ { kKeyKP_End }, // VK_END
79 /* 0x024 */ { kKeyKP_Home }, // VK_HOME
80 /* 0x025 */ { kKeyKP_Left }, // VK_LEFT
81 /* 0x026 */ { kKeyKP_Up }, // VK_UP
82 /* 0x027 */ { kKeyKP_Right }, // VK_RIGHT
83 /* 0x028 */ { kKeyKP_Down }, // VK_DOWN
84 /* 0x029 */ { kKeySelect }, // VK_SELECT
85 /* 0x02a */ { kKeyNone }, // VK_PRINT
86 /* 0x02b */ { kKeyExecute }, // VK_EXECUTE
87 /* 0x02c */ { kKeyPrint }, // VK_SNAPSHOT
88 /* 0x02d */ { kKeyKP_Insert }, // VK_INSERT
89 /* 0x02e */ { kKeyKP_Delete }, // VK_DELETE
90 /* 0x02f */ { kKeyHelp }, // VK_HELP
91 /* 0x030 */ { kKeyNone }, // VK_0
92 /* 0x031 */ { kKeyNone }, // VK_1
93 /* 0x032 */ { kKeyNone }, // VK_2
94 /* 0x033 */ { kKeyNone }, // VK_3
95 /* 0x034 */ { kKeyNone }, // VK_4
96 /* 0x035 */ { kKeyNone }, // VK_5
97 /* 0x036 */ { kKeyNone }, // VK_6
98 /* 0x037 */ { kKeyNone }, // VK_7
99 /* 0x038 */ { kKeyNone }, // VK_8
100 /* 0x039 */ { kKeyNone }, // VK_9
101 /* 0x03a */ { kKeyNone }, // undefined
102 /* 0x03b */ { kKeyNone }, // undefined
103 /* 0x03c */ { kKeyNone }, // undefined
104 /* 0x03d */ { kKeyNone }, // undefined
105 /* 0x03e */ { kKeyNone }, // undefined
106 /* 0x03f */ { kKeyNone }, // undefined
107 /* 0x040 */ { kKeyNone }, // undefined
108 /* 0x041 */ { kKeyNone }, // VK_A
109 /* 0x042 */ { kKeyNone }, // VK_B
110 /* 0x043 */ { kKeyNone }, // VK_C
111 /* 0x044 */ { kKeyNone }, // VK_D
112 /* 0x045 */ { kKeyNone }, // VK_E
113 /* 0x046 */ { kKeyNone }, // VK_F
114 /* 0x047 */ { kKeyNone }, // VK_G
115 /* 0x048 */ { kKeyNone }, // VK_H
116 /* 0x049 */ { kKeyNone }, // VK_I
117 /* 0x04a */ { kKeyNone }, // VK_J
118 /* 0x04b */ { kKeyNone }, // VK_K
119 /* 0x04c */ { kKeyNone }, // VK_L
120 /* 0x04d */ { kKeyNone }, // VK_M
121 /* 0x04e */ { kKeyNone }, // VK_N
122 /* 0x04f */ { kKeyNone }, // VK_O
123 /* 0x050 */ { kKeyNone }, // VK_P
124 /* 0x051 */ { kKeyNone }, // VK_Q
125 /* 0x052 */ { kKeyNone }, // VK_R
126 /* 0x053 */ { kKeyNone }, // VK_S
127 /* 0x054 */ { kKeyNone }, // VK_T
128 /* 0x055 */ { kKeyNone }, // VK_U
129 /* 0x056 */ { kKeyNone }, // VK_V
130 /* 0x057 */ { kKeyNone }, // VK_W
131 /* 0x058 */ { kKeyNone }, // VK_X
132 /* 0x059 */ { kKeyNone }, // VK_Y
133 /* 0x05a */ { kKeyNone }, // VK_Z
134 /* 0x05b */ { kKeySuper_L }, // VK_LWIN
135 /* 0x05c */ { kKeySuper_R }, // VK_RWIN
136 /* 0x05d */ { kKeyMenu }, // VK_APPS
137 /* 0x05e */ { kKeyNone }, // undefined
138 /* 0x05f */ { kKeySleep }, // VK_SLEEP
139 /* 0x060 */ { kKeyKP_0 }, // VK_NUMPAD0
140 /* 0x061 */ { kKeyKP_1 }, // VK_NUMPAD1
141 /* 0x062 */ { kKeyKP_2 }, // VK_NUMPAD2
142 /* 0x063 */ { kKeyKP_3 }, // VK_NUMPAD3
143 /* 0x064 */ { kKeyKP_4 }, // VK_NUMPAD4
144 /* 0x065 */ { kKeyKP_5 }, // VK_NUMPAD5
145 /* 0x066 */ { kKeyKP_6 }, // VK_NUMPAD6
146 /* 0x067 */ { kKeyKP_7 }, // VK_NUMPAD7
147 /* 0x068 */ { kKeyKP_8 }, // VK_NUMPAD8
148 /* 0x069 */ { kKeyKP_9 }, // VK_NUMPAD9
149 /* 0x06a */ { kKeyKP_Multiply },// VK_MULTIPLY
150 /* 0x06b */ { kKeyKP_Add }, // VK_ADD
151 /* 0x06c */ { kKeyKP_Separator },// VK_SEPARATOR
152 /* 0x06d */ { kKeyKP_Subtract },// VK_SUBTRACT
153 /* 0x06e */ { kKeyKP_Decimal }, // VK_DECIMAL
154 /* 0x06f */ { kKeyNone }, // VK_DIVIDE
155 /* 0x070 */ { kKeyF1 }, // VK_F1
156 /* 0x071 */ { kKeyF2 }, // VK_F2
157 /* 0x072 */ { kKeyF3 }, // VK_F3
158 /* 0x073 */ { kKeyF4 }, // VK_F4
159 /* 0x074 */ { kKeyF5 }, // VK_F5
160 /* 0x075 */ { kKeyF6 }, // VK_F6
161 /* 0x076 */ { kKeyF7 }, // VK_F7
162 /* 0x077 */ { kKeyF8 }, // VK_F8
163 /* 0x078 */ { kKeyF9 }, // VK_F9
164 /* 0x079 */ { kKeyF10 }, // VK_F10
165 /* 0x07a */ { kKeyF11 }, // VK_F11
166 /* 0x07b */ { kKeyF12 }, // VK_F12
167 /* 0x07c */ { kKeyF13 }, // VK_F13
168 /* 0x07d */ { kKeyF14 }, // VK_F14
169 /* 0x07e */ { kKeyF15 }, // VK_F15
170 /* 0x07f */ { kKeyF16 }, // VK_F16
171 /* 0x080 */ { kKeyF17 }, // VK_F17
172 /* 0x081 */ { kKeyF18 }, // VK_F18
173 /* 0x082 */ { kKeyF19 }, // VK_F19
174 /* 0x083 */ { kKeyF20 }, // VK_F20
175 /* 0x084 */ { kKeyF21 }, // VK_F21
176 /* 0x085 */ { kKeyF22 }, // VK_F22
177 /* 0x086 */ { kKeyF23 }, // VK_F23
178 /* 0x087 */ { kKeyF24 }, // VK_F24
179 /* 0x088 */ { kKeyNone }, // unassigned
180 /* 0x089 */ { kKeyNone }, // unassigned
181 /* 0x08a */ { kKeyNone }, // unassigned
182 /* 0x08b */ { kKeyNone }, // unassigned
183 /* 0x08c */ { kKeyNone }, // unassigned
184 /* 0x08d */ { kKeyNone }, // unassigned
185 /* 0x08e */ { kKeyNone }, // unassigned
186 /* 0x08f */ { kKeyNone }, // unassigned
187 /* 0x090 */ { kKeyNumLock }, // VK_NUMLOCK
188 /* 0x091 */ { kKeyScrollLock }, // VK_SCROLL
189 /* 0x092 */ { kKeyNone }, // unassigned
190 /* 0x093 */ { kKeyNone }, // unassigned
191 /* 0x094 */ { kKeyNone }, // unassigned
192 /* 0x095 */ { kKeyNone }, // unassigned
193 /* 0x096 */ { kKeyNone }, // unassigned
194 /* 0x097 */ { kKeyNone }, // unassigned
195 /* 0x098 */ { kKeyNone }, // unassigned
196 /* 0x099 */ { kKeyNone }, // unassigned
197 /* 0x09a */ { kKeyNone }, // unassigned
198 /* 0x09b */ { kKeyNone }, // unassigned
199 /* 0x09c */ { kKeyNone }, // unassigned
200 /* 0x09d */ { kKeyNone }, // unassigned
201 /* 0x09e */ { kKeyNone }, // unassigned
202 /* 0x09f */ { kKeyNone }, // unassigned
203 /* 0x0a0 */ { kKeyShift_L }, // VK_LSHIFT
204 /* 0x0a1 */ { kKeyShift_R }, // VK_RSHIFT
205 /* 0x0a2 */ { kKeyControl_L }, // VK_LCONTROL
206 /* 0x0a3 */ { kKeyControl_R }, // VK_RCONTROL
207 /* 0x0a4 */ { kKeyAlt_L }, // VK_LMENU
208 /* 0x0a5 */ { kKeyAlt_R }, // VK_RMENU
209 /* 0x0a6 */ { kKeyNone }, // VK_BROWSER_BACK
210 /* 0x0a7 */ { kKeyNone }, // VK_BROWSER_FORWARD
211 /* 0x0a8 */ { kKeyNone }, // VK_BROWSER_REFRESH
212 /* 0x0a9 */ { kKeyNone }, // VK_BROWSER_STOP
213 /* 0x0aa */ { kKeyNone }, // VK_BROWSER_SEARCH
214 /* 0x0ab */ { kKeyNone }, // VK_BROWSER_FAVORITES
215 /* 0x0ac */ { kKeyNone }, // VK_BROWSER_HOME
216 /* 0x0ad */ { kKeyNone }, // VK_VOLUME_MUTE
217 /* 0x0ae */ { kKeyNone }, // VK_VOLUME_DOWN
218 /* 0x0af */ { kKeyNone }, // VK_VOLUME_UP
219 /* 0x0b0 */ { kKeyNone }, // VK_MEDIA_NEXT_TRACK
220 /* 0x0b1 */ { kKeyNone }, // VK_MEDIA_PREV_TRACK
221 /* 0x0b2 */ { kKeyNone }, // VK_MEDIA_STOP
222 /* 0x0b3 */ { kKeyNone }, // VK_MEDIA_PLAY_PAUSE
223 /* 0x0b4 */ { kKeyNone }, // VK_LAUNCH_MAIL
224 /* 0x0b5 */ { kKeyNone }, // VK_LAUNCH_MEDIA_SELECT
225 /* 0x0b6 */ { kKeyNone }, // VK_LAUNCH_APP1
226 /* 0x0b7 */ { kKeyNone }, // VK_LAUNCH_APP2
227 /* 0x0b8 */ { kKeyNone }, // unassigned
228 /* 0x0b9 */ { kKeyNone }, // unassigned
229 /* 0x0ba */ { kKeyNone }, // OEM specific
230 /* 0x0bb */ { kKeyNone }, // OEM specific
231 /* 0x0bc */ { kKeyNone }, // OEM specific
232 /* 0x0bd */ { kKeyNone }, // OEM specific
233 /* 0x0be */ { kKeyNone }, // OEM specific
234 /* 0x0bf */ { kKeyNone }, // OEM specific
235 /* 0x0c0 */ { kKeyNone }, // OEM specific
236 /* 0x0c1 */ { kKeyNone }, // unassigned
237 /* 0x0c2 */ { kKeyNone }, // unassigned
238 /* 0x0c3 */ { kKeyNone }, // unassigned
239 /* 0x0c4 */ { kKeyNone }, // unassigned
240 /* 0x0c5 */ { kKeyNone }, // unassigned
241 /* 0x0c6 */ { kKeyNone }, // unassigned
242 /* 0x0c7 */ { kKeyNone }, // unassigned
243 /* 0x0c8 */ { kKeyNone }, // unassigned
244 /* 0x0c9 */ { kKeyNone }, // unassigned
245 /* 0x0ca */ { kKeyNone }, // unassigned
246 /* 0x0cb */ { kKeyNone }, // unassigned
247 /* 0x0cc */ { kKeyNone }, // unassigned
248 /* 0x0cd */ { kKeyNone }, // unassigned
249 /* 0x0ce */ { kKeyNone }, // unassigned
250 /* 0x0cf */ { kKeyNone }, // unassigned
251 /* 0x0d0 */ { kKeyNone }, // unassigned
252 /* 0x0d1 */ { kKeyNone }, // unassigned
253 /* 0x0d2 */ { kKeyNone }, // unassigned
254 /* 0x0d3 */ { kKeyNone }, // unassigned
255 /* 0x0d4 */ { kKeyNone }, // unassigned
256 /* 0x0d5 */ { kKeyNone }, // unassigned
257 /* 0x0d6 */ { kKeyNone }, // unassigned
258 /* 0x0d7 */ { kKeyNone }, // unassigned
259 /* 0x0d8 */ { kKeyNone }, // unassigned
260 /* 0x0d9 */ { kKeyNone }, // unassigned
261 /* 0x0da */ { kKeyNone }, // unassigned
262 /* 0x0db */ { kKeyNone }, // OEM specific
263 /* 0x0dc */ { kKeyNone }, // OEM specific
264 /* 0x0dd */ { kKeyNone }, // OEM specific
265 /* 0x0de */ { kKeyNone }, // OEM specific
266 /* 0x0df */ { kKeyNone }, // OEM specific
267 /* 0x0e0 */ { kKeyNone }, // OEM specific
268 /* 0x0e1 */ { kKeyNone }, // OEM specific
269 /* 0x0e2 */ { kKeyNone }, // OEM specific
270 /* 0x0e3 */ { kKeyNone }, // OEM specific
271 /* 0x0e4 */ { kKeyNone }, // OEM specific
272 /* 0x0e5 */ { kKeyNone }, // unassigned
273 /* 0x0e6 */ { kKeyNone }, // OEM specific
274 /* 0x0e7 */ { kKeyNone }, // unassigned
275 /* 0x0e8 */ { kKeyNone }, // unassigned
276 /* 0x0e9 */ { kKeyNone }, // OEM specific
277 /* 0x0ea */ { kKeyNone }, // OEM specific
278 /* 0x0eb */ { kKeyNone }, // OEM specific
279 /* 0x0ec */ { kKeyNone }, // OEM specific
280 /* 0x0ed */ { kKeyNone }, // OEM specific
281 /* 0x0ee */ { kKeyNone }, // OEM specific
282 /* 0x0ef */ { kKeyNone }, // OEM specific
283 /* 0x0f0 */ { kKeyNone }, // OEM specific
284 /* 0x0f1 */ { kKeyNone }, // OEM specific
285 /* 0x0f2 */ { kKeyHiraganaKatakana }, // VK_OEM_COPY
286 /* 0x0f3 */ { kKeyZenkaku }, // VK_OEM_AUTO
287 /* 0x0f4 */ { kKeyZenkaku }, // VK_OEM_ENLW
288 /* 0x0f5 */ { kKeyNone }, // OEM specific
289 /* 0x0f6 */ { kKeyNone }, // VK_ATTN
290 /* 0x0f7 */ { kKeyNone }, // VK_CRSEL
291 /* 0x0f8 */ { kKeyNone }, // VK_EXSEL
292 /* 0x0f9 */ { kKeyNone }, // VK_EREOF
293 /* 0x0fa */ { kKeyNone }, // VK_PLAY
294 /* 0x0fb */ { kKeyNone }, // VK_ZOOM
295 /* 0x0fc */ { kKeyNone }, // reserved
296 /* 0x0fd */ { kKeyNone }, // VK_PA1
297 /* 0x0fe */ { kKeyNone }, // VK_OEM_CLEAR
298 /* 0x0ff */ { kKeyNone }, // reserved
299
300 /* 0x100 */ { kKeyNone }, // reserved
301 /* 0x101 */ { kKeyNone }, // VK_LBUTTON
302 /* 0x102 */ { kKeyNone }, // VK_RBUTTON
303 /* 0x103 */ { kKeyBreak }, // VK_CANCEL
304 /* 0x104 */ { kKeyNone }, // VK_MBUTTON
305 /* 0x105 */ { kKeyNone }, // VK_XBUTTON1
306 /* 0x106 */ { kKeyNone }, // VK_XBUTTON2
307 /* 0x107 */ { kKeyNone }, // undefined
308 /* 0x108 */ { kKeyNone }, // VK_BACK
309 /* 0x109 */ { kKeyNone }, // VK_TAB
310 /* 0x10a */ { kKeyNone }, // undefined
311 /* 0x10b */ { kKeyNone }, // undefined
312 /* 0x10c */ { kKeyClear }, // VK_CLEAR
313 /* 0x10d */ { kKeyKP_Enter }, // VK_RETURN
314 /* 0x10e */ { kKeyNone }, // undefined
315 /* 0x10f */ { kKeyNone }, // undefined
316 /* 0x110 */ { kKeyShift_R }, // VK_SHIFT
317 /* 0x111 */ { kKeyControl_R }, // VK_CONTROL
318 /* 0x112 */ { kKeyAlt_R }, // VK_MENU
319 /* 0x113 */ { kKeyNone }, // VK_PAUSE
320 /* 0x114 */ { kKeyNone }, // VK_CAPITAL
321 /* 0x115 */ { kKeyHangul }, // VK_HANGUL
322 /* 0x116 */ { kKeyNone }, // undefined
323 /* 0x117 */ { kKeyNone }, // VK_JUNJA
324 /* 0x118 */ { kKeyNone }, // VK_FINAL
325 /* 0x119 */ { kKeyHanja }, // VK_HANJA
326 /* 0x11a */ { kKeyNone }, // undefined
327 /* 0x11b */ { kKeyNone }, // VK_ESCAPE
328 /* 0x11c */ { kKeyNone }, // VK_CONVERT
329 /* 0x11d */ { kKeyNone }, // VK_NONCONVERT
330 /* 0x11e */ { kKeyNone }, // VK_ACCEPT
331 /* 0x11f */ { kKeyNone }, // VK_MODECHANGE
332 /* 0x120 */ { kKeyNone }, // VK_SPACE
333 /* 0x121 */ { kKeyPageUp }, // VK_PRIOR
334 /* 0x122 */ { kKeyPageDown }, // VK_NEXT
335 /* 0x123 */ { kKeyEnd }, // VK_END
336 /* 0x124 */ { kKeyHome }, // VK_HOME
337 /* 0x125 */ { kKeyLeft }, // VK_LEFT
338 /* 0x126 */ { kKeyUp }, // VK_UP
339 /* 0x127 */ { kKeyRight }, // VK_RIGHT
340 /* 0x128 */ { kKeyDown }, // VK_DOWN
341 /* 0x129 */ { kKeySelect }, // VK_SELECT
342 /* 0x12a */ { kKeyNone }, // VK_PRINT
343 /* 0x12b */ { kKeyExecute }, // VK_EXECUTE
344 /* 0x12c */ { kKeyPrint }, // VK_SNAPSHOT
345 /* 0x12d */ { kKeyInsert }, // VK_INSERT
346 /* 0x12e */ { kKeyDelete }, // VK_DELETE
347 /* 0x12f */ { kKeyHelp }, // VK_HELP
348 /* 0x130 */ { kKeyNone }, // VK_0
349 /* 0x131 */ { kKeyNone }, // VK_1
350 /* 0x132 */ { kKeyNone }, // VK_2
351 /* 0x133 */ { kKeyNone }, // VK_3
352 /* 0x134 */ { kKeyNone }, // VK_4
353 /* 0x135 */ { kKeyNone }, // VK_5
354 /* 0x136 */ { kKeyNone }, // VK_6
355 /* 0x137 */ { kKeyNone }, // VK_7
356 /* 0x138 */ { kKeyNone }, // VK_8
357 /* 0x139 */ { kKeyNone }, // VK_9
358 /* 0x13a */ { kKeyNone }, // undefined
359 /* 0x13b */ { kKeyNone }, // undefined
360 /* 0x13c */ { kKeyNone }, // undefined
361 /* 0x13d */ { kKeyNone }, // undefined
362 /* 0x13e */ { kKeyNone }, // undefined
363 /* 0x13f */ { kKeyNone }, // undefined
364 /* 0x140 */ { kKeyNone }, // undefined
365 /* 0x141 */ { kKeyNone }, // VK_A
366 /* 0x142 */ { kKeyNone }, // VK_B
367 /* 0x143 */ { kKeyNone }, // VK_C
368 /* 0x144 */ { kKeyNone }, // VK_D
369 /* 0x145 */ { kKeyNone }, // VK_E
370 /* 0x146 */ { kKeyNone }, // VK_F
371 /* 0x147 */ { kKeyNone }, // VK_G
372 /* 0x148 */ { kKeyNone }, // VK_H
373 /* 0x149 */ { kKeyNone }, // VK_I
374 /* 0x14a */ { kKeyNone }, // VK_J
375 /* 0x14b */ { kKeyNone }, // VK_K
376 /* 0x14c */ { kKeyNone }, // VK_L
377 /* 0x14d */ { kKeyNone }, // VK_M
378 /* 0x14e */ { kKeyNone }, // VK_N
379 /* 0x14f */ { kKeyNone }, // VK_O
380 /* 0x150 */ { kKeyNone }, // VK_P
381 /* 0x151 */ { kKeyNone }, // VK_Q
382 /* 0x152 */ { kKeyNone }, // VK_R
383 /* 0x153 */ { kKeyNone }, // VK_S
384 /* 0x154 */ { kKeyNone }, // VK_T
385 /* 0x155 */ { kKeyNone }, // VK_U
386 /* 0x156 */ { kKeyNone }, // VK_V
387 /* 0x157 */ { kKeyNone }, // VK_W
388 /* 0x158 */ { kKeyNone }, // VK_X
389 /* 0x159 */ { kKeyNone }, // VK_Y
390 /* 0x15a */ { kKeyNone }, // VK_Z
391 /* 0x15b */ { kKeySuper_L }, // VK_LWIN
392 /* 0x15c */ { kKeySuper_R }, // VK_RWIN
393 /* 0x15d */ { kKeyMenu }, // VK_APPS
394 /* 0x15e */ { kKeyNone }, // undefined
395 /* 0x15f */ { kKeyNone }, // VK_SLEEP
396 /* 0x160 */ { kKeyNone }, // VK_NUMPAD0
397 /* 0x161 */ { kKeyNone }, // VK_NUMPAD1
398 /* 0x162 */ { kKeyNone }, // VK_NUMPAD2
399 /* 0x163 */ { kKeyNone }, // VK_NUMPAD3
400 /* 0x164 */ { kKeyNone }, // VK_NUMPAD4
401 /* 0x165 */ { kKeyNone }, // VK_NUMPAD5
402 /* 0x166 */ { kKeyNone }, // VK_NUMPAD6
403 /* 0x167 */ { kKeyNone }, // VK_NUMPAD7
404 /* 0x168 */ { kKeyNone }, // VK_NUMPAD8
405 /* 0x169 */ { kKeyNone }, // VK_NUMPAD9
406 /* 0x16a */ { kKeyNone }, // VK_MULTIPLY
407 /* 0x16b */ { kKeyNone }, // VK_ADD
408 /* 0x16c */ { kKeyKP_Separator },// VK_SEPARATOR
409 /* 0x16d */ { kKeyNone }, // VK_SUBTRACT
410 /* 0x16e */ { kKeyNone }, // VK_DECIMAL
411 /* 0x16f */ { kKeyKP_Divide }, // VK_DIVIDE
412 /* 0x170 */ { kKeyNone }, // VK_F1
413 /* 0x171 */ { kKeyNone }, // VK_F2
414 /* 0x172 */ { kKeyNone }, // VK_F3
415 /* 0x173 */ { kKeyNone }, // VK_F4
416 /* 0x174 */ { kKeyNone }, // VK_F5
417 /* 0x175 */ { kKeyNone }, // VK_F6
418 /* 0x176 */ { kKeyNone }, // VK_F7
419 /* 0x177 */ { kKeyNone }, // VK_F8
420 /* 0x178 */ { kKeyNone }, // VK_F9
421 /* 0x179 */ { kKeyNone }, // VK_F10
422 /* 0x17a */ { kKeyNone }, // VK_F11
423 /* 0x17b */ { kKeyNone }, // VK_F12
424 /* 0x17c */ { kKeyF13 }, // VK_F13
425 /* 0x17d */ { kKeyF14 }, // VK_F14
426 /* 0x17e */ { kKeyF15 }, // VK_F15
427 /* 0x17f */ { kKeyF16 }, // VK_F16
428 /* 0x180 */ { kKeyF17 }, // VK_F17
429 /* 0x181 */ { kKeyF18 }, // VK_F18
430 /* 0x182 */ { kKeyF19 }, // VK_F19
431 /* 0x183 */ { kKeyF20 }, // VK_F20
432 /* 0x184 */ { kKeyF21 }, // VK_F21
433 /* 0x185 */ { kKeyF22 }, // VK_F22
434 /* 0x186 */ { kKeyF23 }, // VK_F23
435 /* 0x187 */ { kKeyF24 }, // VK_F24
436 /* 0x188 */ { kKeyNone }, // unassigned
437 /* 0x189 */ { kKeyNone }, // unassigned
438 /* 0x18a */ { kKeyNone }, // unassigned
439 /* 0x18b */ { kKeyNone }, // unassigned
440 /* 0x18c */ { kKeyNone }, // unassigned
441 /* 0x18d */ { kKeyNone }, // unassigned
442 /* 0x18e */ { kKeyNone }, // unassigned
443 /* 0x18f */ { kKeyNone }, // unassigned
444 /* 0x190 */ { kKeyNumLock }, // VK_NUMLOCK
445 /* 0x191 */ { kKeyNone }, // VK_SCROLL
446 /* 0x192 */ { kKeyNone }, // unassigned
447 /* 0x193 */ { kKeyNone }, // unassigned
448 /* 0x194 */ { kKeyNone }, // unassigned
449 /* 0x195 */ { kKeyNone }, // unassigned
450 /* 0x196 */ { kKeyNone }, // unassigned
451 /* 0x197 */ { kKeyNone }, // unassigned
452 /* 0x198 */ { kKeyNone }, // unassigned
453 /* 0x199 */ { kKeyNone }, // unassigned
454 /* 0x19a */ { kKeyNone }, // unassigned
455 /* 0x19b */ { kKeyNone }, // unassigned
456 /* 0x19c */ { kKeyNone }, // unassigned
457 /* 0x19d */ { kKeyNone }, // unassigned
458 /* 0x19e */ { kKeyNone }, // unassigned
459 /* 0x19f */ { kKeyNone }, // unassigned
460 /* 0x1a0 */ { kKeyShift_L }, // VK_LSHIFT
461 /* 0x1a1 */ { kKeyShift_R }, // VK_RSHIFT
462 /* 0x1a2 */ { kKeyControl_L }, // VK_LCONTROL
463 /* 0x1a3 */ { kKeyControl_R }, // VK_RCONTROL
464 /* 0x1a4 */ { kKeyAlt_L }, // VK_LMENU
465 /* 0x1a5 */ { kKeyAlt_R }, // VK_RMENU
466 /* 0x1a6 */ { kKeyWWWBack }, // VK_BROWSER_BACK
467 /* 0x1a7 */ { kKeyWWWForward }, // VK_BROWSER_FORWARD
468 /* 0x1a8 */ { kKeyWWWRefresh }, // VK_BROWSER_REFRESH
469 /* 0x1a9 */ { kKeyWWWStop }, // VK_BROWSER_STOP
470 /* 0x1aa */ { kKeyWWWSearch }, // VK_BROWSER_SEARCH
471 /* 0x1ab */ { kKeyWWWFavorites },// VK_BROWSER_FAVORITES
472 /* 0x1ac */ { kKeyWWWHome }, // VK_BROWSER_HOME
473 /* 0x1ad */ { kKeyAudioMute }, // VK_VOLUME_MUTE
474 /* 0x1ae */ { kKeyAudioDown }, // VK_VOLUME_DOWN
475 /* 0x1af */ { kKeyAudioUp }, // VK_VOLUME_UP
476 /* 0x1b0 */ { kKeyAudioNext }, // VK_MEDIA_NEXT_TRACK
477 /* 0x1b1 */ { kKeyAudioPrev }, // VK_MEDIA_PREV_TRACK
478 /* 0x1b2 */ { kKeyAudioStop }, // VK_MEDIA_STOP
479 /* 0x1b3 */ { kKeyAudioPlay }, // VK_MEDIA_PLAY_PAUSE
480 /* 0x1b4 */ { kKeyAppMail }, // VK_LAUNCH_MAIL
481 /* 0x1b5 */ { kKeyAppMedia }, // VK_LAUNCH_MEDIA_SELECT
482 /* 0x1b6 */ { kKeyAppUser1 }, // VK_LAUNCH_APP1
483 /* 0x1b7 */ { kKeyAppUser2 }, // VK_LAUNCH_APP2
484 /* 0x1b8 */ { kKeyNone }, // unassigned
485 /* 0x1b9 */ { kKeyNone }, // unassigned
486 /* 0x1ba */ { kKeyNone }, // OEM specific
487 /* 0x1bb */ { kKeyNone }, // OEM specific
488 /* 0x1bc */ { kKeyNone }, // OEM specific
489 /* 0x1bd */ { kKeyNone }, // OEM specific
490 /* 0x1be */ { kKeyNone }, // OEM specific
491 /* 0x1bf */ { kKeyNone }, // OEM specific
492 /* 0x1c0 */ { kKeyNone }, // OEM specific
493 /* 0x1c1 */ { kKeyNone }, // unassigned
494 /* 0x1c2 */ { kKeyNone }, // unassigned
495 /* 0x1c3 */ { kKeyNone }, // unassigned
496 /* 0x1c4 */ { kKeyNone }, // unassigned
497 /* 0x1c5 */ { kKeyNone }, // unassigned
498 /* 0x1c6 */ { kKeyNone }, // unassigned
499 /* 0x1c7 */ { kKeyNone }, // unassigned
500 /* 0x1c8 */ { kKeyNone }, // unassigned
501 /* 0x1c9 */ { kKeyNone }, // unassigned
502 /* 0x1ca */ { kKeyNone }, // unassigned
503 /* 0x1cb */ { kKeyNone }, // unassigned
504 /* 0x1cc */ { kKeyNone }, // unassigned
505 /* 0x1cd */ { kKeyNone }, // unassigned
506 /* 0x1ce */ { kKeyNone }, // unassigned
507 /* 0x1cf */ { kKeyNone }, // unassigned
508 /* 0x1d0 */ { kKeyNone }, // unassigned
509 /* 0x1d1 */ { kKeyNone }, // unassigned
510 /* 0x1d2 */ { kKeyNone }, // unassigned
511 /* 0x1d3 */ { kKeyNone }, // unassigned
512 /* 0x1d4 */ { kKeyNone }, // unassigned
513 /* 0x1d5 */ { kKeyNone }, // unassigned
514 /* 0x1d6 */ { kKeyNone }, // unassigned
515 /* 0x1d7 */ { kKeyNone }, // unassigned
516 /* 0x1d8 */ { kKeyNone }, // unassigned
517 /* 0x1d9 */ { kKeyNone }, // unassigned
518 /* 0x1da */ { kKeyNone }, // unassigned
519 /* 0x1db */ { kKeyNone }, // OEM specific
520 /* 0x1dc */ { kKeyNone }, // OEM specific
521 /* 0x1dd */ { kKeyNone }, // OEM specific
522 /* 0x1de */ { kKeyNone }, // OEM specific
523 /* 0x1df */ { kKeyNone }, // OEM specific
524 /* 0x1e0 */ { kKeyNone }, // OEM specific
525 /* 0x1e1 */ { kKeyNone }, // OEM specific
526 /* 0x1e2 */ { kKeyNone }, // OEM specific
527 /* 0x1e3 */ { kKeyNone }, // OEM specific
528 /* 0x1e4 */ { kKeyNone }, // OEM specific
529 /* 0x1e5 */ { kKeyNone }, // unassigned
530 /* 0x1e6 */ { kKeyNone }, // OEM specific
531 /* 0x1e7 */ { kKeyNone }, // unassigned
532 /* 0x1e8 */ { kKeyNone }, // unassigned
533 /* 0x1e9 */ { kKeyNone }, // OEM specific
534 /* 0x1ea */ { kKeyNone }, // OEM specific
535 /* 0x1eb */ { kKeyNone }, // OEM specific
536 /* 0x1ec */ { kKeyNone }, // OEM specific
537 /* 0x1ed */ { kKeyNone }, // OEM specific
538 /* 0x1ee */ { kKeyNone }, // OEM specific
539 /* 0x1ef */ { kKeyNone }, // OEM specific
540 /* 0x1f0 */ { kKeyNone }, // OEM specific
541 /* 0x1f1 */ { kKeyNone }, // OEM specific
542 /* 0x1f2 */ { kKeyNone }, // VK_OEM_COPY
543 /* 0x1f3 */ { kKeyNone }, // VK_OEM_AUTO
544 /* 0x1f4 */ { kKeyNone }, // VK_OEM_ENLW
545 /* 0x1f5 */ { kKeyNone }, // OEM specific
546 /* 0x1f6 */ { kKeyNone }, // VK_ATTN
547 /* 0x1f7 */ { kKeyNone }, // VK_CRSEL
548 /* 0x1f8 */ { kKeyNone }, // VK_EXSEL
549 /* 0x1f9 */ { kKeyNone }, // VK_EREOF
550 /* 0x1fa */ { kKeyNone }, // VK_PLAY
551 /* 0x1fb */ { kKeyNone }, // VK_ZOOM
552 /* 0x1fc */ { kKeyNone }, // reserved
553 /* 0x1fd */ { kKeyNone }, // VK_PA1
554 /* 0x1fe */ { kKeyNone }, // VK_OEM_CLEAR
555 /* 0x1ff */ { kKeyNone } // reserved
556 };
557
558 struct Win32Modifiers {
559 public:
560 UINT m_vk;
561 KeyModifierMask m_mask;
562 };
563
564 static const Win32Modifiers s_modifiers[] =
565 {
566 { VK_SHIFT, KeyModifierShift },
567 { VK_LSHIFT, KeyModifierShift },
568 { VK_RSHIFT, KeyModifierShift },
569 { VK_CONTROL, KeyModifierControl },
570 { VK_LCONTROL, KeyModifierControl },
571 { VK_RCONTROL, KeyModifierControl },
572 { VK_MENU, KeyModifierAlt },
573 { VK_LMENU, KeyModifierAlt },
574 { VK_RMENU, KeyModifierAlt },
575 { VK_LWIN, KeyModifierSuper },
576 { VK_RWIN, KeyModifierSuper }
577 };
578
MSWindowsKeyState(MSWindowsDesks * desks,void * eventTarget,IEventQueue * events)579 MSWindowsKeyState::MSWindowsKeyState(
580 MSWindowsDesks* desks, void* eventTarget, IEventQueue* events) :
581 KeyState(events),
582 m_eventTarget(eventTarget),
583 m_desks(desks),
584 m_keyLayout(GetKeyboardLayout(0)),
585 m_fixTimer(NULL),
586 m_lastDown(0),
587 m_useSavedModifiers(false),
588 m_savedModifiers(0),
589 m_originalSavedModifiers(0),
590 m_events(events)
591 {
592 init();
593 }
594
MSWindowsKeyState(MSWindowsDesks * desks,void * eventTarget,IEventQueue * events,synergy::KeyMap & keyMap)595 MSWindowsKeyState::MSWindowsKeyState(
596 MSWindowsDesks* desks, void* eventTarget, IEventQueue* events, synergy::KeyMap& keyMap) :
597 KeyState(events, keyMap),
598 m_eventTarget(eventTarget),
599 m_desks(desks),
600 m_keyLayout(GetKeyboardLayout(0)),
601 m_fixTimer(NULL),
602 m_lastDown(0),
603 m_useSavedModifiers(false),
604 m_savedModifiers(0),
605 m_originalSavedModifiers(0),
606 m_events(events)
607 {
608 init();
609 }
610
~MSWindowsKeyState()611 MSWindowsKeyState::~MSWindowsKeyState()
612 {
613 disable();
614 }
615
616 void
init()617 MSWindowsKeyState::init()
618 {
619 // look up symbol that's available on winNT family but not win95
620 HMODULE userModule = GetModuleHandle("user32.dll");
621 m_ToUnicodeEx = (ToUnicodeEx_t)GetProcAddress(userModule, "ToUnicodeEx");
622 }
623
624 void
disable()625 MSWindowsKeyState::disable()
626 {
627 if (m_fixTimer != NULL) {
628 m_events->removeHandler(Event::kTimer, m_fixTimer);
629 m_events->deleteTimer(m_fixTimer);
630 m_fixTimer = NULL;
631 }
632 m_lastDown = 0;
633 }
634
635 KeyButton
virtualKeyToButton(UINT virtualKey) const636 MSWindowsKeyState::virtualKeyToButton(UINT virtualKey) const
637 {
638 return m_virtualKeyToButton[virtualKey & 0xffu];
639 }
640
641 void
setKeyLayout(HKL keyLayout)642 MSWindowsKeyState::setKeyLayout(HKL keyLayout)
643 {
644 m_keyLayout = keyLayout;
645 }
646
647 bool
testAutoRepeat(bool press,bool isRepeat,KeyButton button)648 MSWindowsKeyState::testAutoRepeat(bool press, bool isRepeat, KeyButton button)
649 {
650 if (!isRepeat) {
651 isRepeat = (press && m_lastDown != 0 && button == m_lastDown);
652 }
653 if (press) {
654 m_lastDown = button;
655 }
656 else {
657 m_lastDown = 0;
658 }
659 return isRepeat;
660 }
661
662 void
saveModifiers()663 MSWindowsKeyState::saveModifiers()
664 {
665 m_savedModifiers = getActiveModifiers();
666 m_originalSavedModifiers = m_savedModifiers;
667 }
668
669 void
useSavedModifiers(bool enable)670 MSWindowsKeyState::useSavedModifiers(bool enable)
671 {
672 if (enable != m_useSavedModifiers) {
673 m_useSavedModifiers = enable;
674 if (!m_useSavedModifiers) {
675 // transfer any modifier state changes to KeyState's state
676 KeyModifierMask mask = m_originalSavedModifiers ^ m_savedModifiers;
677 getActiveModifiersRValue() =
678 (getActiveModifiers() & ~mask) | (m_savedModifiers & mask);
679 }
680 }
681 }
682
683 KeyID
mapKeyFromEvent(WPARAM charAndVirtKey,LPARAM info,KeyModifierMask * maskOut) const684 MSWindowsKeyState::mapKeyFromEvent(WPARAM charAndVirtKey,
685 LPARAM info, KeyModifierMask* maskOut) const
686 {
687 static const KeyModifierMask s_controlAlt =
688 KeyModifierControl | KeyModifierAlt;
689
690 // extract character, virtual key, and if we didn't use AltGr
691 char c = (char)((charAndVirtKey & 0xff00u) >> 8);
692 UINT vkCode = (charAndVirtKey & 0xffu);
693 bool noAltGr = ((charAndVirtKey & 0xff0000u) != 0);
694
695 // handle some keys via table lookup
696 KeyID id = getKeyID(vkCode, (KeyButton)((info >> 16) & 0x1ffu));
697
698 // check if not in table; map character to key id
699 if (id == kKeyNone && c != 0) {
700 if ((c & 0x80u) == 0) {
701 // ASCII
702 id = static_cast<KeyID>(c) & 0xffu;
703 }
704 else {
705 // character is not really ASCII. instead it's some
706 // character in the current ANSI code page. try to
707 // convert that to a Unicode character. if we fail
708 // then use the single byte character as is.
709 char src = c;
710 wchar_t unicode;
711 if (MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED,
712 &src, 1, &unicode, 1) > 0) {
713 id = static_cast<KeyID>(unicode);
714 }
715 else {
716 id = static_cast<KeyID>(c) & 0xffu;
717 }
718 }
719 }
720
721 // set modifier mask
722 if (maskOut != NULL) {
723 KeyModifierMask active = getActiveModifiers();
724 if (!noAltGr && (active & s_controlAlt) == s_controlAlt) {
725 // if !noAltGr then we're only interested in matching the
726 // key, not the AltGr. AltGr is down (i.e. control and alt
727 // are down) but we don't want the client to have to match
728 // that so we clear it.
729 active &= ~s_controlAlt;
730 }
731 if (id == kKeyHangul) {
732 // If shift-space is used to change input mode, clear shift modifier.
733 active &= ~KeyModifierShift;
734 }
735 *maskOut = active;
736 }
737
738 return id;
739 }
740
741 bool
didGroupsChange() const742 MSWindowsKeyState::didGroupsChange() const
743 {
744 GroupList groups;
745 return (getGroups(groups) && groups != m_groups);
746 }
747
748 UINT
mapKeyToVirtualKey(KeyID key) const749 MSWindowsKeyState::mapKeyToVirtualKey(KeyID key) const
750 {
751 if (key == kKeyNone) {
752 return 0;
753 }
754 KeyToVKMap::const_iterator i = m_keyToVKMap.find(key);
755 if (i == m_keyToVKMap.end()) {
756 return 0;
757 }
758 else {
759 return i->second;
760 }
761 }
762
763 void
onKey(KeyButton button,bool down,KeyModifierMask newState)764 MSWindowsKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState)
765 {
766 KeyState::onKey(button, down, newState);
767 }
768
769 void
sendKeyEvent(void * target,bool press,bool isAutoRepeat,KeyID key,KeyModifierMask mask,SInt32 count,KeyButton button)770 MSWindowsKeyState::sendKeyEvent(void* target,
771 bool press, bool isAutoRepeat,
772 KeyID key, KeyModifierMask mask,
773 SInt32 count, KeyButton button)
774 {
775 if (press || isAutoRepeat) {
776 // send key
777 if (press && !isAutoRepeat) {
778 KeyState::sendKeyEvent(target, true, false,
779 key, mask, 1, button);
780 if (count > 0) {
781 --count;
782 }
783 }
784 if (count >= 1) {
785 KeyState::sendKeyEvent(target, true, true,
786 key, mask, count, button);
787 }
788 }
789 else {
790 // do key up
791 KeyState::sendKeyEvent(target, false, false, key, mask, 1, button);
792 }
793 }
794
795 void
fakeKeyDown(KeyID id,KeyModifierMask mask,KeyButton button)796 MSWindowsKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask,
797 KeyButton button)
798 {
799 KeyState::fakeKeyDown(id, mask, button);
800 }
801
802 bool
fakeKeyRepeat(KeyID id,KeyModifierMask mask,SInt32 count,KeyButton button)803 MSWindowsKeyState::fakeKeyRepeat(KeyID id, KeyModifierMask mask,
804 SInt32 count, KeyButton button)
805 {
806 return KeyState::fakeKeyRepeat(id, mask, count, button);
807 }
808
809 bool
fakeCtrlAltDel()810 MSWindowsKeyState::fakeCtrlAltDel()
811 {
812 // to fake ctrl+alt+del on the NT family we broadcast a suitable
813 // hotkey to all windows on the winlogon desktop. however, the
814 // current thread must be on that desktop to do the broadcast
815 // and we can't switch just any thread because some own windows
816 // or hooks. so start a new thread to do the real work.
817 HANDLE hEvtSendSas = OpenEvent(EVENT_MODIFY_STATE, FALSE, "Global\\SendSAS");
818 if (hEvtSendSas) {
819 LOG((CLOG_DEBUG "found the SendSAS event - signaling my launcher to simulate ctrl+alt+del"));
820 SetEvent(hEvtSendSas);
821 CloseHandle(hEvtSendSas);
822 }
823 else {
824 Thread cad(new FunctionJob(&MSWindowsKeyState::ctrlAltDelThread));
825 cad.wait();
826 }
827
828 return true;
829 }
830
831 void
ctrlAltDelThread(void *)832 MSWindowsKeyState::ctrlAltDelThread(void*)
833 {
834 // get the Winlogon desktop at whatever privilege we can
835 HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED);
836 if (desk != NULL) {
837 if (SetThreadDesktop(desk)) {
838 PostMessage(HWND_BROADCAST, WM_HOTKEY, 0,
839 MAKELPARAM(MOD_CONTROL | MOD_ALT, VK_DELETE));
840 }
841 else {
842 LOG((CLOG_DEBUG "can't switch to Winlogon desk: %d", GetLastError()));
843 }
844 CloseDesktop(desk);
845 }
846 else {
847 LOG((CLOG_DEBUG "can't open Winlogon desk: %d", GetLastError()));
848 }
849 }
850
851 KeyModifierMask
pollActiveModifiers() const852 MSWindowsKeyState::pollActiveModifiers() const
853 {
854 KeyModifierMask state = 0;
855
856 // get non-toggle modifiers from our own shadow key state
857 for (size_t i = 0; i < sizeof(s_modifiers) / sizeof(s_modifiers[0]); ++i) {
858 KeyButton button = virtualKeyToButton(s_modifiers[i].m_vk);
859 if (button != 0 && isKeyDown(button)) {
860 state |= s_modifiers[i].m_mask;
861 }
862 }
863
864 // we can get toggle modifiers from the system
865 if ((GetKeyState(VK_CAPITAL) & 0x01) != 0) {
866 state |= KeyModifierCapsLock;
867 }
868 if ((GetKeyState(VK_NUMLOCK) & 0x01) != 0) {
869 state |= KeyModifierNumLock;
870 }
871 if ((GetKeyState(VK_SCROLL) & 0x01) != 0) {
872 state |= KeyModifierScrollLock;
873 }
874
875 return state;
876 }
877
878 SInt32
pollActiveGroup() const879 MSWindowsKeyState::pollActiveGroup() const
880 {
881 // determine the thread that'll receive this event
882 HWND targetWindow = GetForegroundWindow();
883 DWORD targetThread = GetWindowThreadProcessId(targetWindow, NULL);
884
885 // get keyboard layout for the thread
886 HKL hkl = GetKeyboardLayout(targetThread);
887
888 if (!hkl) {
889 // GetKeyboardLayout failed. Maybe targetWindow is a console window.
890 // We're getting the keyboard layout of the desktop instead.
891 targetWindow = GetDesktopWindow();
892 targetThread = GetWindowThreadProcessId(targetWindow, NULL);
893 hkl = GetKeyboardLayout(targetThread);
894 }
895
896 // get group
897 GroupMap::const_iterator i = m_groupMap.find(hkl);
898 if (i == m_groupMap.end()) {
899 LOG((CLOG_DEBUG1 "can't find keyboard layout %08x", hkl));
900 return 0;
901 }
902
903 return i->second;
904 }
905
906 void
pollPressedKeys(KeyButtonSet & pressedKeys) const907 MSWindowsKeyState::pollPressedKeys(KeyButtonSet& pressedKeys) const
908 {
909 BYTE keyState[256];
910 if (!GetKeyboardState(keyState)) {
911 LOG((CLOG_ERR "GetKeyboardState returned false on pollPressedKeys"));
912 return;
913 }
914 for (KeyButton i = 1; i < 256; ++i) {
915 if ((keyState[i] & 0x80) != 0) {
916 KeyButton keyButton = virtualKeyToButton(i);
917 if (keyButton != 0) {
918 pressedKeys.insert(keyButton);
919 }
920 }
921 }
922 }
923
924 void
getKeyMap(synergy::KeyMap & keyMap)925 MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap)
926 {
927 // update keyboard groups
928 if (getGroups(m_groups)) {
929 m_groupMap.clear();
930 SInt32 numGroups = (SInt32)m_groups.size();
931 for (SInt32 g = 0; g < numGroups; ++g) {
932 m_groupMap[m_groups[g]] = g;
933 }
934 }
935 HKL activeLayout = GetKeyboardLayout(0);
936
937 // clear table
938 memset(m_virtualKeyToButton, 0, sizeof(m_virtualKeyToButton));
939 m_keyToVKMap.clear();
940
941 synergy::KeyMap::KeyItem item;
942 SInt32 numGroups = (SInt32)m_groups.size();
943 for (SInt32 g = 0; g < numGroups; ++g) {
944 item.m_group = g;
945 ActivateKeyboardLayout(m_groups[g], 0);
946
947 // clear tables
948 memset(m_buttonToVK, 0, sizeof(m_buttonToVK));
949 memset(m_buttonToNumpadVK, 0, sizeof(m_buttonToNumpadVK));
950
951 // map buttons (scancodes) to virtual keys
952 for (KeyButton i = 1; i < 256; ++i) {
953 UINT vk = MapVirtualKey(i, 1);
954 if (vk == 0) {
955 // unmapped
956 continue;
957 }
958
959 // deal with certain virtual keys specially
960 switch (vk) {
961 case VK_SHIFT:
962 // this is important for sending the correct modifier to the
963 // client, a patch from bug #242 (right shift broken for ms
964 // remote desktop) removed this to just use left shift, which
965 // caused bug #2799 (right shift broken for osx).
966 // we must not repeat this same mistake and must fix platform
967 // specific bugs in code that only affects that platform.
968 if (MapVirtualKey(VK_RSHIFT, 0) == i) {
969 vk = VK_RSHIFT;
970 }
971 else {
972 vk = VK_LSHIFT;
973 }
974 break;
975
976 case VK_CONTROL:
977 vk = VK_LCONTROL;
978 break;
979
980 case VK_MENU:
981 vk = VK_LMENU;
982 break;
983
984 case VK_NUMLOCK:
985 vk = VK_PAUSE;
986 break;
987
988 case VK_NUMPAD0:
989 case VK_NUMPAD1:
990 case VK_NUMPAD2:
991 case VK_NUMPAD3:
992 case VK_NUMPAD4:
993 case VK_NUMPAD5:
994 case VK_NUMPAD6:
995 case VK_NUMPAD7:
996 case VK_NUMPAD8:
997 case VK_NUMPAD9:
998 case VK_DECIMAL:
999 // numpad keys are saved in their own table
1000 m_buttonToNumpadVK[i] = vk;
1001 continue;
1002
1003 case VK_LWIN:
1004 case VK_RWIN:
1005 break;
1006
1007 case VK_RETURN:
1008 case VK_PRIOR:
1009 case VK_NEXT:
1010 case VK_END:
1011 case VK_HOME:
1012 case VK_LEFT:
1013 case VK_UP:
1014 case VK_RIGHT:
1015 case VK_DOWN:
1016 case VK_INSERT:
1017 case VK_DELETE:
1018 // also add extended key for these
1019 m_buttonToVK[i | 0x100u] = vk;
1020 break;
1021 }
1022
1023 if (m_buttonToVK[i] == 0) {
1024 m_buttonToVK[i] = vk;
1025 }
1026 }
1027
1028 // now map virtual keys to buttons. multiple virtual keys may map
1029 // to a single button. if the virtual key matches the one in
1030 // m_buttonToVK then we use the button as is. if not then it's
1031 // either a numpad key and we use the button as is or it's an
1032 // extended button.
1033 for (UINT i = 1; i < 255; ++i) {
1034 // skip virtual keys we don't want
1035 switch (i) {
1036 case VK_LBUTTON:
1037 case VK_RBUTTON:
1038 case VK_MBUTTON:
1039 case VK_XBUTTON1:
1040 case VK_XBUTTON2:
1041 case VK_SHIFT:
1042 case VK_CONTROL:
1043 case VK_MENU:
1044 continue;
1045 }
1046
1047 // get the button
1048 KeyButton button = static_cast<KeyButton>(MapVirtualKey(i, 0));
1049 if (button == 0) {
1050 continue;
1051 }
1052
1053 // deal with certain virtual keys specially
1054 switch (i) {
1055 case VK_NUMPAD0:
1056 case VK_NUMPAD1:
1057 case VK_NUMPAD2:
1058 case VK_NUMPAD3:
1059 case VK_NUMPAD4:
1060 case VK_NUMPAD5:
1061 case VK_NUMPAD6:
1062 case VK_NUMPAD7:
1063 case VK_NUMPAD8:
1064 case VK_NUMPAD9:
1065 case VK_DECIMAL:
1066 m_buttonToNumpadVK[button] = i;
1067 break;
1068
1069 default:
1070 // add extended key if virtual keys don't match
1071 if (m_buttonToVK[button] != i) {
1072 m_buttonToVK[button | 0x100u] = i;
1073 }
1074 break;
1075 }
1076 }
1077
1078 // add the extended printscreen (alt+printscreen)
1079 // or maybe it's the non-extended printscreen?
1080 // scancodes and keyboard inputs are complicated
1081 if (m_buttonToVK[0x54u] == 0) {
1082 m_buttonToVK[0x54u] = VK_SNAPSHOT;
1083 }
1084
1085 // set virtual key to button table
1086 if (activeLayout == m_groups[g]) {
1087 for (KeyButton i = 0; i < 512; ++i) {
1088 if (m_buttonToVK[i] != 0) {
1089 if (m_virtualKeyToButton[m_buttonToVK[i]] == 0) {
1090 m_virtualKeyToButton[m_buttonToVK[i]] = i;
1091 }
1092 }
1093 if (m_buttonToNumpadVK[i] != 0) {
1094 if (m_virtualKeyToButton[m_buttonToNumpadVK[i]] == 0) {
1095 m_virtualKeyToButton[m_buttonToNumpadVK[i]] = i;
1096 }
1097 }
1098 }
1099 }
1100
1101 // add numpad keys
1102 for (KeyButton i = 0; i < 512; ++i) {
1103 if (m_buttonToNumpadVK[i] != 0) {
1104 item.m_id = getKeyID(m_buttonToNumpadVK[i], i);
1105 item.m_button = i;
1106 item.m_required = KeyModifierNumLock;
1107 item.m_sensitive = KeyModifierNumLock | KeyModifierShift;
1108 item.m_generates = 0;
1109 item.m_client = m_buttonToNumpadVK[i];
1110 addKeyEntry(keyMap, item);
1111 }
1112 }
1113
1114 // add other keys
1115 BYTE keys[256];
1116 memset(keys, 0, sizeof(keys));
1117 for (KeyButton i = 0; i < 512; ++i) {
1118 if (m_buttonToVK[i] != 0) {
1119 // initialize item
1120 item.m_id = getKeyID(m_buttonToVK[i], i);
1121 item.m_button = i;
1122 item.m_required = 0;
1123 item.m_sensitive = 0;
1124 item.m_client = m_buttonToVK[i];
1125
1126 // get flags for modifier keys
1127 synergy::KeyMap::initModifierKey(item);
1128
1129 if (item.m_id == 0) {
1130 // translate virtual key to a character with and without
1131 // shift, caps lock, and AltGr.
1132 struct Modifier {
1133 UINT m_vk1;
1134 UINT m_vk2;
1135 BYTE m_state;
1136 KeyModifierMask m_mask;
1137 };
1138 static const Modifier modifiers[] = {
1139 { VK_SHIFT, VK_SHIFT, 0x80u, KeyModifierShift },
1140 { VK_CAPITAL, VK_CAPITAL, 0x01u, KeyModifierCapsLock },
1141 { VK_CONTROL, VK_MENU, 0x80u, KeyModifierControl |
1142 KeyModifierAlt }
1143 };
1144 static const size_t s_numModifiers =
1145 sizeof(modifiers) / sizeof(modifiers[0]);
1146 static const size_t s_numCombinations = 1 << s_numModifiers;
1147 KeyID id[s_numCombinations];
1148
1149 bool anyFound = false;
1150 KeyButton button = static_cast<KeyButton>(i & 0xffu);
1151 for (size_t j = 0; j < s_numCombinations; ++j) {
1152 for (size_t k = 0; k < s_numModifiers; ++k) {
1153 //if ((j & (1 << k)) != 0) {
1154 // http://msdn.microsoft.com/en-us/library/ke55d167.aspx
1155 if ((j & (1i64 << k)) != 0) {
1156 keys[modifiers[k].m_vk1] = modifiers[k].m_state;
1157 keys[modifiers[k].m_vk2] = modifiers[k].m_state;
1158 }
1159 else {
1160 keys[modifiers[k].m_vk1] = 0;
1161 keys[modifiers[k].m_vk2] = 0;
1162 }
1163 }
1164 id[j] = getIDForKey(item, button,
1165 m_buttonToVK[i], keys, m_groups[g]);
1166 if (id[j] != 0) {
1167 anyFound = true;
1168 }
1169 }
1170
1171 if (anyFound) {
1172 // determine what modifiers we're sensitive to.
1173 // we're sensitive if the KeyID changes when the
1174 // modifier does.
1175 item.m_sensitive = 0;
1176 for (size_t k = 0; k < s_numModifiers; ++k) {
1177 for (size_t j = 0; j < s_numCombinations; ++j) {
1178 //if (id[j] != id[j ^ (1u << k)]) {
1179 // http://msdn.microsoft.com/en-us/library/ke55d167.aspx
1180 if (id[j] != id[j ^ (1ui64 << k)]) {
1181 item.m_sensitive |= modifiers[k].m_mask;
1182 break;
1183 }
1184 }
1185 }
1186
1187 // save each key. the map will automatically discard
1188 // duplicates, like an unshift and shifted version of
1189 // a key that's insensitive to shift.
1190 for (size_t j = 0; j < s_numCombinations; ++j) {
1191 item.m_id = id[j];
1192 item.m_required = 0;
1193 for (size_t k = 0; k < s_numModifiers; ++k) {
1194 if ((j & (1i64 << k)) != 0) {
1195 item.m_required |= modifiers[k].m_mask;
1196 }
1197 }
1198 addKeyEntry(keyMap, item);
1199 }
1200 }
1201 }
1202 else {
1203 // found in table
1204 switch (m_buttonToVK[i]) {
1205 case VK_TAB:
1206 // add kKeyLeftTab, too
1207 item.m_id = kKeyLeftTab;
1208 item.m_required |= KeyModifierShift;
1209 item.m_sensitive |= KeyModifierShift;
1210 addKeyEntry(keyMap, item);
1211 item.m_id = kKeyTab;
1212 item.m_required &= ~KeyModifierShift;
1213 break;
1214
1215 case VK_CANCEL:
1216 item.m_required |= KeyModifierControl;
1217 item.m_sensitive |= KeyModifierControl;
1218 break;
1219
1220 }
1221
1222 addKeyEntry(keyMap, item);
1223 }
1224 }
1225 }
1226 }
1227
1228 // restore keyboard layout
1229 ActivateKeyboardLayout(activeLayout, 0);
1230 }
1231
1232 void
fakeKey(const Keystroke & keystroke)1233 MSWindowsKeyState::fakeKey(const Keystroke& keystroke)
1234 {
1235 switch (keystroke.m_type) {
1236 case Keystroke::kButton: {
1237 LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
1238 KeyButton scanCode = keystroke.m_data.m_button.m_button;
1239
1240 // windows doesn't send key ups for key repeats
1241 if (keystroke.m_data.m_button.m_repeat &&
1242 !keystroke.m_data.m_button.m_press) {
1243 LOG((CLOG_DEBUG1 " discard key repeat release"));
1244 break;
1245 }
1246
1247 // get the virtual key for the button
1248 WORD vk = (WORD)keystroke.m_data.m_button.m_client;
1249 DWORD flags = 0;
1250
1251 if (keystroke.m_data.m_button.m_press == false)
1252 flags |= KEYEVENTF_KEYUP;
1253
1254 // special handling of VK_SNAPSHOT
1255 if (vk == VK_SNAPSHOT)
1256 scanCode = (getActiveModifiers() & KeyModifierAlt) ? 0x54 : 0x137;
1257
1258 if (scanCode & 0x100)
1259 flags |= KEYEVENTF_EXTENDEDKEY;
1260
1261 //vk,sc,flags,keystroke.m_data.m_button.m_repeat
1262
1263 m_desks->fakeKeyEvent(vk, scanCode, flags, keystroke.m_data.m_button.m_repeat);
1264
1265 // synthesize event
1266 //m_desks->fakeKeyEvent(button, vk,
1267 // keystroke.m_data.m_button.m_press,
1268 // keystroke.m_data.m_button.m_repeat);
1269 break;
1270 }
1271
1272 case Keystroke::kGroup:
1273 // we don't restore the group. we'd like to but we can't be
1274 // sure the restoring group change will be processed after the
1275 // key events.
1276 if (!keystroke.m_data.m_group.m_restore) {
1277 if (keystroke.m_data.m_group.m_absolute) {
1278 LOG((CLOG_DEBUG1 " group %d", keystroke.m_data.m_group.m_group));
1279 setWindowGroup(keystroke.m_data.m_group.m_group);
1280 }
1281 else {
1282 LOG((CLOG_DEBUG1 " group %+d", keystroke.m_data.m_group.m_group));
1283 setWindowGroup(getEffectiveGroup(pollActiveGroup(),
1284 keystroke.m_data.m_group.m_group));
1285 }
1286 }
1287 break;
1288 }
1289 }
1290
1291 KeyModifierMask&
getActiveModifiersRValue()1292 MSWindowsKeyState::getActiveModifiersRValue()
1293 {
1294 if (m_useSavedModifiers) {
1295 return m_savedModifiers;
1296 }
1297 else {
1298 return KeyState::getActiveModifiersRValue();
1299 }
1300 }
1301
1302 bool
getGroups(GroupList & groups) const1303 MSWindowsKeyState::getGroups(GroupList& groups) const
1304 {
1305 // get keyboard layouts
1306 UInt32 newNumLayouts = GetKeyboardLayoutList(0, NULL);
1307 if (newNumLayouts == 0) {
1308 LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
1309 return false;
1310 }
1311 HKL* newLayouts = new HKL[newNumLayouts];
1312 newNumLayouts = GetKeyboardLayoutList(newNumLayouts, newLayouts);
1313 if (newNumLayouts == 0) {
1314 LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
1315 delete[] newLayouts;
1316 return false;
1317 }
1318
1319 groups.clear();
1320 groups.insert(groups.end(), newLayouts, newLayouts + newNumLayouts);
1321 delete[] newLayouts;
1322 return true;
1323 }
1324
1325 void
setWindowGroup(SInt32 group)1326 MSWindowsKeyState::setWindowGroup(SInt32 group)
1327 {
1328 HWND targetWindow = GetForegroundWindow();
1329
1330 bool sysCharSet = true;
1331 // XXX -- determine if m_groups[group] can be used with the system
1332 // character set.
1333
1334 PostMessage(targetWindow, WM_INPUTLANGCHANGEREQUEST,
1335 sysCharSet ? 1 : 0, (LPARAM)m_groups[group]);
1336
1337 // XXX -- use a short delay to let the target window process the message
1338 // before it sees the keyboard events. i'm not sure why this is
1339 // necessary since the messages should arrive in order. if we don't
1340 // delay, though, some of our keyboard events may disappear.
1341 Sleep(100);
1342 }
1343
1344 KeyID
getKeyID(UINT virtualKey,KeyButton button) const1345 MSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button) const
1346 {
1347 // Some virtual keycodes have same values.
1348 // VK_HANGUL == VK_KANA, VK_HANJA == NK_KANJI
1349 // which are used to change the input mode of IME.
1350 // But they have different X11 keysym. So we should distinguish them.
1351 if ((LOWORD(m_keyLayout) & 0xffffu) == 0x0412u) { // 0x0412 : Korean Locale ID
1352 if (virtualKey == VK_HANGUL || virtualKey == VK_HANJA) {
1353 // If shift-space is used to change the input mode,
1354 // the extented bit is not set. So add it to get right key id.
1355 button |= 0x100u;
1356 }
1357 }
1358
1359 if ((button & 0x100u) != 0) {
1360 virtualKey += 0x100u;
1361 }
1362 return s_virtualKey[virtualKey];
1363 }
1364
1365 UINT
mapButtonToVirtualKey(KeyButton button) const1366 MSWindowsKeyState::mapButtonToVirtualKey(KeyButton button) const
1367 {
1368 return m_buttonToVK[button];
1369 }
1370
1371 KeyID
getIDForKey(synergy::KeyMap::KeyItem & item,KeyButton button,UINT virtualKey,PBYTE keyState,HKL hkl) const1372 MSWindowsKeyState::getIDForKey(synergy::KeyMap::KeyItem& item,
1373 KeyButton button, UINT virtualKey,
1374 PBYTE keyState, HKL hkl) const
1375 {
1376 WCHAR unicode[2];
1377 int n = m_ToUnicodeEx(
1378 virtualKey, button, keyState, unicode,
1379 sizeof(unicode) / sizeof(unicode[0]), 0, hkl);
1380 KeyID id = static_cast<KeyID>(unicode[0]);
1381
1382 switch (n) {
1383 case -1:
1384 return synergy::KeyMap::getDeadKey(id);
1385
1386 default:
1387 case 0:
1388 // unmapped
1389 return kKeyNone;
1390
1391 case 1:
1392 return id;
1393
1394 case 2:
1395 // left over dead key in buffer. this used to recurse,
1396 // but apparently this causes a stack overflow, so just
1397 // return no key instead.
1398 return kKeyNone;
1399 }
1400 }
1401
1402 void
addKeyEntry(synergy::KeyMap & keyMap,synergy::KeyMap::KeyItem & item)1403 MSWindowsKeyState::addKeyEntry(synergy::KeyMap& keyMap, synergy::KeyMap::KeyItem& item)
1404 {
1405 keyMap.addKeyEntry(item);
1406 if (item.m_group == 0) {
1407 m_keyToVKMap[item.m_id] = static_cast<UINT>(item.m_client);
1408 }
1409 }
1410
1411