Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / ui / events / keycodes / keyboard_code_conversion.cc
blob5973549272b1746d2a96685fc71a41ca75a06466
1 // Copyright (c) 2011 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.
5 #include "ui/events/keycodes/keyboard_code_conversion.h"
7 #include <algorithm>
9 #include "ui/events/event_constants.h"
10 #include "ui/events/keycodes/dom3/dom_code.h"
11 #include "ui/events/keycodes/dom3/dom_key.h"
12 #include "ui/events/keycodes/dom_us_layout_data.h"
14 namespace ui {
16 namespace {
18 bool IsRightSideDomCode(DomCode code) {
19 return (code == DomCode::SHIFT_RIGHT) || (code == DomCode::CONTROL_RIGHT) ||
20 (code == DomCode::ALT_RIGHT) || (code == DomCode::OS_RIGHT);
23 bool IsModifierDomCode(DomCode code) {
24 return (code == DomCode::CONTROL_LEFT) || (code == DomCode::CONTROL_RIGHT) ||
25 (code == DomCode::SHIFT_LEFT) || (code == DomCode::SHIFT_RIGHT) ||
26 (code == DomCode::ALT_LEFT) || (code == DomCode::ALT_RIGHT) ||
27 (code == DomCode::OS_LEFT) || (code == DomCode::OS_RIGHT);
30 // Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|,
31 // assuming a base US English layout. The returned VKEY is located
32 // (e.g. VKEY_LSHIFT).
33 KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code) {
34 const DomCodeToKeyboardCodeEntry* end =
35 kDomCodeToKeyboardCodeMap + arraysize(kDomCodeToKeyboardCodeMap);
36 const DomCodeToKeyboardCodeEntry* found =
37 std::lower_bound(kDomCodeToKeyboardCodeMap, end, dom_code,
38 [](const DomCodeToKeyboardCodeEntry& a, DomCode b) {
39 return static_cast<int>(a.dom_code) < static_cast<int>(b);
40 });
41 if ((found != end) && (found->dom_code == dom_code))
42 return found->key_code;
43 return VKEY_UNKNOWN;
46 } // anonymous namespace
48 base::char16 DomCodeToUsLayoutCharacter(DomCode dom_code, int flags) {
49 base::char16 character;
50 DomKey dom_key;
51 KeyboardCode key_code;
52 if (DomCodeToUsLayoutMeaning(dom_code, flags, &dom_key, &character,
53 &key_code))
54 return character;
55 return 0;
58 bool DomCodeToUsLayoutMeaning(DomCode dom_code,
59 int flags,
60 DomKey* out_dom_key,
61 base::char16* out_character,
62 KeyboardCode* out_key_code) {
63 if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) {
64 if (DomCodeToControlCharacter(dom_code, flags, out_dom_key, out_character,
65 out_key_code)) {
66 return true;
68 if (!IsModifierDomCode(dom_code)) {
69 *out_dom_key = DomKey::UNIDENTIFIED;
70 *out_character = 0;
71 *out_key_code = LocatedToNonLocatedKeyboardCode(
72 DomCodeToUsLayoutKeyboardCode(dom_code));
73 return true;
75 } else {
76 for (const auto& it : kPrintableCodeMap) {
77 if (it.dom_code == dom_code) {
78 int state = ((flags & EF_SHIFT_DOWN) == EF_SHIFT_DOWN);
79 base::char16 ch = it.character[state];
80 *out_dom_key = DomKey::CHARACTER;
81 *out_character = ch;
82 if ((flags & EF_CAPS_LOCK_DOWN) == EF_CAPS_LOCK_DOWN) {
83 ch |= 0x20;
84 if ((ch >= 'a') && (ch <= 'z'))
85 *out_character = it.character[state ^ 1];
87 *out_key_code = LocatedToNonLocatedKeyboardCode(
88 DomCodeToUsLayoutKeyboardCode(dom_code));
89 return true;
93 for (const auto& it : kNonPrintableCodeMap) {
94 if (it.dom_code == dom_code) {
95 *out_dom_key = it.dom_key;
96 *out_character = it.character;
97 *out_key_code = NonPrintableDomKeyToKeyboardCode(it.dom_key);
98 return true;
101 return false;
104 bool DomCodeToControlCharacter(DomCode dom_code,
105 int flags,
106 DomKey* dom_key,
107 base::char16* character,
108 KeyboardCode* key_code) {
109 if ((flags & EF_CONTROL_DOWN) == 0)
110 return false;
112 int code = static_cast<int>(dom_code);
113 const int kKeyA = static_cast<int>(DomCode::KEY_A);
114 // Control-A - Control-Z map to 0x01 - 0x1A.
115 if (code >= kKeyA && code <= static_cast<int>(DomCode::KEY_Z)) {
116 *character = static_cast<base::char16>(code - kKeyA + 1);
117 switch (dom_code) {
118 case DomCode::KEY_H:
119 *dom_key = DomKey::BACKSPACE;
120 *key_code = VKEY_BACK;
121 break;
122 case DomCode::KEY_I:
123 *dom_key = DomKey::TAB;
124 *key_code = VKEY_TAB;
125 break;
126 case DomCode::KEY_M:
127 *dom_key = DomKey::ENTER;
128 *key_code = VKEY_RETURN;
129 break;
130 default:
131 *dom_key = DomKey::CHARACTER;
132 *key_code = static_cast<KeyboardCode>(code - kKeyA + VKEY_A);
133 break;
135 return true;
138 if (flags & EF_SHIFT_DOWN) {
139 switch (dom_code) {
140 case DomCode::DIGIT2:
141 // NUL
142 *character = 0;
143 *dom_key = DomKey::CHARACTER;
144 *key_code = VKEY_2;
145 return true;
146 case DomCode::DIGIT6:
147 // RS
148 *character = 0x1E;
149 *dom_key = DomKey::CHARACTER;
150 *key_code = VKEY_6;
151 return true;
152 case DomCode::MINUS:
153 // US
154 *character = 0x1F;
155 *dom_key = DomKey::CHARACTER;
156 *key_code = VKEY_OEM_MINUS;
157 return true;
158 default:
159 return false;
163 switch (dom_code) {
164 case DomCode::ENTER:
165 // NL
166 *character = 0x0A;
167 *dom_key = DomKey::CHARACTER;
168 *key_code = VKEY_RETURN;
169 return true;
170 case DomCode::BRACKET_LEFT:
171 // ESC
172 *character = 0x1B;
173 *dom_key = DomKey::ESCAPE;
174 *key_code = VKEY_OEM_4;
175 return true;
176 case DomCode::BACKSLASH:
177 // FS
178 *character = 0x1C;
179 *dom_key = DomKey::CHARACTER;
180 *key_code = VKEY_OEM_5;
181 return true;
182 case DomCode::BRACKET_RIGHT:
183 // GS
184 *character = 0x1D;
185 *dom_key = DomKey::CHARACTER;
186 *key_code = VKEY_OEM_6;
187 return true;
188 default:
189 return false;
193 // Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
194 // The returned VKEY is non-positional (e.g. VKEY_SHIFT).
195 KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) {
196 for (const auto& it : kDomKeyToKeyboardCodeMap) {
197 if (it.dom_key == dom_key)
198 return it.key_code;
200 return VKEY_UNKNOWN;
203 // Determine the non-located VKEY corresponding to a located VKEY.
204 KeyboardCode LocatedToNonLocatedKeyboardCode(KeyboardCode key_code) {
205 switch (key_code) {
206 case VKEY_RWIN:
207 return VKEY_LWIN;
208 case VKEY_LSHIFT:
209 case VKEY_RSHIFT:
210 return VKEY_SHIFT;
211 case VKEY_LCONTROL:
212 case VKEY_RCONTROL:
213 return VKEY_CONTROL;
214 case VKEY_LMENU:
215 case VKEY_RMENU:
216 return VKEY_MENU;
217 case VKEY_NUMPAD0:
218 return VKEY_0;
219 case VKEY_NUMPAD1:
220 return VKEY_1;
221 case VKEY_NUMPAD2:
222 return VKEY_2;
223 case VKEY_NUMPAD3:
224 return VKEY_3;
225 case VKEY_NUMPAD4:
226 return VKEY_4;
227 case VKEY_NUMPAD5:
228 return VKEY_5;
229 case VKEY_NUMPAD6:
230 return VKEY_6;
231 case VKEY_NUMPAD7:
232 return VKEY_7;
233 case VKEY_NUMPAD8:
234 return VKEY_8;
235 case VKEY_NUMPAD9:
236 return VKEY_9;
237 default:
238 return key_code;
242 // Determine the located VKEY corresponding to a non-located VKEY.
243 KeyboardCode NonLocatedToLocatedKeyboardCode(KeyboardCode key_code,
244 DomCode dom_code) {
245 switch (key_code) {
246 case VKEY_SHIFT:
247 return IsRightSideDomCode(dom_code) ? VKEY_RSHIFT : VKEY_LSHIFT;
248 case VKEY_CONTROL:
249 return IsRightSideDomCode(dom_code) ? VKEY_RCONTROL : VKEY_LCONTROL;
250 case VKEY_MENU:
251 return IsRightSideDomCode(dom_code) ? VKEY_RMENU : VKEY_LMENU;
252 case VKEY_LWIN:
253 return IsRightSideDomCode(dom_code) ? VKEY_RWIN : VKEY_LWIN;
254 case VKEY_0:
255 return (dom_code == DomCode::NUMPAD0) ? VKEY_NUMPAD0 : VKEY_0;
256 case VKEY_1:
257 return (dom_code == DomCode::NUMPAD1) ? VKEY_NUMPAD1 : VKEY_1;
258 case VKEY_2:
259 return (dom_code == DomCode::NUMPAD2) ? VKEY_NUMPAD2 : VKEY_2;
260 case VKEY_3:
261 return (dom_code == DomCode::NUMPAD3) ? VKEY_NUMPAD3 : VKEY_3;
262 case VKEY_4:
263 return (dom_code == DomCode::NUMPAD4) ? VKEY_NUMPAD4 : VKEY_4;
264 case VKEY_5:
265 return (dom_code == DomCode::NUMPAD5) ? VKEY_NUMPAD5 : VKEY_5;
266 case VKEY_6:
267 return (dom_code == DomCode::NUMPAD6) ? VKEY_NUMPAD6 : VKEY_6;
268 case VKEY_7:
269 return (dom_code == DomCode::NUMPAD7) ? VKEY_NUMPAD7 : VKEY_7;
270 case VKEY_8:
271 return (dom_code == DomCode::NUMPAD8) ? VKEY_NUMPAD8 : VKEY_8;
272 case VKEY_9:
273 return (dom_code == DomCode::NUMPAD9) ? VKEY_NUMPAD9 : VKEY_9;
274 default:
275 return key_code;
279 DomCode UsLayoutKeyboardCodeToDomCode(KeyboardCode key_code) {
280 key_code = NonLocatedToLocatedKeyboardCode(key_code, DomCode::NONE);
281 for (const auto& it : kDomCodeToKeyboardCodeMap) {
282 if (it.key_code == key_code)
283 return it.dom_code;
285 for (const auto& it : kFallbackKeyboardCodeToDomCodeMap) {
286 if (it.key_code == key_code)
287 return it.dom_code;
289 return DomCode::NONE;
292 } // namespace ui