Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / ui / events / keycodes / keyboard_code_conversion_x.cc
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
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
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
443 const char* CodeFromXEvent(XEvent* xev) {
444   return KeycodeConverter::GetInstance()->NativeKeycodeToCode(
445       xev->xkey.keycode);
446 }
447
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 && base::UTF8ToUTF16(buf, bytes_written, &result) &&
455           result.length() == 1) ? result[0] : 0;
456 }
457
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.
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