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

Unified Diff: ui/events/keycodes/keyboard_lookup_win.cc

Issue 1585193002: Build key map DomCodeToKey() for Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleaned API, added unittest Created 4 years, 11 months 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 side-by-side diff with in-line comments
Download patch
Index: ui/events/keycodes/keyboard_lookup_win.cc
diff --git a/ui/events/keycodes/keyboard_lookup_win.cc b/ui/events/keycodes/keyboard_lookup_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f67498e45673d30e08f25b7c98f766a7811b3d45
--- /dev/null
+++ b/ui/events/keycodes/keyboard_lookup_win.cc
@@ -0,0 +1,166 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/keycodes/keyboard_lookup_win.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+
+namespace ui {
+
+const EventFlags WindowsKeyboardLookup::event_flags_index[] = {
dtapuska 2016/01/21 01:59:36 Move to annonymous scope; and add a static_assert
chongz 2016/01/21 15:47:40 Acknowledged.
+ EF_CAPS_LOCK_DOWN,
+ EF_SHIFT_DOWN,
+ EF_CONTROL_DOWN,
+ EF_ALT_DOWN,
+ EF_COMMAND_DOWN,
+ EF_ALTGR_DOWN,
+ EF_NUM_LOCK_DOWN,
+ EF_SCROLL_LOCK_DOWN
+};
+
+WindowsKeyboardLookup* WindowsKeyboardLookup::Create(HKL alayout) {
+ WindowsKeyboardLookup *tmp = new WindowsKeyboardLookup();
+ tmp->CheckOrLoadLayout(alayout);
+ return tmp;
+}
+
+DomKey WindowsKeyboardLookup::VirtualKeyToCurrentLayoutDomKey(
+ KeyboardCode vkcode,
+ int event_flags) {
+ GetInstance()->CheckOrLoadLayout(::GetKeyboardLayout(0));
+ return GetInstance()->VirtualKeyToDomKey(vkcode, event_flags);
+}
+
+DomKey WindowsKeyboardLookup::VirtualKeyToDomKey(KeyboardCode vkcode,
+ int event_flags) const {
+ if (vkcode >= kMaxVirtualKeyCode)
+ return DomKey::NONE;
+ size_t eindex = GetEventFlagsIndex(event_flags);
+ return lookup_table_[vkcode][eindex];
+}
+
+void WindowsKeyboardLookup::CheckOrLoadLayout(HKL alayout) {
+ if (alayout == keyboard_layout_)
+ return;
+ keyboard_layout_ = alayout;
+
+ BYTE keyboard_state[256];
+ BYTE original_keyboard_state[256];
+
+ memset(keyboard_state, 0, sizeof(keyboard_state));
+ ::GetKeyboardState(original_keyboard_state);
+
+ for (size_t eindex = 0; eindex < kMaxKeyboardModifier; ++eindex) {
+ SetModifierState(keyboard_state, EventFlagsFromIndex(eindex));
+ for (size_t vk = 0; vk < kMaxVirtualKeyCode; ++vk) {
+ wchar_t unibuff[5];
+
+ int rv = ::ToUnicodeEx(vk, 0, keyboard_state, unibuff, arraysize(unibuff),
+ 0, keyboard_layout_);
+
+ if (rv < 0) {
+ // Dead key, repeat twice to get character representation
+ rv = ::ToUnicodeEx(vk, 0, keyboard_state, unibuff, arraysize(unibuff),
+ 0, keyboard_layout_);
+ // Must be a repeat of dead key character
+ DCHECK(rv == 2);
+ lookup_table_[vk][eindex] = DomKey::DeadKeyFromCombiningCharacter(
+ unibuff[0]);
+ } else if (rv >= 1) {
+ lookup_table_[vk][eindex] = DomKey::FromCharacter(unibuff[0]);
+ }
+ }
+ }
+ ::SetKeyboardState(original_keyboard_state);
+}
+
+void WindowsKeyboardLookup::SetModifierState(BYTE *keyboard_state,
+ int event_flags) const {
+ // Trying to match system_event_state_lookup.cc
+ if (event_flags & EF_SHIFT_DOWN) {
+ keyboard_state[VK_SHIFT] |= 0x80;
+ } else {
+ keyboard_state[VK_SHIFT] &= ~0x80;
+ keyboard_state[VK_LSHIFT] &= ~0x80;
+ keyboard_state[VK_RSHIFT] &= ~0x80;
+ }
+
+ if (event_flags & EF_CONTROL_DOWN) {
+ keyboard_state[VK_CONTROL] |= 0x80;
+ } else {
+ keyboard_state[VK_CONTROL] &= ~0x80;
+ keyboard_state[VK_LCONTROL] &= ~0x80;
+ keyboard_state[VK_RCONTROL] &= ~0x80;
+ }
+
+ if (event_flags & EF_ALT_DOWN) {
+ keyboard_state[VK_MENU] |= 0x80;
+ } else {
+ keyboard_state[VK_MENU] &= ~0x80;
+ keyboard_state[VK_LMENU] &= ~0x80;
+ keyboard_state[VK_RMENU] &= ~0x80;
+ }
+
+ if (event_flags & EF_ALTGR_DOWN) {
+ keyboard_state[VK_MENU] |= 0x80;
+ keyboard_state[VK_CONTROL] |= 0x80;
+ } else {
+ // Windows does not have a specific key code for AltGr
+ }
+
+ if (event_flags & EF_COMMAND_DOWN) {
+ keyboard_state[VK_LWIN] |= 0x80;
+ } else {
+ keyboard_state[VK_LWIN] &= ~0x80;
+ keyboard_state[VK_RWIN] &= ~0x80;
+ }
+
+ if (event_flags & EF_CAPS_LOCK_DOWN) {
+ keyboard_state[VK_CAPITAL] |= 0x01;
+ } else {
+ keyboard_state[VK_CAPITAL] &= ~0x01;
+ }
+
+ if (event_flags & EF_NUM_LOCK_DOWN) {
+ keyboard_state[VK_NUMLOCK] |= 0x01;
+ } else {
+ keyboard_state[VK_NUMLOCK] &= ~0x01;
+ }
+
+ if (event_flags & EF_SCROLL_LOCK_DOWN) {
+ keyboard_state[VK_SCROLL] |= 0x01;
+ } else {
+ keyboard_state[VK_SCROLL] &= ~0x01;
+ }
+
+ // TODO(chongz): EF_EXTENDED
+}
+
+size_t WindowsKeyboardLookup::GetEventFlagsIndex(int event_flags) const {
+ size_t index = 0;
+ for (size_t i = 0; i < arraysize(event_flags_index); ++i) {
+ if (event_flags & event_flags_index[i])
+ index |= 1 << i;
+ }
+ return index;
+}
+
+int WindowsKeyboardLookup::EventFlagsFromIndex(size_t index) const {
+ int event_flags = EF_NONE;
+ for (size_t i = 0; i < arraysize(event_flags_index); ++i) {
+ if (index & (1 << i))
+ event_flags |= event_flags_index[i];
+ }
+ return event_flags;
+}
+
+WindowsKeyboardLookup* WindowsKeyboardLookup::GetInstance() {
+ static WindowsKeyboardLookup* instance = nullptr;
dtapuska 2016/01/21 01:59:36 You can actually get rid of the GetInstance and ju
chongz 2016/01/21 15:47:40 Acknowledged.
+ if (instance == nullptr)
+ instance = WindowsKeyboardLookup::Create(::GetKeyboardLayout(0));
+ return instance;
+}
+
+} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698