OLD | NEW |
---|---|
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/XF86keysym.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/extensions/XInput2.h> | 13 #include <X11/extensions/XInput2.h> |
14 #include <X11/keysym.h> | 14 #include <X11/keysym.h> |
15 #if !defined(XK_dead_greek) | |
16 // Old versions of <X11/keysymdef.h> don't define XK_dead_greek. If it's not | |
Wez
2014/10/03 17:57:00
Do we ever build on platforms that don't have this
Yuki
2014/10/06 07:50:18
I found that trybots(Precise?) don't define this m
| |
17 // defined, define it for ourselves. (It's not sure that exactly which version | |
18 // of X11 first defined XK_dead_greek.) | |
19 #define XK_dead_greek 0xfe8c | |
20 #endif | |
15 | 21 |
16 #include "base/basictypes.h" | 22 #include "base/basictypes.h" |
17 #include "base/logging.h" | 23 #include "base/logging.h" |
18 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
19 #include "base/strings/sys_string_conversions.h" | 25 #include "base/strings/sys_string_conversions.h" |
20 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
21 #include "ui/events/keycodes/dom4/keycode_converter.h" | 27 #include "ui/events/keycodes/dom4/keycode_converter.h" |
22 #include "ui/events/x/keysym_to_unicode.h" | 28 #include "ui/events/x/keysym_to_unicode.h" |
23 | 29 |
24 #define VKEY_UNSUPPORTED VKEY_UNKNOWN | 30 #define VKEY_UNSUPPORTED VKEY_UNKNOWN |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 | 458 |
453 template <class T_MAP> | 459 template <class T_MAP> |
454 KeyboardCode FindVK(const T_MAP& key, const T_MAP* map, size_t size) { | 460 KeyboardCode FindVK(const T_MAP& key, const T_MAP* map, size_t size) { |
455 T_MAP comp = {0}; | 461 T_MAP comp = {0}; |
456 const T_MAP* p = std::lower_bound(map, map + size, key, comp); | 462 const T_MAP* p = std::lower_bound(map, map + size, key, comp); |
457 if (p != map + size && !comp(*p, key) && !comp(key, *p)) | 463 if (p != map + size && !comp(*p, key) && !comp(key, *p)) |
458 return static_cast<KeyboardCode>(p->vk); | 464 return static_cast<KeyboardCode>(p->vk); |
459 return VKEY_UNKNOWN; | 465 return VKEY_UNKNOWN; |
460 } | 466 } |
461 | 467 |
468 bool IsHardwareKeycodeFallbackAllowed(unsigned int keysym) { | |
469 // The following modifier keys and dead keys should not fall back to | |
470 // the hardware-keycode-based US layout. | |
471 // | |
472 // For example, suppose that keycode 108 (Right Alt key) is bound to | |
473 // XK_ISO_Level3_Latch in order to produce "à" by the latch key + a. | |
474 // If the latch key falls back to VKEY_RMENU, VKEY_RMENU is treated | |
475 // as accelerator key and it focuses the hamburger menu and the | |
476 // following 'a' key cannot produce "à". So these modifier keys and | |
477 // dead keys shouldn't fall back to the hardware-key-based US layout. | |
Wez
2014/10/03 17:57:01
nit: Suggest just "See crbug.com/<bug #>" here.
Yuki
2014/10/06 07:50:18
Done.
| |
478 switch (keysym) { | |
479 case XK_Shift_L: | |
480 case XK_Shift_R: | |
Wez
2014/10/03 17:57:01
Why are these (and Control, etc) in here? We have
Yuki
2014/10/06 07:50:18
You're right. I wanted to define this function in
| |
481 case XK_Control_L: | |
482 case XK_Control_R: | |
483 case XK_Caps_Lock: | |
484 case XK_Shift_Lock: | |
485 case XK_Meta_L: | |
486 case XK_Meta_R: | |
487 case XK_Alt_L: | |
488 case XK_Alt_R: | |
489 case XK_Super_L: | |
490 case XK_Super_R: | |
491 case XK_Hyper_L: | |
492 case XK_Hyper_R: | |
493 case XK_ISO_Lock: | |
494 case XK_ISO_Level2_Latch: | |
495 case XK_ISO_Level3_Shift: | |
496 case XK_ISO_Level3_Latch: | |
497 case XK_ISO_Level3_Lock: | |
498 case XK_ISO_Level5_Shift: | |
499 case XK_ISO_Level5_Latch: | |
500 case XK_ISO_Level5_Lock: | |
501 case XK_ISO_Group_Latch: | |
502 case XK_ISO_Group_Lock: | |
503 case XK_ISO_Next_Group: | |
504 case XK_ISO_Next_Group_Lock: | |
505 case XK_ISO_Prev_Group: | |
506 case XK_ISO_Prev_Group_Lock: | |
507 case XK_ISO_First_Group: | |
508 case XK_ISO_First_Group_Lock: | |
509 case XK_ISO_Last_Group: | |
510 case XK_ISO_Last_Group_Lock: | |
511 case XK_dead_grave: | |
512 case XK_dead_acute: | |
513 case XK_dead_circumflex: | |
514 case XK_dead_tilde: | |
515 case XK_dead_macron: | |
516 case XK_dead_breve: | |
517 case XK_dead_abovedot: | |
518 case XK_dead_diaeresis: | |
519 case XK_dead_abovering: | |
520 case XK_dead_doubleacute: | |
521 case XK_dead_caron: | |
522 case XK_dead_cedilla: | |
523 case XK_dead_ogonek: | |
524 case XK_dead_iota: | |
525 case XK_dead_voiced_sound: | |
526 case XK_dead_semivoiced_sound: | |
527 case XK_dead_belowdot: | |
528 case XK_dead_hook: | |
529 case XK_dead_horn: | |
530 case XK_dead_stroke: | |
531 case XK_dead_abovecomma: | |
532 case XK_dead_abovereversedcomma: | |
533 case XK_dead_doublegrave: | |
534 case XK_dead_belowring: | |
535 case XK_dead_belowmacron: | |
536 case XK_dead_belowcircumflex: | |
537 case XK_dead_belowtilde: | |
538 case XK_dead_belowbreve: | |
539 case XK_dead_belowdiaeresis: | |
540 case XK_dead_invertedbreve: | |
541 case XK_dead_belowcomma: | |
542 case XK_dead_currency: | |
543 case XK_dead_a: | |
544 case XK_dead_A: | |
545 case XK_dead_e: | |
546 case XK_dead_E: | |
547 case XK_dead_i: | |
548 case XK_dead_I: | |
549 case XK_dead_o: | |
550 case XK_dead_O: | |
551 case XK_dead_u: | |
552 case XK_dead_U: | |
553 case XK_dead_small_schwa: | |
554 case XK_dead_capital_schwa: | |
555 case XK_dead_greek: | |
556 case XK_First_Virtual_Screen: | |
557 case XK_Prev_Virtual_Screen: | |
558 case XK_Next_Virtual_Screen: | |
559 case XK_Last_Virtual_Screen: | |
560 case XK_Terminate_Server: | |
561 case XK_AccessX_Enable: | |
562 case XK_AccessX_Feedback_Enable: | |
563 case XK_RepeatKeys_Enable: | |
564 case XK_SlowKeys_Enable: | |
565 case XK_BounceKeys_Enable: | |
566 case XK_StickyKeys_Enable: | |
567 case XK_MouseKeys_Enable: | |
568 case XK_MouseKeys_Accel_Enable: | |
569 case XK_Overlay1_Enable: | |
570 case XK_Overlay2_Enable: | |
571 case XK_AudibleBell_Enable: | |
572 case XK_Pointer_Left: | |
573 case XK_Pointer_Right: | |
574 case XK_Pointer_Up: | |
575 case XK_Pointer_Down: | |
576 case XK_Pointer_UpLeft: | |
577 case XK_Pointer_UpRight: | |
578 case XK_Pointer_DownLeft: | |
579 case XK_Pointer_DownRight: | |
580 case XK_Pointer_Button_Dflt: | |
581 case XK_Pointer_Button1: | |
582 case XK_Pointer_Button2: | |
583 case XK_Pointer_Button3: | |
584 case XK_Pointer_Button4: | |
585 case XK_Pointer_Button5: | |
586 case XK_Pointer_DblClick_Dflt: | |
587 case XK_Pointer_DblClick1: | |
588 case XK_Pointer_DblClick2: | |
589 case XK_Pointer_DblClick3: | |
590 case XK_Pointer_DblClick4: | |
591 case XK_Pointer_DblClick5: | |
592 case XK_Pointer_Drag_Dflt: | |
593 case XK_Pointer_Drag1: | |
594 case XK_Pointer_Drag2: | |
595 case XK_Pointer_Drag3: | |
596 case XK_Pointer_Drag4: | |
597 case XK_Pointer_Drag5: | |
598 case XK_Pointer_EnableKeys: | |
599 case XK_Pointer_Accelerate: | |
600 case XK_Pointer_DfltBtnNext: | |
601 case XK_Pointer_DfltBtnPrev: | |
602 return false; | |
603 default: | |
604 return true; | |
605 } | |
606 } | |
607 | |
462 } // namespace | 608 } // namespace |
463 | 609 |
464 // Get an ui::KeyboardCode from an X keyevent | 610 // Get an ui::KeyboardCode from an X keyevent |
465 KeyboardCode KeyboardCodeFromXKeyEvent(const XEvent* xev) { | 611 KeyboardCode KeyboardCodeFromXKeyEvent(const XEvent* xev) { |
466 // Gets correct VKEY code from XEvent is performed as the following steps: | 612 // Gets correct VKEY code from XEvent is performed as the following steps: |
467 // 1. Gets the keysym without modifier states. | 613 // 1. Gets the keysym without modifier states. |
468 // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly. | 614 // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly. |
469 // 3. Find keysym in map0. | 615 // 3. Find keysym in map0. |
470 // 4. If not found, fallback to find keysym + hardware_code in map1. | 616 // 4. If not found, fallback to find keysym + hardware_code in map1. |
471 // 5. If not found, fallback to find keysym + keysym_shift + hardware_code | 617 // 5. If not found, fallback to find keysym + keysym_shift + hardware_code |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
538 MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0xFFFF, | 684 MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0xFFFF, |
539 0}; | 685 0}; |
540 const MAP3* p = | 686 const MAP3* p = |
541 std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); | 687 std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); |
542 if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc && | 688 if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc && |
543 p->ch1 == key4.ch1) | 689 p->ch1 == key4.ch1) |
544 return static_cast<KeyboardCode>(p->vk); | 690 return static_cast<KeyboardCode>(p->vk); |
545 } | 691 } |
546 | 692 |
547 keycode = KeyboardCodeFromXKeysym(keysym); | 693 keycode = KeyboardCodeFromXKeysym(keysym); |
548 if (keycode == VKEY_UNKNOWN) | 694 if (keycode == VKEY_UNKNOWN && IsHardwareKeycodeFallbackAllowed(keysym)) |
549 keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey->keycode); | 695 keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey->keycode); |
550 | 696 |
551 return keycode; | 697 return keycode; |
552 } | 698 } |
553 | 699 |
554 KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { | 700 KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { |
555 // TODO(sad): Have |keysym| go through the X map list? | 701 // TODO(sad): Have |keysym| go through the X map list? |
556 | 702 |
557 switch (keysym) { | 703 switch (keysym) { |
558 case XK_BackSpace: | 704 case XK_BackSpace: |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1347 // alone does not map to XK_less; XKeysymToKeycode() returns KEY_102ND | 1493 // alone does not map to XK_less; XKeysymToKeycode() returns KEY_102ND |
1348 // (the '<>' key between Shift and Z on 105-key keyboards) which does. | 1494 // (the '<>' key between Shift and Z on 105-key keyboards) which does. |
1349 // | 1495 // |
1350 // crbug.com/386066 and crbug.com/390263 are examples of problems | 1496 // crbug.com/386066 and crbug.com/390263 are examples of problems |
1351 // associated with this. | 1497 // associated with this. |
1352 // | 1498 // |
1353 return XKeysymToKeycode(display, XKeysymForWindowsKeyCode(key_code, false)); | 1499 return XKeysymToKeycode(display, XKeysymForWindowsKeyCode(key_code, false)); |
1354 } | 1500 } |
1355 | 1501 |
1356 } // namespace ui | 1502 } // namespace ui |
OLD | NEW |