| 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 2f1d3db9d22635ff6a0786d7a733be831fc3246e..29593da4bd76103c87a69cccc9df811305ff1b31 100644
|
| --- a/chrome/browser/chromeos/input_method/xkeyboard.cc
|
| +++ b/chrome/browser/chromeos/input_method/xkeyboard.cc
|
| @@ -4,14 +4,12 @@
|
|
|
| #include "chrome/browser/chromeos/input_method/xkeyboard.h"
|
|
|
| +#include <cstdlib>
|
| +#include <cstring>
|
| #include <queue>
|
| #include <set>
|
| -#include <string>
|
| #include <utility>
|
|
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/process_util.h"
|
| @@ -101,9 +99,80 @@ const char* kCapsLockRemapped[] = {
|
| // A string for obtaining a mask value for Num Lock.
|
| const char kNumLockVirtualModifierString[] = "NumLock";
|
|
|
| -} // namespace
|
| +class XKeyboardImpl : public XKeyboard {
|
| + public:
|
| + explicit XKeyboardImpl(const InputMethodUtil& util);
|
| + virtual ~XKeyboardImpl() {}
|
| +
|
| + // Overridden from XKeyboard:
|
| + virtual bool SetCurrentKeyboardLayoutByName(
|
| + const std::string& layout_name) OVERRIDE;
|
| + virtual bool RemapModifierKeys(const ModifierMap& modifier_map) OVERRIDE;
|
| + virtual bool ReapplyCurrentKeyboardLayout() OVERRIDE;
|
| + virtual void ReapplyCurrentModifierLockStatus() OVERRIDE;
|
| + virtual void SetLockedModifiers(
|
| + ModifierLockStatus new_caps_lock_status,
|
| + ModifierLockStatus new_num_lock_status) OVERRIDE;
|
| + virtual void SetNumLockEnabled(bool enable_num_lock) OVERRIDE;
|
| + virtual void SetCapsLockEnabled(bool enable_caps_lock) OVERRIDE;
|
| + virtual bool NumLockIsEnabled() OVERRIDE;
|
| + virtual bool CapsLockIsEnabled() OVERRIDE;
|
| + virtual unsigned int GetNumLockMask() OVERRIDE;
|
| + virtual void GetLockedModifiers(bool* out_caps_lock_enabled,
|
| + bool* out_num_lock_enabled) OVERRIDE;
|
| + virtual std::string CreateFullXkbLayoutName(
|
| + const std::string& layout_name,
|
| + const ModifierMap& modifire_map) OVERRIDE;
|
| +
|
| + private:
|
| + // This function is used by SetLayout() and RemapModifierKeys(). Calls
|
| + // setxkbmap command if needed, and updates the last_full_layout_name_ cache.
|
| + bool SetLayoutInternal(const std::string& layout_name,
|
| + const ModifierMap& modifier_map,
|
| + bool force);
|
| +
|
| + // Executes 'setxkbmap -layout ...' command asynchronously using a layout name
|
| + // in the |execute_queue_|. Do nothing if the queue is empty.
|
| + // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105)
|
| + void MaybeExecuteSetLayoutCommand();
|
| +
|
| + // Returns true if the XKB layout uses the right Alt key for special purposes
|
| + // like AltGr.
|
| + bool KeepRightAlt(const std::string& xkb_layout_name) const;
|
| +
|
| + // Returns true if the XKB layout uses the CapsLock key for special purposes.
|
| + // For example, since US Colemak layout uses the key as back space,
|
| + // KeepCapsLock("us(colemak)") would return true.
|
| + bool KeepCapsLock(const std::string& xkb_layout_name) const;
|
| +
|
| + // Converts |key| to a modifier key name which is used in
|
| + // /usr/share/X11/xkb/symbols/chromeos.
|
| + static std::string ModifierKeyToString(ModifierKey key);
|
| +
|
| + // Called when execve'd setxkbmap process exits.
|
| + static void OnSetLayoutFinish(pid_t pid, int status, XKeyboardImpl* self);
|
| +
|
| + const bool is_running_on_chrome_os_;
|
| + unsigned int num_lock_mask_;
|
| +
|
| + // The current Num Lock and Caps Lock status. If true, enabled.
|
| + bool current_num_lock_status_;
|
| + bool current_caps_lock_status_;
|
| + // The XKB layout name which we set last time like "us" and "us(dvorak)".
|
| + std::string current_layout_name_;
|
| + // The mapping of modifier keys we set last time.
|
| + ModifierMap current_modifier_map_;
|
| +
|
| + // A queue for executing setxkbmap one by one.
|
| + std::queue<std::string> execute_queue_;
|
| +
|
| + std::set<std::string> keep_right_alt_xkb_layout_names_;
|
| + std::set<std::string> caps_lock_remapped_xkb_layout_names_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(XKeyboardImpl);
|
| +};
|
|
|
| -XKeyboard::XKeyboard(const InputMethodUtil& util)
|
| +XKeyboardImpl::XKeyboardImpl(const InputMethodUtil& util)
|
| : is_running_on_chrome_os_(
|
| system::runtime_environment::IsRunningOnChromeOS()) {
|
| num_lock_mask_ = GetNumLockMask();
|
| @@ -116,8 +185,7 @@ XKeyboard::XKeyboard(const InputMethodUtil& util)
|
| CHECK(!is_running_on_chrome_os_ || (num_lock_mask_ == Mod2Mask));
|
| #endif
|
|
|
| - GetLockedModifiers(
|
| - num_lock_mask_, ¤t_caps_lock_status_, ¤t_num_lock_status_);
|
| + GetLockedModifiers(¤t_caps_lock_status_, ¤t_num_lock_status_);
|
|
|
| for (size_t i = 0; i < arraysize(kCustomizableKeys); ++i) {
|
| ModifierKey key = kCustomizableKeys[i];
|
| @@ -144,47 +212,9 @@ 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;
|
| - 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.
|
| - }
|
| - XFree(virtual_mod_str);
|
| - break;
|
| - }
|
| - XFree(virtual_mod_str);
|
| - }
|
| - }
|
| - XkbFreeKeyboard(xkb_desc, 0, True /* free all components */);
|
| - return real_mask;
|
| -}
|
| -
|
| -bool XKeyboard::SetLayoutInternal(const std::string& layout_name,
|
| - const ModifierMap& modifier_map,
|
| - bool force) {
|
| +bool XKeyboardImpl::SetLayoutInternal(const std::string& layout_name,
|
| + const ModifierMap& modifier_map,
|
| + bool force) {
|
| if (!is_running_on_chrome_os_) {
|
| // We should not try to change a layout on Linux or inside ui_tests. Just
|
| // return true.
|
| @@ -229,7 +259,7 @@ bool XKeyboard::SetLayoutInternal(const std::string& layout_name,
|
| // Executes 'setxkbmap -layout ...' command asynchronously using a layout name
|
| // in the |execute_queue_|. Do nothing if the queue is empty.
|
| // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105)
|
| -void XKeyboard::MaybeExecuteSetLayoutCommand() {
|
| +void XKeyboardImpl::MaybeExecuteSetLayoutCommand() {
|
| if (execute_queue_.empty()) {
|
| return;
|
| }
|
| @@ -258,21 +288,84 @@ void XKeyboard::MaybeExecuteSetLayoutCommand() {
|
| VLOG(1) << "ExecuteSetLayoutCommand: " << layout_to_set << ": pid=" << pid;
|
| }
|
|
|
| -// static
|
| -void XKeyboard::OnSetLayoutFinish(pid_t pid, int status, XKeyboard* self) {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - VLOG(1) << "OnSetLayoutFinish: pid=" << pid;
|
| - if (self->execute_queue_.empty()) {
|
| - LOG(ERROR) << "OnSetLayoutFinish: execute_queue_ is empty. "
|
| - << "base::LaunchProcess failed? pid=" << pid;
|
| +bool XKeyboardImpl::NumLockIsEnabled() {
|
| + bool num_lock_enabled = false;
|
| + GetLockedModifiers(NULL /* Caps Lock */, &num_lock_enabled);
|
| + return num_lock_enabled;
|
| +}
|
| +
|
| +bool XKeyboardImpl::CapsLockIsEnabled() {
|
| + bool caps_lock_enabled = false;
|
| + GetLockedModifiers(&caps_lock_enabled, NULL /* Num Lock */);
|
| + return caps_lock_enabled;
|
| +}
|
| +
|
| +unsigned int XKeyboardImpl::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;
|
| + 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.
|
| + }
|
| + XFree(virtual_mod_str);
|
| + break;
|
| + }
|
| + XFree(virtual_mod_str);
|
| + }
|
| + }
|
| + XkbFreeKeyboard(xkb_desc, 0, True /* free all components */);
|
| + return real_mask;
|
| +}
|
| +
|
| +void XKeyboardImpl::GetLockedModifiers(bool* out_caps_lock_enabled,
|
| + bool* out_num_lock_enabled) {
|
| + // For now, don't call CHECK() here to make
|
| + // TabRestoreServiceTest.DontRestorePrintPreviewTab test happy.
|
| + // TODO(yusukes): Fix the test, then fix the if(!BrowserThread...) line below.
|
| + // CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::UI) ||
|
| + (out_num_lock_enabled && !num_lock_mask_)) {
|
| + LOG(ERROR) << "Cannot get locked modifiers.";
|
| + if (out_caps_lock_enabled) {
|
| + *out_caps_lock_enabled = false;
|
| + }
|
| + if (out_num_lock_enabled) {
|
| + *out_num_lock_enabled = false;
|
| + }
|
| return;
|
| }
|
| - self->execute_queue_.pop();
|
| - self->MaybeExecuteSetLayoutCommand();
|
| +
|
| + XkbStateRec status;
|
| + XkbGetState(ui::GetXDisplay(), XkbUseCoreKbd, &status);
|
| + if (out_caps_lock_enabled) {
|
| + *out_caps_lock_enabled = status.locked_mods & LockMask;
|
| + }
|
| + if (out_num_lock_enabled) {
|
| + *out_num_lock_enabled = status.locked_mods & num_lock_mask_;
|
| + }
|
| }
|
|
|
| -std::string XKeyboard::CreateFullXkbLayoutName(
|
| - const std::string& layout_name, const ModifierMap& modifier_map) {
|
| +std::string XKeyboardImpl::CreateFullXkbLayoutName(
|
| + const std::string& layout_name,
|
| + const ModifierMap& modifier_map) {
|
| static const char kValidLayoutNameCharacters[] =
|
| "abcdefghijklmnopqrstuvwxyz0123456789()-_";
|
|
|
| @@ -346,49 +439,8 @@ std::string XKeyboard::CreateFullXkbLayoutName(
|
| return full_xkb_layout_name;
|
| }
|
|
|
| -// static
|
| -bool XKeyboard::SetAutoRepeatEnabled(bool enabled) {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - if (enabled) {
|
| - XAutoRepeatOn(ui::GetXDisplay());
|
| - } else {
|
| - XAutoRepeatOff(ui::GetXDisplay());
|
| - }
|
| - DLOG(INFO) << "Set auto-repeat mode to: " << (enabled ? "on" : "off");
|
| - return true;
|
| -}
|
| -
|
| -// static
|
| -bool XKeyboard::SetAutoRepeatRate(const AutoRepeatRate& rate) {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DLOG(INFO) << "Set auto-repeat rate to: "
|
| - << rate.initial_delay_in_ms << " ms delay, "
|
| - << rate.repeat_interval_in_ms << " ms interval";
|
| - if (XkbSetAutoRepeatRate(ui::GetXDisplay(), XkbUseCoreKbd,
|
| - rate.initial_delay_in_ms,
|
| - rate.repeat_interval_in_ms) != True) {
|
| - LOG(ERROR) << "Failed to set auto-repeat rate";
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -// static
|
| -bool XKeyboard::GetAutoRepeatEnabled() {
|
| - XKeyboardState state = {};
|
| - XGetKeyboardControl(ui::GetXDisplay(), &state);
|
| - return state.global_auto_repeat != AutoRepeatModeOff;
|
| -}
|
| -
|
| -// static
|
| -bool XKeyboard::GetAutoRepeatRate(AutoRepeatRate* out_rate) {
|
| - return XkbGetAutoRepeatRate(ui::GetXDisplay(), XkbUseCoreKbd,
|
| - &(out_rate->initial_delay_in_ms),
|
| - &(out_rate->repeat_interval_in_ms)) == True;
|
| -}
|
| -
|
| -void XKeyboard::SetLockedModifiers(ModifierLockStatus new_caps_lock_status,
|
| - ModifierLockStatus new_num_lock_status) {
|
| +void XKeyboardImpl::SetLockedModifiers(ModifierLockStatus new_caps_lock_status,
|
| + ModifierLockStatus new_num_lock_status) {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| if (!num_lock_mask_) {
|
| LOG(ERROR) << "Cannot set locked modifiers. Num Lock mask unknown.";
|
| @@ -413,73 +465,18 @@ void XKeyboard::SetLockedModifiers(ModifierLockStatus new_caps_lock_status,
|
| }
|
| }
|
|
|
| -void XKeyboard::SetNumLockEnabled(bool enable_num_lock) {
|
| +void XKeyboardImpl::SetNumLockEnabled(bool enable_num_lock) {
|
| SetLockedModifiers(
|
| kDontChange, enable_num_lock ? kEnableLock : kDisableLock);
|
| }
|
|
|
| -void XKeyboard::SetCapsLockEnabled(bool enable_caps_lock) {
|
| +void XKeyboardImpl::SetCapsLockEnabled(bool enable_caps_lock) {
|
| SetLockedModifiers(
|
| enable_caps_lock ? kEnableLock : kDisableLock, kDontChange);
|
| }
|
|
|
| -// static
|
| -void XKeyboard::GetLockedModifiers(unsigned int num_lock_mask,
|
| - bool* out_caps_lock_enabled,
|
| - bool* out_num_lock_enabled) {
|
| - // For now, don't call CHECK() here to make
|
| - // TabRestoreServiceTest.DontRestorePrintPreviewTab test happy.
|
| - // TODO(yusukes): Fix the test, then fix the if(!BrowserThread...) line below.
|
| - // CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (!BrowserThread::CurrentlyOn(BrowserThread::UI) ||
|
| - (out_num_lock_enabled && !num_lock_mask)) {
|
| - LOG(ERROR) << "Cannot get locked modifiers.";
|
| - if (out_caps_lock_enabled) {
|
| - *out_caps_lock_enabled = false;
|
| - }
|
| - if (out_num_lock_enabled) {
|
| - *out_num_lock_enabled = false;
|
| - }
|
| - return;
|
| - }
|
| -
|
| - XkbStateRec status;
|
| - XkbGetState(ui::GetXDisplay(), XkbUseCoreKbd, &status);
|
| - if (out_caps_lock_enabled) {
|
| - *out_caps_lock_enabled = status.locked_mods & LockMask;
|
| - }
|
| - if (out_num_lock_enabled) {
|
| - *out_num_lock_enabled = status.locked_mods & num_lock_mask;
|
| - }
|
| -}
|
| -
|
| -// static
|
| -bool XKeyboard::NumLockIsEnabled(unsigned int num_lock_mask) {
|
| - bool num_lock_enabled = false;
|
| - GetLockedModifiers(num_lock_mask, NULL /* Caps Lock */, &num_lock_enabled);
|
| - return num_lock_enabled;
|
| -}
|
| -
|
| -// static
|
| -bool XKeyboard::CapsLockIsEnabled() {
|
| - bool caps_lock_enabled = false;
|
| - GetLockedModifiers(0, &caps_lock_enabled, NULL /* Num Lock */);
|
| - return caps_lock_enabled;
|
| -}
|
| -
|
| -// static
|
| -bool XKeyboard::ContainsModifierKeyAsReplacement(
|
| - const ModifierMap& modifier_map, ModifierKey key) {
|
| - for (size_t i = 0; i < modifier_map.size(); ++i) {
|
| - if (modifier_map[i].replacement == key) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool XKeyboard::SetCurrentKeyboardLayoutByName(const std::string& layout_name) {
|
| +bool XKeyboardImpl::SetCurrentKeyboardLayoutByName(
|
| + const std::string& layout_name) {
|
| if (SetLayoutInternal(layout_name, current_modifier_map_, false)) {
|
| current_layout_name_ = layout_name;
|
| return true;
|
| @@ -487,7 +484,7 @@ bool XKeyboard::SetCurrentKeyboardLayoutByName(const std::string& layout_name) {
|
| return false;
|
| }
|
|
|
| -bool XKeyboard::ReapplyCurrentKeyboardLayout() {
|
| +bool XKeyboardImpl::ReapplyCurrentKeyboardLayout() {
|
| if (current_layout_name_.empty()) {
|
| LOG(ERROR) << "Can't reapply XKB layout: layout unknown";
|
| return false;
|
| @@ -496,12 +493,12 @@ bool XKeyboard::ReapplyCurrentKeyboardLayout() {
|
| current_layout_name_, current_modifier_map_, true /* force */);
|
| }
|
|
|
| -void XKeyboard::ReapplyCurrentModifierLockStatus() {
|
| +void XKeyboardImpl::ReapplyCurrentModifierLockStatus() {
|
| SetLockedModifiers(current_caps_lock_status_ ? kEnableLock : kDisableLock,
|
| current_num_lock_status_ ? kEnableLock : kDisableLock);
|
| }
|
|
|
| -bool XKeyboard::RemapModifierKeys(const ModifierMap& modifier_map) {
|
| +bool XKeyboardImpl::RemapModifierKeys(const ModifierMap& modifier_map) {
|
| const std::string layout_name = current_layout_name_.empty() ?
|
| kDefaultLayoutName : current_layout_name_;
|
| if (SetLayoutInternal(layout_name, modifier_map, false)) {
|
| @@ -512,16 +509,16 @@ bool XKeyboard::RemapModifierKeys(const ModifierMap& modifier_map) {
|
| return false;
|
| }
|
|
|
| -bool XKeyboard::KeepRightAlt(const std::string& xkb_layout_name) const {
|
| +bool XKeyboardImpl::KeepRightAlt(const std::string& xkb_layout_name) const {
|
| return keep_right_alt_xkb_layout_names_.count(xkb_layout_name) > 0;
|
| }
|
|
|
| -bool XKeyboard::KeepCapsLock(const std::string& xkb_layout_name) const {
|
| +bool XKeyboardImpl::KeepCapsLock(const std::string& xkb_layout_name) const {
|
| return caps_lock_remapped_xkb_layout_names_.count(xkb_layout_name) > 0;
|
| }
|
|
|
| // static
|
| -std::string XKeyboard::ModifierKeyToString(ModifierKey key) {
|
| +std::string XKeyboardImpl::ModifierKeyToString(ModifierKey key) {
|
| switch (key) {
|
| case kSearchKey:
|
| return "search";
|
| @@ -539,5 +536,80 @@ std::string XKeyboard::ModifierKeyToString(ModifierKey key) {
|
| return "";
|
| }
|
|
|
| +// static
|
| +void XKeyboardImpl::OnSetLayoutFinish(pid_t pid,
|
| + int status,
|
| + XKeyboardImpl* self) {
|
| + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + VLOG(1) << "OnSetLayoutFinish: pid=" << pid;
|
| + if (self->execute_queue_.empty()) {
|
| + LOG(ERROR) << "OnSetLayoutFinish: execute_queue_ is empty. "
|
| + << "base::LaunchProcess failed? pid=" << pid;
|
| + return;
|
| + }
|
| + self->execute_queue_.pop();
|
| + self->MaybeExecuteSetLayoutCommand();
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +bool XKeyboard::SetAutoRepeatEnabled(bool enabled) {
|
| + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + if (enabled) {
|
| + XAutoRepeatOn(ui::GetXDisplay());
|
| + } else {
|
| + XAutoRepeatOff(ui::GetXDisplay());
|
| + }
|
| + DLOG(INFO) << "Set auto-repeat mode to: " << (enabled ? "on" : "off");
|
| + return true;
|
| +}
|
| +
|
| +// static
|
| +bool XKeyboard::SetAutoRepeatRate(const AutoRepeatRate& rate) {
|
| + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DLOG(INFO) << "Set auto-repeat rate to: "
|
| + << rate.initial_delay_in_ms << " ms delay, "
|
| + << rate.repeat_interval_in_ms << " ms interval";
|
| + if (XkbSetAutoRepeatRate(ui::GetXDisplay(), XkbUseCoreKbd,
|
| + rate.initial_delay_in_ms,
|
| + rate.repeat_interval_in_ms) != True) {
|
| + LOG(ERROR) << "Failed to set auto-repeat rate";
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// static
|
| +bool XKeyboard::GetAutoRepeatEnabledForTesting() {
|
| + XKeyboardState state = {};
|
| + XGetKeyboardControl(ui::GetXDisplay(), &state);
|
| + return state.global_auto_repeat != AutoRepeatModeOff;
|
| +}
|
| +
|
| +// static
|
| +bool XKeyboard::GetAutoRepeatRateForTesting(AutoRepeatRate* out_rate) {
|
| + return XkbGetAutoRepeatRate(ui::GetXDisplay(), XkbUseCoreKbd,
|
| + &(out_rate->initial_delay_in_ms),
|
| + &(out_rate->repeat_interval_in_ms)) == True;
|
| +}
|
| +
|
| +// static
|
| +bool XKeyboard::ContainsModifierKeyAsReplacement(
|
| + const ModifierMap& modifier_map,
|
| + ModifierKey key) {
|
| + for (size_t i = 0; i < modifier_map.size(); ++i) {
|
| + if (modifier_map[i].replacement == key) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +// static
|
| +XKeyboard* XKeyboard::Create(const InputMethodUtil& util) {
|
| + return new XKeyboardImpl(util);
|
| +}
|
| +
|
| } // namespace input_method
|
| } // namespace chromeos
|
|
|