OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_H_ | 5 #ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_H_ |
6 #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_H_ | 6 #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <queue> | |
10 #include <set> | |
11 #include <string> | 9 #include <string> |
12 #include <vector> | 10 #include <vector> |
13 | 11 |
14 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
15 | 13 |
16 namespace chromeos { | 14 namespace chromeos { |
17 namespace input_method { | 15 namespace input_method { |
18 | 16 |
19 struct AutoRepeatRate { | 17 struct AutoRepeatRate { |
20 AutoRepeatRate() : initial_delay_in_ms(0), repeat_interval_in_ms(0) {} | 18 AutoRepeatRate() : initial_delay_in_ms(0), repeat_interval_in_ms(0) {} |
(...skipping 27 matching lines...) Expand all Loading... |
48 } | 46 } |
49 ModifierKey original; // Replace the key with | 47 ModifierKey original; // Replace the key with |
50 ModifierKey replacement; // this key. | 48 ModifierKey replacement; // this key. |
51 }; | 49 }; |
52 typedef std::vector<ModifierKeyPair> ModifierMap; | 50 typedef std::vector<ModifierKeyPair> ModifierMap; |
53 | 51 |
54 class InputMethodUtil; | 52 class InputMethodUtil; |
55 | 53 |
56 class XKeyboard { | 54 class XKeyboard { |
57 public: | 55 public: |
58 // Note: at this moment, classes other than InputMethodManager should not | 56 virtual ~XKeyboard() {} |
59 // instantiate the XKeyboard class. | |
60 explicit XKeyboard(const InputMethodUtil& util); | |
61 ~XKeyboard(); | |
62 | 57 |
63 // Sets the current keyboard layout to |layout_name|. This function does not | 58 // Sets the current keyboard layout to |layout_name|. This function does not |
64 // change the current mapping of the modifier keys. Returns true on success. | 59 // change the current mapping of the modifier keys. Returns true on success. |
65 bool SetCurrentKeyboardLayoutByName(const std::string& layout_name); | 60 virtual bool SetCurrentKeyboardLayoutByName( |
| 61 const std::string& layout_name) = 0; |
66 | 62 |
67 // Remaps modifier keys. This function does not change the current keyboard | 63 // Remaps modifier keys. This function does not change the current keyboard |
68 // layout. Returns true on success. For now, you can't remap Left Control and | 64 // layout. Returns true on success. For now, you can't remap Left Control and |
69 // Left Alt keys to caps lock. | 65 // Left Alt keys to caps lock. |
70 bool RemapModifierKeys(const ModifierMap& modifier_map); | 66 virtual bool RemapModifierKeys(const ModifierMap& modifier_map) = 0; |
71 | 67 |
72 // Sets the current keyboard layout again. We have to call the function every | 68 // Sets the current keyboard layout again. We have to call the function every |
73 // time when "XI_HierarchyChanged" XInput2 event is sent to Chrome. See | 69 // time when "XI_HierarchyChanged" XInput2 event is sent to Chrome. See |
74 // xinput_hierarchy_changed_event_listener.h for details. | 70 // xinput_hierarchy_changed_event_listener.h for details. |
75 bool ReapplyCurrentKeyboardLayout(); | 71 virtual bool ReapplyCurrentKeyboardLayout() = 0; |
76 | 72 |
77 // Updates keyboard LEDs on all keyboards. | 73 // Updates keyboard LEDs on all keyboards. |
78 // XKB asymmetrically propagates keyboard modifier indicator state changes to | 74 // XKB asymmetrically propagates keyboard modifier indicator state changes to |
79 // slave keyboards. If the state change is initiated from a client to the | 75 // slave keyboards. If the state change is initiated from a client to the |
80 // "core/master keyboard", XKB changes global state and pushes an indication | 76 // "core/master keyboard", XKB changes global state and pushes an indication |
81 // change down to all keyboards. If the state change is initiated by one slave | 77 // change down to all keyboards. If the state change is initiated by one slave |
82 // (physical) keyboard, it changes global state but only pushes an indicator | 78 // (physical) keyboard, it changes global state but only pushes an indicator |
83 // state change down to that one keyboard. | 79 // state change down to that one keyboard. |
84 // This function changes LEDs on all keyboards by explicitly updating the | 80 // This function changes LEDs on all keyboards by explicitly updating the |
85 // core/master keyboard. | 81 // core/master keyboard. |
86 void ReapplyCurrentModifierLockStatus(); | 82 virtual void ReapplyCurrentModifierLockStatus() = 0; |
87 | 83 |
88 // Sets the Caps Lock and Num Lock status. Do not call the function from | 84 // Sets the Caps Lock and Num Lock status. Do not call the function from |
89 // non-UI threads. | 85 // non-UI threads. |
90 void SetLockedModifiers(ModifierLockStatus new_caps_lock_status, | 86 virtual void SetLockedModifiers(ModifierLockStatus new_caps_lock_status, |
91 ModifierLockStatus new_num_lock_status); | 87 ModifierLockStatus new_num_lock_status) = 0; |
92 | 88 |
93 // Sets the num lock status to |enable_num_lock|. Do not call the function | 89 // Sets the num lock status to |enable_num_lock|. Do not call the function |
94 // from non-UI threads. | 90 // from non-UI threads. |
95 void SetNumLockEnabled(bool enable_num_lock); | 91 virtual void SetNumLockEnabled(bool enable_num_lock) = 0; |
96 | 92 |
97 // Sets the caps lock status to |enable_caps_lock|. Do not call the function | 93 // Sets the caps lock status to |enable_caps_lock|. Do not call the function |
98 // from non-UI threads. | 94 // from non-UI threads. |
99 void SetCapsLockEnabled(bool enable_caps_lock); | 95 virtual void SetCapsLockEnabled(bool enable_caps_lock) = 0; |
100 | |
101 // Set true on |out_caps_lock_enabled| if Caps Lock is enabled. Set true on | |
102 // |out_num_lock_enabled| if Num Lock (or to be precise, the modifier | |
103 // specified by |num_lock_mask|) is enabled. Both 'out' parameters can be | |
104 // NULL. When |out_num_lock_enabled| is NULL, |num_lock_mask| is ignored (you | |
105 // can pass 0 in this case). Do not call the function from non-UI threads. | |
106 static void GetLockedModifiers(unsigned int num_lock_mask, | |
107 bool* out_caps_lock_enabled, | |
108 bool* out_num_lock_enabled); | |
109 | 96 |
110 // Returns true if num lock is enabled. Do not call the function from non-UI | 97 // Returns true if num lock is enabled. Do not call the function from non-UI |
111 // threads. | 98 // threads. |
112 static bool NumLockIsEnabled(unsigned int num_lock_mask); | 99 virtual bool NumLockIsEnabled() = 0; |
113 | 100 |
114 // Returns true if caps lock is enabled. Do not call the function from non-UI | 101 // Returns true if caps lock is enabled. Do not call the function from non-UI |
115 // threads. | 102 // threads. |
116 static bool CapsLockIsEnabled(); | 103 virtual bool CapsLockIsEnabled() = 0; |
| 104 |
| 105 // Creates a full XKB layout name like |
| 106 // "gb(extd)+chromeos(leftcontrol_disabled_leftalt),us" |
| 107 // from modifier key mapping and |layout_name|, such as "us", "us(dvorak)", |
| 108 // and "gb(extd)". Returns an empty string on error. Do not call this function |
| 109 // directly: it is public for testability. |
| 110 virtual std::string CreateFullXkbLayoutName( |
| 111 const std::string& layout_name, |
| 112 const ModifierMap& modifire_map) = 0; |
| 113 |
| 114 // Returns a mask (e.g. 1U<<4) for Num Lock. On error, returns 0. |
| 115 // TODO(yusukes): Move this and webdriver::GetXModifierMask() functions in |
| 116 // chrome/test/webdriver/keycode_text_conversion_x.cc to ui/base/x/x11_util. |
| 117 // The two functions are almost the same. |
| 118 virtual unsigned int GetNumLockMask() = 0; |
| 119 |
| 120 // Set true on |out_caps_lock_enabled| if Caps Lock is enabled. Set true on |
| 121 // |out_num_lock_enabled| if Num Lock is enabled. Both out parameters can be |
| 122 // NULL. Do not call the function from non-UI threads. |
| 123 virtual void GetLockedModifiers(bool* out_caps_lock_enabled, |
| 124 bool* out_num_lock_enabled) = 0; |
117 | 125 |
118 // Turns on and off the auto-repeat of the keyboard. Returns true on success. | 126 // Turns on and off the auto-repeat of the keyboard. Returns true on success. |
119 // Do not call the function from non-UI threads. | 127 // Do not call the function from non-UI threads. |
| 128 // TODO(yusukes): Make this function non-static so we can mock it. |
120 static bool SetAutoRepeatEnabled(bool enabled); | 129 static bool SetAutoRepeatEnabled(bool enabled); |
121 | 130 |
122 // Sets the auto-repeat rate of the keyboard, initial delay in ms, and repeat | 131 // Sets the auto-repeat rate of the keyboard, initial delay in ms, and repeat |
123 // interval in ms. Returns true on success. Do not call the function from | 132 // interval in ms. Returns true on success. Do not call the function from |
124 // non-UI threads. | 133 // non-UI threads. |
| 134 // TODO(yusukes): Make this function non-static so we can mock it. |
125 static bool SetAutoRepeatRate(const AutoRepeatRate& rate); | 135 static bool SetAutoRepeatRate(const AutoRepeatRate& rate); |
126 | 136 |
127 // Returns a mask (e.g. 1U<<4) for Num Lock. On error, returns 0. | 137 // Returns true if auto repeat is enabled. This function is protected: for |
128 static unsigned int GetNumLockMask(); | 138 // testability. |
| 139 static bool GetAutoRepeatEnabledForTesting(); |
129 | 140 |
130 protected: | 141 // On success, set current auto repeat rate on |out_rate| and returns true. |
131 // Creates a full XKB layout name like | 142 // Returns false otherwise. This function is protected: for testability. |
132 // "gb(extd)+chromeos(leftcontrol_disabled_leftalt),us" | 143 static bool GetAutoRepeatRateForTesting(AutoRepeatRate* out_rate); |
133 // from modifier key mapping and |layout_name|, such as "us", "us(dvorak)", | |
134 // and "gb(extd)". Returns an empty string on error. This function is | |
135 // protected: for testability. | |
136 std::string CreateFullXkbLayoutName(const std::string& layout_name, | |
137 const ModifierMap& modifire_map); | |
138 | 144 |
139 // Returns true if |key| is in |modifier_map| as replacement. This function is | 145 // Returns true if |key| is in |modifier_map| as replacement. Do not call this |
140 // protected: for testability. | 146 // function directly: it is public for testability. |
141 static bool ContainsModifierKeyAsReplacement(const ModifierMap& modifier_map, | 147 static bool ContainsModifierKeyAsReplacement(const ModifierMap& modifier_map, |
142 ModifierKey key); | 148 ModifierKey key); |
143 | 149 |
144 // THIS FUNCTION IS ONLY FOR UNIT TESTS. | 150 // Note: At this moment, classes other than InputMethodManager should not |
145 // Returns true if auto repeat is enabled. This function is protected: for | 151 // instantiate the XKeyboard class. |
146 // testability. | 152 static XKeyboard* Create(const InputMethodUtil& util); |
147 static bool GetAutoRepeatEnabled(); | |
148 | |
149 // THIS FUNCTION IS ONLY FOR UNIT TESTS. | |
150 // On success, set current auto repeat rate on |out_rate| and returns true. | |
151 // Returns false otherwise. This function is protected: for testability. | |
152 static bool GetAutoRepeatRate(AutoRepeatRate* out_rate); | |
153 | |
154 private: | |
155 // This function is used by SetLayout() and RemapModifierKeys(). Calls | |
156 // setxkbmap command if needed, and updates the last_full_layout_name_ cache. | |
157 bool SetLayoutInternal(const std::string& layout_name, | |
158 const ModifierMap& modifier_map, | |
159 bool force); | |
160 | |
161 // Executes 'setxkbmap -layout ...' command asynchronously using a layout name | |
162 // in the |execute_queue_|. Do nothing if the queue is empty. | |
163 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) | |
164 void MaybeExecuteSetLayoutCommand(); | |
165 | |
166 // Returns true if the XKB layout uses the right Alt key for special purposes | |
167 // like AltGr. | |
168 bool KeepRightAlt(const std::string& xkb_layout_name) const; | |
169 | |
170 // Returns true if the XKB layout uses the CapsLock key for special purposes. | |
171 // For example, since US Colemak layout uses the key as back space, | |
172 // KeepCapsLock("us(colemak)") would return true. | |
173 bool KeepCapsLock(const std::string& xkb_layout_name) const; | |
174 | |
175 // Converts |key| to a modifier key name which is used in | |
176 // /usr/share/X11/xkb/symbols/chromeos. | |
177 static std::string ModifierKeyToString(ModifierKey key); | |
178 | |
179 // Called when execve'd setxkbmap process exits. | |
180 static void OnSetLayoutFinish(pid_t pid, int status, XKeyboard* self); | |
181 | |
182 const bool is_running_on_chrome_os_; | |
183 unsigned int num_lock_mask_; | |
184 | |
185 // The current Num Lock and Caps Lock status. If true, enabled. | |
186 bool current_num_lock_status_; | |
187 bool current_caps_lock_status_; | |
188 // The XKB layout name which we set last time like "us" and "us(dvorak)". | |
189 std::string current_layout_name_; | |
190 // The mapping of modifier keys we set last time. | |
191 ModifierMap current_modifier_map_; | |
192 | |
193 // A queue for executing setxkbmap one by one. | |
194 std::queue<std::string> execute_queue_; | |
195 | |
196 std::set<std::string> keep_right_alt_xkb_layout_names_; | |
197 std::set<std::string> caps_lock_remapped_xkb_layout_names_; | |
198 | |
199 DISALLOW_COPY_AND_ASSIGN(XKeyboard); | |
200 }; | 153 }; |
201 | 154 |
202 } // namespace input_method | 155 } // namespace input_method |
203 } // namespace chromeos | 156 } // namespace chromeos |
204 | 157 |
205 #endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_H_ | 158 #endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_H_ |
OLD | NEW |