summaryrefslogtreecommitdiffstats
path: root/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
diff options
context:
space:
mode:
authorfengyuan <fengyuan@chromium.org>2015-01-07 19:39:31 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-08 03:40:31 +0000
commit13f75ccd1ac6eb218a0d45be6d678ddd780db81b (patch)
treeac5f133d2e23e7c2ac1d4d84b8ffff0e201808fd /ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
parent6f6121790f0f4f5f97fc3b125b261f4e5efd8334 (diff)
downloadchromium_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.cc100
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 {