Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(402)

Side by Side Diff: ui/events/keycodes/keyboard_code_conversion_x.cc

Issue 336403005: Use XInput2 events for keyboard events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments (sadrul) 3 Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/keycodes/keyboard_code_conversion_x.h ('k') | ui/events/test/events_test_utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 5 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #define XK_3270 // for XK_3270_BackTab 9 #define XK_3270 // for XK_3270_BackTab
10 #include <X11/keysym.h> 10 #include <X11/XF86keysym.h>
11 #include <X11/Xlib.h> 11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h> 12 #include <X11/Xutil.h>
13 #include <X11/XF86keysym.h> 13 #include <X11/extensions/XInput2.h>
14 #include <X11/keysym.h>
14 15
15 #include "base/basictypes.h" 16 #include "base/basictypes.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
18 #include "base/strings/sys_string_conversions.h" 19 #include "base/strings/sys_string_conversions.h"
19 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
20 #include "ui/events/keycodes/dom4/keycode_converter.h" 21 #include "ui/events/keycodes/dom4/keycode_converter.h"
21 22
22 #define VKEY_UNSUPPORTED VKEY_UNKNOWN 23 #define VKEY_UNSUPPORTED VKEY_UNKNOWN
23 24
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 T_MAP comp = {0}; 454 T_MAP comp = {0};
454 const T_MAP* p = std::lower_bound(map, map + size, key, comp); 455 const T_MAP* p = std::lower_bound(map, map + size, key, comp);
455 if (p != map + size && !comp(*p, key) && !comp(key, *p)) 456 if (p != map + size && !comp(*p, key) && !comp(key, *p))
456 return static_cast<KeyboardCode>(p->vk); 457 return static_cast<KeyboardCode>(p->vk);
457 return VKEY_UNKNOWN; 458 return VKEY_UNKNOWN;
458 } 459 }
459 460
460 } // namespace 461 } // namespace
461 462
462 // Get an ui::KeyboardCode from an X keyevent 463 // Get an ui::KeyboardCode from an X keyevent
463 KeyboardCode KeyboardCodeFromXKeyEvent(XEvent* xev) { 464 KeyboardCode KeyboardCodeFromXKeyEvent(const XEvent* xev) {
464 // Gets correct VKEY code from XEvent is performed as the following steps: 465 // Gets correct VKEY code from XEvent is performed as the following steps:
465 // 1. Gets the keysym without modifier states. 466 // 1. Gets the keysym without modifier states.
466 // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly. 467 // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly.
467 // 3. Find keysym in map0. 468 // 3. Find keysym in map0.
468 // 4. If not found, fallback to find keysym + hardware_code in map1. 469 // 4. If not found, fallback to find keysym + hardware_code in map1.
469 // 5. If not found, fallback to find keysym + keysym_shift + hardware_code 470 // 5. If not found, fallback to find keysym + keysym_shift + hardware_code
470 // in map2. 471 // in map2.
471 // 6. If not found, fallback to find keysym + keysym_shift + keysym_altgr + 472 // 6. If not found, fallback to find keysym + keysym_shift + keysym_altgr +
472 // hardware_code in map3. 473 // hardware_code in map3.
473 // 7. If not found, fallback to find in KeyboardCodeFromXKeysym(), which 474 // 7. If not found, fallback to find in KeyboardCodeFromXKeysym(), which
474 // mainly for non-letter keys. 475 // mainly for non-letter keys.
475 // 8. If not found, fallback to find with the hardware code in US layout. 476 // 8. If not found, fallback to find with the hardware code in US layout.
476 477
477 KeySym keysym = NoSymbol; 478 KeySym keysym = NoSymbol;
478 XKeyEvent xkey = xev->xkey; 479 XEvent xkeyevent;
479 xkey.state &= (~0xFF | Mod2Mask); // Clears the xkey's state except numlock. 480 if (xev->type == GenericEvent) {
481 // Convert the XI2 key event into a core key event so that we can
482 // continue to use XLookupString() until crbug.com/367732 is complete.
483 InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent);
484 } else {
485 xkeyevent.xkey = xev->xkey;
486 }
487 XKeyEvent* xkey = &xkeyevent.xkey;
488 xkey->state &= (~0xFF | Mod2Mask); // Clears the xkey's state except numlock.
480 // XLookupKeysym does not take into consideration the state of the lock/shift 489 // XLookupKeysym does not take into consideration the state of the lock/shift
481 // etc. keys. So it is necessary to use XLookupString instead. 490 // etc. keys. So it is necessary to use XLookupString instead.
482 XLookupString(&xkey, NULL, 0, &keysym, NULL); 491 XLookupString(xkey, NULL, 0, &keysym, NULL);
483 492
484 // [a-z] cases. 493 // [a-z] cases.
485 if (keysym >= XK_a && keysym <= XK_z) 494 if (keysym >= XK_a && keysym <= XK_z)
486 return static_cast<KeyboardCode>(VKEY_A + keysym - XK_a); 495 return static_cast<KeyboardCode>(VKEY_A + keysym - XK_a);
487 496
488 // [0-9] cases. 497 // [0-9] cases.
489 if (keysym >= XK_0 && keysym <= XK_9) 498 if (keysym >= XK_0 && keysym <= XK_9)
490 return static_cast<KeyboardCode>(VKEY_0 + keysym - XK_0); 499 return static_cast<KeyboardCode>(VKEY_0 + keysym - XK_0);
491 500
492 KeyboardCode keycode = VKEY_UNKNOWN; 501 KeyboardCode keycode = VKEY_UNKNOWN;
493 502
494 if (!IsKeypadKey(keysym) && !IsPrivateKeypadKey(keysym) && 503 if (!IsKeypadKey(keysym) && !IsPrivateKeypadKey(keysym) &&
495 !IsCursorKey(keysym) && !IsPFKey(keysym) && !IsFunctionKey(keysym) && 504 !IsCursorKey(keysym) && !IsPFKey(keysym) && !IsFunctionKey(keysym) &&
496 !IsModifierKey(keysym)) { 505 !IsModifierKey(keysym)) {
497 MAP0 key0 = {keysym & 0xFFFF, 0}; 506 MAP0 key0 = {keysym & 0xFFFF, 0};
498 keycode = FindVK(key0, map0, arraysize(map0)); 507 keycode = FindVK(key0, map0, arraysize(map0));
499 if (keycode != VKEY_UNKNOWN) 508 if (keycode != VKEY_UNKNOWN)
500 return keycode; 509 return keycode;
501 510
502 MAP1 key1 = {keysym & 0xFFFF, xkey.keycode, 0}; 511 MAP1 key1 = {keysym & 0xFFFF, xkey->keycode, 0};
503 keycode = FindVK(key1, map1, arraysize(map1)); 512 keycode = FindVK(key1, map1, arraysize(map1));
504 if (keycode != VKEY_UNKNOWN) 513 if (keycode != VKEY_UNKNOWN)
505 return keycode; 514 return keycode;
506 515
507 KeySym keysym_shift = NoSymbol; 516 KeySym keysym_shift = NoSymbol;
508 xkey.state |= ShiftMask; 517 xkey->state |= ShiftMask;
509 XLookupString(&xkey, NULL, 0, &keysym_shift, NULL); 518 XLookupString(xkey, NULL, 0, &keysym_shift, NULL);
510 MAP2 key2 = {keysym & 0xFFFF, xkey.keycode, keysym_shift & 0xFFFF, 0}; 519 MAP2 key2 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0};
511 keycode = FindVK(key2, map2, arraysize(map2)); 520 keycode = FindVK(key2, map2, arraysize(map2));
512 if (keycode != VKEY_UNKNOWN) 521 if (keycode != VKEY_UNKNOWN)
513 return keycode; 522 return keycode;
514 523
515 KeySym keysym_altgr = NoSymbol; 524 KeySym keysym_altgr = NoSymbol;
516 xkey.state &= ~ShiftMask; 525 xkey->state &= ~ShiftMask;
517 xkey.state |= Mod1Mask; 526 xkey->state |= Mod1Mask;
518 XLookupString(&xkey, NULL, 0, &keysym_altgr, NULL); 527 XLookupString(xkey, NULL, 0, &keysym_altgr, NULL);
519 MAP3 key3 = {keysym & 0xFFFF, xkey.keycode, keysym_shift & 0xFFFF, 528 MAP3 key3 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF,
520 keysym_altgr & 0xFFFF, 0}; 529 keysym_altgr & 0xFFFF, 0};
521 keycode = FindVK(key3, map3, arraysize(map3)); 530 keycode = FindVK(key3, map3, arraysize(map3));
522 if (keycode != VKEY_UNKNOWN) 531 if (keycode != VKEY_UNKNOWN)
523 return keycode; 532 return keycode;
524 533
525 // On Linux some keys has AltGr char but not on Windows. 534 // On Linux some keys has AltGr char but not on Windows.
526 // So if cannot find VKEY with (ch0+sc+ch1+ch2) in map3, tries to fallback 535 // So if cannot find VKEY with (ch0+sc+ch1+ch2) in map3, tries to fallback
527 // to just find VKEY with (ch0+sc+ch1). This is the best we could do. 536 // to just find VKEY with (ch0+sc+ch1). This is the best we could do.
528 MAP3 key4 = {keysym & 0xFFFF, xkey.keycode, keysym_shift & 0xFFFF, 0xFFFF, 537 MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0xFFFF,
529 0}; 538 0};
530 const MAP3* p = 539 const MAP3* p =
531 std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); 540 std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3());
532 if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc && 541 if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc &&
533 p->ch1 == key4.ch1) 542 p->ch1 == key4.ch1)
534 return static_cast<KeyboardCode>(p->vk); 543 return static_cast<KeyboardCode>(p->vk);
535 } 544 }
536 545
537 keycode = KeyboardCodeFromXKeysym(keysym); 546 keycode = KeyboardCodeFromXKeysym(keysym);
538 if (keycode == VKEY_UNKNOWN) 547 if (keycode == VKEY_UNKNOWN)
539 keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey.keycode); 548 keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey->keycode);
540 549
541 return keycode; 550 return keycode;
542 } 551 }
543 552
544 KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { 553 KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) {
545 // TODO(sad): Have |keysym| go through the X map list? 554 // TODO(sad): Have |keysym| go through the X map list?
546 555
547 switch (keysym) { 556 switch (keysym) {
548 case XK_BackSpace: 557 case XK_BackSpace:
549 return VKEY_BACK; 558 return VKEY_BACK;
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 return VKEY_KBD_BRIGHTNESS_DOWN; 825 return VKEY_KBD_BRIGHTNESS_DOWN;
817 case XF86XK_KbdBrightnessUp: 826 case XF86XK_KbdBrightnessUp:
818 return VKEY_KBD_BRIGHTNESS_UP; 827 return VKEY_KBD_BRIGHTNESS_UP;
819 828
820 // TODO(sad): some keycodes are still missing. 829 // TODO(sad): some keycodes are still missing.
821 } 830 }
822 DLOG(WARNING) << "Unknown keysym: " << base::StringPrintf("0x%x", keysym); 831 DLOG(WARNING) << "Unknown keysym: " << base::StringPrintf("0x%x", keysym);
823 return VKEY_UNKNOWN; 832 return VKEY_UNKNOWN;
824 } 833 }
825 834
826 const char* CodeFromXEvent(XEvent* xev) { 835 const char* CodeFromXEvent(const XEvent* xev) {
827 return KeycodeConverter::GetInstance()->NativeKeycodeToCode( 836 int keycode = (xev->type == GenericEvent)
828 xev->xkey.keycode); 837 ? static_cast<XIDeviceEvent*>(xev->xcookie.data)->detail
838 : xev->xkey.keycode;
839 return KeycodeConverter::GetInstance()->NativeKeycodeToCode(keycode);
829 } 840 }
830 841
831 uint16 GetCharacterFromXEvent(XEvent* xev) { 842 uint16 GetCharacterFromXEvent(const XEvent* xev) {
843 XEvent xkeyevent;
844 const XKeyEvent* xkey = NULL;
832 char buf[6]; 845 char buf[6];
833 int bytes_written = XLookupString(&xev->xkey, buf, 6, NULL, NULL); 846 if (xev->type == GenericEvent) {
847 // Convert the XI2 key event into a core key event so that we can
848 // continue to use XLookupString() until crbug.com/367732 is complete.
849 InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent);
850 xkey = &xkeyevent.xkey;
851 } else {
852 xkey = &xev->xkey;
853 }
854 int bytes_written =
855 XLookupString(const_cast<XKeyEvent*>(xkey), buf, 6, NULL, NULL);
834 DCHECK_LE(bytes_written, 6); 856 DCHECK_LE(bytes_written, 6);
835 857
836 if (bytes_written <= 0) 858 if (bytes_written <= 0)
837 return 0; 859 return 0;
838 const base::string16& result = base::WideToUTF16( 860 const base::string16& result = base::WideToUTF16(
839 base::SysNativeMBToWide(base::StringPiece(buf, bytes_written))); 861 base::SysNativeMBToWide(base::StringPiece(buf, bytes_written)));
840 return result.length() == 1 ? result[0] : 0; 862 return result.length() == 1 ? result[0] : 0;
841 } 863 }
842 864
843 KeyboardCode DefaultKeyboardCodeFromHardwareKeycode( 865 KeyboardCode DefaultKeyboardCodeFromHardwareKeycode(
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 return XF86XK_KbdBrightnessDown; 1291 return XF86XK_KbdBrightnessDown;
1270 case VKEY_KBD_BRIGHTNESS_UP: 1292 case VKEY_KBD_BRIGHTNESS_UP:
1271 return XF86XK_KbdBrightnessUp; 1293 return XF86XK_KbdBrightnessUp;
1272 1294
1273 default: 1295 default:
1274 LOG(WARNING) << "Unknown keycode:" << keycode; 1296 LOG(WARNING) << "Unknown keycode:" << keycode;
1275 return 0; 1297 return 0;
1276 } 1298 }
1277 } 1299 }
1278 1300
1301 void InitXKeyEventFromXIDeviceEvent(const XEvent& src, XEvent* xkeyevent) {
1302 DCHECK(src.type == GenericEvent);
1303 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(src.xcookie.data);
1304 switch (xievent->evtype) {
1305 case XI_KeyPress:
1306 xkeyevent->type = KeyPress;
1307 break;
1308 case XI_KeyRelease:
1309 xkeyevent->type = KeyRelease;
1310 break;
1311 default:
1312 NOTREACHED();
1313 }
1314 xkeyevent->xkey.serial = xievent->serial;
1315 xkeyevent->xkey.send_event = xievent->send_event;
1316 xkeyevent->xkey.display = xievent->display;
1317 xkeyevent->xkey.window = xievent->event;
1318 xkeyevent->xkey.root = xievent->root;
1319 xkeyevent->xkey.subwindow = xievent->child;
1320 xkeyevent->xkey.time = xievent->time;
1321 xkeyevent->xkey.x = xievent->event_x;
1322 xkeyevent->xkey.y = xievent->event_y;
1323 xkeyevent->xkey.x_root = xievent->root_x;
1324 xkeyevent->xkey.y_root = xievent->root_y;
1325 xkeyevent->xkey.state = xievent->mods.effective;
1326 xkeyevent->xkey.keycode = xievent->detail;
1327 xkeyevent->xkey.same_screen = 1;
1328 }
1329
1279 } // namespace ui 1330 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/keycodes/keyboard_code_conversion_x.h ('k') | ui/events/test/events_test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698