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) { |