Index: chrome/browser/chromeos/input_method/xkeyboard.cc |
diff --git a/chrome/browser/chromeos/input_method/xkeyboard.cc b/chrome/browser/chromeos/input_method/xkeyboard.cc |
index aaf89d9ee022329b70a84a32c2a521f5c0ff1216..685824f6a40755bf1d0ad1f7180179f9597a653e 100644 |
--- a/chrome/browser/chromeos/input_method/xkeyboard.cc |
+++ b/chrome/browser/chromeos/input_method/xkeyboard.cc |
@@ -96,15 +96,23 @@ const char* kCapsLockRemapped[] = { |
"xkb:us:colemak:eng", |
}; |
+// A string for obtaining a mask value for Num Lock. |
+const char kNumLockVirtualModifierString[] = "NumLock"; |
+ |
} // namespace |
XKeyboard::XKeyboard(const InputMethodUtil& util) |
: is_running_on_chrome_os_( |
system::runtime_environment::IsRunningOnChromeOS()) { |
+ num_lock_mask_ = GetNumLockMask(); |
+ current_num_lock_status_ = NumLockIsEnabled(num_lock_mask_); |
+ current_caps_lock_status_ = CapsLockIsEnabled(); |
+ |
for (size_t i = 0; i < arraysize(kCustomizableKeys); ++i) { |
ModifierKey key = kCustomizableKeys[i]; |
current_modifier_map_.push_back(ModifierKeyPair(key, key)); |
} |
+ |
std::string layout; |
for (size_t i = 0; i < arraysize(kKeepRightAltInputMethods); ++i) { |
layout = util.GetKeyboardLayoutName(kKeepRightAltInputMethods[i]); |
@@ -127,6 +135,46 @@ XKeyboard::XKeyboard(const InputMethodUtil& util) |
XKeyboard::~XKeyboard() { |
} |
+// static |
+unsigned int XKeyboard::GetNumLockMask() { |
+ static const unsigned int kBadMask = 0; |
+ |
+ unsigned int real_mask = kBadMask; |
+ XkbDescPtr xkb_desc = |
+ XkbGetKeyboard(ui::GetXDisplay(), XkbAllComponentsMask, XkbUseCoreKbd); |
+ if (!xkb_desc) { |
+ return kBadMask; |
+ } |
+ |
+ if (xkb_desc->dpy && xkb_desc->names && xkb_desc->names->vmods) { |
+ const std::string string_to_find(kNumLockVirtualModifierString); |
+ for (size_t i = 0; i < XkbNumVirtualMods; ++i) { |
+ const unsigned int virtual_mod_mask = 1U << i; |
+ const char* virtual_mod_str = |
+ XGetAtomName(xkb_desc->dpy, xkb_desc->names->vmods[i]); |
+ if (!virtual_mod_str) { |
+ continue; |
+ } |
+ if (string_to_find == virtual_mod_str) { |
+ if (!XkbVirtualModsToReal(xkb_desc, virtual_mod_mask, &real_mask)) { |
+ LOG(ERROR) << "XkbVirtualModsToReal failed"; |
+ real_mask = kBadMask; // reset the return value, just in case. |
+ } |
+ break; |
+ } |
+ } |
+ } |
+ XkbFreeKeyboard(xkb_desc, 0, True /* free all components */); |
+ |
+ // Some code in Chrome, e.g. web_input_event_aurax11.cc, assume that Mod2Mask |
+ // is always assigned to Num Lock. |
+ // TODO(yusukes): Check the assumption is really okay. If not, modify such |
+ // code, and then remove the CHECK below. |
+ CHECK(real_mask == Mod2Mask); |
+ |
+ return real_mask; |
+} |
+ |
bool XKeyboard::SetLayoutInternal(const std::string& layout_name, |
const ModifierMap& modifier_map, |
bool force) { |
@@ -327,11 +375,34 @@ bool XKeyboard::CapsLockIsEnabled() { |
return status.locked_mods & LockMask; |
} |
-// static |
void XKeyboard::SetCapsLockEnabled(bool enable_caps_lock) { |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
XkbLockModifiers(ui::GetXDisplay(), XkbUseCoreKbd, LockMask, |
enable_caps_lock ? LockMask : 0); |
+ current_caps_lock_status_ = enable_caps_lock; |
+} |
+ |
+// static |
+bool XKeyboard::NumLockIsEnabled(unsigned int num_lock_mask) { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!num_lock_mask) { |
+ LOG(ERROR) << "Cannot get Num Lock status. Mask unknown."; |
+ return true; |
+ } |
+ XkbStateRec status; |
+ XkbGetState(ui::GetXDisplay(), XkbUseCoreKbd, &status); |
+ return status.locked_mods & num_lock_mask; |
+} |
+ |
+void XKeyboard::SetNumLockEnabled(bool enable_num_lock) { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!num_lock_mask_) { |
+ LOG(ERROR) << "Cannot set Num Lock status. Mask unknown."; |
+ return; |
+ } |
+ XkbLockModifiers(ui::GetXDisplay(), XkbUseCoreKbd, num_lock_mask_, |
+ enable_num_lock ? num_lock_mask_ : 0); |
+ current_num_lock_status_ = enable_num_lock; |
} |
// static |
@@ -362,6 +433,11 @@ bool XKeyboard::ReapplyCurrentKeyboardLayout() { |
current_layout_name_, current_modifier_map_, true /* force */); |
} |
+void XKeyboard::ReapplyCurrentModifierLockStatus() { |
+ 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.
|
+ SetNumLockEnabled(current_num_lock_status_); |
+} |
+ |
bool XKeyboard::RemapModifierKeys(const ModifierMap& modifier_map) { |
const std::string layout_name = current_layout_name_.empty() ? |
kDefaultLayoutName : current_layout_name_; |