Home | History | Annotate | Download | only in keycodes
      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 && 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
    815