gdiplus: Add GdipGetPenCompoundCount implementation.
[wine.git] / dlls / wineandroid.drv / keyboard.c
blob82035cc14ddfc93b5c6806fd35f02f49d01a816a
1 /*
2 * Keyboard related functions
4 * Copyright 1993 Bob Amstadt
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1997 David Faure
7 * Copyright 1998 Morten Welinder
8 * Copyright 1998 Ulrich Weigand
9 * Copyright 1999 Ove Kåven
10 * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
11 * Copyright 2013 Alexandre Julliard
12 * Copyright 2015 Josh DuBois for CodeWeavers Inc.
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #if 0
30 #pragma makedep unix
31 #endif
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
36 #include "config.h"
38 #include "android.h"
39 #include "wine/server.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(keyboard);
43 WINE_DECLARE_DEBUG_CHANNEL(key);
45 static const UINT keycode_to_vkey[] =
47 0, /* AKEYCODE_UNKNOWN */
48 0, /* AKEYCODE_SOFT_LEFT */
49 0, /* AKEYCODE_SOFT_RIGHT */
50 0, /* AKEYCODE_HOME */
51 0, /* AKEYCODE_BACK */
52 0, /* AKEYCODE_CALL */
53 0, /* AKEYCODE_ENDCALL */
54 '0', /* AKEYCODE_0 */
55 '1', /* AKEYCODE_1 */
56 '2', /* AKEYCODE_2 */
57 '3', /* AKEYCODE_3 */
58 '4', /* AKEYCODE_4 */
59 '5', /* AKEYCODE_5 */
60 '6', /* AKEYCODE_6 */
61 '7', /* AKEYCODE_7 */
62 '8', /* AKEYCODE_8 */
63 '9', /* AKEYCODE_9 */
64 0, /* AKEYCODE_STAR */
65 0, /* AKEYCODE_POUND */
66 VK_UP, /* AKEYCODE_DPAD_UP */
67 VK_DOWN, /* AKEYCODE_DPAD_DOWN */
68 VK_LEFT, /* AKEYCODE_DPAD_LEFT */
69 VK_RIGHT, /* AKEYCODE_DPAD_RIGHT */
70 0, /* AKEYCODE_DPAD_CENTER */
71 0, /* AKEYCODE_VOLUME_UP */
72 0, /* AKEYCODE_VOLUME_DOWN */
73 0, /* AKEYCODE_POWER */
74 0, /* AKEYCODE_CAMERA */
75 0, /* AKEYCODE_CLEAR */
76 'A', /* AKEYCODE_A */
77 'B', /* AKEYCODE_B */
78 'C', /* AKEYCODE_C */
79 'D', /* AKEYCODE_D */
80 'E', /* AKEYCODE_E */
81 'F', /* AKEYCODE_F */
82 'G', /* AKEYCODE_G */
83 'H', /* AKEYCODE_H */
84 'I', /* AKEYCODE_I */
85 'J', /* AKEYCODE_J */
86 'K', /* AKEYCODE_K */
87 'L', /* AKEYCODE_L */
88 'M', /* AKEYCODE_M */
89 'N', /* AKEYCODE_N */
90 'O', /* AKEYCODE_O */
91 'P', /* AKEYCODE_P */
92 'Q', /* AKEYCODE_Q */
93 'R', /* AKEYCODE_R */
94 'S', /* AKEYCODE_S */
95 'T', /* AKEYCODE_T */
96 'U', /* AKEYCODE_U */
97 'V', /* AKEYCODE_V */
98 'W', /* AKEYCODE_W */
99 'X', /* AKEYCODE_X */
100 'Y', /* AKEYCODE_Y */
101 'Z', /* AKEYCODE_Z */
102 VK_OEM_COMMA, /* AKEYCODE_COMMA */
103 VK_OEM_PERIOD, /* AKEYCODE_PERIOD */
104 VK_LMENU, /* AKEYCODE_ALT_LEFT */
105 VK_RMENU, /* AKEYCODE_ALT_RIGHT */
106 VK_LSHIFT, /* AKEYCODE_SHIFT_LEFT */
107 VK_RSHIFT, /* AKEYCODE_SHIFT_RIGHT */
108 VK_TAB, /* AKEYCODE_TAB */
109 VK_SPACE, /* AKEYCODE_SPACE */
110 0, /* AKEYCODE_SYM */
111 0, /* AKEYCODE_EXPLORER */
112 0, /* AKEYCODE_ENVELOPE */
113 VK_RETURN, /* AKEYCODE_ENTER */
114 VK_BACK, /* AKEYCODE_DEL */
115 VK_OEM_3, /* AKEYCODE_GRAVE */
116 VK_OEM_MINUS, /* AKEYCODE_MINUS */
117 VK_OEM_PLUS, /* AKEYCODE_EQUALS */
118 VK_OEM_4, /* AKEYCODE_LEFT_BRACKET */
119 VK_OEM_6, /* AKEYCODE_RIGHT_BRACKET */
120 VK_OEM_5, /* AKEYCODE_BACKSLASH */
121 VK_OEM_1, /* AKEYCODE_SEMICOLON */
122 VK_OEM_7, /* AKEYCODE_APOSTROPHE */
123 VK_OEM_2, /* AKEYCODE_SLASH */
124 0, /* AKEYCODE_AT */
125 0, /* AKEYCODE_NUM */
126 0, /* AKEYCODE_HEADSETHOOK */
127 0, /* AKEYCODE_FOCUS */
128 0, /* AKEYCODE_PLUS */
129 0, /* AKEYCODE_MENU */
130 0, /* AKEYCODE_NOTIFICATION */
131 0, /* AKEYCODE_SEARCH */
132 VK_MEDIA_PLAY_PAUSE, /* AKEYCODE_MEDIA_PLAY_PAUSE */
133 VK_MEDIA_STOP, /* AKEYCODE_MEDIA_STOP */
134 VK_MEDIA_NEXT_TRACK, /* AKEYCODE_MEDIA_NEXT */
135 VK_MEDIA_PREV_TRACK, /* AKEYCODE_MEDIA_PREVIOUS */
136 0, /* AKEYCODE_MEDIA_REWIND */
137 0, /* AKEYCODE_MEDIA_FAST_FORWARD */
138 0, /* AKEYCODE_MUTE */
139 VK_PRIOR, /* AKEYCODE_PAGE_UP */
140 VK_NEXT, /* AKEYCODE_PAGE_DOWN */
141 0, /* AKEYCODE_PICTSYMBOLS */
142 0, /* AKEYCODE_SWITCH_CHARSET */
143 0, /* AKEYCODE_BUTTON_A */
144 0, /* AKEYCODE_BUTTON_B */
145 0, /* AKEYCODE_BUTTON_C */
146 0, /* AKEYCODE_BUTTON_X */
147 0, /* AKEYCODE_BUTTON_Y */
148 0, /* AKEYCODE_BUTTON_Z */
149 0, /* AKEYCODE_BUTTON_L1 */
150 0, /* AKEYCODE_BUTTON_R1 */
151 0, /* AKEYCODE_BUTTON_L2 */
152 0, /* AKEYCODE_BUTTON_R2 */
153 0, /* AKEYCODE_BUTTON_THUMBL */
154 0, /* AKEYCODE_BUTTON_THUMBR */
155 0, /* AKEYCODE_BUTTON_START */
156 0, /* AKEYCODE_BUTTON_SELECT */
157 0, /* AKEYCODE_BUTTON_MODE */
158 VK_ESCAPE, /* AKEYCODE_ESCAPE */
159 VK_DELETE, /* AKEYCODE_FORWARD_DEL */
160 VK_LCONTROL, /* AKEYCODE_CTRL_LEFT */
161 VK_RCONTROL, /* AKEYCODE_CTRL_RIGHT */
162 VK_CAPITAL, /* AKEYCODE_CAPS_LOCK */
163 VK_SCROLL, /* AKEYCODE_SCROLL_LOCK */
164 VK_LWIN, /* AKEYCODE_META_LEFT */
165 VK_RWIN, /* AKEYCODE_META_RIGHT */
166 0, /* AKEYCODE_FUNCTION */
167 0, /* AKEYCODE_SYSRQ */
168 0, /* AKEYCODE_BREAK */
169 VK_HOME, /* AKEYCODE_MOVE_HOME */
170 VK_END, /* AKEYCODE_MOVE_END */
171 VK_INSERT, /* AKEYCODE_INSERT */
172 0, /* AKEYCODE_FORWARD */
173 0, /* AKEYCODE_MEDIA_PLAY */
174 0, /* AKEYCODE_MEDIA_PAUSE */
175 0, /* AKEYCODE_MEDIA_CLOSE */
176 0, /* AKEYCODE_MEDIA_EJECT */
177 0, /* AKEYCODE_MEDIA_RECORD */
178 VK_F1, /* AKEYCODE_F1 */
179 VK_F2, /* AKEYCODE_F2 */
180 VK_F3, /* AKEYCODE_F3 */
181 VK_F4, /* AKEYCODE_F4 */
182 VK_F5, /* AKEYCODE_F5 */
183 VK_F6, /* AKEYCODE_F6 */
184 VK_F7, /* AKEYCODE_F7 */
185 VK_F8, /* AKEYCODE_F8 */
186 VK_F9, /* AKEYCODE_F9 */
187 VK_F10, /* AKEYCODE_F10 */
188 VK_F11, /* AKEYCODE_F11 */
189 VK_F12, /* AKEYCODE_F12 */
190 VK_NUMLOCK, /* AKEYCODE_NUM_LOCK */
191 VK_NUMPAD0, /* AKEYCODE_NUMPAD_0 */
192 VK_NUMPAD1, /* AKEYCODE_NUMPAD_1 */
193 VK_NUMPAD2, /* AKEYCODE_NUMPAD_2 */
194 VK_NUMPAD3, /* AKEYCODE_NUMPAD_3 */
195 VK_NUMPAD4, /* AKEYCODE_NUMPAD_4 */
196 VK_NUMPAD5, /* AKEYCODE_NUMPAD_5 */
197 VK_NUMPAD6, /* AKEYCODE_NUMPAD_6 */
198 VK_NUMPAD7, /* AKEYCODE_NUMPAD_7 */
199 VK_NUMPAD8, /* AKEYCODE_NUMPAD_8 */
200 VK_NUMPAD9, /* AKEYCODE_NUMPAD_9 */
201 VK_DIVIDE, /* AKEYCODE_NUMPAD_DIVIDE */
202 VK_MULTIPLY, /* AKEYCODE_NUMPAD_MULTIPLY */
203 VK_SUBTRACT, /* AKEYCODE_NUMPAD_SUBTRACT */
204 VK_ADD, /* AKEYCODE_NUMPAD_ADD */
205 VK_DECIMAL, /* AKEYCODE_NUMPAD_DOT */
206 0, /* AKEYCODE_NUMPAD_COMMA */
207 0, /* AKEYCODE_NUMPAD_ENTER */
208 0, /* AKEYCODE_NUMPAD_EQUALS */
209 0, /* AKEYCODE_NUMPAD_LEFT_PAREN */
210 0, /* AKEYCODE_NUMPAD_RIGHT_PAREN */
211 0, /* AKEYCODE_VOLUME_MUTE */
212 0, /* AKEYCODE_INFO */
213 0, /* AKEYCODE_CHANNEL_UP */
214 0, /* AKEYCODE_CHANNEL_DOWN */
215 0, /* AKEYCODE_ZOOM_IN */
216 0, /* AKEYCODE_ZOOM_OUT */
217 0, /* AKEYCODE_TV */
218 0, /* AKEYCODE_WINDOW */
219 0, /* AKEYCODE_GUIDE */
220 0, /* AKEYCODE_DVR */
221 0, /* AKEYCODE_BOOKMARK */
222 0, /* AKEYCODE_CAPTIONS */
223 0, /* AKEYCODE_SETTINGS */
224 0, /* AKEYCODE_TV_POWER */
225 0, /* AKEYCODE_TV_INPUT */
226 0, /* AKEYCODE_STB_POWER */
227 0, /* AKEYCODE_STB_INPUT */
228 0, /* AKEYCODE_AVR_POWER */
229 0, /* AKEYCODE_AVR_INPUT */
230 0, /* AKEYCODE_PROG_RED */
231 0, /* AKEYCODE_PROG_GREEN */
232 0, /* AKEYCODE_PROG_YELLOW */
233 0, /* AKEYCODE_PROG_BLUE */
234 0, /* AKEYCODE_APP_SWITCH */
235 0, /* AKEYCODE_BUTTON_1 */
236 0, /* AKEYCODE_BUTTON_2 */
237 0, /* AKEYCODE_BUTTON_3 */
238 0, /* AKEYCODE_BUTTON_4 */
239 0, /* AKEYCODE_BUTTON_5 */
240 0, /* AKEYCODE_BUTTON_6 */
241 0, /* AKEYCODE_BUTTON_7 */
242 0, /* AKEYCODE_BUTTON_8 */
243 0, /* AKEYCODE_BUTTON_9 */
244 0, /* AKEYCODE_BUTTON_10 */
245 0, /* AKEYCODE_BUTTON_11 */
246 0, /* AKEYCODE_BUTTON_12 */
247 0, /* AKEYCODE_BUTTON_13 */
248 0, /* AKEYCODE_BUTTON_14 */
249 0, /* AKEYCODE_BUTTON_15 */
250 0, /* AKEYCODE_BUTTON_16 */
251 0, /* AKEYCODE_LANGUAGE_SWITCH */
252 0, /* AKEYCODE_MANNER_MODE */
253 0, /* AKEYCODE_3D_MODE */
254 0, /* AKEYCODE_CONTACTS */
255 0, /* AKEYCODE_CALENDAR */
256 0, /* AKEYCODE_MUSIC */
257 0, /* AKEYCODE_CALCULATOR */
258 0, /* AKEYCODE_ZENKAKU_HANKAKU */
259 0, /* AKEYCODE_EISU */
260 0, /* AKEYCODE_MUHENKAN */
261 0, /* AKEYCODE_HENKAN */
262 0, /* AKEYCODE_KATAKANA_HIRAGANA */
263 0, /* AKEYCODE_YEN */
264 0, /* AKEYCODE_RO */
265 VK_KANA, /* AKEYCODE_KANA */
266 0, /* AKEYCODE_ASSIST */
269 static const WORD vkey_to_scancode[] =
271 0, /* 0x00 undefined */
272 0, /* VK_LBUTTON */
273 0, /* VK_RBUTTON */
274 0, /* VK_CANCEL */
275 0, /* VK_MBUTTON */
276 0, /* VK_XBUTTON1 */
277 0, /* VK_XBUTTON2 */
278 0, /* 0x07 undefined */
279 0x0e, /* VK_BACK */
280 0x0f, /* VK_TAB */
281 0, /* 0x0a undefined */
282 0, /* 0x0b undefined */
283 0, /* VK_CLEAR */
284 0x1c, /* VK_RETURN */
285 0, /* 0x0e undefined */
286 0, /* 0x0f undefined */
287 0x2a, /* VK_SHIFT */
288 0x1d, /* VK_CONTROL */
289 0x38, /* VK_MENU */
290 0, /* VK_PAUSE */
291 0x3a, /* VK_CAPITAL */
292 0, /* VK_KANA */
293 0, /* 0x16 undefined */
294 0, /* VK_JUNJA */
295 0, /* VK_FINAL */
296 0, /* VK_HANJA */
297 0, /* 0x1a undefined */
298 0x01, /* VK_ESCAPE */
299 0, /* VK_CONVERT */
300 0, /* VK_NONCONVERT */
301 0, /* VK_ACCEPT */
302 0, /* VK_MODECHANGE */
303 0x39, /* VK_SPACE */
304 0x149, /* VK_PRIOR */
305 0x151, /* VK_NEXT */
306 0x14f, /* VK_END */
307 0x147, /* VK_HOME */
308 0x14b, /* VK_LEFT */
309 0x148, /* VK_UP */
310 0x14d, /* VK_RIGHT */
311 0x150, /* VK_DOWN */
312 0, /* VK_SELECT */
313 0, /* VK_PRINT */
314 0, /* VK_EXECUTE */
315 0, /* VK_SNAPSHOT */
316 0x152, /* VK_INSERT */
317 0x153, /* VK_DELETE */
318 0, /* VK_HELP */
319 0x0b, /* VK_0 */
320 0x02, /* VK_1 */
321 0x03, /* VK_2 */
322 0x04, /* VK_3 */
323 0x05, /* VK_4 */
324 0x06, /* VK_5 */
325 0x07, /* VK_6 */
326 0x08, /* VK_7 */
327 0x09, /* VK_8 */
328 0x0a, /* VK_9 */
329 0, /* 0x3a undefined */
330 0, /* 0x3b undefined */
331 0, /* 0x3c undefined */
332 0, /* 0x3d undefined */
333 0, /* 0x3e undefined */
334 0, /* 0x3f undefined */
335 0, /* 0x40 undefined */
336 0x1e, /* VK_A */
337 0x30, /* VK_B */
338 0x2e, /* VK_C */
339 0x20, /* VK_D */
340 0x12, /* VK_E */
341 0x21, /* VK_F */
342 0x22, /* VK_G */
343 0x23, /* VK_H */
344 0x17, /* VK_I */
345 0x24, /* VK_J */
346 0x25, /* VK_K */
347 0x26, /* VK_L */
348 0x32, /* VK_M */
349 0x31, /* VK_N */
350 0x18, /* VK_O */
351 0x19, /* VK_P */
352 0x10, /* VK_Q */
353 0x13, /* VK_R */
354 0x1f, /* VK_S */
355 0x14, /* VK_T */
356 0x16, /* VK_U */
357 0x2f, /* VK_V */
358 0x11, /* VK_W */
359 0x2d, /* VK_X */
360 0x15, /* VK_Y */
361 0x2c, /* VK_Z */
362 0, /* VK_LWIN */
363 0, /* VK_RWIN */
364 0, /* VK_APPS */
365 0, /* 0x5e undefined */
366 0, /* VK_SLEEP */
367 0x52, /* VK_NUMPAD0 */
368 0x4f, /* VK_NUMPAD1 */
369 0x50, /* VK_NUMPAD2 */
370 0x51, /* VK_NUMPAD3 */
371 0x4b, /* VK_NUMPAD4 */
372 0x4c, /* VK_NUMPAD5 */
373 0x4d, /* VK_NUMPAD6 */
374 0x47, /* VK_NUMPAD7 */
375 0x48, /* VK_NUMPAD8 */
376 0x49, /* VK_NUMPAD9 */
377 0x37, /* VK_MULTIPLY */
378 0x4e, /* VK_ADD */
379 0x7e, /* VK_SEPARATOR */
380 0x4a, /* VK_SUBTRACT */
381 0x53, /* VK_DECIMAL */
382 0135, /* VK_DIVIDE */
383 0x3b, /* VK_F1 */
384 0x3c, /* VK_F2 */
385 0x3d, /* VK_F3 */
386 0x3e, /* VK_F4 */
387 0x3f, /* VK_F5 */
388 0x40, /* VK_F6 */
389 0x41, /* VK_F7 */
390 0x42, /* VK_F8 */
391 0x43, /* VK_F9 */
392 0x44, /* VK_F10 */
393 0x57, /* VK_F11 */
394 0x58, /* VK_F12 */
395 0x64, /* VK_F13 */
396 0x65, /* VK_F14 */
397 0x66, /* VK_F15 */
398 0x67, /* VK_F16 */
399 0x68, /* VK_F17 */
400 0x69, /* VK_F18 */
401 0x6a, /* VK_F19 */
402 0x6b, /* VK_F20 */
403 0, /* VK_F21 */
404 0, /* VK_F22 */
405 0, /* VK_F23 */
406 0, /* VK_F24 */
407 0, /* 0x88 undefined */
408 0, /* 0x89 undefined */
409 0, /* 0x8a undefined */
410 0, /* 0x8b undefined */
411 0, /* 0x8c undefined */
412 0, /* 0x8d undefined */
413 0, /* 0x8e undefined */
414 0, /* 0x8f undefined */
415 0, /* VK_NUMLOCK */
416 0, /* VK_SCROLL */
417 0x10d, /* VK_OEM_NEC_EQUAL */
418 0, /* VK_OEM_FJ_JISHO */
419 0, /* VK_OEM_FJ_MASSHOU */
420 0, /* VK_OEM_FJ_TOUROKU */
421 0, /* VK_OEM_FJ_LOYA */
422 0, /* VK_OEM_FJ_ROYA */
423 0, /* 0x97 undefined */
424 0, /* 0x98 undefined */
425 0, /* 0x99 undefined */
426 0, /* 0x9a undefined */
427 0, /* 0x9b undefined */
428 0, /* 0x9c undefined */
429 0, /* 0x9d undefined */
430 0, /* 0x9e undefined */
431 0, /* 0x9f undefined */
432 0x2a, /* VK_LSHIFT */
433 0x36, /* VK_RSHIFT */
434 0x1d, /* VK_LCONTROL */
435 0x11d, /* VK_RCONTROL */
436 0x38, /* VK_LMENU */
437 0x138, /* VK_RMENU */
438 0, /* VK_BROWSER_BACK */
439 0, /* VK_BROWSER_FORWARD */
440 0, /* VK_BROWSER_REFRESH */
441 0, /* VK_BROWSER_STOP */
442 0, /* VK_BROWSER_SEARCH */
443 0, /* VK_BROWSER_FAVORITES */
444 0, /* VK_BROWSER_HOME */
445 0x100, /* VK_VOLUME_MUTE */
446 0x100, /* VK_VOLUME_DOWN */
447 0x100, /* VK_VOLUME_UP */
448 0, /* VK_MEDIA_NEXT_TRACK */
449 0, /* VK_MEDIA_PREV_TRACK */
450 0, /* VK_MEDIA_STOP */
451 0, /* VK_MEDIA_PLAY_PAUSE */
452 0, /* VK_LAUNCH_MAIL */
453 0, /* VK_LAUNCH_MEDIA_SELECT */
454 0, /* VK_LAUNCH_APP1 */
455 0, /* VK_LAUNCH_APP2 */
456 0, /* 0xb8 undefined */
457 0, /* 0xb9 undefined */
458 0x27, /* VK_OEM_1 */
459 0x0d, /* VK_OEM_PLUS */
460 0x33, /* VK_OEM_COMMA */
461 0x0c, /* VK_OEM_MINUS */
462 0x34, /* VK_OEM_PERIOD */
463 0x35, /* VK_OEM_2 */
464 0x29, /* VK_OEM_3 */
465 0, /* 0xc1 undefined */
466 0, /* 0xc2 undefined */
467 0, /* 0xc3 undefined */
468 0, /* 0xc4 undefined */
469 0, /* 0xc5 undefined */
470 0, /* 0xc6 undefined */
471 0, /* 0xc7 undefined */
472 0, /* 0xc8 undefined */
473 0, /* 0xc9 undefined */
474 0, /* 0xca undefined */
475 0, /* 0xcb undefined */
476 0, /* 0xcc undefined */
477 0, /* 0xcd undefined */
478 0, /* 0xce undefined */
479 0, /* 0xcf undefined */
480 0, /* 0xd0 undefined */
481 0, /* 0xd1 undefined */
482 0, /* 0xd2 undefined */
483 0, /* 0xd3 undefined */
484 0, /* 0xd4 undefined */
485 0, /* 0xd5 undefined */
486 0, /* 0xd6 undefined */
487 0, /* 0xd7 undefined */
488 0, /* 0xd8 undefined */
489 0, /* 0xd9 undefined */
490 0, /* 0xda undefined */
491 0x1a, /* VK_OEM_4 */
492 0x2b, /* VK_OEM_5 */
493 0x1b, /* VK_OEM_6 */
494 0x28, /* VK_OEM_7 */
495 0, /* VK_OEM_8 */
496 0, /* 0xe0 undefined */
497 0, /* VK_OEM_AX */
498 0x56, /* VK_OEM_102 */
499 0, /* VK_ICO_HELP */
500 0, /* VK_ICO_00 */
501 0, /* VK_PROCESSKEY */
502 0, /* VK_ICO_CLEAR */
503 0, /* VK_PACKET */
504 0, /* 0xe8 undefined */
505 0x71, /* VK_OEM_RESET */
506 0, /* VK_OEM_JUMP */
507 0, /* VK_OEM_PA1 */
508 0, /* VK_OEM_PA2 */
509 0, /* VK_OEM_PA3 */
510 0, /* VK_OEM_WSCTRL */
511 0, /* VK_OEM_CUSEL */
512 0, /* VK_OEM_ATTN */
513 0, /* VK_OEM_FINISH */
514 0, /* VK_OEM_COPY */
515 0, /* VK_OEM_AUTO */
516 0, /* VK_OEM_ENLW */
517 0, /* VK_OEM_BACKTAB */
518 0, /* VK_ATTN */
519 0, /* VK_CRSEL */
520 0, /* VK_EXSEL */
521 0, /* VK_EREOF */
522 0, /* VK_PLAY */
523 0, /* VK_ZOOM */
524 0, /* VK_NONAME */
525 0, /* VK_PA1 */
526 0x59, /* VK_OEM_CLEAR */
527 0, /* 0xff undefined */
530 static const struct
532 DWORD vkey;
533 const char *name;
534 } vkey_names[] = {
535 { VK_ADD, "Num +" },
536 { VK_BACK, "Backspace" },
537 { VK_CAPITAL, "Caps Lock" },
538 { VK_CONTROL, "Ctrl" },
539 { VK_DECIMAL, "Num Del" },
540 { VK_DELETE | 0x100, "Delete" },
541 { VK_DIVIDE | 0x100, "Num /" },
542 { VK_DOWN | 0x100, "Down" },
543 { VK_END | 0x100, "End" },
544 { VK_ESCAPE, "Esc" },
545 { VK_F1, "F1" },
546 { VK_F2, "F2" },
547 { VK_F3, "F3" },
548 { VK_F4, "F4" },
549 { VK_F5, "F5" },
550 { VK_F6, "F6" },
551 { VK_F7, "F7" },
552 { VK_F8, "F8" },
553 { VK_F9, "F9" },
554 { VK_F10, "F10" },
555 { VK_F11, "F11" },
556 { VK_F12, "F12" },
557 { VK_F13, "F13" },
558 { VK_F14, "F14" },
559 { VK_F15, "F15" },
560 { VK_F16, "F16" },
561 { VK_F17, "F17" },
562 { VK_F18, "F18" },
563 { VK_F19, "F19" },
564 { VK_F20, "F20" },
565 { VK_F21, "F21" },
566 { VK_F22, "F22" },
567 { VK_F23, "F23" },
568 { VK_F24, "F24" },
569 { VK_HELP | 0x100, "Help" },
570 { VK_HOME | 0x100, "Home" },
571 { VK_INSERT | 0x100, "Insert" },
572 { VK_LCONTROL, "Ctrl" },
573 { VK_LEFT | 0x100, "Left" },
574 { VK_LMENU, "Alt" },
575 { VK_LSHIFT, "Shift" },
576 { VK_LWIN | 0x100, "Win" },
577 { VK_MENU, "Alt" },
578 { VK_MULTIPLY, "Num *" },
579 { VK_NEXT | 0x100, "Page Down" },
580 { VK_NUMLOCK | 0x100, "Num Lock" },
581 { VK_NUMPAD0, "Num 0" },
582 { VK_NUMPAD1, "Num 1" },
583 { VK_NUMPAD2, "Num 2" },
584 { VK_NUMPAD3, "Num 3" },
585 { VK_NUMPAD4, "Num 4" },
586 { VK_NUMPAD5, "Num 5" },
587 { VK_NUMPAD6, "Num 6" },
588 { VK_NUMPAD7, "Num 7" },
589 { VK_NUMPAD8, "Num 8" },
590 { VK_NUMPAD9, "Num 9" },
591 { VK_OEM_CLEAR, "Num Clear" },
592 { VK_OEM_NEC_EQUAL | 0x100, "Num =" },
593 { VK_PRIOR | 0x100, "Page Up" },
594 { VK_RCONTROL | 0x100, "Right Ctrl" },
595 { VK_RETURN, "Return" },
596 { VK_RETURN | 0x100, "Num Enter" },
597 { VK_RIGHT | 0x100, "Right" },
598 { VK_RMENU | 0x100, "Right Alt" },
599 { VK_RSHIFT, "Right Shift" },
600 { VK_RWIN | 0x100, "Right Win" },
601 { VK_SEPARATOR, "Num ," },
602 { VK_SHIFT, "Shift" },
603 { VK_SPACE, "Space" },
604 { VK_SUBTRACT, "Num -" },
605 { VK_TAB, "Tab" },
606 { VK_UP | 0x100, "Up" },
607 { VK_VOLUME_DOWN | 0x100, "Volume Down" },
608 { VK_VOLUME_MUTE | 0x100, "Mute" },
609 { VK_VOLUME_UP | 0x100, "Volume Up" },
610 { VK_OEM_MINUS, "-" },
611 { VK_OEM_PLUS, "=" },
612 { VK_OEM_1, ";" },
613 { VK_OEM_2, "/" },
614 { VK_OEM_3, "`" },
615 { VK_OEM_4, "[" },
616 { VK_OEM_5, "\\" },
617 { VK_OEM_6, "]" },
618 { VK_OEM_7, "'" },
619 { VK_OEM_COMMA, "," },
620 { VK_OEM_PERIOD, "." },
623 static const SHORT char_vkey_map[] =
625 0x332, 0x241, 0x242, 0x003, 0x244, 0x245, 0x246, 0x247, 0x008, 0x009,
626 0x20d, 0x24b, 0x24c, 0x00d, 0x24e, 0x24f, 0x250, 0x251, 0x252, 0x253,
627 0x254, 0x255, 0x256, 0x257, 0x258, 0x259, 0x25a, 0x01b, 0x2dc, 0x2dd,
628 0x336, 0x3bd, 0x020, 0x131, 0x1de, 0x133, 0x134, 0x135, 0x137, 0x0de,
629 0x139, 0x130, 0x138, 0x1bb, 0x0bc, 0x0bd, 0x0be, 0x0bf, 0x030, 0x031,
630 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x1ba, 0x0ba,
631 0x1bc, 0x0bb, 0x1be, 0x1bf, 0x132, 0x141, 0x142, 0x143, 0x144, 0x145,
632 0x146, 0x147, 0x148, 0x149, 0x14a, 0x14b, 0x14c, 0x14d, 0x14e, 0x14f,
633 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, 0x158, 0x159,
634 0x15a, 0x0db, 0x0dc, 0x0dd, 0x136, 0x1bd, 0x0c0, 0x041, 0x042, 0x043,
635 0x044, 0x045, 0x046, 0x047, 0x048, 0x049, 0x04a, 0x04b, 0x04c, 0x04d,
636 0x04e, 0x04f, 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057,
637 0x058, 0x059, 0x05a, 0x1db, 0x1dc, 0x1dd, 0x1c0, 0x208
640 static UINT scancode_to_vkey( UINT scan )
642 UINT j;
644 for (j = 0; j < ARRAY_SIZE( vkey_to_scancode ); j++)
645 if (vkey_to_scancode[j] == scan)
646 return j;
647 return 0;
650 static const char* vkey_to_name( UINT vkey )
652 UINT j;
654 for (j = 0; j < ARRAY_SIZE( vkey_names ); j++)
655 if (vkey_names[j].vkey == vkey)
656 return vkey_names[j].name;
657 return NULL;
660 static BOOL get_async_key_state( BYTE state[256] )
662 BOOL ret;
664 SERVER_START_REQ( get_key_state )
666 req->async = 1;
667 req->key = -1;
668 wine_server_set_reply( req, state, 256 );
669 ret = !wine_server_call( req );
671 SERVER_END_REQ;
672 return ret;
675 static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
677 INPUT input;
679 input.type = INPUT_KEYBOARD;
680 input.u.ki.wVk = vkey;
681 input.u.ki.wScan = scan;
682 input.u.ki.dwFlags = flags;
683 input.u.ki.time = 0;
684 input.u.ki.dwExtraInfo = 0;
686 __wine_send_input( hwnd, &input, NULL );
689 /***********************************************************************
690 * update_keyboard_lock_state
692 void update_keyboard_lock_state( WORD vkey, UINT state )
694 BYTE keystate[256];
696 if (!get_async_key_state( keystate )) return;
698 if (!(keystate[VK_CAPITAL] & 0x01) != !(state & AMETA_CAPS_LOCK_ON) && vkey != VK_CAPITAL)
700 TRACE( "adjusting CapsLock state (%02x)\n", keystate[VK_CAPITAL] );
701 send_keyboard_input( 0, VK_CAPITAL, 0x3a, 0 );
702 send_keyboard_input( 0, VK_CAPITAL, 0x3a, KEYEVENTF_KEYUP );
705 if (!(keystate[VK_NUMLOCK] & 0x01) != !(state & AMETA_NUM_LOCK_ON) && (vkey & 0xff) != VK_NUMLOCK)
707 TRACE( "adjusting NumLock state (%02x)\n", keystate[VK_NUMLOCK] );
708 send_keyboard_input( 0, VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY );
709 send_keyboard_input( 0, VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP );
712 if (!(keystate[VK_SCROLL] & 0x01) != !(state & AMETA_SCROLL_LOCK_ON) && vkey != VK_SCROLL)
714 TRACE( "adjusting ScrollLock state (%02x)\n", keystate[VK_SCROLL] );
715 send_keyboard_input( 0, VK_SCROLL, 0x46, 0 );
716 send_keyboard_input( 0, VK_SCROLL, 0x46, KEYEVENTF_KEYUP );
721 /***********************************************************************
722 * keyboard_event
724 * JNI callback, runs in the context of the Java thread.
726 jboolean keyboard_event( JNIEnv *env, jobject obj, jint win, jint action, jint keycode, jint state )
728 union event_data data;
730 if ((unsigned int)keycode >= ARRAY_SIZE( keycode_to_vkey ) ||
731 !keycode_to_vkey[keycode])
733 p__android_log_print( ANDROID_LOG_WARN, "wine",
734 "keyboard_event: win %x code %u unmapped key, ignoring", win, keycode );
735 return JNI_FALSE;
737 data.type = KEYBOARD_EVENT;
738 data.kbd.hwnd = LongToHandle( win );
739 data.kbd.lock_state = state;
740 data.kbd.input.type = INPUT_KEYBOARD;
741 data.kbd.input.u.ki.wVk = keycode_to_vkey[keycode];
742 data.kbd.input.u.ki.wScan = vkey_to_scancode[data.kbd.input.u.ki.wVk];
743 data.kbd.input.u.ki.time = 0;
744 data.kbd.input.u.ki.dwExtraInfo = 0;
745 data.kbd.input.u.ki.dwFlags = (data.kbd.input.u.ki.wScan & 0x100) ? KEYEVENTF_EXTENDEDKEY : 0;
746 if (action == AKEY_EVENT_ACTION_UP) data.kbd.input.u.ki.dwFlags |= KEYEVENTF_KEYUP;
748 p__android_log_print( ANDROID_LOG_INFO, "wine",
749 "keyboard_event: win %x code %u vkey %x scan %x meta %x",
750 win, keycode, data.kbd.input.u.ki.wVk, data.kbd.input.u.ki.wScan, state );
751 send_event( &data );
752 return JNI_TRUE;
756 /***********************************************************************
757 * ANDROID_GetKeyNameText
759 INT ANDROID_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
761 int scancode, vkey;
762 const char *name;
763 char key[2];
764 DWORD len;
766 scancode = (lparam >> 16) & 0x1FF;
767 vkey = scancode_to_vkey( scancode );
769 if (lparam & (1 << 25))
771 /* Caller doesn't care about distinctions between left and
772 right keys. */
773 switch (vkey)
775 case VK_LSHIFT:
776 case VK_RSHIFT:
777 vkey = VK_SHIFT; break;
778 case VK_LCONTROL:
779 case VK_RCONTROL:
780 vkey = VK_CONTROL; break;
781 case VK_LMENU:
782 case VK_RMENU:
783 vkey = VK_MENU; break;
787 if (scancode & 0x100) vkey |= 0x100;
789 if ((vkey >= 0x30 && vkey <= 0x39) || (vkey >= 0x41 && vkey <= 0x5a))
791 key[0] = vkey;
792 if (vkey >= 0x41)
793 key[0] += 0x20;
794 key[1] = 0;
795 name = key;
797 else
799 name = vkey_to_name( vkey );
802 RtlUTF8ToUnicodeN( buffer, size * sizeof(WCHAR), &len, name, strlen( name ) + 1 );
803 len /= sizeof(WCHAR);
804 if (len) len--;
806 if (!len)
808 char name[16];
809 len = sprintf( name, "Key 0x%02x", vkey );
810 len = min( len + 1, size );
811 ascii_to_unicode( buffer, name, len );
812 if (len) buffer[--len] = 0;
815 TRACE( "lparam 0x%08x -> %s\n", lparam, debugstr_w( buffer ));
816 return len;
820 /***********************************************************************
821 * ANDROID_MapVirtualKeyEx
823 UINT ANDROID_MapVirtualKeyEx( UINT code, UINT maptype, HKL hkl )
825 UINT ret = 0;
826 const char *s;
828 TRACE_(key)( "code=0x%x, maptype=%d, hkl %p\n", code, maptype, hkl );
830 switch (maptype)
832 case MAPVK_VK_TO_VSC_EX:
833 case MAPVK_VK_TO_VSC:
834 /* vkey to scancode */
835 switch (code)
837 case VK_SHIFT:
838 code = VK_LSHIFT;
839 break;
840 case VK_CONTROL:
841 code = VK_LCONTROL;
842 break;
843 case VK_MENU:
844 code = VK_LMENU;
845 break;
847 if (code < ARRAY_SIZE( vkey_to_scancode )) ret = vkey_to_scancode[code];
849 /* set scan code prefix */
850 if (maptype == MAPVK_VK_TO_VSC_EX &&
851 (code == VK_RCONTROL || code == VK_RMENU))
852 ret |= 0xe000;
853 break;
854 case MAPVK_VSC_TO_VK:
855 case MAPVK_VSC_TO_VK_EX:
856 /* scancode to vkey */
857 ret = scancode_to_vkey( code );
858 if (maptype == MAPVK_VSC_TO_VK)
859 switch (ret)
861 case VK_LSHIFT:
862 case VK_RSHIFT:
863 ret = VK_SHIFT; break;
864 case VK_LCONTROL:
865 case VK_RCONTROL:
866 ret = VK_CONTROL; break;
867 case VK_LMENU:
868 case VK_RMENU:
869 ret = VK_MENU; break;
871 break;
872 case MAPVK_VK_TO_CHAR:
873 s = vkey_to_name( code );
874 if (s && (strlen( s ) == 1))
875 ret = s[0];
876 else
877 ret = 0;
878 break;
879 default:
880 FIXME( "Unknown maptype %d\n", maptype );
881 break;
883 TRACE_(key)( "returning 0x%04x\n", ret );
884 return ret;
888 /***********************************************************************
889 * ANDROID_VkKeyScanEx
891 SHORT ANDROID_VkKeyScanEx( WCHAR ch, HKL hkl )
893 SHORT ret = -1;
894 if (ch < ARRAY_SIZE( char_vkey_map )) ret = char_vkey_map[ch];
895 TRACE_(key)( "ch %04x hkl %p -> %04x\n", ch, hkl, ret );
896 return ret;