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

Side by Side Diff: ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc

Issue 1284433002: Revise ui::DomKey to unify character and non-character codes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698