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 0a226fcef288331b983ee292914fcd5ab7bb0d76..e97f19a1a6e70df2ea1e18ca2dbab3121f8023f3 100644 |
--- a/ui/events/keycodes/keyboard_code_conversion_x.cc |
+++ b/ui/events/keycodes/keyboard_code_conversion_x.cc |
@@ -7,10 +7,11 @@ |
#include <algorithm> |
#define XK_3270 // for XK_3270_BackTab |
-#include <X11/keysym.h> |
+#include <X11/XF86keysym.h> |
#include <X11/Xlib.h> |
#include <X11/Xutil.h> |
-#include <X11/XF86keysym.h> |
+#include <X11/extensions/XInput2.h> |
+#include <X11/keysym.h> |
#include "base/basictypes.h" |
#include "base/logging.h" |
@@ -460,7 +461,7 @@ KeyboardCode FindVK(const T_MAP& key, const T_MAP* map, size_t size) { |
} // namespace |
// Get an ui::KeyboardCode from an X keyevent |
-KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) { |
+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. |
@@ -475,11 +476,19 @@ KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) { |
// 8. If not found, fallback to find with the hardware code in US layout. |
KeySym keysym = NoSymbol; |
- XKeyEvent xkey = xev->xkey; |
- xkey.state &= (~0xFF | Mod2Mask); // Clears the xkey's state except numlock. |
+ XEvent xkeyevent; |
+ 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); |
+ XLookupString(xkey, NULL, 0, &keysym, NULL); |
// [a-z] cases. |
if (keysym >= XK_a && keysym <= XK_z) |
@@ -499,24 +508,24 @@ KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) { |
if (keycode != VKEY_UNKNOWN) |
return keycode; |
- MAP1 key1 = {keysym & 0xFFFF, xkey.keycode, 0}; |
+ 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}; |
+ 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, |
+ 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) |
@@ -525,7 +534,7 @@ KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) { |
// 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, |
+ MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0xFFFF, |
0}; |
const MAP3* p = |
std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); |
@@ -536,7 +545,7 @@ KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) { |
keycode = KeyboardCodeFromXKeysym(keysym); |
if (keycode == VKEY_UNKNOWN) |
- keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey.keycode); |
+ keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey->keycode); |
return keycode; |
} |
@@ -823,14 +832,27 @@ KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { |
return VKEY_UNKNOWN; |
} |
-const char* CodeFromXEvent(XEvent* xev) { |
- return KeycodeConverter::GetInstance()->NativeKeycodeToCode( |
- xev->xkey.keycode); |
+const char* CodeFromXEvent(const XEvent* xev) { |
+ int keycode = (xev->type == GenericEvent) |
+ ? static_cast<XIDeviceEvent*>(xev->xcookie.data)->detail |
+ : xev->xkey.keycode; |
+ return KeycodeConverter::GetInstance()->NativeKeycodeToCode(keycode); |
} |
-uint16 GetCharacterFromXEvent(XEvent* xev) { |
+uint16 GetCharacterFromXEvent(const XEvent* xev) { |
+ XEvent xkeyevent; |
+ const XKeyEvent* xkey = NULL; |
char buf[6]; |
- int bytes_written = XLookupString(&xev->xkey, buf, 6, NULL, NULL); |
+ 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); |
+ xkey = &xkeyevent.xkey; |
+ } else { |
+ xkey = &xev->xkey; |
+ } |
+ int bytes_written = |
+ XLookupString(const_cast<XKeyEvent*>(xkey), buf, 6, NULL, NULL); |
DCHECK_LE(bytes_written, 6); |
if (bytes_written <= 0) |
@@ -1276,4 +1298,33 @@ int XKeysymForWindowsKeyCode(KeyboardCode keycode, bool shift) { |
} |
} |
+void InitXKeyEventFromXIDeviceEvent(const XEvent& src, XEvent* xkeyevent) { |
+ DCHECK(src.type == GenericEvent); |
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(src.xcookie.data); |
+ switch (xievent->evtype) { |
+ case XI_KeyPress: |
+ xkeyevent->type = KeyPress; |
+ break; |
+ case XI_KeyRelease: |
+ xkeyevent->type = KeyRelease; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ xkeyevent->xkey.serial = xievent->serial; |
+ xkeyevent->xkey.send_event = xievent->send_event; |
+ xkeyevent->xkey.display = xievent->display; |
+ xkeyevent->xkey.window = xievent->event; |
+ xkeyevent->xkey.root = xievent->root; |
+ xkeyevent->xkey.subwindow = xievent->child; |
+ xkeyevent->xkey.time = xievent->time; |
+ xkeyevent->xkey.x = xievent->event_x; |
+ xkeyevent->xkey.y = xievent->event_y; |
+ xkeyevent->xkey.x_root = xievent->root_x; |
+ xkeyevent->xkey.y_root = xievent->root_y; |
+ xkeyevent->xkey.state = xievent->mods.effective; |
+ xkeyevent->xkey.keycode = xievent->detail; |
+ xkeyevent->xkey.same_screen = 1; |
+} |
+ |
} // namespace ui |