Chromium Code Reviews| 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 |