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