1 // Copyright 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.
5 #include "ui/events/keycodes/keyboard_code_conversion.h"
7 #include "base/basictypes.h"
8 #include "base/strings/stringprintf.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/events/event_constants.h"
11 #include "ui/events/keycodes/dom/dom_code.h"
12 #include "ui/events/keycodes/dom/dom_key.h"
13 #include "ui/events/keycodes/dom/keycode_converter.h"
14 #include "ui/events/keycodes/dom_us_layout_data.h"
15 #include "ui/events/keycodes/keyboard_codes.h"
22 base::char16 character
;
23 ui::KeyboardCode legacy_key_code
;
26 const Meaning kUndefined
= {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
};
28 void CheckDomCodeToMeaning(const char* label
,
29 bool f(ui::DomCode dom_code
,
31 ui::DomKey
* out_dom_key
,
32 base::char16
* out_character
,
33 ui::KeyboardCode
* out_key_code
),
36 const Meaning
& result
) {
37 ui::DomKey result_dom_key
= ui::DomKey::NONE
;
38 base::char16 result_character
= 0;
39 ui::KeyboardCode result_legacy_key_code
= ui::VKEY_UNKNOWN
;
40 bool success
= f(dom_code
, event_flags
, &result_dom_key
, &result_character
,
41 &result_legacy_key_code
);
43 base::StringPrintf("%s %s %06X:%04X", label
,
44 ui::KeycodeConverter::DomCodeToCodeString(dom_code
),
45 static_cast<int>(dom_code
), event_flags
));
46 EXPECT_EQ(result
.defined
, success
);
48 EXPECT_EQ(result
.dom_key
, result_dom_key
)
50 << ui::KeycodeConverter::DomKeyToKeyString(result
.dom_key
)
52 << ui::KeycodeConverter::DomKeyToKeyString(result_dom_key
) << "'";
53 EXPECT_EQ(result
.character
, result_character
);
54 EXPECT_EQ(result
.legacy_key_code
, result_legacy_key_code
);
56 // Should not have touched output parameters.
57 EXPECT_EQ(ui::DomKey::NONE
, result_dom_key
);
58 EXPECT_EQ(0, result_character
);
59 EXPECT_EQ(ui::VKEY_UNKNOWN
, result_legacy_key_code
);
63 TEST(KeyboardCodeConversion
, ControlCharacters
) {
64 // The codes in this table are handled by |DomCodeToControlCharacter()|.
68 Meaning control_shift
;
69 } kControlCharacters
[] = {
71 {true, ui::DomKey::CHARACTER
, 0x01, ui::VKEY_A
},
72 {true, ui::DomKey::CHARACTER
, 0x01, ui::VKEY_A
}},
74 {true, ui::DomKey::CHARACTER
, 0x02, ui::VKEY_B
},
75 {true, ui::DomKey::CHARACTER
, 0x02, ui::VKEY_B
}},
77 {true, ui::DomKey::CHARACTER
, 0x03, ui::VKEY_C
},
78 {true, ui::DomKey::CHARACTER
, 0x03, ui::VKEY_C
}},
80 {true, ui::DomKey::CHARACTER
, 0x04, ui::VKEY_D
},
81 {true, ui::DomKey::CHARACTER
, 0x04, ui::VKEY_D
}},
83 {true, ui::DomKey::CHARACTER
, 0x05, ui::VKEY_E
},
84 {true, ui::DomKey::CHARACTER
, 0x05, ui::VKEY_E
}},
86 {true, ui::DomKey::CHARACTER
, 0x06, ui::VKEY_F
},
87 {true, ui::DomKey::CHARACTER
, 0x06, ui::VKEY_F
}},
89 {true, ui::DomKey::CHARACTER
, 0x07, ui::VKEY_G
},
90 {true, ui::DomKey::CHARACTER
, 0x07, ui::VKEY_G
}},
92 {true, ui::DomKey::BACKSPACE
, 0x08, ui::VKEY_BACK
},
93 {true, ui::DomKey::BACKSPACE
, 0x08, ui::VKEY_BACK
}},
95 {true, ui::DomKey::TAB
, 0x09, ui::VKEY_TAB
},
96 {true, ui::DomKey::TAB
, 0x09, ui::VKEY_TAB
}},
98 {true, ui::DomKey::CHARACTER
, 0x0A, ui::VKEY_J
},
99 {true, ui::DomKey::CHARACTER
, 0x0A, ui::VKEY_J
}},
101 {true, ui::DomKey::CHARACTER
, 0x0B, ui::VKEY_K
},
102 {true, ui::DomKey::CHARACTER
, 0x0B, ui::VKEY_K
}},
104 {true, ui::DomKey::CHARACTER
, 0x0C, ui::VKEY_L
},
105 {true, ui::DomKey::CHARACTER
, 0x0C, ui::VKEY_L
}},
107 {true, ui::DomKey::ENTER
, 0x0D, ui::VKEY_RETURN
},
108 {true, ui::DomKey::ENTER
, 0x0D, ui::VKEY_RETURN
}},
110 {true, ui::DomKey::CHARACTER
, 0x0E, ui::VKEY_N
},
111 {true, ui::DomKey::CHARACTER
, 0x0E, ui::VKEY_N
}},
113 {true, ui::DomKey::CHARACTER
, 0x0F, ui::VKEY_O
},
114 {true, ui::DomKey::CHARACTER
, 0x0F, ui::VKEY_O
}},
116 {true, ui::DomKey::CHARACTER
, 0x10, ui::VKEY_P
},
117 {true, ui::DomKey::CHARACTER
, 0x10, ui::VKEY_P
}},
119 {true, ui::DomKey::CHARACTER
, 0x11, ui::VKEY_Q
},
120 {true, ui::DomKey::CHARACTER
, 0x11, ui::VKEY_Q
}},
122 {true, ui::DomKey::CHARACTER
, 0x12, ui::VKEY_R
},
123 {true, ui::DomKey::CHARACTER
, 0x12, ui::VKEY_R
}},
125 {true, ui::DomKey::CHARACTER
, 0x13, ui::VKEY_S
},
126 {true, ui::DomKey::CHARACTER
, 0x13, ui::VKEY_S
}},
128 {true, ui::DomKey::CHARACTER
, 0x14, ui::VKEY_T
},
129 {true, ui::DomKey::CHARACTER
, 0x14, ui::VKEY_T
}},
131 {true, ui::DomKey::CHARACTER
, 0x15, ui::VKEY_U
},
132 {true, ui::DomKey::CHARACTER
, 0x15, ui::VKEY_U
}},
134 {true, ui::DomKey::CHARACTER
, 0x16, ui::VKEY_V
},
135 {true, ui::DomKey::CHARACTER
, 0x16, ui::VKEY_V
}},
137 {true, ui::DomKey::CHARACTER
, 0x17, ui::VKEY_W
},
138 {true, ui::DomKey::CHARACTER
, 0x17, ui::VKEY_W
}},
140 {true, ui::DomKey::CHARACTER
, 0x18, ui::VKEY_X
},
141 {true, ui::DomKey::CHARACTER
, 0x18, ui::VKEY_X
}},
143 {true, ui::DomKey::CHARACTER
, 0x19, ui::VKEY_Y
},
144 {true, ui::DomKey::CHARACTER
, 0x19, ui::VKEY_Y
}},
146 {true, ui::DomKey::CHARACTER
, 0x1A, ui::VKEY_Z
},
147 {true, ui::DomKey::CHARACTER
, 0x1A, ui::VKEY_Z
}},
149 for (const auto& it
: kControlCharacters
) {
150 // Verify |DomCodeToControlCharacter()|.
151 CheckDomCodeToMeaning("c_cc_n", ui::DomCodeToControlCharacter
, it
.dom_code
,
152 ui::EF_NONE
, kUndefined
);
153 CheckDomCodeToMeaning("c_cc_c", ui::DomCodeToControlCharacter
, it
.dom_code
,
154 ui::EF_CONTROL_DOWN
, it
.control
);
155 CheckDomCodeToMeaning("c_cc_cs", ui::DomCodeToControlCharacter
, it
.dom_code
,
156 ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
,
158 // Verify |DomCodeToUsLayoutMeaning()|.
159 CheckDomCodeToMeaning("c_us_c", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
160 ui::EF_CONTROL_DOWN
, it
.control
);
161 CheckDomCodeToMeaning("c_us_cs", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
162 ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
,
166 // The codes in this table are sensitive to the Shift state, so they are
167 // handled differently by |DomCodeToControlCharacter()|, which returns false
168 // for unknown combinations, vs |DomCodeToUsLayoutMeaning()|, which returns
169 // true with DomKey::UNIDENTIFIED.
170 static const struct {
171 ui::DomCode dom_code
;
173 Meaning cc_control_shift
;
175 Meaning us_control_shift
;
176 } kShiftControlCharacters
[] = {
177 {ui::DomCode::DIGIT2
,
178 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
179 {true, ui::DomKey::CHARACTER
, 0, ui::VKEY_2
},
180 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_2
},
181 {true, ui::DomKey::CHARACTER
, 0, ui::VKEY_2
}},
182 {ui::DomCode::DIGIT6
,
183 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
184 {true, ui::DomKey::CHARACTER
, 0x1E, ui::VKEY_6
},
185 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_6
},
186 {true, ui::DomKey::CHARACTER
, 0x1E, ui::VKEY_6
}},
188 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
189 {true, ui::DomKey::CHARACTER
, 0x1F, ui::VKEY_OEM_MINUS
},
190 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_OEM_MINUS
},
191 {true, ui::DomKey::CHARACTER
, 0x1F, ui::VKEY_OEM_MINUS
}},
193 {true, ui::DomKey::CHARACTER
, 0x0A, ui::VKEY_RETURN
},
194 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
195 {true, ui::DomKey::CHARACTER
, 0x0A, ui::VKEY_RETURN
},
196 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_RETURN
}},
197 {ui::DomCode::BRACKET_LEFT
,
198 {true, ui::DomKey::ESCAPE
, 0x1B, ui::VKEY_OEM_4
},
199 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
200 {true, ui::DomKey::ESCAPE
, 0x1B, ui::VKEY_OEM_4
},
201 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_OEM_4
}},
202 {ui::DomCode::BACKSLASH
,
203 {true, ui::DomKey::CHARACTER
, 0x1C, ui::VKEY_OEM_5
},
204 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
205 {true, ui::DomKey::CHARACTER
, 0x1C, ui::VKEY_OEM_5
},
206 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_OEM_5
}},
207 {ui::DomCode::BRACKET_RIGHT
,
208 {true, ui::DomKey::CHARACTER
, 0x1D, ui::VKEY_OEM_6
},
209 {false, ui::DomKey::NONE
, 0, ui::VKEY_UNKNOWN
},
210 {true, ui::DomKey::CHARACTER
, 0x1D, ui::VKEY_OEM_6
},
211 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_OEM_6
}},
213 for (const auto& it
: kShiftControlCharacters
) {
214 // Verify |DomCodeToControlCharacter()|.
215 CheckDomCodeToMeaning("s_cc_n", ui::DomCodeToControlCharacter
, it
.dom_code
,
216 ui::EF_NONE
, kUndefined
);
217 CheckDomCodeToMeaning("s_cc_c", ui::DomCodeToControlCharacter
, it
.dom_code
,
218 ui::EF_CONTROL_DOWN
, it
.cc_control
);
219 CheckDomCodeToMeaning("s_cc_cs", ui::DomCodeToControlCharacter
, it
.dom_code
,
220 ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
,
221 it
.cc_control_shift
);
222 // Verify |DomCodeToUsLayoutMeaning()|.
223 CheckDomCodeToMeaning("s_us_c", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
224 ui::EF_CONTROL_DOWN
, it
.us_control
);
225 CheckDomCodeToMeaning("s_us_cs", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
226 ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
,
227 it
.us_control_shift
);
230 // These codes are not handled by |DomCodeToControlCharacter()| directly.
231 static const struct {
232 ui::DomCode dom_code
;
235 } kNonControlCharacters
[] = {
236 // Modifiers are handled by |DomCodeToUsLayoutMeaning()| without regard
237 // to whether Control is down.
238 {ui::DomCode::CONTROL_LEFT
,
239 {true, ui::DomKey::CONTROL
, 0, ui::VKEY_CONTROL
},
240 {true, ui::DomKey::CONTROL
, 0, ui::VKEY_CONTROL
}},
241 {ui::DomCode::CONTROL_RIGHT
,
242 {true, ui::DomKey::CONTROL
, 0, ui::VKEY_CONTROL
},
243 {true, ui::DomKey::CONTROL
, 0, ui::VKEY_CONTROL
}},
244 {ui::DomCode::SHIFT_LEFT
,
245 {true, ui::DomKey::SHIFT
, 0, ui::VKEY_SHIFT
},
246 {true, ui::DomKey::SHIFT
, 0, ui::VKEY_SHIFT
}},
247 {ui::DomCode::SHIFT_RIGHT
,
248 {true, ui::DomKey::SHIFT
, 0, ui::VKEY_SHIFT
},
249 {true, ui::DomKey::SHIFT
, 0, ui::VKEY_SHIFT
}},
250 {ui::DomCode::ALT_LEFT
,
251 {true, ui::DomKey::ALT
, 0, ui::VKEY_MENU
},
252 {true, ui::DomKey::ALT
, 0, ui::VKEY_MENU
}},
253 {ui::DomCode::ALT_RIGHT
,
254 {true, ui::DomKey::ALT
, 0, ui::VKEY_MENU
},
255 {true, ui::DomKey::ALT
, 0, ui::VKEY_MENU
}},
256 {ui::DomCode::OS_LEFT
,
257 {true, ui::DomKey::OS
, 0, ui::VKEY_LWIN
},
258 {true, ui::DomKey::OS
, 0, ui::VKEY_LWIN
}},
259 {ui::DomCode::OS_RIGHT
,
260 {true, ui::DomKey::OS
, 0, ui::VKEY_LWIN
},
261 {true, ui::DomKey::OS
, 0, ui::VKEY_LWIN
}},
262 // Non-modifiers (a representative sample here) succeed with
263 // DomKey::UNIDENTIFIED when Control is down.
264 {ui::DomCode::DIGIT1
,
265 {true, ui::DomKey::CHARACTER
, '1', ui::VKEY_1
},
266 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_1
}},
268 {true, ui::DomKey::CHARACTER
, '=', ui::VKEY_OEM_PLUS
},
269 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_OEM_PLUS
}},
271 {true, ui::DomKey::TAB
, 9, ui::VKEY_TAB
},
272 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_TAB
}},
274 {true, ui::DomKey::F1
, 0, ui::VKEY_F1
},
275 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_F1
}},
276 {ui::DomCode::VOLUME_UP
,
277 {true, ui::DomKey::VOLUME_UP
, 0, ui::VKEY_VOLUME_UP
},
278 {true, ui::DomKey::UNIDENTIFIED
, 0, ui::VKEY_VOLUME_UP
}},
280 for (const auto& it
: kNonControlCharacters
) {
281 // Verify |DomCodeToControlCharacter()|.
282 CheckDomCodeToMeaning("n_cc_n", ui::DomCodeToControlCharacter
, it
.dom_code
,
283 ui::EF_NONE
, kUndefined
);
284 CheckDomCodeToMeaning("n_cc_c", ui::DomCodeToControlCharacter
, it
.dom_code
,
285 ui::EF_CONTROL_DOWN
, kUndefined
);
286 CheckDomCodeToMeaning("n_cc_cs", ui::DomCodeToControlCharacter
, it
.dom_code
,
287 ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
, kUndefined
);
288 // Verify |DomCodeToUsLayoutMeaning()|.
289 CheckDomCodeToMeaning("n_us_n", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
290 ui::EF_NONE
, it
.normal
);
291 CheckDomCodeToMeaning("n_us_c", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
292 ui::EF_CONTROL_DOWN
, it
.control
);
293 CheckDomCodeToMeaning("n_us_cs", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
294 ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
, it
.control
);
298 TEST(KeyboardCodeConversion
, UsLayout
) {
299 static const struct {
300 ui::DomCode dom_code
;
303 } kPrintableUsLayout
[] = {
305 {true, ui::DomKey::CHARACTER
, 'a', ui::VKEY_A
},
306 {true, ui::DomKey::CHARACTER
, 'A', ui::VKEY_A
}},
308 {true, ui::DomKey::CHARACTER
, 'b', ui::VKEY_B
},
309 {true, ui::DomKey::CHARACTER
, 'B', ui::VKEY_B
}},
311 {true, ui::DomKey::CHARACTER
, 'c', ui::VKEY_C
},
312 {true, ui::DomKey::CHARACTER
, 'C', ui::VKEY_C
}},
314 {true, ui::DomKey::CHARACTER
, 'd', ui::VKEY_D
},
315 {true, ui::DomKey::CHARACTER
, 'D', ui::VKEY_D
}},
317 {true, ui::DomKey::CHARACTER
, 'e', ui::VKEY_E
},
318 {true, ui::DomKey::CHARACTER
, 'E', ui::VKEY_E
}},
320 {true, ui::DomKey::CHARACTER
, 'f', ui::VKEY_F
},
321 {true, ui::DomKey::CHARACTER
, 'F', ui::VKEY_F
}},
323 {true, ui::DomKey::CHARACTER
, 'g', ui::VKEY_G
},
324 {true, ui::DomKey::CHARACTER
, 'G', ui::VKEY_G
}},
326 {true, ui::DomKey::CHARACTER
, 'h', ui::VKEY_H
},
327 {true, ui::DomKey::CHARACTER
, 'H', ui::VKEY_H
}},
329 {true, ui::DomKey::CHARACTER
, 'i', ui::VKEY_I
},
330 {true, ui::DomKey::CHARACTER
, 'I', ui::VKEY_I
}},
332 {true, ui::DomKey::CHARACTER
, 'j', ui::VKEY_J
},
333 {true, ui::DomKey::CHARACTER
, 'J', ui::VKEY_J
}},
335 {true, ui::DomKey::CHARACTER
, 'k', ui::VKEY_K
},
336 {true, ui::DomKey::CHARACTER
, 'K', ui::VKEY_K
}},
338 {true, ui::DomKey::CHARACTER
, 'l', ui::VKEY_L
},
339 {true, ui::DomKey::CHARACTER
, 'L', ui::VKEY_L
}},
341 {true, ui::DomKey::CHARACTER
, 'm', ui::VKEY_M
},
342 {true, ui::DomKey::CHARACTER
, 'M', ui::VKEY_M
}},
344 {true, ui::DomKey::CHARACTER
, 'n', ui::VKEY_N
},
345 {true, ui::DomKey::CHARACTER
, 'N', ui::VKEY_N
}},
347 {true, ui::DomKey::CHARACTER
, 'o', ui::VKEY_O
},
348 {true, ui::DomKey::CHARACTER
, 'O', ui::VKEY_O
}},
350 {true, ui::DomKey::CHARACTER
, 'p', ui::VKEY_P
},
351 {true, ui::DomKey::CHARACTER
, 'P', ui::VKEY_P
}},
353 {true, ui::DomKey::CHARACTER
, 'q', ui::VKEY_Q
},
354 {true, ui::DomKey::CHARACTER
, 'Q', ui::VKEY_Q
}},
356 {true, ui::DomKey::CHARACTER
, 'r', ui::VKEY_R
},
357 {true, ui::DomKey::CHARACTER
, 'R', ui::VKEY_R
}},
359 {true, ui::DomKey::CHARACTER
, 's', ui::VKEY_S
},
360 {true, ui::DomKey::CHARACTER
, 'S', ui::VKEY_S
}},
362 {true, ui::DomKey::CHARACTER
, 't', ui::VKEY_T
},
363 {true, ui::DomKey::CHARACTER
, 'T', ui::VKEY_T
}},
365 {true, ui::DomKey::CHARACTER
, 'u', ui::VKEY_U
},
366 {true, ui::DomKey::CHARACTER
, 'U', ui::VKEY_U
}},
368 {true, ui::DomKey::CHARACTER
, 'v', ui::VKEY_V
},
369 {true, ui::DomKey::CHARACTER
, 'V', ui::VKEY_V
}},
371 {true, ui::DomKey::CHARACTER
, 'w', ui::VKEY_W
},
372 {true, ui::DomKey::CHARACTER
, 'W', ui::VKEY_W
}},
374 {true, ui::DomKey::CHARACTER
, 'x', ui::VKEY_X
},
375 {true, ui::DomKey::CHARACTER
, 'X', ui::VKEY_X
}},
377 {true, ui::DomKey::CHARACTER
, 'y', ui::VKEY_Y
},
378 {true, ui::DomKey::CHARACTER
, 'Y', ui::VKEY_Y
}},
380 {true, ui::DomKey::CHARACTER
, 'z', ui::VKEY_Z
},
381 {true, ui::DomKey::CHARACTER
, 'Z', ui::VKEY_Z
}},
382 {ui::DomCode::DIGIT1
,
383 {true, ui::DomKey::CHARACTER
, '1', ui::VKEY_1
},
384 {true, ui::DomKey::CHARACTER
, '!', ui::VKEY_1
}},
385 {ui::DomCode::DIGIT2
,
386 {true, ui::DomKey::CHARACTER
, '2', ui::VKEY_2
},
387 {true, ui::DomKey::CHARACTER
, '@', ui::VKEY_2
}},
388 {ui::DomCode::DIGIT3
,
389 {true, ui::DomKey::CHARACTER
, '3', ui::VKEY_3
},
390 {true, ui::DomKey::CHARACTER
, '#', ui::VKEY_3
}},
391 {ui::DomCode::DIGIT4
,
392 {true, ui::DomKey::CHARACTER
, '4', ui::VKEY_4
},
393 {true, ui::DomKey::CHARACTER
, '$', ui::VKEY_4
}},
394 {ui::DomCode::DIGIT5
,
395 {true, ui::DomKey::CHARACTER
, '5', ui::VKEY_5
},
396 {true, ui::DomKey::CHARACTER
, '%', ui::VKEY_5
}},
397 {ui::DomCode::DIGIT6
,
398 {true, ui::DomKey::CHARACTER
, '6', ui::VKEY_6
},
399 {true, ui::DomKey::CHARACTER
, '^', ui::VKEY_6
}},
400 {ui::DomCode::DIGIT7
,
401 {true, ui::DomKey::CHARACTER
, '7', ui::VKEY_7
},
402 {true, ui::DomKey::CHARACTER
, '&', ui::VKEY_7
}},
403 {ui::DomCode::DIGIT8
,
404 {true, ui::DomKey::CHARACTER
, '8', ui::VKEY_8
},
405 {true, ui::DomKey::CHARACTER
, '*', ui::VKEY_8
}},
406 {ui::DomCode::DIGIT9
,
407 {true, ui::DomKey::CHARACTER
, '9', ui::VKEY_9
},
408 {true, ui::DomKey::CHARACTER
, '(', ui::VKEY_9
}},
409 {ui::DomCode::DIGIT0
,
410 {true, ui::DomKey::CHARACTER
, '0', ui::VKEY_0
},
411 {true, ui::DomKey::CHARACTER
, ')', ui::VKEY_0
}},
413 {true, ui::DomKey::CHARACTER
, ' ', ui::VKEY_SPACE
},
414 {true, ui::DomKey::CHARACTER
, ' ', ui::VKEY_SPACE
}},
416 {true, ui::DomKey::CHARACTER
, '-', ui::VKEY_OEM_MINUS
},
417 {true, ui::DomKey::CHARACTER
, '_', ui::VKEY_OEM_MINUS
}},
419 {true, ui::DomKey::CHARACTER
, '=', ui::VKEY_OEM_PLUS
},
420 {true, ui::DomKey::CHARACTER
, '+', ui::VKEY_OEM_PLUS
}},
421 {ui::DomCode::BRACKET_LEFT
,
422 {true, ui::DomKey::CHARACTER
, '[', ui::VKEY_OEM_4
},
423 {true, ui::DomKey::CHARACTER
, '{', ui::VKEY_OEM_4
}},
424 {ui::DomCode::BRACKET_RIGHT
,
425 {true, ui::DomKey::CHARACTER
, ']', ui::VKEY_OEM_6
},
426 {true, ui::DomKey::CHARACTER
, '}', ui::VKEY_OEM_6
}},
427 {ui::DomCode::BACKSLASH
,
428 {true, ui::DomKey::CHARACTER
, '\\', ui::VKEY_OEM_5
},
429 {true, ui::DomKey::CHARACTER
, '|', ui::VKEY_OEM_5
}},
430 {ui::DomCode::SEMICOLON
,
431 {true, ui::DomKey::CHARACTER
, ';', ui::VKEY_OEM_1
},
432 {true, ui::DomKey::CHARACTER
, ':', ui::VKEY_OEM_1
}},
434 {true, ui::DomKey::CHARACTER
, '\'', ui::VKEY_OEM_7
},
435 {true, ui::DomKey::CHARACTER
, '"', ui::VKEY_OEM_7
}},
436 {ui::DomCode::BACKQUOTE
,
437 {true, ui::DomKey::CHARACTER
, '`', ui::VKEY_OEM_3
},
438 {true, ui::DomKey::CHARACTER
, '~', ui::VKEY_OEM_3
}},
440 {true, ui::DomKey::CHARACTER
, ',', ui::VKEY_OEM_COMMA
},
441 {true, ui::DomKey::CHARACTER
, '<', ui::VKEY_OEM_COMMA
}},
442 {ui::DomCode::PERIOD
,
443 {true, ui::DomKey::CHARACTER
, '.', ui::VKEY_OEM_PERIOD
},
444 {true, ui::DomKey::CHARACTER
, '>', ui::VKEY_OEM_PERIOD
}},
446 {true, ui::DomKey::CHARACTER
, '/', ui::VKEY_OEM_2
},
447 {true, ui::DomKey::CHARACTER
, '?', ui::VKEY_OEM_2
}},
448 {ui::DomCode::INTL_BACKSLASH
,
449 {true, ui::DomKey::CHARACTER
, '<', ui::VKEY_OEM_102
},
450 {true, ui::DomKey::CHARACTER
, '>', ui::VKEY_OEM_102
}},
451 {ui::DomCode::INTL_YEN
,
452 {true, ui::DomKey::CHARACTER
, 0x00A5, ui::VKEY_OEM_5
},
453 {true, ui::DomKey::CHARACTER
, '|', ui::VKEY_OEM_5
}},
454 {ui::DomCode::NUMPAD_DIVIDE
,
455 {true, ui::DomKey::CHARACTER
, '/', ui::VKEY_DIVIDE
},
456 {true, ui::DomKey::CHARACTER
, '/', ui::VKEY_DIVIDE
}},
457 {ui::DomCode::NUMPAD_MULTIPLY
,
458 {true, ui::DomKey::CHARACTER
, '*', ui::VKEY_MULTIPLY
},
459 {true, ui::DomKey::CHARACTER
, '*', ui::VKEY_MULTIPLY
}},
460 {ui::DomCode::NUMPAD_SUBTRACT
,
461 {true, ui::DomKey::CHARACTER
, '-', ui::VKEY_SUBTRACT
},
462 {true, ui::DomKey::CHARACTER
, '-', ui::VKEY_SUBTRACT
}},
463 {ui::DomCode::NUMPAD_ADD
,
464 {true, ui::DomKey::CHARACTER
, '+', ui::VKEY_ADD
},
465 {true, ui::DomKey::CHARACTER
, '+', ui::VKEY_ADD
}},
466 {ui::DomCode::NUMPAD1
,
467 {true, ui::DomKey::CHARACTER
, '1', ui::VKEY_1
},
468 {true, ui::DomKey::CHARACTER
, '1', ui::VKEY_1
}},
469 {ui::DomCode::NUMPAD2
,
470 {true, ui::DomKey::CHARACTER
, '2', ui::VKEY_2
},
471 {true, ui::DomKey::CHARACTER
, '2', ui::VKEY_2
}},
472 {ui::DomCode::NUMPAD3
,
473 {true, ui::DomKey::CHARACTER
, '3', ui::VKEY_3
},
474 {true, ui::DomKey::CHARACTER
, '3', ui::VKEY_3
}},
475 {ui::DomCode::NUMPAD4
,
476 {true, ui::DomKey::CHARACTER
, '4', ui::VKEY_4
},
477 {true, ui::DomKey::CHARACTER
, '4', ui::VKEY_4
}},
478 {ui::DomCode::NUMPAD5
,
479 {true, ui::DomKey::CHARACTER
, '5', ui::VKEY_5
},
480 {true, ui::DomKey::CHARACTER
, '5', ui::VKEY_5
}},
481 {ui::DomCode::NUMPAD6
,
482 {true, ui::DomKey::CHARACTER
, '6', ui::VKEY_6
},
483 {true, ui::DomKey::CHARACTER
, '6', ui::VKEY_6
}},
484 {ui::DomCode::NUMPAD7
,
485 {true, ui::DomKey::CHARACTER
, '7', ui::VKEY_7
},
486 {true, ui::DomKey::CHARACTER
, '7', ui::VKEY_7
}},
487 {ui::DomCode::NUMPAD8
,
488 {true, ui::DomKey::CHARACTER
, '8', ui::VKEY_8
},
489 {true, ui::DomKey::CHARACTER
, '8', ui::VKEY_8
}},
490 {ui::DomCode::NUMPAD9
,
491 {true, ui::DomKey::CHARACTER
, '9', ui::VKEY_9
},
492 {true, ui::DomKey::CHARACTER
, '9', ui::VKEY_9
}},
493 {ui::DomCode::NUMPAD0
,
494 {true, ui::DomKey::CHARACTER
, '0', ui::VKEY_0
},
495 {true, ui::DomKey::CHARACTER
, '0', ui::VKEY_0
}},
496 {ui::DomCode::NUMPAD_DECIMAL
,
497 {true, ui::DomKey::CHARACTER
, '.', ui::VKEY_DECIMAL
},
498 {true, ui::DomKey::CHARACTER
, '.', ui::VKEY_DECIMAL
}},
499 {ui::DomCode::NUMPAD_EQUAL
,
500 {true, ui::DomKey::CHARACTER
, '=', ui::VKEY_UNKNOWN
},
501 {true, ui::DomKey::CHARACTER
, '=', ui::VKEY_UNKNOWN
}},
502 {ui::DomCode::NUMPAD_COMMA
,
503 {true, ui::DomKey::CHARACTER
, ',', ui::VKEY_OEM_COMMA
},
504 {true, ui::DomKey::CHARACTER
, ',', ui::VKEY_OEM_COMMA
}},
505 {ui::DomCode::NUMPAD_PAREN_LEFT
,
506 {true, ui::DomKey::CHARACTER
, '(', ui::VKEY_UNKNOWN
},
507 {true, ui::DomKey::CHARACTER
, '(', ui::VKEY_UNKNOWN
}},
508 {ui::DomCode::NUMPAD_PAREN_RIGHT
,
509 {true, ui::DomKey::CHARACTER
, ')', ui::VKEY_UNKNOWN
},
510 {true, ui::DomKey::CHARACTER
, ')', ui::VKEY_UNKNOWN
}},
511 {ui::DomCode::NUMPAD_SIGN_CHANGE
,
512 {true, ui::DomKey::CHARACTER
, 0xB1, ui::VKEY_UNKNOWN
},
513 {true, ui::DomKey::CHARACTER
, 0xB1, ui::VKEY_UNKNOWN
}},
516 for (const auto& it
: kPrintableUsLayout
) {
517 CheckDomCodeToMeaning("p_us_n", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
518 ui::EF_NONE
, it
.normal
);
519 CheckDomCodeToMeaning("p_us_s", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
520 ui::EF_SHIFT_DOWN
, it
.shift
);
521 CheckDomCodeToMeaning("p_us_a", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
522 ui::EF_ALTGR_DOWN
, it
.normal
);
523 CheckDomCodeToMeaning("p_us_a", ui::DomCodeToUsLayoutMeaning
, it
.dom_code
,
524 ui::EF_ALTGR_DOWN
|ui::EF_SHIFT_DOWN
, it
.shift
);
528 TEST(KeyboardCodeConversion
, Tables
) {
529 // Verify that kDomCodeToKeyboardCodeMap is ordered by DomCode value.
530 uint32_t previous
= 0;
531 for (const auto& it
: ui::kDomCodeToKeyboardCodeMap
) {
532 uint32_t current
= static_cast<uint32_t>(it
.dom_code
);
533 EXPECT_LT(previous
, current
);