Upstream version 7.36.149.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     // For supporting multimedia buttons on a USB keyboard.
375     case XF86XK_Back:
376       return VKEY_BROWSER_BACK;
377     case XF86XK_Forward:
378       return VKEY_BROWSER_FORWARD;
379     case XF86XK_Reload:
380       return VKEY_BROWSER_REFRESH;
381     case XF86XK_Stop:
382       return VKEY_BROWSER_STOP;
383     case XF86XK_Search:
384       return VKEY_BROWSER_SEARCH;
385     case XF86XK_Favorites:
386       return VKEY_BROWSER_FAVORITES;
387     case XF86XK_HomePage:
388       return VKEY_BROWSER_HOME;
389     case XF86XK_AudioMute:
390       return VKEY_VOLUME_MUTE;
391     case XF86XK_AudioLowerVolume:
392       return VKEY_VOLUME_DOWN;
393     case XF86XK_AudioRaiseVolume:
394       return VKEY_VOLUME_UP;
395     case XF86XK_AudioNext:
396       return VKEY_MEDIA_NEXT_TRACK;
397     case XF86XK_AudioPrev:
398       return VKEY_MEDIA_PREV_TRACK;
399     case XF86XK_AudioStop:
400       return VKEY_MEDIA_STOP;
401     case XF86XK_AudioPlay:
402       return VKEY_MEDIA_PLAY_PAUSE;
403     case XF86XK_Mail:
404       return VKEY_MEDIA_LAUNCH_MAIL;
405     case XF86XK_LaunchA:  // F3 on an Apple keyboard.
406       return VKEY_MEDIA_LAUNCH_APP1;
407     case XF86XK_LaunchB:  // F4 on an Apple keyboard.
408     case XF86XK_Calculator:
409       return VKEY_MEDIA_LAUNCH_APP2;
410     case XF86XK_WLAN:
411       return VKEY_WLAN;
412     case XF86XK_PowerOff:
413       return VKEY_POWER;
414     case XF86XK_MonBrightnessDown:
415       return VKEY_BRIGHTNESS_DOWN;
416     case XF86XK_MonBrightnessUp:
417       return VKEY_BRIGHTNESS_UP;
418     case XF86XK_KbdBrightnessDown:
419       return VKEY_KBD_BRIGHTNESS_DOWN;
420     case XF86XK_KbdBrightnessUp:
421       return VKEY_KBD_BRIGHTNESS_UP;
422
423     // TODO(sad): some keycodes are still missing.
424   }
425   DLOG(WARNING) << "Unknown keysym: " << base::StringPrintf("0x%x", keysym);
426   return VKEY_UNKNOWN;
427 }
428
429 const char* CodeFromXEvent(XEvent* xev) {
430   return KeycodeConverter::GetInstance()->NativeKeycodeToCode(
431       xev->xkey.keycode);
432 }
433
434 uint16 GetCharacterFromXEvent(XEvent* xev) {
435   char buf[6];
436   int bytes_written = XLookupString(&xev->xkey, buf, 6, NULL, NULL);
437   DCHECK_LE(bytes_written, 6);
438
439   base::string16 result;
440   return (bytes_written > 0 && base::UTF8ToUTF16(buf, bytes_written, &result) &&
441           result.length() == 1) ? result[0] : 0;
442 }
443
444 unsigned int DefaultXKeysymFromHardwareKeycode(unsigned int hardware_code) {
445   static const unsigned int kHardwareKeycodeMap[] = {
446     0,                // 0x00:
447     0,                // 0x01:
448     0,                // 0x02:
449     0,                // 0x03:
450     0,                // 0x04:
451     0,                // 0x05:
452     0,                // 0x06:
453     0,                // 0x07:
454     0,                // 0x08:
455     XK_Escape,        // 0x09: XK_Escape
456     XK_1,             // 0x0A: XK_1
457     XK_2,             // 0x0B: XK_2
458     XK_3,             // 0x0C: XK_3
459     XK_4,             // 0x0D: XK_4
460     XK_5,             // 0x0E: XK_5
461     XK_6,             // 0x0F: XK_6
462     XK_7,             // 0x10: XK_7
463     XK_8,             // 0x11: XK_8
464     XK_9,             // 0x12: XK_9
465     XK_0,             // 0x13: XK_0
466     XK_minus,         // 0x14: XK_minus
467     XK_equal,         // 0x15: XK_equal
468     XK_BackSpace,     // 0x16: XK_BackSpace
469     XK_Tab,           // 0x17: XK_Tab
470     XK_q,             // 0x18: XK_q
471     XK_w,             // 0x19: XK_w
472     XK_e,             // 0x1A: XK_e
473     XK_r,             // 0x1B: XK_r
474     XK_t,             // 0x1C: XK_t
475     XK_y,             // 0x1D: XK_y
476     XK_u,             // 0x1E: XK_u
477     XK_i,             // 0x1F: XK_i
478     XK_o,             // 0x20: XK_o
479     XK_p,             // 0x21: XK_p
480     XK_bracketleft,   // 0x22: XK_bracketleft
481     XK_bracketright,  // 0x23: XK_bracketright
482     XK_Return,        // 0x24: XK_Return
483     XK_Control_L,     // 0x25: XK_Control_L
484     XK_a,             // 0x26: XK_a
485     XK_s,             // 0x27: XK_s
486     XK_d,             // 0x28: XK_d
487     XK_f,             // 0x29: XK_f
488     XK_g,             // 0x2A: XK_g
489     XK_h,             // 0x2B: XK_h
490     XK_j,             // 0x2C: XK_j
491     XK_k,             // 0x2D: XK_k
492     XK_l,             // 0x2E: XK_l
493     XK_semicolon,     // 0x2F: XK_semicolon
494     XK_apostrophe,    // 0x30: XK_apostrophe
495     XK_grave,         // 0x31: XK_grave
496     XK_Shift_L,       // 0x32: XK_Shift_L
497     XK_backslash,     // 0x33: XK_backslash
498     XK_z,             // 0x34: XK_z
499     XK_x,             // 0x35: XK_x
500     XK_c,             // 0x36: XK_c
501     XK_v,             // 0x37: XK_v
502     XK_b,             // 0x38: XK_b
503     XK_n,             // 0x39: XK_n
504     XK_m,             // 0x3A: XK_m
505     XK_comma,         // 0x3B: XK_comma
506     XK_period,        // 0x3C: XK_period
507     XK_slash,         // 0x3D: XK_slash
508     XK_Shift_R,       // 0x3E: XK_Shift_R
509     0,                // 0x3F: XK_KP_Multiply
510     XK_Alt_L,         // 0x40: XK_Alt_L
511     XK_space,         // 0x41: XK_space
512     XK_Caps_Lock,     // 0x42: XK_Caps_Lock
513     XK_F1,            // 0x43: XK_F1
514     XK_F2,            // 0x44: XK_F2
515     XK_F3,            // 0x45: XK_F3
516     XK_F4,            // 0x46: XK_F4
517     XK_F5,            // 0x47: XK_F5
518     XK_F6,            // 0x48: XK_F6
519     XK_F7,            // 0x49: XK_F7
520     XK_F8,            // 0x4A: XK_F8
521     XK_F9,            // 0x4B: XK_F9
522     XK_F10,           // 0x4C: XK_F10
523     XK_Num_Lock,      // 0x4D: XK_Num_Lock
524     XK_Scroll_Lock,   // 0x4E: XK_Scroll_Lock
525   };
526
527   if (hardware_code >= arraysize(kHardwareKeycodeMap)) {
528     // Checks for arrow keys.
529     switch (hardware_code) {
530       case 0x6f:
531         return XK_Up;
532       case 0x71:
533         return XK_Left;
534       case 0x72:
535         return XK_Right;
536       case 0x74:
537         return XK_Down;
538     }
539     return 0;
540   }
541   return kHardwareKeycodeMap[hardware_code];
542 }
543
544 // TODO(jcampan): this method might be incomplete.
545 int XKeysymForWindowsKeyCode(KeyboardCode keycode, bool shift) {
546   switch (keycode) {
547     case VKEY_NUMPAD0:
548       return XK_KP_0;
549     case VKEY_NUMPAD1:
550       return XK_KP_1;
551     case VKEY_NUMPAD2:
552       return XK_KP_2;
553     case VKEY_NUMPAD3:
554       return XK_KP_3;
555     case VKEY_NUMPAD4:
556       return XK_KP_4;
557     case VKEY_NUMPAD5:
558       return XK_KP_5;
559     case VKEY_NUMPAD6:
560       return XK_KP_6;
561     case VKEY_NUMPAD7:
562       return XK_KP_7;
563     case VKEY_NUMPAD8:
564       return XK_KP_8;
565     case VKEY_NUMPAD9:
566       return XK_KP_9;
567     case VKEY_MULTIPLY:
568       return XK_KP_Multiply;
569     case VKEY_ADD:
570       return XK_KP_Add;
571     case VKEY_SUBTRACT:
572       return XK_KP_Subtract;
573     case VKEY_DECIMAL:
574       return XK_KP_Decimal;
575     case VKEY_DIVIDE:
576       return XK_KP_Divide;
577
578     case VKEY_BACK:
579       return XK_BackSpace;
580     case VKEY_TAB:
581       return shift ? XK_ISO_Left_Tab : XK_Tab;
582     case VKEY_CLEAR:
583       return XK_Clear;
584     case VKEY_RETURN:
585       return XK_Return;
586     case VKEY_SHIFT:
587       return XK_Shift_L;
588     case VKEY_CONTROL:
589       return XK_Control_L;
590     case VKEY_MENU:
591       return XK_Alt_L;
592     case VKEY_APPS:
593       return XK_Menu;
594     case VKEY_ALTGR:
595       return XK_ISO_Level3_Shift;
596     case VKEY_COMPOSE:
597       return XK_Multi_key;
598
599     case VKEY_PAUSE:
600       return XK_Pause;
601     case VKEY_CAPITAL:
602       return XK_Caps_Lock;
603     case VKEY_KANA:
604       return XK_Kana_Lock;
605     case VKEY_HANJA:
606       return XK_Hangul_Hanja;
607     case VKEY_CONVERT:
608       return XK_Henkan;
609     case VKEY_NONCONVERT:
610       return XK_Muhenkan;
611     case VKEY_DBE_SBCSCHAR:
612       return XK_Zenkaku_Hankaku;
613     case VKEY_DBE_DBCSCHAR:
614       return XK_Zenkaku_Hankaku;
615     case VKEY_ESCAPE:
616       return XK_Escape;
617     case VKEY_SPACE:
618       return XK_space;
619     case VKEY_PRIOR:
620       return XK_Page_Up;
621     case VKEY_NEXT:
622       return XK_Page_Down;
623     case VKEY_END:
624       return XK_End;
625     case VKEY_HOME:
626       return XK_Home;
627     case VKEY_LEFT:
628       return XK_Left;
629     case VKEY_UP:
630       return XK_Up;
631     case VKEY_RIGHT:
632       return XK_Right;
633     case VKEY_DOWN:
634       return XK_Down;
635     case VKEY_SELECT:
636       return XK_Select;
637     case VKEY_PRINT:
638       return XK_Print;
639     case VKEY_EXECUTE:
640       return XK_Execute;
641     case VKEY_INSERT:
642       return XK_Insert;
643     case VKEY_DELETE:
644       return XK_Delete;
645     case VKEY_HELP:
646       return XK_Help;
647     case VKEY_0:
648       return shift ? XK_parenright : XK_0;
649     case VKEY_1:
650       return shift ? XK_exclam : XK_1;
651     case VKEY_2:
652       return shift ? XK_at : XK_2;
653     case VKEY_3:
654       return shift ? XK_numbersign : XK_3;
655     case VKEY_4:
656       return shift ? XK_dollar : XK_4;
657     case VKEY_5:
658       return shift ? XK_percent : XK_5;
659     case VKEY_6:
660       return shift ? XK_asciicircum : XK_6;
661     case VKEY_7:
662       return shift ? XK_ampersand : XK_7;
663     case VKEY_8:
664       return shift ? XK_asterisk : XK_8;
665     case VKEY_9:
666       return shift ? XK_parenleft : XK_9;
667
668     case VKEY_A:
669     case VKEY_B:
670     case VKEY_C:
671     case VKEY_D:
672     case VKEY_E:
673     case VKEY_F:
674     case VKEY_G:
675     case VKEY_H:
676     case VKEY_I:
677     case VKEY_J:
678     case VKEY_K:
679     case VKEY_L:
680     case VKEY_M:
681     case VKEY_N:
682     case VKEY_O:
683     case VKEY_P:
684     case VKEY_Q:
685     case VKEY_R:
686     case VKEY_S:
687     case VKEY_T:
688     case VKEY_U:
689     case VKEY_V:
690     case VKEY_W:
691     case VKEY_X:
692     case VKEY_Y:
693     case VKEY_Z:
694       return (shift ? XK_A : XK_a) + (keycode - VKEY_A);
695
696     case VKEY_LWIN:
697       return XK_Super_L;
698     case VKEY_RWIN:
699       return XK_Super_R;
700
701     case VKEY_NUMLOCK:
702       return XK_Num_Lock;
703
704     case VKEY_SCROLL:
705       return XK_Scroll_Lock;
706
707     case VKEY_OEM_1:
708       return shift ? XK_colon : XK_semicolon;
709     case VKEY_OEM_PLUS:
710       return shift ? XK_plus : XK_equal;
711     case VKEY_OEM_COMMA:
712       return shift ? XK_less : XK_comma;
713     case VKEY_OEM_MINUS:
714       return shift ? XK_underscore : XK_minus;
715     case VKEY_OEM_PERIOD:
716       return shift ? XK_greater : XK_period;
717     case VKEY_OEM_2:
718       return shift ? XK_question : XK_slash;
719     case VKEY_OEM_3:
720       return shift ? XK_asciitilde : XK_quoteleft;
721     case VKEY_OEM_4:
722       return shift ? XK_braceleft : XK_bracketleft;
723     case VKEY_OEM_5:
724       return shift ? XK_bar : XK_backslash;
725     case VKEY_OEM_6:
726       return shift ? XK_braceright : XK_bracketright;
727     case VKEY_OEM_7:
728       return shift ? XK_quotedbl : XK_quoteright;
729     case VKEY_OEM_8:
730       return XK_ISO_Level5_Shift;
731     case VKEY_OEM_102:
732       return shift ? XK_guillemotleft : XK_guillemotright;
733
734     case VKEY_F1:
735     case VKEY_F2:
736     case VKEY_F3:
737     case VKEY_F4:
738     case VKEY_F5:
739     case VKEY_F6:
740     case VKEY_F7:
741     case VKEY_F8:
742     case VKEY_F9:
743     case VKEY_F10:
744     case VKEY_F11:
745     case VKEY_F12:
746     case VKEY_F13:
747     case VKEY_F14:
748     case VKEY_F15:
749     case VKEY_F16:
750     case VKEY_F17:
751     case VKEY_F18:
752     case VKEY_F19:
753     case VKEY_F20:
754     case VKEY_F21:
755     case VKEY_F22:
756     case VKEY_F23:
757     case VKEY_F24:
758       return XK_F1 + (keycode - VKEY_F1);
759
760     case VKEY_BROWSER_BACK:
761       return XF86XK_Back;
762     case VKEY_BROWSER_FORWARD:
763       return XF86XK_Forward;
764     case VKEY_BROWSER_REFRESH:
765       return XF86XK_Reload;
766     case VKEY_BROWSER_STOP:
767       return XF86XK_Stop;
768     case VKEY_BROWSER_SEARCH:
769       return XF86XK_Search;
770     case VKEY_BROWSER_FAVORITES:
771       return XF86XK_Favorites;
772     case VKEY_BROWSER_HOME:
773       return XF86XK_HomePage;
774     case VKEY_VOLUME_MUTE:
775       return XF86XK_AudioMute;
776     case VKEY_VOLUME_DOWN:
777       return XF86XK_AudioLowerVolume;
778     case VKEY_VOLUME_UP:
779       return XF86XK_AudioRaiseVolume;
780     case VKEY_MEDIA_NEXT_TRACK:
781       return XF86XK_AudioNext;
782     case VKEY_MEDIA_PREV_TRACK:
783       return XF86XK_AudioPrev;
784     case VKEY_MEDIA_STOP:
785       return XF86XK_AudioStop;
786     case VKEY_MEDIA_PLAY_PAUSE:
787       return XF86XK_AudioPlay;
788     case VKEY_MEDIA_LAUNCH_MAIL:
789       return XF86XK_Mail;
790     case VKEY_MEDIA_LAUNCH_APP1:
791       return XF86XK_LaunchA;
792     case VKEY_MEDIA_LAUNCH_APP2:
793       return XF86XK_LaunchB;
794     case VKEY_WLAN:
795       return XF86XK_WLAN;
796     case VKEY_POWER:
797       return XF86XK_PowerOff;
798     case VKEY_BRIGHTNESS_DOWN:
799       return XF86XK_MonBrightnessDown;
800     case VKEY_BRIGHTNESS_UP:
801       return XF86XK_MonBrightnessUp;
802     case VKEY_KBD_BRIGHTNESS_DOWN:
803       return XF86XK_KbdBrightnessDown;
804     case VKEY_KBD_BRIGHTNESS_UP:
805       return XF86XK_KbdBrightnessUp;
806
807     default:
808       LOG(WARNING) << "Unknown keycode:" << keycode;
809       return 0;
810     }
811 }
812
813 }  // namespace ui