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

Side by Side Diff: chrome/browser/chromeos/input_method/xkeyboard.cc

Issue 8356040: Reapply Caps Lock and Num Lock to core keyboard whenever new X input device is added (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix unit_tests Created 9 years, 1 month 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
OLDNEW
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 #include "chrome/browser/chromeos/input_method/xkeyboard.h" 5 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 "xkb:us:altgr-intl:eng", 89 "xkb:us:altgr-intl:eng",
90 "xkb:us:intl:eng", 90 "xkb:us:intl:eng",
91 }; 91 };
92 92
93 // These are the overlay names with caps lock remapped 93 // These are the overlay names with caps lock remapped
94 const char* kCapsLockRemapped[] = { 94 const char* kCapsLockRemapped[] = {
95 "xkb:de:neo:ger", 95 "xkb:de:neo:ger",
96 "xkb:us:colemak:eng", 96 "xkb:us:colemak:eng",
97 }; 97 };
98 98
99 // A string for obtaining a mask value for Num Lock.
100 const char kNumLockVirtualModifierString[] = "NumLock";
101
99 } // namespace 102 } // namespace
100 103
101 XKeyboard::XKeyboard(const InputMethodUtil& util) 104 XKeyboard::XKeyboard(const InputMethodUtil& util)
102 : is_running_on_chrome_os_( 105 : is_running_on_chrome_os_(
103 system::runtime_environment::IsRunningOnChromeOS()) { 106 system::runtime_environment::IsRunningOnChromeOS()) {
107 num_lock_mask_ = GetNumLockMask();
108 current_num_lock_status_ = NumLockIsEnabled(num_lock_mask_);
109 current_caps_lock_status_ = CapsLockIsEnabled();
110
104 for (size_t i = 0; i < arraysize(kCustomizableKeys); ++i) { 111 for (size_t i = 0; i < arraysize(kCustomizableKeys); ++i) {
105 ModifierKey key = kCustomizableKeys[i]; 112 ModifierKey key = kCustomizableKeys[i];
106 current_modifier_map_.push_back(ModifierKeyPair(key, key)); 113 current_modifier_map_.push_back(ModifierKeyPair(key, key));
107 } 114 }
115
108 std::string layout; 116 std::string layout;
109 for (size_t i = 0; i < arraysize(kKeepRightAltInputMethods); ++i) { 117 for (size_t i = 0; i < arraysize(kKeepRightAltInputMethods); ++i) {
110 layout = util.GetKeyboardLayoutName(kKeepRightAltInputMethods[i]); 118 layout = util.GetKeyboardLayoutName(kKeepRightAltInputMethods[i]);
111 // The empty check is necessary since TOUCH_UI build does not support some 119 // The empty check is necessary since TOUCH_UI build does not support some
112 // of the kKeepRightAltInputMethods elements. For example, when TOUCH_UI is 120 // of the kKeepRightAltInputMethods elements. For example, when TOUCH_UI is
113 // defined, util.GetKeyboardLayoutName("xkb:us:intl:eng") would return "". 121 // defined, util.GetKeyboardLayoutName("xkb:us:intl:eng") would return "".
114 if (!layout.empty()) { 122 if (!layout.empty()) {
115 keep_right_alt_xkb_layout_names_.insert(layout); 123 keep_right_alt_xkb_layout_names_.insert(layout);
116 } 124 }
117 } 125 }
118 for (size_t i = 0; i < arraysize(kCapsLockRemapped); ++i) { 126 for (size_t i = 0; i < arraysize(kCapsLockRemapped); ++i) {
119 layout = util.GetKeyboardLayoutName(kCapsLockRemapped[i]); 127 layout = util.GetKeyboardLayoutName(kCapsLockRemapped[i]);
120 // The empty check is for TOUCH_UI build. See above. 128 // The empty check is for TOUCH_UI build. See above.
121 if (!layout.empty()) { 129 if (!layout.empty()) {
122 caps_lock_remapped_xkb_layout_names_.insert(layout); 130 caps_lock_remapped_xkb_layout_names_.insert(layout);
123 } 131 }
124 } 132 }
125 } 133 }
126 134
127 XKeyboard::~XKeyboard() { 135 XKeyboard::~XKeyboard() {
128 } 136 }
129 137
138 // static
139 unsigned int XKeyboard::GetNumLockMask() {
140 static const unsigned int kBadMask = 0;
141
142 unsigned int real_mask = kBadMask;
143 XkbDescPtr xkb_desc =
144 XkbGetKeyboard(ui::GetXDisplay(), XkbAllComponentsMask, XkbUseCoreKbd);
145 if (!xkb_desc) {
146 return kBadMask;
147 }
148
149 if (xkb_desc->dpy && xkb_desc->names && xkb_desc->names->vmods) {
150 const std::string string_to_find(kNumLockVirtualModifierString);
151 for (size_t i = 0; i < XkbNumVirtualMods; ++i) {
152 const unsigned int virtual_mod_mask = 1U << i;
153 const char* virtual_mod_str =
154 XGetAtomName(xkb_desc->dpy, xkb_desc->names->vmods[i]);
155 if (!virtual_mod_str) {
156 continue;
157 }
158 if (string_to_find == virtual_mod_str) {
159 if (!XkbVirtualModsToReal(xkb_desc, virtual_mod_mask, &real_mask)) {
160 LOG(ERROR) << "XkbVirtualModsToReal failed";
161 real_mask = kBadMask; // reset the return value, just in case.
162 }
163 break;
164 }
165 }
166 }
167 XkbFreeKeyboard(xkb_desc, 0, True /* free all components */);
168
169 // Some code in Chrome, e.g. web_input_event_aurax11.cc, assume that Mod2Mask
170 // is always assigned to Num Lock.
171 // TODO(yusukes): Check the assumption is really okay. If not, modify such
172 // code, and then remove the CHECK below.
173 CHECK(real_mask == Mod2Mask);
174
175 return real_mask;
176 }
177
130 bool XKeyboard::SetLayoutInternal(const std::string& layout_name, 178 bool XKeyboard::SetLayoutInternal(const std::string& layout_name,
131 const ModifierMap& modifier_map, 179 const ModifierMap& modifier_map,
132 bool force) { 180 bool force) {
133 if (!is_running_on_chrome_os_) { 181 if (!is_running_on_chrome_os_) {
134 // We should not try to change a layout on Linux or inside ui_tests. Just 182 // We should not try to change a layout on Linux or inside ui_tests. Just
135 // return true. 183 // return true.
136 return true; 184 return true;
137 } 185 }
138 186
139 const std::string layout_to_set = CreateFullXkbLayoutName( 187 const std::string layout_to_set = CreateFullXkbLayoutName(
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 368 }
321 369
322 // static 370 // static
323 bool XKeyboard::CapsLockIsEnabled() { 371 bool XKeyboard::CapsLockIsEnabled() {
324 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 372 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
325 XkbStateRec status; 373 XkbStateRec status;
326 XkbGetState(ui::GetXDisplay(), XkbUseCoreKbd, &status); 374 XkbGetState(ui::GetXDisplay(), XkbUseCoreKbd, &status);
327 return status.locked_mods & LockMask; 375 return status.locked_mods & LockMask;
328 } 376 }
329 377
330 // static
331 void XKeyboard::SetCapsLockEnabled(bool enable_caps_lock) { 378 void XKeyboard::SetCapsLockEnabled(bool enable_caps_lock) {
332 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 379 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
333 XkbLockModifiers(ui::GetXDisplay(), XkbUseCoreKbd, LockMask, 380 XkbLockModifiers(ui::GetXDisplay(), XkbUseCoreKbd, LockMask,
334 enable_caps_lock ? LockMask : 0); 381 enable_caps_lock ? LockMask : 0);
382 current_caps_lock_status_ = enable_caps_lock;
335 } 383 }
336 384
337 // static 385 // static
386 bool XKeyboard::NumLockIsEnabled(unsigned int num_lock_mask) {
387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
388 if (!num_lock_mask) {
389 LOG(ERROR) << "Cannot get Num Lock status. Mask unknown.";
390 return true;
391 }
392 XkbStateRec status;
393 XkbGetState(ui::GetXDisplay(), XkbUseCoreKbd, &status);
394 return status.locked_mods & num_lock_mask;
395 }
396
397 void XKeyboard::SetNumLockEnabled(bool enable_num_lock) {
398 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
399 if (!num_lock_mask_) {
400 LOG(ERROR) << "Cannot set Num Lock status. Mask unknown.";
401 return;
402 }
403 XkbLockModifiers(ui::GetXDisplay(), XkbUseCoreKbd, num_lock_mask_,
404 enable_num_lock ? num_lock_mask_ : 0);
405 current_num_lock_status_ = enable_num_lock;
406 }
407
408 // static
338 bool XKeyboard::ContainsModifierKeyAsReplacement( 409 bool XKeyboard::ContainsModifierKeyAsReplacement(
339 const ModifierMap& modifier_map, ModifierKey key) { 410 const ModifierMap& modifier_map, ModifierKey key) {
340 for (size_t i = 0; i < modifier_map.size(); ++i) { 411 for (size_t i = 0; i < modifier_map.size(); ++i) {
341 if (modifier_map[i].replacement == key) { 412 if (modifier_map[i].replacement == key) {
342 return true; 413 return true;
343 } 414 }
344 } 415 }
345 return false; 416 return false;
346 } 417 }
347 418
348 bool XKeyboard::SetCurrentKeyboardLayoutByName(const std::string& layout_name) { 419 bool XKeyboard::SetCurrentKeyboardLayoutByName(const std::string& layout_name) {
349 if (SetLayoutInternal(layout_name, current_modifier_map_, false)) { 420 if (SetLayoutInternal(layout_name, current_modifier_map_, false)) {
350 current_layout_name_ = layout_name; 421 current_layout_name_ = layout_name;
351 return true; 422 return true;
352 } 423 }
353 return false; 424 return false;
354 } 425 }
355 426
356 bool XKeyboard::ReapplyCurrentKeyboardLayout() { 427 bool XKeyboard::ReapplyCurrentKeyboardLayout() {
357 if (current_layout_name_.empty()) { 428 if (current_layout_name_.empty()) {
358 LOG(ERROR) << "Can't reapply XKB layout: layout unknown"; 429 LOG(ERROR) << "Can't reapply XKB layout: layout unknown";
359 return false; 430 return false;
360 } 431 }
361 return SetLayoutInternal( 432 return SetLayoutInternal(
362 current_layout_name_, current_modifier_map_, true /* force */); 433 current_layout_name_, current_modifier_map_, true /* force */);
363 } 434 }
364 435
436 void XKeyboard::ReapplyCurrentModifierLockStatus() {
437 SetCapsLockEnabled(current_caps_lock_status_);
Daniel Kurtz 2011/11/04 11:49:18 Save yourself a round trip to the server by applyi
Yusuke Sato 2011/11/07 04:31:28 Done.
438 SetNumLockEnabled(current_num_lock_status_);
439 }
440
365 bool XKeyboard::RemapModifierKeys(const ModifierMap& modifier_map) { 441 bool XKeyboard::RemapModifierKeys(const ModifierMap& modifier_map) {
366 const std::string layout_name = current_layout_name_.empty() ? 442 const std::string layout_name = current_layout_name_.empty() ?
367 kDefaultLayoutName : current_layout_name_; 443 kDefaultLayoutName : current_layout_name_;
368 if (SetLayoutInternal(layout_name, modifier_map, false)) { 444 if (SetLayoutInternal(layout_name, modifier_map, false)) {
369 current_layout_name_ = layout_name; 445 current_layout_name_ = layout_name;
370 current_modifier_map_ = modifier_map; 446 current_modifier_map_ = modifier_map;
371 return true; 447 return true;
372 } 448 }
373 return false; 449 return false;
374 } 450 }
(...skipping 20 matching lines...) Expand all
395 case kCapsLockKey: 471 case kCapsLockKey:
396 return "capslock"; 472 return "capslock";
397 case kNumModifierKeys: 473 case kNumModifierKeys:
398 break; 474 break;
399 } 475 }
400 return ""; 476 return "";
401 } 477 }
402 478
403 } // namespace input_method 479 } // namespace input_method
404 } // namespace chromeos 480 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698