1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
6
7 #define XK_3270 // for XK_3270_BackTab
8 #include <X11/keysym.h>
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include <X11/XF86keysym.h>
12
13 #include "base/basictypes.h"
14 #include "base/logging.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "ui/events/keycodes/dom4/keycode_converter.h"
18
19 namespace ui {
20
21 // Get an ui::KeyboardCode from an X keyevent
KeyboardCodeFromXKeyEvent(XEvent * xev)22 KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) {
23 // XLookupKeysym does not take into consideration the state of the lock/shift
24 // etc. keys. So it is necessary to use XLookupString instead.
25 KeySym keysym;
26 XLookupString(&xev->xkey, NULL, 0, &keysym, NULL);
27 KeyboardCode keycode = KeyboardCodeFromXKeysym(keysym);
28 if (keycode == VKEY_UNKNOWN) {
29 keysym = DefaultXKeysymFromHardwareKeycode(xev->xkey.keycode);
30 keycode = KeyboardCodeFromXKeysym(keysym);
31 }
32
33 return keycode;
34 }
35
KeyboardCodeFromXKeysym(unsigned int keysym)36 KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) {
37 // TODO(sad): Have |keysym| go through the X map list?
38
39 switch (keysym) {
40 case XK_BackSpace:
41 return VKEY_BACK;
42 case XK_Delete:
43 case XK_KP_Delete:
44 return VKEY_DELETE;
45 case XK_Tab:
46 case XK_KP_Tab:
47 case XK_ISO_Left_Tab:
48 case XK_3270_BackTab:
49 return VKEY_TAB;
50 case XK_Linefeed:
51 case XK_Return:
52 case XK_KP_Enter:
53 case XK_ISO_Enter:
54 return VKEY_RETURN;
55 case XK_Clear:
56 case XK_KP_Begin: // NumPad 5 without Num Lock, for crosbug.com/29169.
57 return VKEY_CLEAR;
58 case XK_KP_Space:
59 case XK_space:
60 return VKEY_SPACE;
61 case XK_Home:
62 case XK_KP_Home:
63 return VKEY_HOME;
64 case XK_End:
65 case XK_KP_End:
66 return VKEY_END;
67 case XK_Page_Up:
68 case XK_KP_Page_Up: // aka XK_KP_Prior
69 return VKEY_PRIOR;
70 case XK_Page_Down:
71 case XK_KP_Page_Down: // aka XK_KP_Next
72 return VKEY_NEXT;
73 case XK_Left:
74 case XK_KP_Left:
75 return VKEY_LEFT;
76 case XK_Right:
77 case XK_KP_Right:
78 return VKEY_RIGHT;
79 case XK_Down:
80 case XK_KP_Down:
81 return VKEY_DOWN;
82 case XK_Up:
83 case XK_KP_Up:
84 return VKEY_UP;
85 case XK_Escape:
86 return VKEY_ESCAPE;
87 case XK_Kana_Lock:
88 case XK_Kana_Shift:
89 return VKEY_KANA;
90 case XK_Hangul:
91 return VKEY_HANGUL;
92 case XK_Hangul_Hanja:
93 return VKEY_HANJA;
94 case XK_Kanji:
95 return VKEY_KANJI;
96 case XK_Henkan:
97 return VKEY_CONVERT;
98 case XK_Muhenkan:
99 return VKEY_NONCONVERT;
100 case XK_Zenkaku_Hankaku:
101 return VKEY_DBE_DBCSCHAR;
102 case XK_A:
103 case XK_a:
104 return VKEY_A;
105 case XK_B:
106 case XK_b:
107 return VKEY_B;
108 case XK_C:
109 case XK_c:
110 return VKEY_C;
111 case XK_D:
112 case XK_d:
113 return VKEY_D;
114 case XK_E:
115 case XK_e:
116 return VKEY_E;
117 case XK_F:
118 case XK_f:
119 return VKEY_F;
120 case XK_G:
121 case XK_g:
122 return VKEY_G;
123 case XK_H:
124 case XK_h:
125 return VKEY_H;
126 case XK_I:
127 case XK_i:
128 return VKEY_I;
129 case XK_J:
130 case XK_j:
131 return VKEY_J;
132 case XK_K:
133 case XK_k:
134 return VKEY_K;
135 case XK_L:
136 case XK_l:
137 return VKEY_L;
138 case XK_M:
139 case XK_m:
140 return VKEY_M;
141 case XK_N:
142 case XK_n:
143 return VKEY_N;
144 case XK_O:
145 case XK_o:
146 return VKEY_O;
147 case XK_P:
148 case XK_p:
149 return VKEY_P;
150 case XK_Q:
151 case XK_q:
152 return VKEY_Q;
153 case XK_R:
154 case XK_r:
155 return VKEY_R;
156 case XK_S:
157 case XK_s:
158 return VKEY_S;
159 case XK_T:
160 case XK_t:
161 return VKEY_T;
162 case XK_U:
163 case XK_u:
164 return VKEY_U;
165 case XK_V:
166 case XK_v:
167 return VKEY_V;
168 case XK_W:
169 case XK_w:
170 return VKEY_W;
171 case XK_X:
172 case XK_x:
173 return VKEY_X;
174 case XK_Y:
175 case XK_y:
176 return VKEY_Y;
177 case XK_Z:
178 case XK_z:
179 return VKEY_Z;
180
181 case XK_0:
182 case XK_1:
183 case XK_2:
184 case XK_3:
185 case XK_4:
186 case XK_5:
187 case XK_6:
188 case XK_7:
189 case XK_8:
190 case XK_9:
191 return static_cast<KeyboardCode>(VKEY_0 + (keysym - XK_0));
192
193 case XK_parenright:
194 return VKEY_0;
195 case XK_exclam:
196 return VKEY_1;
197 case XK_at:
198 return VKEY_2;
199 case XK_numbersign:
200 return VKEY_3;
201 case XK_dollar:
202 return VKEY_4;
203 case XK_percent:
204 return VKEY_5;
205 case XK_asciicircum:
206 return VKEY_6;
207 case XK_ampersand:
208 return VKEY_7;
209 case XK_asterisk:
210 return VKEY_8;
211 case XK_parenleft:
212 return VKEY_9;
213
214 case XK_KP_0:
215 case XK_KP_1:
216 case XK_KP_2:
217 case XK_KP_3:
218 case XK_KP_4:
219 case XK_KP_5:
220 case XK_KP_6:
221 case XK_KP_7:
222 case XK_KP_8:
223 case XK_KP_9:
224 return static_cast<KeyboardCode>(VKEY_NUMPAD0 + (keysym - XK_KP_0));
225
226 case XK_multiply:
227 case XK_KP_Multiply:
228 return VKEY_MULTIPLY;
229 case XK_KP_Add:
230 return VKEY_ADD;
231 case XK_KP_Separator:
232 return VKEY_SEPARATOR;
233 case XK_KP_Subtract:
234 return VKEY_SUBTRACT;
235 case XK_KP_Decimal:
236 return VKEY_DECIMAL;
237 case XK_KP_Divide:
238 return VKEY_DIVIDE;
239 case XK_KP_Equal:
240 case XK_equal:
241 case XK_plus:
242 return VKEY_OEM_PLUS;
243 case XK_comma:
244 case XK_less:
245 return VKEY_OEM_COMMA;
246 case XK_minus:
247 case XK_underscore:
248 return VKEY_OEM_MINUS;
249 case XK_greater:
250 case XK_period:
251 return VKEY_OEM_PERIOD;
252 case XK_colon:
253 case XK_semicolon:
254 return VKEY_OEM_1;
255 case XK_question:
256 case XK_slash:
257 return VKEY_OEM_2;
258 case XK_asciitilde:
259 case XK_quoteleft:
260 return VKEY_OEM_3;
261 case XK_bracketleft:
262 case XK_braceleft:
263 return VKEY_OEM_4;
264 case XK_backslash:
265 case XK_bar:
266 return VKEY_OEM_5;
267 case XK_bracketright:
268 case XK_braceright:
269 return VKEY_OEM_6;
270 case XK_quoteright:
271 case XK_quotedbl:
272 return VKEY_OEM_7;
273 case XK_ISO_Level5_Shift:
274 return VKEY_OEM_8;
275 case XK_Shift_L:
276 case XK_Shift_R:
277 return VKEY_SHIFT;
278 case XK_Control_L:
279 case XK_Control_R:
280 return VKEY_CONTROL;
281 case XK_Meta_L:
282 case XK_Meta_R:
283 case XK_Alt_L:
284 case XK_Alt_R:
285 return VKEY_MENU;
286 case XK_ISO_Level3_Shift:
287 return VKEY_ALTGR;
288 case XK_Multi_key:
289 return VKEY_COMPOSE;
290 case XK_Pause:
291 return VKEY_PAUSE;
292 case XK_Caps_Lock:
293 return VKEY_CAPITAL;
294 case XK_Num_Lock:
295 return VKEY_NUMLOCK;
296 case XK_Scroll_Lock:
297 return VKEY_SCROLL;
298 case XK_Select:
299 return VKEY_SELECT;
300 case XK_Print:
301 return VKEY_PRINT;
302 case XK_Execute:
303 return VKEY_EXECUTE;
304 case XK_Insert:
305 case XK_KP_Insert:
306 return VKEY_INSERT;
307 case XK_Help:
308 return VKEY_HELP;
309 case XK_Super_L:
310 return VKEY_LWIN;
311 case XK_Super_R:
312 return VKEY_RWIN;
313 case XK_Menu:
314 return VKEY_APPS;
315 case XK_F1:
316 case XK_F2:
317 case XK_F3:
318 case XK_F4:
319 case XK_F5:
320 case XK_F6:
321 case XK_F7:
322 case XK_F8:
323 case XK_F9:
324 case XK_F10:
325 case XK_F11:
326 case XK_F12:
327 case XK_F13:
328 case XK_F14:
329 case XK_F15:
330 case XK_F16:
331 case XK_F17:
332 case XK_F18:
333 case XK_F19:
334 case XK_F20:
335 case XK_F21:
336 case XK_F22:
337 case XK_F23:
338 case XK_F24:
339 return static_cast<KeyboardCode>(VKEY_F1 + (keysym - XK_F1));
340 case XK_KP_F1:
341 case XK_KP_F2:
342 case XK_KP_F3:
343 case XK_KP_F4:
344 return static_cast<KeyboardCode>(VKEY_F1 + (keysym - XK_KP_F1));
345
346 case XK_guillemotleft:
347 case XK_guillemotright:
348 case XK_degree:
349 // In the case of canadian multilingual keyboard layout, VKEY_OEM_102 is
350 // assigned to ugrave key.
351 case XK_ugrave:
352 case XK_Ugrave:
353 case XK_brokenbar:
354 return VKEY_OEM_102; // international backslash key in 102 keyboard.
355
356 // When evdev is in use, /usr/share/X11/xkb/symbols/inet maps F13-18 keys
357 // to the special XF86XK symbols to support Microsoft Ergonomic keyboards:
358 // https://bugs.freedesktop.org/show_bug.cgi?id=5783
359 // In Chrome, we map these X key symbols back to F13-18 since we don't have
360 // VKEYs for these XF86XK symbols.
361 case XF86XK_Tools:
362 return VKEY_F13;
363 case XF86XK_Launch5:
364 return VKEY_F14;
365 case XF86XK_Launch6:
366 return VKEY_F15;
367 case XF86XK_Launch7:
368 return VKEY_F16;
369 case XF86XK_Launch8:
370 return VKEY_F17;
371 case XF86XK_Launch9:
372 return VKEY_F18;
373
374 #if defined(TOOLKIT_GTK)
375 case XF86XK_Refresh:
376 case XF86XK_History:
377 case XF86XK_OpenURL:
378 case XF86XK_AddFavorite:
379 case XF86XK_Go:
380 case XF86XK_ZoomIn:
381 case XF86XK_ZoomOut:
382 // ui::AcceleratorGtk tries to convert the XF86XK_ keysyms on Chrome
383 // startup. It's safe to return VKEY_UNKNOWN here since ui::AcceleratorGtk
384 // also checks a Gdk keysym. http://crbug.com/109843
385 return VKEY_UNKNOWN;
386 #endif
387
388 // For supporting multimedia buttons on a USB keyboard.
389 case XF86XK_Back:
390 return VKEY_BROWSER_BACK;
391 case XF86XK_Forward:
392 return VKEY_BROWSER_FORWARD;
393 case XF86XK_Reload:
394 return VKEY_BROWSER_REFRESH;
395 case XF86XK_Stop:
396 return VKEY_BROWSER_STOP;
397 case XF86XK_Search:
398 return VKEY_BROWSER_SEARCH;
399 case XF86XK_Favorites:
400 return VKEY_BROWSER_FAVORITES;
401 case XF86XK_HomePage:
402 return VKEY_BROWSER_HOME;
403 case XF86XK_AudioMute:
404 return VKEY_VOLUME_MUTE;
405 case XF86XK_AudioLowerVolume:
406 return VKEY_VOLUME_DOWN;
407 case XF86XK_AudioRaiseVolume:
408 return VKEY_VOLUME_UP;
409 case XF86XK_AudioNext:
410 return VKEY_MEDIA_NEXT_TRACK;
411 case XF86XK_AudioPrev:
412 return VKEY_MEDIA_PREV_TRACK;
413 case XF86XK_AudioStop:
414 return VKEY_MEDIA_STOP;
415 case XF86XK_AudioPlay:
416 return VKEY_MEDIA_PLAY_PAUSE;
417 case XF86XK_Mail:
418 return VKEY_MEDIA_LAUNCH_MAIL;
419 case XF86XK_LaunchA: // F3 on an Apple keyboard.
420 return VKEY_MEDIA_LAUNCH_APP1;
421 case XF86XK_LaunchB: // F4 on an Apple keyboard.
422 case XF86XK_Calculator:
423 return VKEY_MEDIA_LAUNCH_APP2;
424 case XF86XK_WLAN:
425 return VKEY_WLAN;
426 case XF86XK_PowerOff:
427 return VKEY_POWER;
428 case XF86XK_MonBrightnessDown:
429 return VKEY_BRIGHTNESS_DOWN;
430 case XF86XK_MonBrightnessUp:
431 return VKEY_BRIGHTNESS_UP;
432 case XF86XK_KbdBrightnessDown:
433 return VKEY_KBD_BRIGHTNESS_DOWN;
434 case XF86XK_KbdBrightnessUp:
435 return VKEY_KBD_BRIGHTNESS_UP;
436
437 // TODO(sad): some keycodes are still missing.
438 }
439 DLOG(WARNING) << "Unknown keysym: " << base::StringPrintf("0x%x", keysym);
440 return VKEY_UNKNOWN;
441 }
442
CodeFromXEvent(XEvent * xev)443 const char* CodeFromXEvent(XEvent* xev) {
444 return KeycodeConverter::GetInstance()->NativeKeycodeToCode(
445 xev->xkey.keycode);
446 }
447
GetCharacterFromXEvent(XEvent * xev)448 uint16 GetCharacterFromXEvent(XEvent* xev) {
449 char buf[6];
450 int bytes_written = XLookupString(&xev->xkey, buf, 6, NULL, NULL);
451 DCHECK_LE(bytes_written, 6);
452
453 base::string16 result;
454 return (bytes_written > 0 && UTF8ToUTF16(buf, bytes_written, &result) &&
455 result.length() == 1) ? result[0] : 0;
456 }
457
DefaultXKeysymFromHardwareKeycode(unsigned int hardware_code)458 unsigned int DefaultXKeysymFromHardwareKeycode(unsigned int hardware_code) {
459 static const unsigned int kHardwareKeycodeMap[] = {
460 0, // 0x00:
461 0, // 0x01:
462 0, // 0x02:
463 0, // 0x03:
464 0, // 0x04:
465 0, // 0x05:
466 0, // 0x06:
467 0, // 0x07:
468 0, // 0x08:
469 XK_Escape, // 0x09: XK_Escape
470 XK_1, // 0x0A: XK_1
471 XK_2, // 0x0B: XK_2
472 XK_3, // 0x0C: XK_3
473 XK_4, // 0x0D: XK_4
474 XK_5, // 0x0E: XK_5
475 XK_6, // 0x0F: XK_6
476 XK_7, // 0x10: XK_7
477 XK_8, // 0x11: XK_8
478 XK_9, // 0x12: XK_9
479 XK_0, // 0x13: XK_0
480 XK_minus, // 0x14: XK_minus
481 XK_equal, // 0x15: XK_equal
482 XK_BackSpace, // 0x16: XK_BackSpace
483 XK_Tab, // 0x17: XK_Tab
484 XK_q, // 0x18: XK_q
485 XK_w, // 0x19: XK_w
486 XK_e, // 0x1A: XK_e
487 XK_r, // 0x1B: XK_r
488 XK_t, // 0x1C: XK_t
489 XK_y, // 0x1D: XK_y
490 XK_u, // 0x1E: XK_u
491 XK_i, // 0x1F: XK_i
492 XK_o, // 0x20: XK_o
493 XK_p, // 0x21: XK_p
494 XK_bracketleft, // 0x22: XK_bracketleft
495 XK_bracketright, // 0x23: XK_bracketright
496 XK_Return, // 0x24: XK_Return
497 XK_Control_L, // 0x25: XK_Control_L
498 XK_a, // 0x26: XK_a
499 XK_s, // 0x27: XK_s
500 XK_d, // 0x28: XK_d
501 XK_f, // 0x29: XK_f
502 XK_g, // 0x2A: XK_g
503 XK_h, // 0x2B: XK_h
504 XK_j, // 0x2C: XK_j
505 XK_k, // 0x2D: XK_k
506 XK_l, // 0x2E: XK_l
507 XK_semicolon, // 0x2F: XK_semicolon
508 XK_apostrophe, // 0x30: XK_apostrophe
509 XK_grave, // 0x31: XK_grave
510 XK_Shift_L, // 0x32: XK_Shift_L
511 XK_backslash, // 0x33: XK_backslash
512 XK_z, // 0x34: XK_z
513 XK_x, // 0x35: XK_x
514 XK_c, // 0x36: XK_c
515 XK_v, // 0x37: XK_v
516 XK_b, // 0x38: XK_b
517 XK_n, // 0x39: XK_n
518 XK_m, // 0x3A: XK_m
519 XK_comma, // 0x3B: XK_comma
520 XK_period, // 0x3C: XK_period
521 XK_slash, // 0x3D: XK_slash
522 XK_Shift_R, // 0x3E: XK_Shift_R
523 0, // 0x3F: XK_KP_Multiply
524 XK_Alt_L, // 0x40: XK_Alt_L
525 XK_space, // 0x41: XK_space
526 XK_Caps_Lock, // 0x42: XK_Caps_Lock
527 XK_F1, // 0x43: XK_F1
528 XK_F2, // 0x44: XK_F2
529 XK_F3, // 0x45: XK_F3
530 XK_F4, // 0x46: XK_F4
531 XK_F5, // 0x47: XK_F5
532 XK_F6, // 0x48: XK_F6
533 XK_F7, // 0x49: XK_F7
534 XK_F8, // 0x4A: XK_F8
535 XK_F9, // 0x4B: XK_F9
536 XK_F10, // 0x4C: XK_F10
537 XK_Num_Lock, // 0x4D: XK_Num_Lock
538 XK_Scroll_Lock, // 0x4E: XK_Scroll_Lock
539 };
540
541 return hardware_code < arraysize(kHardwareKeycodeMap) ?
542 kHardwareKeycodeMap[hardware_code] : 0;
543 }
544
545 // TODO(jcampan): this method might be incomplete.
XKeysymForWindowsKeyCode(KeyboardCode keycode,bool shift)546 int XKeysymForWindowsKeyCode(KeyboardCode keycode, bool shift) {
547 switch (keycode) {
548 case VKEY_NUMPAD0:
549 return XK_KP_0;
550 case VKEY_NUMPAD1:
551 return XK_KP_1;
552 case VKEY_NUMPAD2:
553 return XK_KP_2;
554 case VKEY_NUMPAD3:
555 return XK_KP_3;
556 case VKEY_NUMPAD4:
557 return XK_KP_4;
558 case VKEY_NUMPAD5:
559 return XK_KP_5;
560 case VKEY_NUMPAD6:
561 return XK_KP_6;
562 case VKEY_NUMPAD7:
563 return XK_KP_7;
564 case VKEY_NUMPAD8:
565 return XK_KP_8;
566 case VKEY_NUMPAD9:
567 return XK_KP_9;
568 case VKEY_MULTIPLY:
569 return XK_KP_Multiply;
570 case VKEY_ADD:
571 return XK_KP_Add;
572 case VKEY_SUBTRACT:
573 return XK_KP_Subtract;
574 case VKEY_DECIMAL:
575 return XK_KP_Decimal;
576 case VKEY_DIVIDE:
577 return XK_KP_Divide;
578
579 case VKEY_BACK:
580 return XK_BackSpace;
581 case VKEY_TAB:
582 return shift ? XK_ISO_Left_Tab : XK_Tab;
583 case VKEY_CLEAR:
584 return XK_Clear;
585 case VKEY_RETURN:
586 return XK_Return;
587 case VKEY_SHIFT:
588 return XK_Shift_L;
589 case VKEY_CONTROL:
590 return XK_Control_L;
591 case VKEY_MENU:
592 return XK_Alt_L;
593 case VKEY_APPS:
594 return XK_Menu;
595 case VKEY_ALTGR:
596 return XK_ISO_Level3_Shift;
597 case VKEY_COMPOSE:
598 return XK_Multi_key;
599
600 case VKEY_PAUSE:
601 return XK_Pause;
602 case VKEY_CAPITAL:
603 return XK_Caps_Lock;
604 case VKEY_KANA:
605 return XK_Kana_Lock;
606 case VKEY_HANJA:
607 return XK_Hangul_Hanja;
608 case VKEY_CONVERT:
609 return XK_Henkan;
610 case VKEY_NONCONVERT:
611 return XK_Muhenkan;
612 case VKEY_DBE_SBCSCHAR:
613 return XK_Zenkaku_Hankaku;
614 case VKEY_DBE_DBCSCHAR:
615 return XK_Zenkaku_Hankaku;
616 case VKEY_ESCAPE:
617 return XK_Escape;
618 case VKEY_SPACE:
619 return XK_space;
620 case VKEY_PRIOR:
621 return XK_Page_Up;
622 case VKEY_NEXT:
623 return XK_Page_Down;
624 case VKEY_END:
625 return XK_End;
626 case VKEY_HOME:
627 return XK_Home;
628 case VKEY_LEFT:
629 return XK_Left;
630 case VKEY_UP:
631 return XK_Up;
632 case VKEY_RIGHT:
633 return XK_Right;
634 case VKEY_DOWN:
635 return XK_Down;
636 case VKEY_SELECT:
637 return XK_Select;
638 case VKEY_PRINT:
639 return XK_Print;
640 case VKEY_EXECUTE:
641 return XK_Execute;
642 case VKEY_INSERT:
643 return XK_Insert;
644 case VKEY_DELETE:
645 return XK_Delete;
646 case VKEY_HELP:
647 return XK_Help;
648 case VKEY_0:
649 return shift ? XK_parenright : XK_0;
650 case VKEY_1:
651 return shift ? XK_exclam : XK_1;
652 case VKEY_2:
653 return shift ? XK_at : XK_2;
654 case VKEY_3:
655 return shift ? XK_numbersign : XK_3;
656 case VKEY_4:
657 return shift ? XK_dollar : XK_4;
658 case VKEY_5:
659 return shift ? XK_percent : XK_5;
660 case VKEY_6:
661 return shift ? XK_asciicircum : XK_6;
662 case VKEY_7:
663 return shift ? XK_ampersand : XK_7;
664 case VKEY_8:
665 return shift ? XK_asterisk : XK_8;
666 case VKEY_9:
667 return shift ? XK_parenleft : XK_9;
668
669 case VKEY_A:
670 case VKEY_B:
671 case VKEY_C:
672 case VKEY_D:
673 case VKEY_E:
674 case VKEY_F:
675 case VKEY_G:
676 case VKEY_H:
677 case VKEY_I:
678 case VKEY_J:
679 case VKEY_K:
680 case VKEY_L:
681 case VKEY_M:
682 case VKEY_N:
683 case VKEY_O:
684 case VKEY_P:
685 case VKEY_Q:
686 case VKEY_R:
687 case VKEY_S:
688 case VKEY_T:
689 case VKEY_U:
690 case VKEY_V:
691 case VKEY_W:
692 case VKEY_X:
693 case VKEY_Y:
694 case VKEY_Z:
695 return (shift ? XK_A : XK_a) + (keycode - VKEY_A);
696
697 case VKEY_LWIN:
698 return XK_Super_L;
699 case VKEY_RWIN:
700 return XK_Super_R;
701
702 case VKEY_NUMLOCK:
703 return XK_Num_Lock;
704
705 case VKEY_SCROLL:
706 return XK_Scroll_Lock;
707
708 case VKEY_OEM_1:
709 return shift ? XK_colon : XK_semicolon;
710 case VKEY_OEM_PLUS:
711 return shift ? XK_plus : XK_equal;
712 case VKEY_OEM_COMMA:
713 return shift ? XK_less : XK_comma;
714 case VKEY_OEM_MINUS:
715 return shift ? XK_underscore : XK_minus;
716 case VKEY_OEM_PERIOD:
717 return shift ? XK_greater : XK_period;
718 case VKEY_OEM_2:
719 return shift ? XK_question : XK_slash;
720 case VKEY_OEM_3:
721 return shift ? XK_asciitilde : XK_quoteleft;
722 case VKEY_OEM_4:
723 return shift ? XK_braceleft : XK_bracketleft;
724 case VKEY_OEM_5:
725 return shift ? XK_bar : XK_backslash;
726 case VKEY_OEM_6:
727 return shift ? XK_braceright : XK_bracketright;
728 case VKEY_OEM_7:
729 return shift ? XK_quotedbl : XK_quoteright;
730 case VKEY_OEM_8:
731 return XK_ISO_Level5_Shift;
732 case VKEY_OEM_102:
733 return shift ? XK_guillemotleft : XK_guillemotright;
734
735 case VKEY_F1:
736 case VKEY_F2:
737 case VKEY_F3:
738 case VKEY_F4:
739 case VKEY_F5:
740 case VKEY_F6:
741 case VKEY_F7:
742 case VKEY_F8:
743 case VKEY_F9:
744 case VKEY_F10:
745 case VKEY_F11:
746 case VKEY_F12:
747 case VKEY_F13:
748 case VKEY_F14:
749 case VKEY_F15:
750 case VKEY_F16:
751 case VKEY_F17:
752 case VKEY_F18:
753 case VKEY_F19:
754 case VKEY_F20:
755 case VKEY_F21:
756 case VKEY_F22:
757 case VKEY_F23:
758 case VKEY_F24:
759 return XK_F1 + (keycode - VKEY_F1);
760
761 case VKEY_BROWSER_BACK:
762 return XF86XK_Back;
763 case VKEY_BROWSER_FORWARD:
764 return XF86XK_Forward;
765 case VKEY_BROWSER_REFRESH:
766 return XF86XK_Reload;
767 case VKEY_BROWSER_STOP:
768 return XF86XK_Stop;
769 case VKEY_BROWSER_SEARCH:
770 return XF86XK_Search;
771 case VKEY_BROWSER_FAVORITES:
772 return XF86XK_Favorites;
773 case VKEY_BROWSER_HOME:
774 return XF86XK_HomePage;
775 case VKEY_VOLUME_MUTE:
776 return XF86XK_AudioMute;
777 case VKEY_VOLUME_DOWN:
778 return XF86XK_AudioLowerVolume;
779 case VKEY_VOLUME_UP:
780 return XF86XK_AudioRaiseVolume;
781 case VKEY_MEDIA_NEXT_TRACK:
782 return XF86XK_AudioNext;
783 case VKEY_MEDIA_PREV_TRACK:
784 return XF86XK_AudioPrev;
785 case VKEY_MEDIA_STOP:
786 return XF86XK_AudioStop;
787 case VKEY_MEDIA_PLAY_PAUSE:
788 return XF86XK_AudioPlay;
789 case VKEY_MEDIA_LAUNCH_MAIL:
790 return XF86XK_Mail;
791 case VKEY_MEDIA_LAUNCH_APP1:
792 return XF86XK_LaunchA;
793 case VKEY_MEDIA_LAUNCH_APP2:
794 return XF86XK_LaunchB;
795 case VKEY_WLAN:
796 return XF86XK_WLAN;
797 case VKEY_POWER:
798 return XF86XK_PowerOff;
799 case VKEY_BRIGHTNESS_DOWN:
800 return XF86XK_MonBrightnessDown;
801 case VKEY_BRIGHTNESS_UP:
802 return XF86XK_MonBrightnessUp;
803 case VKEY_KBD_BRIGHTNESS_DOWN:
804 return XF86XK_KbdBrightnessDown;
805 case VKEY_KBD_BRIGHTNESS_UP:
806 return XF86XK_KbdBrightnessUp;
807
808 default:
809 LOG(WARNING) << "Unknown keycode:" << keycode;
810 return 0;
811 }
812 }
813
814 } // namespace ui
815