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

Side by Side Diff: chromeos/ime/xkeyboard.cc

Issue 189663009: cros: Simplify chromeos::input_method::XKeyboard interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « chromeos/ime/xkeyboard.h ('k') | chromeos/ime/xkeyboard_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chromeos/ime/xkeyboard.h" 5 #include "chromeos/ime/xkeyboard.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 #include <cstring> 8 #include <cstring>
9 #include <queue> 9 #include <queue>
10 #include <set> 10 #include <set>
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 class XKeyboardImpl : public XKeyboard { 67 class XKeyboardImpl : public XKeyboard {
68 public: 68 public:
69 XKeyboardImpl(); 69 XKeyboardImpl();
70 virtual ~XKeyboardImpl() {} 70 virtual ~XKeyboardImpl() {}
71 71
72 // Overridden from XKeyboard: 72 // Overridden from XKeyboard:
73 virtual bool SetCurrentKeyboardLayoutByName( 73 virtual bool SetCurrentKeyboardLayoutByName(
74 const std::string& layout_name) OVERRIDE; 74 const std::string& layout_name) OVERRIDE;
75 virtual bool ReapplyCurrentKeyboardLayout() OVERRIDE; 75 virtual bool ReapplyCurrentKeyboardLayout() OVERRIDE;
76 virtual void ReapplyCurrentModifierLockStatus() OVERRIDE; 76 virtual void ReapplyCurrentModifierLockStatus() OVERRIDE;
77 virtual void SetLockedModifiers( 77 virtual void DisableNumLock() OVERRIDE;
78 ModifierLockStatus new_caps_lock_status,
79 ModifierLockStatus new_num_lock_status) OVERRIDE;
80 virtual void SetNumLockEnabled(bool enable_num_lock) OVERRIDE;
81 virtual void SetCapsLockEnabled(bool enable_caps_lock) OVERRIDE; 78 virtual void SetCapsLockEnabled(bool enable_caps_lock) OVERRIDE;
82 virtual bool NumLockIsEnabled() OVERRIDE;
83 virtual bool CapsLockIsEnabled() OVERRIDE; 79 virtual bool CapsLockIsEnabled() OVERRIDE;
84 virtual unsigned int GetNumLockMask() OVERRIDE;
85 virtual void GetLockedModifiers(bool* out_caps_lock_enabled,
86 bool* out_num_lock_enabled) OVERRIDE;
87 virtual bool SetAutoRepeatEnabled(bool enabled) OVERRIDE; 80 virtual bool SetAutoRepeatEnabled(bool enabled) OVERRIDE;
88 virtual bool SetAutoRepeatRate(const AutoRepeatRate& rate) OVERRIDE; 81 virtual bool SetAutoRepeatRate(const AutoRepeatRate& rate) OVERRIDE;
89 82
90 private: 83 private:
84 unsigned int GetNumLockMask();
Daniel Erat 2014/03/09 04:17:55 nit: add a comment documenting what this returns (
sadrul 2014/03/09 04:52:26 Done.
85 void SetLockedModifiers(bool caps_lock_enabled);
Daniel Erat 2014/03/09 04:17:55 nit: blank line between the previous method and th
sadrul 2014/03/09 04:52:26 Done.
86
91 // This function is used by SetLayout() and RemapModifierKeys(). Calls 87 // This function is used by SetLayout() and RemapModifierKeys(). Calls
92 // setxkbmap command if needed, and updates the last_full_layout_name_ cache. 88 // setxkbmap command if needed, and updates the last_full_layout_name_ cache.
93 bool SetLayoutInternal(const std::string& layout_name, bool force); 89 bool SetLayoutInternal(const std::string& layout_name, bool force);
94 90
95 // Executes 'setxkbmap -layout ...' command asynchronously using a layout name 91 // Executes 'setxkbmap -layout ...' command asynchronously using a layout name
96 // in the |execute_queue_|. Do nothing if the queue is empty. 92 // in the |execute_queue_|. Do nothing if the queue is empty.
97 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) 93 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105)
98 void MaybeExecuteSetLayoutCommand(); 94 void MaybeExecuteSetLayoutCommand();
99 95
100 // Polls to see setxkbmap process exits. 96 // Polls to see setxkbmap process exits.
101 void PollUntilChildFinish(const base::ProcessHandle handle); 97 void PollUntilChildFinish(const base::ProcessHandle handle);
102 98
103 // Called when execve'd setxkbmap process exits. 99 // Called when execve'd setxkbmap process exits.
104 void OnSetLayoutFinish(); 100 void OnSetLayoutFinish();
105 101
106 const bool is_running_on_chrome_os_; 102 const bool is_running_on_chrome_os_;
107 unsigned int num_lock_mask_; 103 unsigned int num_lock_mask_;
108 104
109 // The current Num Lock and Caps Lock status. If true, enabled. 105 // The current Caps Lock status. If true, enabled.
110 bool current_num_lock_status_;
111 bool current_caps_lock_status_; 106 bool current_caps_lock_status_;
107
112 // The XKB layout name which we set last time like "us" and "us(dvorak)". 108 // The XKB layout name which we set last time like "us" and "us(dvorak)".
113 std::string current_layout_name_; 109 std::string current_layout_name_;
114 110
115 // A queue for executing setxkbmap one by one. 111 // A queue for executing setxkbmap one by one.
116 std::queue<std::string> execute_queue_; 112 std::queue<std::string> execute_queue_;
117 113
118 base::ThreadChecker thread_checker_; 114 base::ThreadChecker thread_checker_;
119 115
120 base::WeakPtrFactory<XKeyboardImpl> weak_factory_; 116 base::WeakPtrFactory<XKeyboardImpl> weak_factory_;
121 117
(...skipping 10 matching lines...) Expand all
132 128
133 if (is_running_on_chrome_os_) { 129 if (is_running_on_chrome_os_) {
134 // Some code seems to assume that Mod2Mask is always assigned to 130 // Some code seems to assume that Mod2Mask is always assigned to
135 // Num Lock. 131 // Num Lock.
136 // 132 //
137 // TODO(yusukes): Check the assumption is really okay. If not, 133 // TODO(yusukes): Check the assumption is really okay. If not,
138 // modify the Aura code, and then remove the CHECK below. 134 // modify the Aura code, and then remove the CHECK below.
139 LOG_IF(ERROR, num_lock_mask_ != Mod2Mask) 135 LOG_IF(ERROR, num_lock_mask_ != Mod2Mask)
140 << "NumLock is not assigned to Mod2Mask. : " << num_lock_mask_; 136 << "NumLock is not assigned to Mod2Mask. : " << num_lock_mask_;
141 } 137 }
142 GetLockedModifiers(&current_caps_lock_status_, &current_num_lock_status_); 138
139 current_caps_lock_status_ = CapsLockIsEnabled();
140 }
141
142 unsigned int XKeyboardImpl::GetNumLockMask() {
143 DCHECK(thread_checker_.CalledOnValidThread());
144 static const unsigned int kBadMask = 0;
145
146 unsigned int real_mask = kBadMask;
147 XkbDescPtr xkb_desc =
148 XkbGetKeyboard(GetXDisplay(), XkbAllComponentsMask, XkbUseCoreKbd);
149 if (!xkb_desc)
150 return kBadMask;
151
152 if (xkb_desc->dpy && xkb_desc->names && xkb_desc->names->vmods) {
153 const std::string string_to_find(kNumLockVirtualModifierString);
154 for (size_t i = 0; i < XkbNumVirtualMods; ++i) {
155 const unsigned int virtual_mod_mask = 1U << i;
156 char* virtual_mod_str_raw_ptr =
157 XGetAtomName(xkb_desc->dpy, xkb_desc->names->vmods[i]);
158 if (!virtual_mod_str_raw_ptr)
159 continue;
160 const std::string virtual_mod_str = virtual_mod_str_raw_ptr;
161 XFree(virtual_mod_str_raw_ptr);
162
163 if (string_to_find == virtual_mod_str) {
164 if (!XkbVirtualModsToReal(xkb_desc, virtual_mod_mask, &real_mask)) {
165 DVLOG(1) << "XkbVirtualModsToReal failed";
166 real_mask = kBadMask; // reset the return value, just in case.
167 }
168 break;
169 }
170 }
171 }
172 XkbFreeKeyboard(xkb_desc, 0, True /* free all components */);
173 return real_mask;
174 }
175
176 void XKeyboardImpl::SetLockedModifiers(bool caps_lock_enabled) {
177 DCHECK(thread_checker_.CalledOnValidThread());
178
179 unsigned int affect_mask = 0;
180 unsigned int value_mask = 0;
181 if (caps_lock_enabled != current_caps_lock_status_) {
182 affect_mask |= LockMask;
183 value_mask |= (caps_lock_enabled ? LockMask : 0);
184 current_caps_lock_status_ = caps_lock_enabled;
185 }
186
187 // Always turn off num lock.
188 affect_mask |= num_lock_mask_;
189
190 XkbLockModifiers(GetXDisplay(), XkbUseCoreKbd, affect_mask, value_mask);
143 } 191 }
144 192
145 bool XKeyboardImpl::SetLayoutInternal(const std::string& layout_name, 193 bool XKeyboardImpl::SetLayoutInternal(const std::string& layout_name,
146 bool force) { 194 bool force) {
147 if (!is_running_on_chrome_os_) { 195 if (!is_running_on_chrome_os_) {
148 // We should not try to change a layout on Linux or inside ui_tests. Just 196 // We should not try to change a layout on Linux or inside ui_tests. Just
149 // return true. 197 // return true.
150 return true; 198 return true;
151 } 199 }
152 200
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 OnSetLayoutFinish(); 273 OnSetLayoutFinish();
226 return; 274 return;
227 275
228 default: 276 default:
229 NOTIMPLEMENTED(); 277 NOTIMPLEMENTED();
230 OnSetLayoutFinish(); 278 OnSetLayoutFinish();
231 return; 279 return;
232 } 280 }
233 } 281 }
234 282
235 bool XKeyboardImpl::NumLockIsEnabled() {
236 bool num_lock_enabled = false;
237 GetLockedModifiers(NULL /* Caps Lock */, &num_lock_enabled);
238 return num_lock_enabled;
239 }
240
241 bool XKeyboardImpl::CapsLockIsEnabled() { 283 bool XKeyboardImpl::CapsLockIsEnabled() {
242 bool caps_lock_enabled = false;
243 GetLockedModifiers(&caps_lock_enabled, NULL /* Num Lock */);
244 return caps_lock_enabled;
245 }
246
247 unsigned int XKeyboardImpl::GetNumLockMask() {
248 DCHECK(thread_checker_.CalledOnValidThread()); 284 DCHECK(thread_checker_.CalledOnValidThread());
249 static const unsigned int kBadMask = 0;
250
251 unsigned int real_mask = kBadMask;
252 XkbDescPtr xkb_desc =
253 XkbGetKeyboard(GetXDisplay(), XkbAllComponentsMask, XkbUseCoreKbd);
254 if (!xkb_desc)
255 return kBadMask;
256
257 if (xkb_desc->dpy && xkb_desc->names && xkb_desc->names->vmods) {
258 const std::string string_to_find(kNumLockVirtualModifierString);
259 for (size_t i = 0; i < XkbNumVirtualMods; ++i) {
260 const unsigned int virtual_mod_mask = 1U << i;
261 char* virtual_mod_str_raw_ptr =
262 XGetAtomName(xkb_desc->dpy, xkb_desc->names->vmods[i]);
263 if (!virtual_mod_str_raw_ptr)
264 continue;
265 const std::string virtual_mod_str = virtual_mod_str_raw_ptr;
266 XFree(virtual_mod_str_raw_ptr);
267
268 if (string_to_find == virtual_mod_str) {
269 if (!XkbVirtualModsToReal(xkb_desc, virtual_mod_mask, &real_mask)) {
270 DVLOG(1) << "XkbVirtualModsToReal failed";
271 real_mask = kBadMask; // reset the return value, just in case.
272 }
273 break;
274 }
275 }
276 }
277 XkbFreeKeyboard(xkb_desc, 0, True /* free all components */);
278 return real_mask;
279 }
280
281 void XKeyboardImpl::GetLockedModifiers(bool* out_caps_lock_enabled,
282 bool* out_num_lock_enabled) {
283 DCHECK(thread_checker_.CalledOnValidThread());
284
285 if (out_num_lock_enabled && !num_lock_mask_) {
286 DVLOG(1) << "Cannot get locked modifiers. Num Lock mask unknown.";
287 if (out_caps_lock_enabled)
288 *out_caps_lock_enabled = false;
289 if (out_num_lock_enabled)
290 *out_num_lock_enabled = false;
291 return;
292 }
293
294 XkbStateRec status; 285 XkbStateRec status;
295 XkbGetState(GetXDisplay(), XkbUseCoreKbd, &status); 286 XkbGetState(GetXDisplay(), XkbUseCoreKbd, &status);
296 if (out_caps_lock_enabled) 287 return (status.locked_mods & LockMask);
297 *out_caps_lock_enabled = status.locked_mods & LockMask;
298 if (out_num_lock_enabled)
299 *out_num_lock_enabled = status.locked_mods & num_lock_mask_;
300 } 288 }
301 289
302 bool XKeyboardImpl::SetAutoRepeatEnabled(bool enabled) { 290 bool XKeyboardImpl::SetAutoRepeatEnabled(bool enabled) {
303 if (enabled) 291 if (enabled)
304 XAutoRepeatOn(GetXDisplay()); 292 XAutoRepeatOn(GetXDisplay());
305 else 293 else
306 XAutoRepeatOff(GetXDisplay()); 294 XAutoRepeatOff(GetXDisplay());
307 DVLOG(1) << "Set auto-repeat mode to: " << (enabled ? "on" : "off"); 295 DVLOG(1) << "Set auto-repeat mode to: " << (enabled ? "on" : "off");
308 return true; 296 return true;
309 } 297 }
310 298
311 bool XKeyboardImpl::SetAutoRepeatRate(const AutoRepeatRate& rate) { 299 bool XKeyboardImpl::SetAutoRepeatRate(const AutoRepeatRate& rate) {
312 DVLOG(1) << "Set auto-repeat rate to: " 300 DVLOG(1) << "Set auto-repeat rate to: "
313 << rate.initial_delay_in_ms << " ms delay, " 301 << rate.initial_delay_in_ms << " ms delay, "
314 << rate.repeat_interval_in_ms << " ms interval"; 302 << rate.repeat_interval_in_ms << " ms interval";
315 if (XkbSetAutoRepeatRate(GetXDisplay(), XkbUseCoreKbd, 303 if (XkbSetAutoRepeatRate(GetXDisplay(), XkbUseCoreKbd,
316 rate.initial_delay_in_ms, 304 rate.initial_delay_in_ms,
317 rate.repeat_interval_in_ms) != True) { 305 rate.repeat_interval_in_ms) != True) {
318 DVLOG(1) << "Failed to set auto-repeat rate"; 306 DVLOG(1) << "Failed to set auto-repeat rate";
319 return false; 307 return false;
320 } 308 }
321 return true; 309 return true;
322 } 310 }
323 311
324 void XKeyboardImpl::SetLockedModifiers(ModifierLockStatus new_caps_lock_status,
325 ModifierLockStatus new_num_lock_status) {
326 DCHECK(thread_checker_.CalledOnValidThread());
327 if (!num_lock_mask_) {
328 DVLOG(1) << "Cannot set locked modifiers. Num Lock mask unknown.";
329 return;
330 }
331
332 unsigned int affect_mask = 0;
333 unsigned int value_mask = 0;
334 if (new_caps_lock_status != kDontChange) {
335 affect_mask |= LockMask;
336 value_mask |= ((new_caps_lock_status == kEnableLock) ? LockMask : 0);
337 current_caps_lock_status_ = (new_caps_lock_status == kEnableLock);
338 }
339 if (new_num_lock_status != kDontChange) {
340 affect_mask |= num_lock_mask_;
341 value_mask |= ((new_num_lock_status == kEnableLock) ? num_lock_mask_ : 0);
342 current_num_lock_status_ = (new_num_lock_status == kEnableLock);
343 }
344
345 if (affect_mask)
346 XkbLockModifiers(GetXDisplay(), XkbUseCoreKbd, affect_mask, value_mask);
347 }
348
349 void XKeyboardImpl::SetNumLockEnabled(bool enable_num_lock) {
350 SetLockedModifiers(
351 kDontChange, enable_num_lock ? kEnableLock : kDisableLock);
352 }
353
354 void XKeyboardImpl::SetCapsLockEnabled(bool enable_caps_lock) { 312 void XKeyboardImpl::SetCapsLockEnabled(bool enable_caps_lock) {
355 SetLockedModifiers( 313 SetLockedModifiers(enable_caps_lock);
356 enable_caps_lock ? kEnableLock : kDisableLock, kDontChange);
357 } 314 }
358 315
359 bool XKeyboardImpl::SetCurrentKeyboardLayoutByName( 316 bool XKeyboardImpl::SetCurrentKeyboardLayoutByName(
360 const std::string& layout_name) { 317 const std::string& layout_name) {
361 if (SetLayoutInternal(layout_name, false)) { 318 if (SetLayoutInternal(layout_name, false)) {
362 current_layout_name_ = layout_name; 319 current_layout_name_ = layout_name;
363 return true; 320 return true;
364 } 321 }
365 return false; 322 return false;
366 } 323 }
367 324
368 bool XKeyboardImpl::ReapplyCurrentKeyboardLayout() { 325 bool XKeyboardImpl::ReapplyCurrentKeyboardLayout() {
369 if (current_layout_name_.empty()) { 326 if (current_layout_name_.empty()) {
370 DVLOG(1) << "Can't reapply XKB layout: layout unknown"; 327 DVLOG(1) << "Can't reapply XKB layout: layout unknown";
371 return false; 328 return false;
372 } 329 }
373 return SetLayoutInternal(current_layout_name_, true /* force */); 330 return SetLayoutInternal(current_layout_name_, true /* force */);
374 } 331 }
375 332
376 void XKeyboardImpl::ReapplyCurrentModifierLockStatus() { 333 void XKeyboardImpl::ReapplyCurrentModifierLockStatus() {
377 SetLockedModifiers(current_caps_lock_status_ ? kEnableLock : kDisableLock, 334 SetLockedModifiers(current_caps_lock_status_);
378 current_num_lock_status_ ? kEnableLock : kDisableLock); 335 }
336
337 void XKeyboardImpl::DisableNumLock() {
338 SetCapsLockEnabled(current_caps_lock_status_);
379 } 339 }
380 340
381 void XKeyboardImpl::OnSetLayoutFinish() { 341 void XKeyboardImpl::OnSetLayoutFinish() {
382 if (execute_queue_.empty()) { 342 if (execute_queue_.empty()) {
383 DVLOG(1) << "OnSetLayoutFinish: execute_queue_ is empty. " 343 DVLOG(1) << "OnSetLayoutFinish: execute_queue_ is empty. "
384 << "base::LaunchProcess failed?"; 344 << "base::LaunchProcess failed?";
385 return; 345 return;
386 } 346 }
387 execute_queue_.pop(); 347 execute_queue_.pop();
388 MaybeExecuteSetLayoutCommand(); 348 MaybeExecuteSetLayoutCommand();
(...skipping 20 matching lines...) Expand all
409 return CheckLayoutName(layout_name); 369 return CheckLayoutName(layout_name);
410 } 370 }
411 371
412 // static 372 // static
413 XKeyboard* XKeyboard::Create() { 373 XKeyboard* XKeyboard::Create() {
414 return new XKeyboardImpl(); 374 return new XKeyboardImpl();
415 } 375 }
416 376
417 } // namespace input_method 377 } // namespace input_method
418 } // namespace chromeos 378 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/ime/xkeyboard.h ('k') | chromeos/ime/xkeyboard_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698