Chromium Code Reviews| Index: ui/events/keycodes/keyboard_code_conversion_x.cc | 
| diff --git a/ui/events/keycodes/keyboard_code_conversion_x.cc b/ui/events/keycodes/keyboard_code_conversion_x.cc | 
| index 4311a96f7e5b34d7d41cabf086b4104c738540e2..01d4a478766ac1ddf74e69642a948a966770af3c 100644 | 
| --- a/ui/events/keycodes/keyboard_code_conversion_x.cc | 
| +++ b/ui/events/keycodes/keyboard_code_conversion_x.cc | 
| @@ -12,6 +12,9 @@ | 
| #include <X11/Xutil.h> | 
| #include <X11/extensions/XInput2.h> | 
| #include <X11/keysym.h> | 
| +#if !defined(XK_dead_greek) | 
| 
 
Wez
2014/10/03 12:38:44
Under what circumstances will this be undefined?
 
Yuki
2014/10/03 14:33:47
Added a comment.
XK_dead_greek was recently added
 
 | 
| +#define XK_dead_greek 0xfe8c | 
| +#endif | 
| #include "base/basictypes.h" | 
| #include "base/logging.h" | 
| @@ -459,99 +462,175 @@ KeyboardCode FindVK(const T_MAP& key, const T_MAP* map, size_t size) { | 
| return VKEY_UNKNOWN; | 
| } | 
| -} // namespace | 
| - | 
| -// Get an ui::KeyboardCode from an X keyevent | 
| -KeyboardCode KeyboardCodeFromXKeyEvent(const XEvent* xev) { | 
| - // Gets correct VKEY code from XEvent is performed as the following steps: | 
| - // 1. Gets the keysym without modifier states. | 
| - // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly. | 
| - // 3. Find keysym in map0. | 
| - // 4. If not found, fallback to find keysym + hardware_code in map1. | 
| - // 5. If not found, fallback to find keysym + keysym_shift + hardware_code | 
| - // in map2. | 
| - // 6. If not found, fallback to find keysym + keysym_shift + keysym_altgr + | 
| - // hardware_code in map3. | 
| - // 7. If not found, fallback to find in KeyboardCodeFromXKeysym(), which | 
| - // mainly for non-letter keys. | 
| - // 8. If not found, fallback to find with the hardware code in US layout. | 
| - | 
| - KeySym keysym = NoSymbol; | 
| - XEvent xkeyevent = {0}; | 
| - if (xev->type == GenericEvent) { | 
| - // Convert the XI2 key event into a core key event so that we can | 
| - // continue to use XLookupString() until crbug.com/367732 is complete. | 
| - InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent); | 
| - } else { | 
| - xkeyevent.xkey = xev->xkey; | 
| - } | 
| - XKeyEvent* xkey = &xkeyevent.xkey; | 
| - xkey->state &= (~0xFF | Mod2Mask); // Clears the xkey's state except numlock. | 
| - // XLookupKeysym does not take into consideration the state of the lock/shift | 
| - // etc. keys. So it is necessary to use XLookupString instead. | 
| - XLookupString(xkey, NULL, 0, &keysym, NULL); | 
| - | 
| - // [a-z] cases. | 
| - if (keysym >= XK_a && keysym <= XK_z) | 
| - return static_cast<KeyboardCode>(VKEY_A + keysym - XK_a); | 
| - | 
| - // [0-9] cases. | 
| - if (keysym >= XK_0 && keysym <= XK_9) | 
| - return static_cast<KeyboardCode>(VKEY_0 + keysym - XK_0); | 
| - | 
| - KeyboardCode keycode = VKEY_UNKNOWN; | 
| - | 
| - if (!IsKeypadKey(keysym) && !IsPrivateKeypadKey(keysym) && | 
| - !IsCursorKey(keysym) && !IsPFKey(keysym) && !IsFunctionKey(keysym) && | 
| - !IsModifierKey(keysym)) { | 
| - MAP0 key0 = {keysym & 0xFFFF, 0}; | 
| - keycode = FindVK(key0, map0, arraysize(map0)); | 
| - if (keycode != VKEY_UNKNOWN) | 
| - return keycode; | 
| - | 
| - MAP1 key1 = {keysym & 0xFFFF, xkey->keycode, 0}; | 
| - keycode = FindVK(key1, map1, arraysize(map1)); | 
| - if (keycode != VKEY_UNKNOWN) | 
| - return keycode; | 
| - | 
| - KeySym keysym_shift = NoSymbol; | 
| - xkey->state |= ShiftMask; | 
| - XLookupString(xkey, NULL, 0, &keysym_shift, NULL); | 
| - MAP2 key2 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0}; | 
| - keycode = FindVK(key2, map2, arraysize(map2)); | 
| - if (keycode != VKEY_UNKNOWN) | 
| - return keycode; | 
| - | 
| - KeySym keysym_altgr = NoSymbol; | 
| - xkey->state &= ~ShiftMask; | 
| - xkey->state |= Mod1Mask; | 
| - XLookupString(xkey, NULL, 0, &keysym_altgr, NULL); | 
| - MAP3 key3 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, | 
| - keysym_altgr & 0xFFFF, 0}; | 
| - keycode = FindVK(key3, map3, arraysize(map3)); | 
| - if (keycode != VKEY_UNKNOWN) | 
| - return keycode; | 
| +KeyboardCode KeyboardCodeFromHardwareKeycode( | 
| + unsigned int hardware_code) { | 
| + // This function assumes that X11 is using evdev-based keycodes. | 
| + static const KeyboardCode kHardwareKeycodeMap[] = { | 
| + // Please refer to below links for the table content: | 
| + // http://www.w3.org/TR/DOM-Level-3-Events-code/#keyboard-101 | 
| + // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode | 
| + // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf | 
| + VKEY_UNKNOWN, // 0x00: | 
| + VKEY_UNKNOWN, // 0x01: | 
| + VKEY_UNKNOWN, // 0x02: | 
| + VKEY_UNKNOWN, // 0x03: | 
| + VKEY_UNKNOWN, // 0x04: | 
| + VKEY_UNKNOWN, // 0x05: | 
| + VKEY_UNKNOWN, // 0x06: | 
| + VKEY_UNKNOWN, // XKB evdev (XKB - 8) X KeySym | 
| + VKEY_UNKNOWN, // === =============== ====== | 
| + VKEY_ESCAPE, // 0x09: KEY_ESC Escape | 
| + VKEY_1, // 0x0A: KEY_1 1 | 
| + VKEY_2, // 0x0B: KEY_2 2 | 
| + VKEY_3, // 0x0C: KEY_3 3 | 
| + VKEY_4, // 0x0D: KEY_4 4 | 
| + VKEY_5, // 0x0E: KEY_5 5 | 
| + VKEY_6, // 0x0F: KEY_6 6 | 
| + VKEY_7, // 0x10: KEY_7 7 | 
| + VKEY_8, // 0x11: KEY_8 8 | 
| + VKEY_9, // 0x12: KEY_9 9 | 
| + VKEY_0, // 0x13: KEY_0 0 | 
| + VKEY_OEM_MINUS, // 0x14: KEY_MINUS minus | 
| + VKEY_OEM_PLUS, // 0x15: KEY_EQUAL equal | 
| + VKEY_BACK, // 0x16: KEY_BACKSPACE BackSpace | 
| + VKEY_TAB, // 0x17: KEY_TAB Tab | 
| + VKEY_Q, // 0x18: KEY_Q q | 
| + VKEY_W, // 0x19: KEY_W w | 
| + VKEY_E, // 0x1A: KEY_E e | 
| + VKEY_R, // 0x1B: KEY_R r | 
| + VKEY_T, // 0x1C: KEY_T t | 
| + VKEY_Y, // 0x1D: KEY_Y y | 
| + VKEY_U, // 0x1E: KEY_U u | 
| + VKEY_I, // 0x1F: KEY_I i | 
| + VKEY_O, // 0x20: KEY_O o | 
| + VKEY_P, // 0x21: KEY_P p | 
| + VKEY_OEM_4, // 0x22: KEY_LEFTBRACE bracketleft | 
| + VKEY_OEM_6, // 0x23: KEY_RIGHTBRACE bracketright | 
| + VKEY_RETURN, // 0x24: KEY_ENTER Return | 
| + VKEY_LCONTROL, // 0x25: KEY_LEFTCTRL Control_L | 
| + VKEY_A, // 0x26: KEY_A a | 
| + VKEY_S, // 0x27: KEY_S s | 
| + VKEY_D, // 0x28: KEY_D d | 
| + VKEY_F, // 0x29: KEY_F f | 
| + VKEY_G, // 0x2A: KEY_G g | 
| + VKEY_H, // 0x2B: KEY_H h | 
| + VKEY_J, // 0x2C: KEY_J j | 
| + VKEY_K, // 0x2D: KEY_K k | 
| + VKEY_L, // 0x2E: KEY_L l | 
| + VKEY_OEM_1, // 0x2F: KEY_SEMICOLON semicolon | 
| + VKEY_OEM_7, // 0x30: KEY_APOSTROPHE apostrophe | 
| + VKEY_OEM_3, // 0x31: KEY_GRAVE grave | 
| + VKEY_LSHIFT, // 0x32: KEY_LEFTSHIFT Shift_L | 
| + VKEY_OEM_5, // 0x33: KEY_BACKSLASH backslash | 
| + VKEY_Z, // 0x34: KEY_Z z | 
| + VKEY_X, // 0x35: KEY_X x | 
| + VKEY_C, // 0x36: KEY_C c | 
| + VKEY_V, // 0x37: KEY_V v | 
| + VKEY_B, // 0x38: KEY_B b | 
| + VKEY_N, // 0x39: KEY_N n | 
| + VKEY_M, // 0x3A: KEY_M m | 
| + VKEY_OEM_COMMA, // 0x3B: KEY_COMMA comma | 
| + VKEY_OEM_PERIOD, // 0x3C: KEY_DOT period | 
| + VKEY_OEM_2, // 0x3D: KEY_SLASH slash | 
| + VKEY_RSHIFT, // 0x3E: KEY_RIGHTSHIFT Shift_R | 
| + VKEY_MULTIPLY, // 0x3F: KEY_KPASTERISK KP_Multiply | 
| + VKEY_LMENU, // 0x40: KEY_LEFTALT Alt_L | 
| + VKEY_SPACE, // 0x41: KEY_SPACE space | 
| + VKEY_CAPITAL, // 0x42: KEY_CAPSLOCK Caps_Lock | 
| + VKEY_F1, // 0x43: KEY_F1 F1 | 
| + VKEY_F2, // 0x44: KEY_F2 F2 | 
| + VKEY_F3, // 0x45: KEY_F3 F3 | 
| + VKEY_F4, // 0x46: KEY_F4 F4 | 
| + VKEY_F5, // 0x47: KEY_F5 F5 | 
| + VKEY_F6, // 0x48: KEY_F6 F6 | 
| + VKEY_F7, // 0x49: KEY_F7 F7 | 
| + VKEY_F8, // 0x4A: KEY_F8 F8 | 
| + VKEY_F9, // 0x4B: KEY_F9 F9 | 
| + VKEY_F10, // 0x4C: KEY_F10 F10 | 
| + VKEY_NUMLOCK, // 0x4D: KEY_NUMLOCK Num_Lock | 
| + VKEY_SCROLL, // 0x4E: KEY_SCROLLLOCK Scroll_Lock | 
| + VKEY_NUMPAD7, // 0x4F: KEY_KP7 KP_7 | 
| + VKEY_NUMPAD8, // 0x50: KEY_KP8 KP_8 | 
| + VKEY_NUMPAD9, // 0x51: KEY_KP9 KP_9 | 
| + VKEY_SUBTRACT, // 0x52: KEY_KPMINUS KP_Subtract | 
| + VKEY_NUMPAD4, // 0x53: KEY_KP4 KP_4 | 
| + VKEY_NUMPAD5, // 0x54: KEY_KP5 KP_5 | 
| + VKEY_NUMPAD6, // 0x55: KEY_KP6 KP_6 | 
| + VKEY_ADD, // 0x56: KEY_KPPLUS KP_Add | 
| + VKEY_NUMPAD1, // 0x57: KEY_KP1 KP_1 | 
| + VKEY_NUMPAD2, // 0x58: KEY_KP2 KP_2 | 
| + VKEY_NUMPAD3, // 0x59: KEY_KP3 KP_3 | 
| + VKEY_NUMPAD0, // 0x5A: KEY_KP0 KP_0 | 
| + VKEY_DECIMAL, // 0x5B: KEY_KPDOT KP_Decimal | 
| + VKEY_UNKNOWN, // 0x5C: | 
| + VKEY_DBE_DBCSCHAR, // 0x5D: KEY_ZENKAKUHANKAKU Zenkaku_Hankaku | 
| + VKEY_OEM_5, // 0x5E: KEY_102ND backslash | 
| + VKEY_F11, // 0x5F: KEY_F11 F11 | 
| + VKEY_F12, // 0x60: KEY_F12 F12 | 
| + VKEY_OEM_102, // 0x61: KEY_RO Romaji | 
| + VKEY_UNSUPPORTED, // 0x62: KEY_KATAKANA Katakana | 
| + VKEY_UNSUPPORTED, // 0x63: KEY_HIRAGANA Hiragana | 
| + VKEY_CONVERT, // 0x64: KEY_HENKAN Henkan | 
| + VKEY_UNSUPPORTED, // 0x65: KEY_KATAKANAHIRAGANA Hiragana_Katakana | 
| + VKEY_NONCONVERT, // 0x66: KEY_MUHENKAN Muhenkan | 
| + VKEY_SEPARATOR, // 0x67: KEY_KPJPCOMMA KP_Separator | 
| + VKEY_RETURN, // 0x68: KEY_KPENTER KP_Enter | 
| + VKEY_RCONTROL, // 0x69: KEY_RIGHTCTRL Control_R | 
| + VKEY_DIVIDE, // 0x6A: KEY_KPSLASH KP_Divide | 
| + VKEY_PRINT, // 0x6B: KEY_SYSRQ Print | 
| + VKEY_RMENU, // 0x6C: KEY_RIGHTALT Alt_R | 
| + VKEY_RETURN, // 0x6D: KEY_LINEFEED Linefeed | 
| + VKEY_HOME, // 0x6E: KEY_HOME Home | 
| + VKEY_UP, // 0x6F: KEY_UP Up | 
| + VKEY_PRIOR, // 0x70: KEY_PAGEUP Page_Up | 
| + VKEY_LEFT, // 0x71: KEY_LEFT Left | 
| + VKEY_RIGHT, // 0x72: KEY_RIGHT Right | 
| + VKEY_END, // 0x73: KEY_END End | 
| + VKEY_DOWN, // 0x74: KEY_DOWN Down | 
| + VKEY_NEXT, // 0x75: KEY_PAGEDOWN Page_Down | 
| + VKEY_INSERT, // 0x76: KEY_INSERT Insert | 
| + VKEY_DELETE, // 0x77: KEY_DELETE Delete | 
| + VKEY_UNSUPPORTED, // 0x78: KEY_MACRO | 
| + VKEY_VOLUME_MUTE, // 0x79: KEY_MUTE XF86AudioMute | 
| + VKEY_VOLUME_DOWN, // 0x7A: KEY_VOLUMEDOWN XF86AudioLowerVolume | 
| + VKEY_VOLUME_UP, // 0x7B: KEY_VOLUMEUP XF86AudioRaiseVolume | 
| + VKEY_POWER, // 0x7C: KEY_POWER XF86PowerOff | 
| + VKEY_OEM_PLUS, // 0x7D: KEY_KPEQUAL KP_Equal | 
| + VKEY_UNSUPPORTED, // 0x7E: KEY_KPPLUSMINUS plusminus | 
| + VKEY_PAUSE, // 0x7F: KEY_PAUSE Pause | 
| + VKEY_MEDIA_LAUNCH_APP1, // 0x80: KEY_SCALE XF86LaunchA | 
| + VKEY_DECIMAL, // 0x81: KEY_KPCOMMA KP_Decimal | 
| + VKEY_HANGUL, // 0x82: KEY_HANGUEL Hangul | 
| + VKEY_HANJA, // 0x83: KEY_HANJA Hangul_Hanja | 
| + VKEY_OEM_5, // 0x84: KEY_YEN yen | 
| + VKEY_LWIN, // 0x85: KEY_LEFTMETA Super_L | 
| + VKEY_RWIN, // 0x86: KEY_RIGHTMETA Super_R | 
| + VKEY_COMPOSE, // 0x87: KEY_COMPOSE Menu | 
| + }; | 
| - // On Linux some keys has AltGr char but not on Windows. | 
| - // So if cannot find VKEY with (ch0+sc+ch1+ch2) in map3, tries to fallback | 
| - // to just find VKEY with (ch0+sc+ch1). This is the best we could do. | 
| - MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0xFFFF, | 
| - 0}; | 
| - const MAP3* p = | 
| - std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); | 
| - if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc && | 
| - p->ch1 == key4.ch1) | 
| - return static_cast<KeyboardCode>(p->vk); | 
| + if (hardware_code >= arraysize(kHardwareKeycodeMap)) { | 
| + // Additional keycodes used by the Chrome OS top row special function keys. | 
| + switch (hardware_code) { | 
| + case 0xA6: // KEY_BACK | 
| + return VKEY_BACK; | 
| + case 0xA7: // KEY_FORWARD | 
| + return VKEY_BROWSER_FORWARD; | 
| + case 0xB5: // KEY_REFRESH | 
| + return VKEY_BROWSER_REFRESH; | 
| + case 0xD4: // KEY_DASHBOARD | 
| + return VKEY_MEDIA_LAUNCH_APP2; | 
| + case 0xE8: // KEY_BRIGHTNESSDOWN | 
| + return VKEY_BRIGHTNESS_DOWN; | 
| + case 0xE9: // KEY_BRIGHTNESSUP | 
| + return VKEY_BRIGHTNESS_UP; | 
| + } | 
| + return VKEY_UNKNOWN; | 
| } | 
| - | 
| - keycode = KeyboardCodeFromXKeysym(keysym); | 
| - if (keycode == VKEY_UNKNOWN) | 
| - keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey->keycode); | 
| - | 
| - return keycode; | 
| + return kHardwareKeycodeMap[hardware_code]; | 
| } | 
| -KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { | 
| +KeyboardCode KeyboardCodeFromXKeysymOrHardwareKeycode(unsigned int keysym, | 
| + unsigned int keycode) { | 
| // TODO(sad): Have |keysym| go through the X map list? | 
| switch (keysym) { | 
| @@ -761,6 +840,117 @@ KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { | 
| case XK_brokenbar: | 
| return VKEY_OEM_102; // international backslash key in 102 keyboard. | 
| + case XK_Hyper_L: | 
| 
 
Wez
2014/10/03 12:38:44
Regardless of where this list of always-UNKNOWN co
 
Yuki
2014/10/03 14:33:47
Added a comment.
 
 | 
| + case XK_Hyper_R: | 
| + case XK_ISO_Lock: | 
| + case XK_ISO_Level2_Latch: | 
| + case XK_ISO_Level3_Latch: | 
| + case XK_ISO_Level3_Lock: | 
| + case XK_ISO_Level5_Latch: | 
| + case XK_ISO_Level5_Lock: | 
| + case XK_ISO_Group_Latch: | 
| + case XK_ISO_Group_Lock: | 
| + case XK_ISO_Next_Group: | 
| + case XK_ISO_Next_Group_Lock: | 
| + case XK_ISO_Prev_Group: | 
| + case XK_ISO_Prev_Group_Lock: | 
| + case XK_ISO_First_Group: | 
| + case XK_ISO_First_Group_Lock: | 
| + case XK_ISO_Last_Group: | 
| + case XK_ISO_Last_Group_Lock: | 
| + case XK_dead_grave: | 
| + case XK_dead_acute: | 
| + case XK_dead_circumflex: | 
| + case XK_dead_tilde: | 
| + case XK_dead_macron: | 
| + case XK_dead_breve: | 
| + case XK_dead_abovedot: | 
| + case XK_dead_diaeresis: | 
| + case XK_dead_abovering: | 
| + case XK_dead_doubleacute: | 
| + case XK_dead_caron: | 
| + case XK_dead_cedilla: | 
| + case XK_dead_ogonek: | 
| + case XK_dead_iota: | 
| + case XK_dead_voiced_sound: | 
| + case XK_dead_semivoiced_sound: | 
| + case XK_dead_belowdot: | 
| + case XK_dead_hook: | 
| + case XK_dead_horn: | 
| + case XK_dead_stroke: | 
| + case XK_dead_abovecomma: | 
| + case XK_dead_abovereversedcomma: | 
| + case XK_dead_doublegrave: | 
| + case XK_dead_belowring: | 
| + case XK_dead_belowmacron: | 
| + case XK_dead_belowcircumflex: | 
| + case XK_dead_belowtilde: | 
| + case XK_dead_belowbreve: | 
| + case XK_dead_belowdiaeresis: | 
| + case XK_dead_invertedbreve: | 
| + case XK_dead_belowcomma: | 
| + case XK_dead_currency: | 
| + case XK_dead_a: | 
| + case XK_dead_A: | 
| + case XK_dead_e: | 
| + case XK_dead_E: | 
| + case XK_dead_i: | 
| + case XK_dead_I: | 
| + case XK_dead_o: | 
| + case XK_dead_O: | 
| + case XK_dead_u: | 
| + case XK_dead_U: | 
| + case XK_dead_small_schwa: | 
| + case XK_dead_capital_schwa: | 
| + case XK_dead_greek: | 
| + case XK_First_Virtual_Screen: | 
| + case XK_Prev_Virtual_Screen: | 
| + case XK_Next_Virtual_Screen: | 
| + case XK_Last_Virtual_Screen: | 
| + case XK_Terminate_Server: | 
| + case XK_AccessX_Enable: | 
| + case XK_AccessX_Feedback_Enable: | 
| + case XK_RepeatKeys_Enable: | 
| + case XK_SlowKeys_Enable: | 
| + case XK_BounceKeys_Enable: | 
| + case XK_StickyKeys_Enable: | 
| + case XK_MouseKeys_Enable: | 
| + case XK_MouseKeys_Accel_Enable: | 
| + case XK_Overlay1_Enable: | 
| + case XK_Overlay2_Enable: | 
| + case XK_AudibleBell_Enable: | 
| + case XK_Pointer_Left: | 
| + case XK_Pointer_Right: | 
| + case XK_Pointer_Up: | 
| + case XK_Pointer_Down: | 
| + case XK_Pointer_UpLeft: | 
| + case XK_Pointer_UpRight: | 
| + case XK_Pointer_DownLeft: | 
| + case XK_Pointer_DownRight: | 
| + case XK_Pointer_Button_Dflt: | 
| + case XK_Pointer_Button1: | 
| + case XK_Pointer_Button2: | 
| + case XK_Pointer_Button3: | 
| + case XK_Pointer_Button4: | 
| + case XK_Pointer_Button5: | 
| + case XK_Pointer_DblClick_Dflt: | 
| + case XK_Pointer_DblClick1: | 
| + case XK_Pointer_DblClick2: | 
| + case XK_Pointer_DblClick3: | 
| + case XK_Pointer_DblClick4: | 
| + case XK_Pointer_DblClick5: | 
| + case XK_Pointer_Drag_Dflt: | 
| + case XK_Pointer_Drag1: | 
| + case XK_Pointer_Drag2: | 
| + case XK_Pointer_Drag3: | 
| + case XK_Pointer_Drag4: | 
| + case XK_Pointer_Drag5: | 
| + case XK_Pointer_EnableKeys: | 
| + case XK_Pointer_Accelerate: | 
| + case XK_Pointer_DfltBtnNext: | 
| + case XK_Pointer_DfltBtnPrev: | 
| + return VKEY_UNKNOWN; | 
| + | 
| // When evdev is in use, /usr/share/X11/xkb/symbols/inet maps F13-18 keys | 
| // to the special XF86XK symbols to support Microsoft Ergonomic keyboards: | 
| // https://bugs.freedesktop.org/show_bug.cgi?id=5783 | 
| @@ -835,8 +1025,101 @@ KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { | 
| // TODO(sad): some keycodes are still missing. | 
| } | 
| + | 
| DVLOG(1) << "Unknown keysym: " << base::StringPrintf("0x%x", keysym); | 
| - return VKEY_UNKNOWN; | 
| + return KeyboardCodeFromHardwareKeycode(keycode); | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +// Get an ui::KeyboardCode from an X keyevent | 
| +KeyboardCode KeyboardCodeFromXKeyEvent(const XEvent* xev) { | 
| + // Gets correct VKEY code from XEvent is performed as the following steps: | 
| + // 1. Gets the keysym without modifier states. | 
| + // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly. | 
| + // 3. Find keysym in map0. | 
| + // 4. If not found, fallback to find keysym + hardware_code in map1. | 
| + // 5. If not found, fallback to find keysym + keysym_shift + hardware_code | 
| + // in map2. | 
| + // 6. If not found, fallback to find keysym + keysym_shift + keysym_altgr + | 
| + // hardware_code in map3. | 
| + // 7. If not found, fallback to find in KeyboardCodeFromXKeysym(), which | 
| + // mainly for non-letter keys. | 
| + // 8. If not found, fallback to find with the hardware code in US layout. | 
| 
 
Wez
2014/10/03 12:38:44
Looks like steps #7 and #8 are now folded into Fro
 
Yuki
2014/10/03 14:33:47
Thanks for the suggestion.  I made a separate func
 
 | 
| + | 
| + KeySym keysym = NoSymbol; | 
| + XEvent xkeyevent = {0}; | 
| + if (xev->type == GenericEvent) { | 
| + // Convert the XI2 key event into a core key event so that we can | 
| + // continue to use XLookupString() until crbug.com/367732 is complete. | 
| + InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent); | 
| + } else { | 
| + xkeyevent.xkey = xev->xkey; | 
| + } | 
| + XKeyEvent* xkey = &xkeyevent.xkey; | 
| + xkey->state &= (~0xFF | Mod2Mask); // Clears the xkey's state except numlock. | 
| + // XLookupKeysym does not take into consideration the state of the lock/shift | 
| + // etc. keys. So it is necessary to use XLookupString instead. | 
| + XLookupString(xkey, NULL, 0, &keysym, NULL); | 
| + | 
| + // [a-z] cases. | 
| + if (keysym >= XK_a && keysym <= XK_z) | 
| + return static_cast<KeyboardCode>(VKEY_A + keysym - XK_a); | 
| + | 
| + // [0-9] cases. | 
| + if (keysym >= XK_0 && keysym <= XK_9) | 
| + return static_cast<KeyboardCode>(VKEY_0 + keysym - XK_0); | 
| + | 
| + KeyboardCode keycode = VKEY_UNKNOWN; | 
| + | 
| + if (!IsKeypadKey(keysym) && !IsPrivateKeypadKey(keysym) && | 
| + !IsCursorKey(keysym) && !IsPFKey(keysym) && !IsFunctionKey(keysym) && | 
| + !IsModifierKey(keysym)) { | 
| + MAP0 key0 = {keysym & 0xFFFF, 0}; | 
| + keycode = FindVK(key0, map0, arraysize(map0)); | 
| + if (keycode != VKEY_UNKNOWN) | 
| + return keycode; | 
| + | 
| + MAP1 key1 = {keysym & 0xFFFF, xkey->keycode, 0}; | 
| + keycode = FindVK(key1, map1, arraysize(map1)); | 
| + if (keycode != VKEY_UNKNOWN) | 
| + return keycode; | 
| + | 
| + KeySym keysym_shift = NoSymbol; | 
| + xkey->state |= ShiftMask; | 
| + XLookupString(xkey, NULL, 0, &keysym_shift, NULL); | 
| + MAP2 key2 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0}; | 
| + keycode = FindVK(key2, map2, arraysize(map2)); | 
| + if (keycode != VKEY_UNKNOWN) | 
| + return keycode; | 
| + | 
| + KeySym keysym_altgr = NoSymbol; | 
| + xkey->state &= ~ShiftMask; | 
| + xkey->state |= Mod1Mask; | 
| + XLookupString(xkey, NULL, 0, &keysym_altgr, NULL); | 
| + MAP3 key3 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, | 
| + keysym_altgr & 0xFFFF, 0}; | 
| + keycode = FindVK(key3, map3, arraysize(map3)); | 
| + if (keycode != VKEY_UNKNOWN) | 
| + return keycode; | 
| + | 
| + // On Linux some keys has AltGr char but not on Windows. | 
| + // So if cannot find VKEY with (ch0+sc+ch1+ch2) in map3, tries to fallback | 
| + // to just find VKEY with (ch0+sc+ch1). This is the best we could do. | 
| + MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0xFFFF, | 
| + 0}; | 
| + const MAP3* p = | 
| + std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); | 
| + if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc && | 
| + p->ch1 == key4.ch1) | 
| + return static_cast<KeyboardCode>(p->vk); | 
| + } | 
| + | 
| + return KeyboardCodeFromXKeysymOrHardwareKeycode(keysym, xkey->keycode); | 
| +} | 
| + | 
| +KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { | 
| + return KeyboardCodeFromXKeysymOrHardwareKeycode(keysym, 0); | 
| } | 
| const char* CodeFromXEvent(const XEvent* xev) { | 
| @@ -862,173 +1145,6 @@ uint16 GetCharacterFromXEvent(const XEvent* xev) { | 
| return GetUnicodeCharacterFromXKeySym(keysym); | 
| } | 
| -KeyboardCode DefaultKeyboardCodeFromHardwareKeycode( | 
| - unsigned int hardware_code) { | 
| - // This function assumes that X11 is using evdev-based keycodes. | 
| - static const KeyboardCode kHardwareKeycodeMap[] = { | 
| - // Please refer to below links for the table content: | 
| - // http://www.w3.org/TR/DOM-Level-3-Events-code/#keyboard-101 | 
| - // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode | 
| - // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf | 
| - VKEY_UNKNOWN, // 0x00: | 
| - VKEY_UNKNOWN, // 0x01: | 
| - VKEY_UNKNOWN, // 0x02: | 
| - VKEY_UNKNOWN, // 0x03: | 
| - VKEY_UNKNOWN, // 0x04: | 
| - VKEY_UNKNOWN, // 0x05: | 
| - VKEY_UNKNOWN, // 0x06: | 
| - VKEY_UNKNOWN, // XKB evdev (XKB - 8) X KeySym | 
| - VKEY_UNKNOWN, // === =============== ====== | 
| - VKEY_ESCAPE, // 0x09: KEY_ESC Escape | 
| - VKEY_1, // 0x0A: KEY_1 1 | 
| - VKEY_2, // 0x0B: KEY_2 2 | 
| - VKEY_3, // 0x0C: KEY_3 3 | 
| - VKEY_4, // 0x0D: KEY_4 4 | 
| - VKEY_5, // 0x0E: KEY_5 5 | 
| - VKEY_6, // 0x0F: KEY_6 6 | 
| - VKEY_7, // 0x10: KEY_7 7 | 
| - VKEY_8, // 0x11: KEY_8 8 | 
| - VKEY_9, // 0x12: KEY_9 9 | 
| - VKEY_0, // 0x13: KEY_0 0 | 
| - VKEY_OEM_MINUS, // 0x14: KEY_MINUS minus | 
| - VKEY_OEM_PLUS, // 0x15: KEY_EQUAL equal | 
| - VKEY_BACK, // 0x16: KEY_BACKSPACE BackSpace | 
| - VKEY_TAB, // 0x17: KEY_TAB Tab | 
| - VKEY_Q, // 0x18: KEY_Q q | 
| - VKEY_W, // 0x19: KEY_W w | 
| - VKEY_E, // 0x1A: KEY_E e | 
| - VKEY_R, // 0x1B: KEY_R r | 
| - VKEY_T, // 0x1C: KEY_T t | 
| - VKEY_Y, // 0x1D: KEY_Y y | 
| - VKEY_U, // 0x1E: KEY_U u | 
| - VKEY_I, // 0x1F: KEY_I i | 
| - VKEY_O, // 0x20: KEY_O o | 
| - VKEY_P, // 0x21: KEY_P p | 
| - VKEY_OEM_4, // 0x22: KEY_LEFTBRACE bracketleft | 
| - VKEY_OEM_6, // 0x23: KEY_RIGHTBRACE bracketright | 
| - VKEY_RETURN, // 0x24: KEY_ENTER Return | 
| - VKEY_LCONTROL, // 0x25: KEY_LEFTCTRL Control_L | 
| - VKEY_A, // 0x26: KEY_A a | 
| - VKEY_S, // 0x27: KEY_S s | 
| - VKEY_D, // 0x28: KEY_D d | 
| - VKEY_F, // 0x29: KEY_F f | 
| - VKEY_G, // 0x2A: KEY_G g | 
| - VKEY_H, // 0x2B: KEY_H h | 
| - VKEY_J, // 0x2C: KEY_J j | 
| - VKEY_K, // 0x2D: KEY_K k | 
| - VKEY_L, // 0x2E: KEY_L l | 
| - VKEY_OEM_1, // 0x2F: KEY_SEMICOLON semicolon | 
| - VKEY_OEM_7, // 0x30: KEY_APOSTROPHE apostrophe | 
| - VKEY_OEM_3, // 0x31: KEY_GRAVE grave | 
| - VKEY_LSHIFT, // 0x32: KEY_LEFTSHIFT Shift_L | 
| - VKEY_OEM_5, // 0x33: KEY_BACKSLASH backslash | 
| - VKEY_Z, // 0x34: KEY_Z z | 
| - VKEY_X, // 0x35: KEY_X x | 
| - VKEY_C, // 0x36: KEY_C c | 
| - VKEY_V, // 0x37: KEY_V v | 
| - VKEY_B, // 0x38: KEY_B b | 
| - VKEY_N, // 0x39: KEY_N n | 
| - VKEY_M, // 0x3A: KEY_M m | 
| - VKEY_OEM_COMMA, // 0x3B: KEY_COMMA comma | 
| - VKEY_OEM_PERIOD, // 0x3C: KEY_DOT period | 
| - VKEY_OEM_2, // 0x3D: KEY_SLASH slash | 
| - VKEY_RSHIFT, // 0x3E: KEY_RIGHTSHIFT Shift_R | 
| - VKEY_MULTIPLY, // 0x3F: KEY_KPASTERISK KP_Multiply | 
| - VKEY_LMENU, // 0x40: KEY_LEFTALT Alt_L | 
| - VKEY_SPACE, // 0x41: KEY_SPACE space | 
| - VKEY_CAPITAL, // 0x42: KEY_CAPSLOCK Caps_Lock | 
| - VKEY_F1, // 0x43: KEY_F1 F1 | 
| - VKEY_F2, // 0x44: KEY_F2 F2 | 
| - VKEY_F3, // 0x45: KEY_F3 F3 | 
| - VKEY_F4, // 0x46: KEY_F4 F4 | 
| - VKEY_F5, // 0x47: KEY_F5 F5 | 
| - VKEY_F6, // 0x48: KEY_F6 F6 | 
| - VKEY_F7, // 0x49: KEY_F7 F7 | 
| - VKEY_F8, // 0x4A: KEY_F8 F8 | 
| - VKEY_F9, // 0x4B: KEY_F9 F9 | 
| - VKEY_F10, // 0x4C: KEY_F10 F10 | 
| - VKEY_NUMLOCK, // 0x4D: KEY_NUMLOCK Num_Lock | 
| - VKEY_SCROLL, // 0x4E: KEY_SCROLLLOCK Scroll_Lock | 
| - VKEY_NUMPAD7, // 0x4F: KEY_KP7 KP_7 | 
| - VKEY_NUMPAD8, // 0x50: KEY_KP8 KP_8 | 
| - VKEY_NUMPAD9, // 0x51: KEY_KP9 KP_9 | 
| - VKEY_SUBTRACT, // 0x52: KEY_KPMINUS KP_Subtract | 
| - VKEY_NUMPAD4, // 0x53: KEY_KP4 KP_4 | 
| - VKEY_NUMPAD5, // 0x54: KEY_KP5 KP_5 | 
| - VKEY_NUMPAD6, // 0x55: KEY_KP6 KP_6 | 
| - VKEY_ADD, // 0x56: KEY_KPPLUS KP_Add | 
| - VKEY_NUMPAD1, // 0x57: KEY_KP1 KP_1 | 
| - VKEY_NUMPAD2, // 0x58: KEY_KP2 KP_2 | 
| - VKEY_NUMPAD3, // 0x59: KEY_KP3 KP_3 | 
| - VKEY_NUMPAD0, // 0x5A: KEY_KP0 KP_0 | 
| - VKEY_DECIMAL, // 0x5B: KEY_KPDOT KP_Decimal | 
| - VKEY_UNKNOWN, // 0x5C: | 
| - VKEY_DBE_DBCSCHAR, // 0x5D: KEY_ZENKAKUHANKAKU Zenkaku_Hankaku | 
| - VKEY_OEM_5, // 0x5E: KEY_102ND backslash | 
| - VKEY_F11, // 0x5F: KEY_F11 F11 | 
| - VKEY_F12, // 0x60: KEY_F12 F12 | 
| - VKEY_OEM_102, // 0x61: KEY_RO Romaji | 
| - VKEY_UNSUPPORTED, // 0x62: KEY_KATAKANA Katakana | 
| - VKEY_UNSUPPORTED, // 0x63: KEY_HIRAGANA Hiragana | 
| - VKEY_CONVERT, // 0x64: KEY_HENKAN Henkan | 
| - VKEY_UNSUPPORTED, // 0x65: KEY_KATAKANAHIRAGANA Hiragana_Katakana | 
| - VKEY_NONCONVERT, // 0x66: KEY_MUHENKAN Muhenkan | 
| - VKEY_SEPARATOR, // 0x67: KEY_KPJPCOMMA KP_Separator | 
| - VKEY_RETURN, // 0x68: KEY_KPENTER KP_Enter | 
| - VKEY_RCONTROL, // 0x69: KEY_RIGHTCTRL Control_R | 
| - VKEY_DIVIDE, // 0x6A: KEY_KPSLASH KP_Divide | 
| - VKEY_PRINT, // 0x6B: KEY_SYSRQ Print | 
| - VKEY_RMENU, // 0x6C: KEY_RIGHTALT Alt_R | 
| - VKEY_RETURN, // 0x6D: KEY_LINEFEED Linefeed | 
| - VKEY_HOME, // 0x6E: KEY_HOME Home | 
| - VKEY_UP, // 0x6F: KEY_UP Up | 
| - VKEY_PRIOR, // 0x70: KEY_PAGEUP Page_Up | 
| - VKEY_LEFT, // 0x71: KEY_LEFT Left | 
| - VKEY_RIGHT, // 0x72: KEY_RIGHT Right | 
| - VKEY_END, // 0x73: KEY_END End | 
| - VKEY_DOWN, // 0x74: KEY_DOWN Down | 
| - VKEY_NEXT, // 0x75: KEY_PAGEDOWN Page_Down | 
| - VKEY_INSERT, // 0x76: KEY_INSERT Insert | 
| - VKEY_DELETE, // 0x77: KEY_DELETE Delete | 
| - VKEY_UNSUPPORTED, // 0x78: KEY_MACRO | 
| - VKEY_VOLUME_MUTE, // 0x79: KEY_MUTE XF86AudioMute | 
| - VKEY_VOLUME_DOWN, // 0x7A: KEY_VOLUMEDOWN XF86AudioLowerVolume | 
| - VKEY_VOLUME_UP, // 0x7B: KEY_VOLUMEUP XF86AudioRaiseVolume | 
| - VKEY_POWER, // 0x7C: KEY_POWER XF86PowerOff | 
| - VKEY_OEM_PLUS, // 0x7D: KEY_KPEQUAL KP_Equal | 
| - VKEY_UNSUPPORTED, // 0x7E: KEY_KPPLUSMINUS plusminus | 
| - VKEY_PAUSE, // 0x7F: KEY_PAUSE Pause | 
| - VKEY_MEDIA_LAUNCH_APP1, // 0x80: KEY_SCALE XF86LaunchA | 
| - VKEY_DECIMAL, // 0x81: KEY_KPCOMMA KP_Decimal | 
| - VKEY_HANGUL, // 0x82: KEY_HANGUEL Hangul | 
| - VKEY_HANJA, // 0x83: KEY_HANJA Hangul_Hanja | 
| - VKEY_OEM_5, // 0x84: KEY_YEN yen | 
| - VKEY_LWIN, // 0x85: KEY_LEFTMETA Super_L | 
| - VKEY_RWIN, // 0x86: KEY_RIGHTMETA Super_R | 
| - VKEY_COMPOSE, // 0x87: KEY_COMPOSE Menu | 
| - }; | 
| - | 
| - if (hardware_code >= arraysize(kHardwareKeycodeMap)) { | 
| - // Additional keycodes used by the Chrome OS top row special function keys. | 
| - switch (hardware_code) { | 
| - case 0xA6: // KEY_BACK | 
| - return VKEY_BACK; | 
| - case 0xA7: // KEY_FORWARD | 
| - return VKEY_BROWSER_FORWARD; | 
| - case 0xB5: // KEY_REFRESH | 
| - return VKEY_BROWSER_REFRESH; | 
| - case 0xD4: // KEY_DASHBOARD | 
| - return VKEY_MEDIA_LAUNCH_APP2; | 
| - case 0xE8: // KEY_BRIGHTNESSDOWN | 
| - return VKEY_BRIGHTNESS_DOWN; | 
| - case 0xE9: // KEY_BRIGHTNESSUP | 
| - return VKEY_BRIGHTNESS_UP; | 
| - } | 
| - return VKEY_UNKNOWN; | 
| - } | 
| - return kHardwareKeycodeMap[hardware_code]; | 
| -} | 
| - | 
| // TODO(jcampan): this method might be incomplete. | 
| int XKeysymForWindowsKeyCode(KeyboardCode keycode, bool shift) { | 
| switch (keycode) { |