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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/events/keycodes/keyboard_lookup_win.h"
6
7 #include "base/logging.h"
8 #include "base/macros.h"
9
10 namespace ui {
11
12 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.
13 EF_CAPS_LOCK_DOWN,
14 EF_SHIFT_DOWN,
15 EF_CONTROL_DOWN,
16 EF_ALT_DOWN,
17 EF_COMMAND_DOWN,
18 EF_ALTGR_DOWN,
19 EF_NUM_LOCK_DOWN,
20 EF_SCROLL_LOCK_DOWN
21 };
22
23 WindowsKeyboardLookup* WindowsKeyboardLookup::Create(HKL alayout) {
24 WindowsKeyboardLookup *tmp = new WindowsKeyboardLookup();
25 tmp->CheckOrLoadLayout(alayout);
26 return tmp;
27 }
28
29 DomKey WindowsKeyboardLookup::VirtualKeyToCurrentLayoutDomKey(
30 KeyboardCode vkcode,
31 int event_flags) {
32 GetInstance()->CheckOrLoadLayout(::GetKeyboardLayout(0));
33 return GetInstance()->VirtualKeyToDomKey(vkcode, event_flags);
34 }
35
36 DomKey WindowsKeyboardLookup::VirtualKeyToDomKey(KeyboardCode vkcode,
37 int event_flags) const {
38 if (vkcode >= kMaxVirtualKeyCode)
39 return DomKey::NONE;
40 size_t eindex = GetEventFlagsIndex(event_flags);
41 return lookup_table_[vkcode][eindex];
42 }
43
44 void WindowsKeyboardLookup::CheckOrLoadLayout(HKL alayout) {
45 if (alayout == keyboard_layout_)
46 return;
47 keyboard_layout_ = alayout;
48
49 BYTE keyboard_state[256];
50 BYTE original_keyboard_state[256];
51
52 memset(keyboard_state, 0, sizeof(keyboard_state));
53 ::GetKeyboardState(original_keyboard_state);
54
55 for (size_t eindex = 0; eindex < kMaxKeyboardModifier; ++eindex) {
56 SetModifierState(keyboard_state, EventFlagsFromIndex(eindex));
57 for (size_t vk = 0; vk < kMaxVirtualKeyCode; ++vk) {
58 wchar_t unibuff[5];
59
60 int rv = ::ToUnicodeEx(vk, 0, keyboard_state, unibuff, arraysize(unibuff),
61 0, keyboard_layout_);
62
63 if (rv < 0) {
64 // Dead key, repeat twice to get character representation
65 rv = ::ToUnicodeEx(vk, 0, keyboard_state, unibuff, arraysize(unibuff),
66 0, keyboard_layout_);
67 // Must be a repeat of dead key character
68 DCHECK(rv == 2);
69 lookup_table_[vk][eindex] = DomKey::DeadKeyFromCombiningCharacter(
70 unibuff[0]);
71 } else if (rv >= 1) {
72 lookup_table_[vk][eindex] = DomKey::FromCharacter(unibuff[0]);
73 }
74 }
75 }
76 ::SetKeyboardState(original_keyboard_state);
77 }
78
79 void WindowsKeyboardLookup::SetModifierState(BYTE *keyboard_state,
80 int event_flags) const {
81 // Trying to match system_event_state_lookup.cc
82 if (event_flags & EF_SHIFT_DOWN) {
83 keyboard_state[VK_SHIFT] |= 0x80;
84 } else {
85 keyboard_state[VK_SHIFT] &= ~0x80;
86 keyboard_state[VK_LSHIFT] &= ~0x80;
87 keyboard_state[VK_RSHIFT] &= ~0x80;
88 }
89
90 if (event_flags & EF_CONTROL_DOWN) {
91 keyboard_state[VK_CONTROL] |= 0x80;
92 } else {
93 keyboard_state[VK_CONTROL] &= ~0x80;
94 keyboard_state[VK_LCONTROL] &= ~0x80;
95 keyboard_state[VK_RCONTROL] &= ~0x80;
96 }
97
98 if (event_flags & EF_ALT_DOWN) {
99 keyboard_state[VK_MENU] |= 0x80;
100 } else {
101 keyboard_state[VK_MENU] &= ~0x80;
102 keyboard_state[VK_LMENU] &= ~0x80;
103 keyboard_state[VK_RMENU] &= ~0x80;
104 }
105
106 if (event_flags & EF_ALTGR_DOWN) {
107 keyboard_state[VK_MENU] |= 0x80;
108 keyboard_state[VK_CONTROL] |= 0x80;
109 } else {
110 // Windows does not have a specific key code for AltGr
111 }
112
113 if (event_flags & EF_COMMAND_DOWN) {
114 keyboard_state[VK_LWIN] |= 0x80;
115 } else {
116 keyboard_state[VK_LWIN] &= ~0x80;
117 keyboard_state[VK_RWIN] &= ~0x80;
118 }
119
120 if (event_flags & EF_CAPS_LOCK_DOWN) {
121 keyboard_state[VK_CAPITAL] |= 0x01;
122 } else {
123 keyboard_state[VK_CAPITAL] &= ~0x01;
124 }
125
126 if (event_flags & EF_NUM_LOCK_DOWN) {
127 keyboard_state[VK_NUMLOCK] |= 0x01;
128 } else {
129 keyboard_state[VK_NUMLOCK] &= ~0x01;
130 }
131
132 if (event_flags & EF_SCROLL_LOCK_DOWN) {
133 keyboard_state[VK_SCROLL] |= 0x01;
134 } else {
135 keyboard_state[VK_SCROLL] &= ~0x01;
136 }
137
138 // TODO(chongz): EF_EXTENDED
139 }
140
141 size_t WindowsKeyboardLookup::GetEventFlagsIndex(int event_flags) const {
142 size_t index = 0;
143 for (size_t i = 0; i < arraysize(event_flags_index); ++i) {
144 if (event_flags & event_flags_index[i])
145 index |= 1 << i;
146 }
147 return index;
148 }
149
150 int WindowsKeyboardLookup::EventFlagsFromIndex(size_t index) const {
151 int event_flags = EF_NONE;
152 for (size_t i = 0; i < arraysize(event_flags_index); ++i) {
153 if (index & (1 << i))
154 event_flags |= event_flags_index[i];
155 }
156 return event_flags;
157 }
158
159 WindowsKeyboardLookup* WindowsKeyboardLookup::GetInstance() {
160 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.
161 if (instance == nullptr)
162 instance = WindowsKeyboardLookup::Create(::GetKeyboardLayout(0));
163 return instance;
164 }
165
166 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698