diff options
author | fengyuan <fengyuan@chromium.org> | 2015-01-07 19:39:31 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-08 03:40:31 +0000 |
commit | 13f75ccd1ac6eb218a0d45be6d678ddd780db81b (patch) | |
tree | ac5f133d2e23e7c2ac1d4d84b8ffff0e201808fd /ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc | |
parent | 6f6121790f0f4f5f97fc3b125b261f4e5efd8334 (diff) | |
download | chromium_src-13f75ccd1ac6eb218a0d45be6d678ddd780db81b.zip chromium_src-13f75ccd1ac6eb218a0d45be6d678ddd780db81b.tar.gz chromium_src-13f75ccd1ac6eb218a0d45be6d678ddd780db81b.tar.bz2 |
ozone: xkb: Load keymaps on worker thread & cache them
1. Free xkb keymaps in the destructor.
2. Moves kemap load into another worker thread.
3. Adds keymap caching.
BUG=430194
Review URL: https://codereview.chromium.org/842603002
Cr-Commit-Position: refs/heads/master@{#310448}
Diffstat (limited to 'ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc')
-rw-r--r-- | ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc | 100 |
1 files changed, 78 insertions, 22 deletions
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc index ccd3866..49f29a1 100644 --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc @@ -6,7 +6,13 @@ #include <xkbcommon/xkbcommon-names.h> +#include "base/bind.h" +#include "base/location.h" #include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "base/threading/worker_pool.h" #include "ui/events/event_constants.h" #include "ui/events/keycodes/dom3/dom_code.h" #include "ui/events/keycodes/dom3/dom_key.h" @@ -18,6 +24,9 @@ namespace ui { namespace { +typedef base::Callback<void(const std::string&, const char*)> + LoadKeymapCallback; + DomKey CharacterToDomKey(base::char16 character) { switch (character) { case 0x08: @@ -616,6 +625,22 @@ const PrintableSimpleEntry kSimpleMap[] = { {0x0259, VKEY_OEM_3}, // schwa }; +void LoadKeymap(const std::string& layout_name, + scoped_ptr<xkb_rule_names> names, + scoped_refptr<base::SingleThreadTaskRunner> reply_runner, + const LoadKeymapCallback& reply_callback) { + scoped_ptr<xkb_context, XkbContextDeleter> context; + context.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES)); + xkb_context_include_path_append(context.get(), "/usr/share/X11/xkb"); + scoped_ptr<xkb_keymap, XkbKeymapDeleter> keymap; + keymap.reset(xkb_keymap_new_from_names(context.get(), names.get(), + XKB_KEYMAP_COMPILE_NO_FLAGS)); + char* keymap_str = + xkb_keymap_get_as_string(keymap.get(), XKB_KEYMAP_FORMAT_TEXT_V1); + reply_runner->PostTask(FROM_HERE, base::Bind(reply_callback, layout_name, + base::Owned(keymap_str))); +} + } // anonymous namespace XkbKeyCodeConverter::XkbKeyCodeConverter() { @@ -627,7 +652,8 @@ XkbKeyCodeConverter::~XkbKeyCodeConverter() { XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( const XkbKeyCodeConverter& converter) : num_lock_mod_mask_(0), - key_code_converter_(converter) { + key_code_converter_(converter), + weak_ptr_factory_(this) { // TODO: add XKB_CONTEXT_NO_ENVIRONMENT_NAMES xkb_context_.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES)); xkb_context_include_path_append(xkb_context_.get(), @@ -635,6 +661,9 @@ XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( } XkbKeyboardLayoutEngine::~XkbKeyboardLayoutEngine() { + for (const auto& entry : xkb_keymaps_) { + xkb_keymap_unref(entry.keymap); + } } bool XkbKeyboardLayoutEngine::CanSetCurrentLayout() const { @@ -647,8 +676,35 @@ bool XkbKeyboardLayoutEngine::CanSetCurrentLayout() const { bool XkbKeyboardLayoutEngine::SetCurrentLayoutByName( const std::string& layout_name) { - xkb_keymap* keymap = NULL; #if defined(OS_CHROMEOS) + current_layout_name_ = layout_name; + for (const auto& entry : xkb_keymaps_) { + if (entry.layout_name == layout_name) { + SetKeymap(entry.keymap); + return true; + } + } + LoadKeymapCallback reply_callback = base::Bind( + &XkbKeyboardLayoutEngine::OnKeymapLoaded, weak_ptr_factory_.GetWeakPtr()); + scoped_ptr<xkb_rule_names> names = GetXkbRuleNames(layout_name); + base::WorkerPool::PostTask( + FROM_HERE, + base::Bind(&LoadKeymap, layout_name, base::Passed(&names), + base::ThreadTaskRunnerHandle::Get(), reply_callback), + true); +#else + xkb_keymap* keymap = xkb_map_new_from_string( + xkb_context_.get(), layout_name.c_str(), XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) + return false; + SetKeymap(keymap); +#endif // defined(OS_CHROMEOS) + return true; +} + +scoped_ptr<xkb_rule_names> XkbKeyboardLayoutEngine::GetXkbRuleNames( + const std::string& layout_name) { size_t dash_index = layout_name.find('-'); size_t parentheses_index = layout_name.find('('); std::string layout_id = layout_name; @@ -664,27 +720,27 @@ bool XkbKeyboardLayoutEngine::SetCurrentLayoutByName( layout_id = layout_name.substr(0, dash_index); layout_variant = layout_name.substr(dash_index + 1); } - struct xkb_rule_names names = { - .rules = NULL, - .model = "pc101", - .layout = layout_id.c_str(), - .variant = layout_variant.c_str(), - .options = "" - }; - keymap = xkb_keymap_new_from_names(xkb_context_.get(), - &names, - XKB_KEYMAP_COMPILE_NO_FLAGS); -#else - keymap = xkb_map_new_from_string(xkb_context_.get(), - layout_name.c_str(), - XKB_KEYMAP_FORMAT_TEXT_V1, - XKB_KEYMAP_COMPILE_NO_FLAGS); -#endif // defined(OS_CHROMEOS) - if (!keymap) - return false; + return make_scoped_ptr<xkb_rule_names>( + new xkb_rule_names{.rules = NULL, + .model = "pc101", + .layout = layout_id.c_str(), + .variant = layout_variant.c_str(), + .options = ""}); +} - SetKeymap(keymap); - return true; +void XkbKeyboardLayoutEngine::OnKeymapLoaded(const std::string& layout_name, + const char* keymap_str) { + if (keymap_str) { + xkb_keymap* keymap = xkb_map_new_from_string(xkb_context_.get(), keymap_str, + XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + XkbKeymapEntry entry = {layout_name, keymap}; + xkb_keymaps_.push_back(entry); + if (layout_name == current_layout_name_) + SetKeymap(keymap); + } else { + LOG(ERROR) << "Keymap file fail to load: " << layout_name; + } } bool XkbKeyboardLayoutEngine::UsesISOLevel5Shift() const { |