OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/ozone/layout/xkb/xkb_keyboard_layout_engine.h" | 5 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h" |
6 | 6 |
7 #include <xkbcommon/xkbcommon-names.h> | 7 #include <xkbcommon/xkbcommon-names.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
13 #include "base/task_runner.h" | 13 #include "base/task_runner.h" |
14 #include "base/thread_task_runner_handle.h" | 14 #include "base/thread_task_runner_handle.h" |
15 #include "base/threading/worker_pool.h" | 15 #include "base/threading/worker_pool.h" |
16 #include "ui/events/event_constants.h" | 16 #include "ui/events/event_constants.h" |
17 #include "ui/events/keycodes/dom/dom_code.h" | 17 #include "ui/events/keycodes/dom/dom_code.h" |
18 #include "ui/events/keycodes/dom/dom_key.h" | 18 #include "ui/events/keycodes/dom/dom_key.h" |
19 #include "ui/events/keycodes/dom/keycode_converter.h" | 19 #include "ui/events/keycodes/dom/keycode_converter.h" |
20 #include "ui/events/keycodes/keyboard_code_conversion.h" | 20 #include "ui/events/keycodes/keyboard_code_conversion.h" |
21 #include "ui/events/keycodes/keyboard_code_conversion_xkb.h" | 21 #include "ui/events/keycodes/keyboard_code_conversion_xkb.h" |
22 #include "ui/events/ozone/layout/xkb/xkb_keyboard_code_conversion.h" | |
23 | 22 |
24 namespace ui { | 23 namespace ui { |
25 | 24 |
26 namespace { | 25 namespace { |
27 | 26 |
28 typedef base::Callback<void(const std::string&, | 27 typedef base::Callback<void(const std::string&, |
29 scoped_ptr<char, base::FreeDeleter>)> | 28 scoped_ptr<char, base::FreeDeleter>)> |
30 LoadKeymapCallback; | 29 LoadKeymapCallback; |
31 | 30 |
32 KeyboardCode AlphanumericKeyboardCode(base::char16 character) { | 31 KeyboardCode AlphanumericKeyboardCode(base::char16 character) { |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 } | 708 } |
710 | 709 |
711 bool XkbKeyboardLayoutEngine::UsesAltGr() const { | 710 bool XkbKeyboardLayoutEngine::UsesAltGr() const { |
712 // NOTIMPLEMENTED(); | 711 // NOTIMPLEMENTED(); |
713 return false; | 712 return false; |
714 } | 713 } |
715 | 714 |
716 bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, | 715 bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, |
717 int flags, | 716 int flags, |
718 DomKey* dom_key, | 717 DomKey* dom_key, |
719 base::char16* character, | |
720 KeyboardCode* key_code, | 718 KeyboardCode* key_code, |
721 uint32* platform_keycode) const { | 719 uint32_t* platform_keycode) const { |
722 if (dom_code == DomCode::NONE) | 720 if (dom_code == DomCode::NONE) |
723 return false; | 721 return false; |
724 // Convert DOM physical key to XKB representation. | 722 // Convert DOM physical key to XKB representation. |
725 xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code); | 723 xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code); |
726 if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) { | 724 if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) { |
727 LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex | 725 LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex |
728 << static_cast<int>(dom_code) << " '" | 726 << static_cast<int>(dom_code) << " '" |
729 << KeycodeConverter::DomCodeToCodeString(dom_code) << "'"; | 727 << KeycodeConverter::DomCodeToCodeString(dom_code) << "'"; |
730 return false; | 728 return false; |
731 } | 729 } |
732 xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags); | 730 xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags); |
733 // Obtain keysym and character. | 731 // Obtain keysym and character. |
734 xkb_keysym_t xkb_keysym; | 732 xkb_keysym_t xkb_keysym; |
735 if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, character)) | 733 uint32_t character = 0; |
734 if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, &character)) | |
736 return false; | 735 return false; |
737 *platform_keycode = xkb_keysym; | 736 *platform_keycode = xkb_keysym; |
738 // Classify the keysym and convert to DOM and VKEY representations. | 737 // Classify the keysym and convert to DOM and VKEY representations. |
739 *dom_key = NonPrintableXKeySymToDomKey(xkb_keysym); | 738 *dom_key = NonPrintableXKeySymToDomKey(xkb_keysym); |
740 if (*dom_key == DomKey::NONE) { | 739 if (*dom_key == DomKey::NONE) { |
741 *dom_key = CharacterToDomKey(*character); | 740 *dom_key = character; |
742 *key_code = AlphanumericKeyboardCode(*character); | 741 *key_code = AlphanumericKeyboardCode(character); |
743 if (*key_code == VKEY_UNKNOWN) { | 742 if (*key_code == VKEY_UNKNOWN) { |
744 *key_code = DifficultKeyboardCode(dom_code, flags, xkb_keycode, xkb_flags, | 743 *key_code = DifficultKeyboardCode(dom_code, flags, xkb_keycode, xkb_flags, |
745 xkb_keysym, *dom_key, *character); | 744 xkb_keysym, character); |
746 if (*key_code == VKEY_UNKNOWN) { | 745 if (*key_code == VKEY_UNKNOWN) |
747 *key_code = LocatedToNonLocatedKeyboardCode( | 746 *key_code = LocatedToNonLocatedKeyboardCode( |
748 DomCodeToUsLayoutKeyboardCode(dom_code)); | 747 DomCodeToUsLayoutKeyboardCode(dom_code)); |
749 } | |
750 } | 748 } |
751 // If the Control key is down, only allow ASCII control characters to be | 749 // If the Control key is down, only allow ASCII control characters to be |
752 // returned, regardless of the key layout. crbug.com/450849 | 750 // returned, regardless of the key layout. crbug.com/450849 |
753 if ((flags & EF_CONTROL_DOWN) && (*character >= 0x20)) | 751 if ((flags & EF_CONTROL_DOWN) && (character >= 0x20)) |
754 *character = 0; | 752 *dom_key = DomKey::UNIDENTIFIED; |
755 } else if (*dom_key == DomKey::DEAD) { | |
kpschoedel
2015/08/07 20:42:12
Dead keys now have distinct codes, handled by NonP
| |
756 *character = DeadXkbKeySymToCombiningCharacter(xkb_keysym); | |
757 *key_code = LocatedToNonLocatedKeyboardCode( | |
758 DomCodeToUsLayoutKeyboardCode(dom_code)); | |
759 } else { | 753 } else { |
760 *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); | 754 *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); |
761 if (*key_code == VKEY_UNKNOWN) { | 755 if (*key_code == VKEY_UNKNOWN) { |
762 *key_code = LocatedToNonLocatedKeyboardCode( | 756 *key_code = LocatedToNonLocatedKeyboardCode( |
763 DomCodeToUsLayoutKeyboardCode(dom_code)); | 757 DomCodeToUsLayoutKeyboardCode(dom_code)); |
764 } | 758 } |
765 } | 759 } |
766 return true; | 760 return true; |
767 } | 761 } |
768 | 762 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
808 xkb_flags |= entry.xkb_flag; | 802 xkb_flags |= entry.xkb_flag; |
809 } | 803 } |
810 // NumLock is always on. | 804 // NumLock is always on. |
811 xkb_flags |= num_lock_mod_mask_; | 805 xkb_flags |= num_lock_mod_mask_; |
812 return xkb_flags; | 806 return xkb_flags; |
813 } | 807 } |
814 | 808 |
815 bool XkbKeyboardLayoutEngine::XkbLookup(xkb_keycode_t xkb_keycode, | 809 bool XkbKeyboardLayoutEngine::XkbLookup(xkb_keycode_t xkb_keycode, |
816 xkb_mod_mask_t xkb_flags, | 810 xkb_mod_mask_t xkb_flags, |
817 xkb_keysym_t* xkb_keysym, | 811 xkb_keysym_t* xkb_keysym, |
818 base::char16* character) const { | 812 uint32_t* character) const { |
819 if (!xkb_state_) { | 813 if (!xkb_state_) { |
820 LOG(ERROR) << "No current XKB state"; | 814 LOG(ERROR) << "No current XKB state"; |
821 return false; | 815 return false; |
822 } | 816 } |
823 xkb_state_update_mask(xkb_state_.get(), xkb_flags, 0, 0, 0, 0, 0); | 817 xkb_state_update_mask(xkb_state_.get(), xkb_flags, 0, 0, 0, 0, 0); |
824 *xkb_keysym = xkb_state_key_get_one_sym(xkb_state_.get(), xkb_keycode); | 818 *xkb_keysym = xkb_state_key_get_one_sym(xkb_state_.get(), xkb_keycode); |
825 if (*xkb_keysym == XKB_KEY_NoSymbol) | 819 if (*xkb_keysym == XKB_KEY_NoSymbol) |
826 return false; | 820 return false; |
827 uint32_t c = xkb_state_key_get_utf32(xkb_state_.get(), xkb_keycode); | 821 *character = xkb_state_key_get_utf32(xkb_state_.get(), xkb_keycode); |
828 DLOG_IF(ERROR, c != (c & 0xFFFF)) << "Non-BMP character:" << c; | 822 DLOG_IF(ERROR, *character != (*character & 0xFFFF)) |
829 *character = static_cast<base::char16>(c); | 823 << "Non-BMP character:" << *character; |
830 return true; | 824 return true; |
831 } | 825 } |
832 | 826 |
833 KeyboardCode XkbKeyboardLayoutEngine::DifficultKeyboardCode( | 827 KeyboardCode XkbKeyboardLayoutEngine::DifficultKeyboardCode( |
834 DomCode dom_code, | 828 DomCode dom_code, |
835 int ui_flags, | 829 int ui_flags, |
836 xkb_keycode_t xkb_keycode, | 830 xkb_keycode_t xkb_keycode, |
837 xkb_mod_mask_t xkb_flags, | 831 xkb_mod_mask_t xkb_flags, |
838 xkb_keysym_t xkb_keysym, | 832 xkb_keysym_t xkb_keysym, |
839 DomKey dom_key, | |
840 base::char16 character) const { | 833 base::char16 character) const { |
841 // Get the layout interpretation without modifiers, so that | 834 // Get the layout interpretation without modifiers, so that |
842 // e.g. Ctrl+D correctly generates VKEY_D. | 835 // e.g. Ctrl+D correctly generates VKEY_D. |
843 xkb_keysym_t plain_keysym; | 836 xkb_keysym_t plain_keysym; |
844 base::char16 plain_character; | 837 uint32_t plain_character; |
845 if (!XkbLookup(xkb_keycode, 0, &plain_keysym, &plain_character)) | 838 if (!XkbLookup(xkb_keycode, 0, &plain_keysym, &plain_character)) |
846 return VKEY_UNKNOWN; | 839 return VKEY_UNKNOWN; |
847 | 840 |
848 // If the plain key is non-printable, that determines the VKEY. | 841 // If the plain key is non-printable, that determines the VKEY. |
849 DomKey plain_key = NonPrintableXKeySymToDomKey(plain_keysym); | 842 DomKey plain_key = NonPrintableXKeySymToDomKey(plain_keysym); |
850 if (plain_key != ui::DomKey::NONE) | 843 if (plain_key != ui::DomKey::NONE) |
851 return NonPrintableDomKeyToKeyboardCode(dom_key); | 844 return NonPrintableDomKeyToKeyboardCode(plain_key); |
852 | 845 |
853 // Plain ASCII letters and digits map directly to VKEY values. | 846 // Plain ASCII letters and digits map directly to VKEY values. |
854 KeyboardCode key_code = AlphanumericKeyboardCode(plain_character); | 847 KeyboardCode key_code = AlphanumericKeyboardCode(plain_character); |
855 if (key_code != VKEY_UNKNOWN) | 848 if (key_code != VKEY_UNKNOWN) |
856 return key_code; | 849 return key_code; |
857 | 850 |
858 // Check the multi-character tables. | 851 // Check the multi-character tables. |
859 const PrintableMultiEntry* multi_end = kMultiMap + arraysize(kMultiMap); | 852 const PrintableMultiEntry* multi_end = kMultiMap + arraysize(kMultiMap); |
860 const PrintableMultiEntry* multi = | 853 const PrintableMultiEntry* multi = |
861 std::lower_bound(kMultiMap, multi_end, plain_character, | 854 std::lower_bound(kMultiMap, multi_end, plain_character, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
904 | 897 |
905 base::char16 XkbKeyboardLayoutEngine::XkbSubCharacter( | 898 base::char16 XkbKeyboardLayoutEngine::XkbSubCharacter( |
906 xkb_keycode_t xkb_keycode, | 899 xkb_keycode_t xkb_keycode, |
907 xkb_mod_mask_t base_flags, | 900 xkb_mod_mask_t base_flags, |
908 base::char16 base_character, | 901 base::char16 base_character, |
909 int ui_flags) const { | 902 int ui_flags) const { |
910 xkb_mod_mask_t flags = EventFlagsToXkbFlags(ui_flags); | 903 xkb_mod_mask_t flags = EventFlagsToXkbFlags(ui_flags); |
911 if (flags == base_flags) | 904 if (flags == base_flags) |
912 return base_character; | 905 return base_character; |
913 xkb_keysym_t keysym; | 906 xkb_keysym_t keysym; |
914 base::char16 character = 0; | 907 uint32_t character = 0; |
915 if (!XkbLookup(xkb_keycode, flags, &keysym, &character)) | 908 if (!XkbLookup(xkb_keycode, flags, &keysym, &character)) |
916 character = kNone; | 909 character = kNone; |
917 return character; | 910 return character; |
918 } | 911 } |
919 | 912 |
920 void XkbKeyboardLayoutEngine::ParseLayoutName(const std::string& layout_name, | 913 void XkbKeyboardLayoutEngine::ParseLayoutName(const std::string& layout_name, |
921 std::string* layout_id, | 914 std::string* layout_id, |
922 std::string* layout_variant) { | 915 std::string* layout_variant) { |
923 size_t dash_index = layout_name.find('-'); | 916 size_t dash_index = layout_name.find('-'); |
924 size_t parentheses_index = layout_name.find('('); | 917 size_t parentheses_index = layout_name.find('('); |
925 *layout_id = layout_name; | 918 *layout_id = layout_name; |
926 *layout_variant = ""; | 919 *layout_variant = ""; |
927 if (parentheses_index != std::string::npos) { | 920 if (parentheses_index != std::string::npos) { |
928 *layout_id = layout_name.substr(0, parentheses_index); | 921 *layout_id = layout_name.substr(0, parentheses_index); |
929 size_t close_index = layout_name.find(')', parentheses_index); | 922 size_t close_index = layout_name.find(')', parentheses_index); |
930 if (close_index == std::string::npos) | 923 if (close_index == std::string::npos) |
931 close_index = layout_name.size(); | 924 close_index = layout_name.size(); |
932 *layout_variant = layout_name.substr(parentheses_index + 1, | 925 *layout_variant = layout_name.substr(parentheses_index + 1, |
933 close_index - parentheses_index - 1); | 926 close_index - parentheses_index - 1); |
934 } else if (dash_index != std::string::npos) { | 927 } else if (dash_index != std::string::npos) { |
935 *layout_id = layout_name.substr(0, dash_index); | 928 *layout_id = layout_name.substr(0, dash_index); |
936 *layout_variant = layout_name.substr(dash_index + 1); | 929 *layout_variant = layout_name.substr(dash_index + 1); |
937 } | 930 } |
938 } | 931 } |
939 | 932 |
940 } // namespace ui | 933 } // namespace ui |
OLD | NEW |