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

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 // Returns a mask for Num Lock (e.g. 1U << 4). Returns 0 on error.
85 unsigned int GetNumLockMask();
86
87 // Sets the caps-lock status. Note that calling this function always disables
88 // the num-lock.
89 void SetLockedModifiers(bool caps_lock_enabled);
90
91 // This function is used by SetLayout() and RemapModifierKeys(). Calls 91 // This function is used by SetLayout() and RemapModifierKeys(). Calls
92 // setxkbmap command if needed, and updates the last_full_layout_name_ cache. 92 // setxkbmap command if needed, and updates the last_full_layout_name_ cache.
93 bool SetLayoutInternal(const std::string& layout_name, bool force); 93 bool SetLayoutInternal(const std::string& layout_name, bool force);
94 94
95 // Executes 'setxkbmap -layout ...' command asynchronously using a layout name 95 // Executes 'setxkbmap -layout ...' command asynchronously using a layout name
96 // in the |execute_queue_|. Do nothing if the queue is empty. 96 // in the |execute_queue_|. Do nothing if the queue is empty.
97 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) 97 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105)
98 void MaybeExecuteSetLayoutCommand(); 98 void MaybeExecuteSetLayoutCommand();
99 99
100 // Polls to see setxkbmap process exits. 100 // Polls to see setxkbmap process exits.
101 void PollUntilChildFinish(const base::ProcessHandle handle); 101 void PollUntilChildFinish(const base::ProcessHandle handle);
102 102
103 // Called when execve'd setxkbmap process exits. 103 // Called when execve'd setxkbmap process exits.
104 void OnSetLayoutFinish(); 104 void OnSetLayoutFinish();
105 105
106 const bool is_running_on_chrome_os_; 106 const bool is_running_on_chrome_os_;
107 unsigned int num_lock_mask_; 107 unsigned int num_lock_mask_;
108 108
109 // The current Num Lock and Caps Lock status. If true, enabled. 109 // The current Caps Lock status. If true, enabled.
110 bool current_num_lock_status_;
111 bool current_caps_lock_status_; 110 bool current_caps_lock_status_;
111
112 // The XKB layout name which we set last time like "us" and "us(dvorak)". 112 // The XKB layout name which we set last time like "us" and "us(dvorak)".
113 std::string current_layout_name_; 113 std::string current_layout_name_;
114 114
115 // A queue for executing setxkbmap one by one. 115 // A queue for executing setxkbmap one by one.
116 std::queue<std::string> execute_queue_; 116 std::queue<std::string> execute_queue_;
117 117
118 base::ThreadChecker thread_checker_; 118 base::ThreadChecker thread_checker_;
119 119
120 base::WeakPtrFactory<XKeyboardImpl> weak_factory_; 120 base::WeakPtrFactory<XKeyboardImpl> weak_factory_;
121 121
(...skipping 10 matching lines...) Expand all
132 132
133 if (is_running_on_chrome_os_) { 133 if (is_running_on_chrome_os_) {
134 // Some code seems to assume that Mod2Mask is always assigned to 134 // Some code seems to assume that Mod2Mask is always assigned to
135 // Num Lock. 135 // Num Lock.
136 // 136 //
137 // TODO(yusukes): Check the assumption is really okay. If not, 137 // TODO(yusukes): Check the assumption is really okay. If not,
138 // modify the Aura code, and then remove the CHECK below. 138 // modify the Aura code, and then remove the CHECK below.
139 LOG_IF(ERROR, num_lock_mask_ != Mod2Mask) 139 LOG_IF(ERROR, num_lock_mask_ != Mod2Mask)
140 << "NumLock is not assigned to Mod2Mask. : " << num_lock_mask_; 140 << "NumLock is not assigned to Mod2Mask. : " << num_lock_mask_;
141 } 141 }
142 GetLockedModifiers(&current_caps_lock_status_, &current_num_lock_status_); 142
143 current_caps_lock_status_ = CapsLockIsEnabled();
144 }
145
146 unsigned int XKeyboardImpl::GetNumLockMask() {
147 DCHECK(thread_checker_.CalledOnValidThread());
148 static const unsigned int kBadMask = 0;
149
150 unsigned int real_mask = kBadMask;
151 XkbDescPtr xkb_desc =
152 XkbGetKeyboard(GetXDisplay(), XkbAllComponentsMask, XkbUseCoreKbd);
153 if (!xkb_desc)
154 return kBadMask;
155
156 if (xkb_desc->dpy && xkb_desc->names && xkb_desc->names->vmods) {
157 const std::string string_to_find(kNumLockVirtualModifierString);
158 for (size_t i = 0; i < XkbNumVirtualMods; ++i) {
159 const unsigned int virtual_mod_mask = 1U << i;
160 char* virtual_mod_str_raw_ptr =
161 XGetAtomName(xkb_desc->dpy, xkb_desc->names->vmods[i]);
162 if (!virtual_mod_str_raw_ptr)
163 continue;
164 const std::string virtual_mod_str = virtual_mod_str_raw_ptr;
165 XFree(virtual_mod_str_raw_ptr);
166
167 if (string_to_find == virtual_mod_str) {
168 if (!XkbVirtualModsToReal(xkb_desc, virtual_mod_mask, &real_mask)) {
169 DVLOG(1) << "XkbVirtualModsToReal failed";
170 real_mask = kBadMask; // reset the return value, just in case.
171 }
172 break;
173 }
174 }
175 }
176 XkbFreeKeyboard(xkb_desc, 0, True /* free all components */);
177 return real_mask;
178 }
179
180 void XKeyboardImpl::SetLockedModifiers(bool caps_lock_enabled) {
181 DCHECK(thread_checker_.CalledOnValidThread());
182
183 unsigned int affect_mask = 0;
184 unsigned int value_mask = 0;
185 if (caps_lock_enabled != current_caps_lock_status_) {
186 affect_mask |= LockMask;
187 value_mask |= (caps_lock_enabled ? LockMask : 0);
188 current_caps_lock_status_ = caps_lock_enabled;
189 }
190
191 // Always turn off num lock.
192 affect_mask |= num_lock_mask_;
193
194 if (affect_mask)
Yuki 2014/03/10 03:53:49 I think |num_lock_mask_| never be zero, so is not
sadrul 2014/03/10 04:00:46 Done.
195 XkbLockModifiers(GetXDisplay(), XkbUseCoreKbd, affect_mask, value_mask);
143 } 196 }
144 197
145 bool XKeyboardImpl::SetLayoutInternal(const std::string& layout_name, 198 bool XKeyboardImpl::SetLayoutInternal(const std::string& layout_name,
146 bool force) { 199 bool force) {
147 if (!is_running_on_chrome_os_) { 200 if (!is_running_on_chrome_os_) {
148 // We should not try to change a layout on Linux or inside ui_tests. Just 201 // We should not try to change a layout on Linux or inside ui_tests. Just
149 // return true. 202 // return true.
150 return true; 203 return true;
151 } 204 }
152 205
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 OnSetLayoutFinish(); 278 OnSetLayoutFinish();
226 return; 279 return;
227 280
228 default: 281 default:
229 NOTIMPLEMENTED(); 282 NOTIMPLEMENTED();
230 OnSetLayoutFinish(); 283 OnSetLayoutFinish();
231 return; 284 return;
232 } 285 }
233 } 286 }
234 287
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() { 288 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()); 289 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; 290 XkbStateRec status;
295 XkbGetState(GetXDisplay(), XkbUseCoreKbd, &status); 291 XkbGetState(GetXDisplay(), XkbUseCoreKbd, &status);
296 if (out_caps_lock_enabled) 292 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 } 293 }
301 294
302 bool XKeyboardImpl::SetAutoRepeatEnabled(bool enabled) { 295 bool XKeyboardImpl::SetAutoRepeatEnabled(bool enabled) {
303 if (enabled) 296 if (enabled)
304 XAutoRepeatOn(GetXDisplay()); 297 XAutoRepeatOn(GetXDisplay());
305 else 298 else
306 XAutoRepeatOff(GetXDisplay()); 299 XAutoRepeatOff(GetXDisplay());
307 DVLOG(1) << "Set auto-repeat mode to: " << (enabled ? "on" : "off"); 300 DVLOG(1) << "Set auto-repeat mode to: " << (enabled ? "on" : "off");
308 return true; 301 return true;
309 } 302 }
310 303
311 bool XKeyboardImpl::SetAutoRepeatRate(const AutoRepeatRate& rate) { 304 bool XKeyboardImpl::SetAutoRepeatRate(const AutoRepeatRate& rate) {
312 DVLOG(1) << "Set auto-repeat rate to: " 305 DVLOG(1) << "Set auto-repeat rate to: "
313 << rate.initial_delay_in_ms << " ms delay, " 306 << rate.initial_delay_in_ms << " ms delay, "
314 << rate.repeat_interval_in_ms << " ms interval"; 307 << rate.repeat_interval_in_ms << " ms interval";
315 if (XkbSetAutoRepeatRate(GetXDisplay(), XkbUseCoreKbd, 308 if (XkbSetAutoRepeatRate(GetXDisplay(), XkbUseCoreKbd,
316 rate.initial_delay_in_ms, 309 rate.initial_delay_in_ms,
317 rate.repeat_interval_in_ms) != True) { 310 rate.repeat_interval_in_ms) != True) {
318 DVLOG(1) << "Failed to set auto-repeat rate"; 311 DVLOG(1) << "Failed to set auto-repeat rate";
319 return false; 312 return false;
320 } 313 }
321 return true; 314 return true;
322 } 315 }
323 316
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) { 317 void XKeyboardImpl::SetCapsLockEnabled(bool enable_caps_lock) {
355 SetLockedModifiers( 318 SetLockedModifiers(enable_caps_lock);
356 enable_caps_lock ? kEnableLock : kDisableLock, kDontChange);
357 } 319 }
358 320
359 bool XKeyboardImpl::SetCurrentKeyboardLayoutByName( 321 bool XKeyboardImpl::SetCurrentKeyboardLayoutByName(
360 const std::string& layout_name) { 322 const std::string& layout_name) {
361 if (SetLayoutInternal(layout_name, false)) { 323 if (SetLayoutInternal(layout_name, false)) {
362 current_layout_name_ = layout_name; 324 current_layout_name_ = layout_name;
363 return true; 325 return true;
364 } 326 }
365 return false; 327 return false;
366 } 328 }
367 329
368 bool XKeyboardImpl::ReapplyCurrentKeyboardLayout() { 330 bool XKeyboardImpl::ReapplyCurrentKeyboardLayout() {
369 if (current_layout_name_.empty()) { 331 if (current_layout_name_.empty()) {
370 DVLOG(1) << "Can't reapply XKB layout: layout unknown"; 332 DVLOG(1) << "Can't reapply XKB layout: layout unknown";
371 return false; 333 return false;
372 } 334 }
373 return SetLayoutInternal(current_layout_name_, true /* force */); 335 return SetLayoutInternal(current_layout_name_, true /* force */);
374 } 336 }
375 337
376 void XKeyboardImpl::ReapplyCurrentModifierLockStatus() { 338 void XKeyboardImpl::ReapplyCurrentModifierLockStatus() {
377 SetLockedModifiers(current_caps_lock_status_ ? kEnableLock : kDisableLock, 339 SetLockedModifiers(current_caps_lock_status_);
378 current_num_lock_status_ ? kEnableLock : kDisableLock); 340 }
341
342 void XKeyboardImpl::DisableNumLock() {
343 SetCapsLockEnabled(current_caps_lock_status_);
379 } 344 }
380 345
381 void XKeyboardImpl::OnSetLayoutFinish() { 346 void XKeyboardImpl::OnSetLayoutFinish() {
382 if (execute_queue_.empty()) { 347 if (execute_queue_.empty()) {
383 DVLOG(1) << "OnSetLayoutFinish: execute_queue_ is empty. " 348 DVLOG(1) << "OnSetLayoutFinish: execute_queue_ is empty. "
384 << "base::LaunchProcess failed?"; 349 << "base::LaunchProcess failed?";
385 return; 350 return;
386 } 351 }
387 execute_queue_.pop(); 352 execute_queue_.pop();
388 MaybeExecuteSetLayoutCommand(); 353 MaybeExecuteSetLayoutCommand();
(...skipping 20 matching lines...) Expand all
409 return CheckLayoutName(layout_name); 374 return CheckLayoutName(layout_name);
410 } 375 }
411 376
412 // static 377 // static
413 XKeyboard* XKeyboard::Create() { 378 XKeyboard* XKeyboard::Create() {
414 return new XKeyboardImpl(); 379 return new XKeyboardImpl();
415 } 380 }
416 381
417 } // namespace input_method 382 } // namespace input_method
418 } // namespace chromeos 383 } // 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