OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/keycodes/keyboard_code_conversion.h" | 5 #include "ui/events/keycodes/keyboard_code_conversion.h" |
6 | 6 |
7 #include "ui/events/event_constants.h" | 7 #include "ui/events/event_constants.h" |
8 #include "ui/events/keycodes/dom3/dom_key.h" | |
8 | 9 |
9 namespace ui { | 10 namespace ui { |
10 | 11 |
11 uint16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags) { | 12 base::char16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags) { |
13 ui::DomKey dom_key; | |
14 base::char16 character; | |
15 if (GetMeaningFromKeyCode(key_code, flags, &dom_key, &character)) | |
16 return character; | |
17 return 0; | |
18 } | |
19 | |
20 EVENTS_BASE_EXPORT bool GetMeaningFromKeyCode(KeyboardCode key_code, | |
21 int flags, | |
22 DomKey* dom_key, | |
23 base::char16* character) { | |
12 const bool ctrl = (flags & EF_CONTROL_DOWN) != 0; | 24 const bool ctrl = (flags & EF_CONTROL_DOWN) != 0; |
13 const bool shift = (flags & EF_SHIFT_DOWN) != 0; | 25 const bool shift = (flags & EF_SHIFT_DOWN) != 0; |
14 const bool upper = shift ^ ((flags & EF_CAPS_LOCK_DOWN) != 0); | 26 const bool upper = shift ^ ((flags & EF_CAPS_LOCK_DOWN) != 0); |
15 | 27 |
16 // Following Windows behavior to map ctrl-a ~ ctrl-z to \x01 ~ \x1A. | 28 // Control characters. |
17 if (key_code >= VKEY_A && key_code <= VKEY_Z) { | |
18 return static_cast<uint16> | |
19 (key_code - VKEY_A + (ctrl ? 1 : (upper ? 'A' : 'a'))); | |
20 } | |
21 | |
22 // Other ctrl characters | |
23 if (ctrl) { | 29 if (ctrl) { |
30 // Following Windows behavior to map ctrl-a ~ ctrl-z to \x01 ~ \x1A. | |
31 if (key_code >= VKEY_A && key_code <= VKEY_Z) { | |
32 *character = static_cast<uint16>(key_code - VKEY_A + 1); | |
33 switch (key_code) { | |
34 case VKEY_H: | |
35 *dom_key = DomKey::BACKSPACE; | |
36 break; | |
37 case VKEY_I: | |
38 *dom_key = DomKey::TAB; | |
39 break; | |
40 case VKEY_J: | |
41 case VKEY_M: | |
42 *dom_key = DomKey::ENTER; | |
43 break; | |
44 default: | |
45 *dom_key = DomKey::CHARACTER; | |
46 break; | |
47 } | |
48 return true; | |
49 } | |
50 // Other ctrl characters | |
24 if (shift) { | 51 if (shift) { |
25 // following graphics chars require shift key to input. | 52 // following graphics chars require shift key to input. |
26 switch (key_code) { | 53 switch (key_code) { |
27 // ctrl-@ maps to \x00 (Null byte) | 54 // ctrl-@ maps to \x00 (Null byte) |
28 case VKEY_2: | 55 case VKEY_2: |
29 return 0; | 56 *dom_key = DomKey::CHARACTER; |
57 *character = 0; | |
58 return true; | |
30 // ctrl-^ maps to \x1E (Record separator, Information separator two) | 59 // ctrl-^ maps to \x1E (Record separator, Information separator two) |
31 case VKEY_6: | 60 case VKEY_6: |
32 return 0x1E; | 61 *dom_key = DomKey::CHARACTER; |
62 *character = 0x1E; | |
63 return true; | |
33 // ctrl-_ maps to \x1F (Unit separator, Information separator one) | 64 // ctrl-_ maps to \x1F (Unit separator, Information separator one) |
34 case VKEY_OEM_MINUS: | 65 case VKEY_OEM_MINUS: |
35 return 0x1F; | 66 *dom_key = DomKey::CHARACTER; |
67 *character = 0x1F; | |
68 return true; | |
36 // Returns 0 for all other keys to avoid inputting unexpected chars. | 69 // Returns 0 for all other keys to avoid inputting unexpected chars. |
37 default: | 70 default: |
38 return 0; | 71 *dom_key = DomKey::UNIDENTIFIED; |
72 *character = 0; | |
73 return false; | |
39 } | 74 } |
40 } else { | 75 } else { |
41 switch (key_code) { | 76 switch (key_code) { |
42 // ctrl-[ maps to \x1B (Escape) | 77 // ctrl-[ maps to \x1B (Escape) |
43 case VKEY_OEM_4: | 78 case VKEY_OEM_4: |
44 return 0x1B; | 79 *dom_key = DomKey::ESCAPE; |
80 *character = 0x1B; | |
81 return true; | |
45 // ctrl-\ maps to \x1C (File separator, Information separator four) | 82 // ctrl-\ maps to \x1C (File separator, Information separator four) |
46 case VKEY_OEM_5: | 83 case VKEY_OEM_5: |
47 return 0x1C; | 84 *dom_key = DomKey::CHARACTER; |
85 *character = 0x1C; | |
86 return true; | |
48 // ctrl-] maps to \x1D (Group separator, Information separator three) | 87 // ctrl-] maps to \x1D (Group separator, Information separator three) |
49 case VKEY_OEM_6: | 88 case VKEY_OEM_6: |
50 return 0x1D; | 89 *dom_key = DomKey::CHARACTER; |
90 *character = 0x1D; | |
91 return true; | |
51 // ctrl-Enter maps to \x0A (Line feed) | 92 // ctrl-Enter maps to \x0A (Line feed) |
52 case VKEY_RETURN: | 93 case VKEY_RETURN: |
53 return 0x0A; | 94 *dom_key = DomKey::CHARACTER; |
95 *character = 0x0A; | |
96 return true; | |
54 // Returns 0 for all other keys to avoid inputting unexpected chars. | 97 // Returns 0 for all other keys to avoid inputting unexpected chars. |
55 default: | 98 default: |
56 return 0; | 99 *dom_key = DomKey::UNIDENTIFIED; |
100 *character = 0; | |
101 return false; | |
57 } | 102 } |
58 } | 103 } |
59 } | 104 } |
60 | 105 |
61 // For IME support. | |
62 if (key_code == ui::VKEY_PROCESSKEY) | |
63 return 0xE5; | |
64 | |
65 // Normal characters | 106 // Normal characters |
107 if (key_code >= VKEY_A && key_code <= VKEY_Z) { | |
108 *dom_key = DomKey::CHARACTER; | |
109 *character = static_cast<uint16>(key_code - VKEY_A + (upper ? 'A' : 'a')); | |
110 return true; | |
111 } | |
66 if (key_code >= VKEY_0 && key_code <= VKEY_9) { | 112 if (key_code >= VKEY_0 && key_code <= VKEY_9) { |
67 return shift ? ")!@#$%^&*("[key_code - VKEY_0] : | 113 *dom_key = DomKey::CHARACTER; |
68 static_cast<uint16>(key_code); | 114 *character = |
69 } else if (key_code >= VKEY_NUMPAD0 && key_code <= VKEY_NUMPAD9) { | 115 shift ? ")!@#$%^&*("[key_code - VKEY_0] : static_cast<uint16>(key_code); |
70 return static_cast<uint16>(key_code - VKEY_NUMPAD0 + '0'); | 116 return true; |
71 } | 117 } |
72 | 118 if (key_code >= VKEY_NUMPAD0 && key_code <= VKEY_NUMPAD9) { |
119 *dom_key = DomKey::CHARACTER; | |
120 *character = static_cast<uint16>(key_code - VKEY_NUMPAD0 + '0'); | |
121 return true; | |
122 } | |
123 | |
124 // Function keys | |
125 if (key_code >= VKEY_F1 && key_code <= VKEY_F24) { | |
126 *dom_key = | |
127 static_cast<DomKey>(key_code - VKEY_F1 + static_cast<int>(DomKey::F1)); | |
128 *character = 0; | |
129 return true; | |
130 } | |
131 | |
132 // Isolated characters. | |
133 *dom_key = DomKey::CHARACTER; | |
134 *character = 0; | |
73 switch (key_code) { | 135 switch (key_code) { |
Wez
2014/12/09 07:00:33
The switches in these functions feels like they'd
kpschoedel
2014/12/09 19:58:43
OK. I agree tables are generally clearer. (Histori
| |
136 case VKEY_BACK: | |
137 *dom_key = DomKey::BACKSPACE; | |
138 *character = '\b'; | |
139 return true; | |
74 case VKEY_TAB: | 140 case VKEY_TAB: |
75 return '\t'; | 141 *dom_key = DomKey::TAB; |
142 *character = '\t'; | |
143 return true; | |
76 case VKEY_RETURN: | 144 case VKEY_RETURN: |
77 return '\r'; | 145 *dom_key = DomKey::ENTER; |
146 *character = '\r'; | |
147 return true; | |
148 case VKEY_ESCAPE: | |
149 *dom_key = DomKey::ESCAPE; | |
150 *character = 0x1B; | |
151 return true; | |
152 case VKEY_SPACE: | |
153 *character = ' '; | |
154 return true; | |
78 case VKEY_MULTIPLY: | 155 case VKEY_MULTIPLY: |
79 return '*'; | 156 *character = '*'; |
157 return true; | |
80 case VKEY_ADD: | 158 case VKEY_ADD: |
81 return '+'; | 159 *character = '+'; |
160 return true; | |
161 case VKEY_SEPARATOR: | |
162 *character = ','; | |
163 return true; | |
82 case VKEY_SUBTRACT: | 164 case VKEY_SUBTRACT: |
83 return '-'; | 165 *character = '-'; |
166 return true; | |
84 case VKEY_DECIMAL: | 167 case VKEY_DECIMAL: |
85 return '.'; | 168 *character = '.'; |
169 return true; | |
86 case VKEY_DIVIDE: | 170 case VKEY_DIVIDE: |
87 return '/'; | 171 *character = '/'; |
88 case VKEY_SPACE: | 172 return true; |
89 return ' '; | |
90 case VKEY_OEM_1: | 173 case VKEY_OEM_1: |
91 return shift ? ':' : ';'; | 174 *character = shift ? ':' : ';'; |
175 return true; | |
92 case VKEY_OEM_PLUS: | 176 case VKEY_OEM_PLUS: |
93 return shift ? '+' : '='; | 177 *character = shift ? '+' : '='; |
178 return true; | |
94 case VKEY_OEM_COMMA: | 179 case VKEY_OEM_COMMA: |
95 return shift ? '<' : ','; | 180 *character = shift ? '<' : ','; |
181 return true; | |
96 case VKEY_OEM_MINUS: | 182 case VKEY_OEM_MINUS: |
97 return shift ? '_' : '-'; | 183 *character = shift ? '_' : '-'; |
184 return true; | |
98 case VKEY_OEM_PERIOD: | 185 case VKEY_OEM_PERIOD: |
99 return shift ? '>' : '.'; | 186 *character = shift ? '>' : '.'; |
187 return true; | |
100 case VKEY_OEM_2: | 188 case VKEY_OEM_2: |
101 return shift ? '?' : '/'; | 189 *character = shift ? '?' : '/'; |
190 return true; | |
102 case VKEY_OEM_3: | 191 case VKEY_OEM_3: |
103 return shift ? '~' : '`'; | 192 *character = shift ? '~' : '`'; |
193 return true; | |
104 case VKEY_OEM_4: | 194 case VKEY_OEM_4: |
105 return shift ? '{' : '['; | 195 *character = shift ? '{' : '['; |
196 return true; | |
106 case VKEY_OEM_5: | 197 case VKEY_OEM_5: |
107 return shift ? '|' : '\\'; | 198 *character = shift ? '|' : '\\'; |
199 return true; | |
108 case VKEY_OEM_6: | 200 case VKEY_OEM_6: |
109 return shift ? '}' : ']'; | 201 *character = shift ? '}' : ']'; |
202 return true; | |
110 case VKEY_OEM_7: | 203 case VKEY_OEM_7: |
111 return shift ? '"' : '\''; | 204 *character = shift ? '"' : '\''; |
205 return true; | |
206 case VKEY_OEM_102: | |
207 *character = shift ? '>' : '<'; | |
208 return true; | |
209 case VKEY_CLEAR: | |
210 *dom_key = DomKey::CLEAR; | |
211 return true; | |
212 case VKEY_SHIFT: | |
213 *dom_key = DomKey::SHIFT; | |
214 return true; | |
215 case VKEY_CONTROL: | |
216 *dom_key = DomKey::CONTROL; | |
217 return true; | |
218 case VKEY_MENU: | |
219 *dom_key = DomKey::ALT; | |
220 return true; | |
221 case VKEY_PAUSE: | |
222 *dom_key = DomKey::PAUSE; | |
223 return true; | |
224 case VKEY_CAPITAL: | |
225 *dom_key = DomKey::CAPS_LOCK; | |
226 return true; | |
227 case VKEY_KANA: | |
228 // Windows conflates 'KanaMode' and 'HangulMode' | |
229 *dom_key = DomKey::KANA_MODE; | |
230 return true; | |
231 case VKEY_JUNJA: | |
232 *dom_key = DomKey::JUNJA_MODE; | |
233 return true; | |
234 case VKEY_FINAL: | |
235 *dom_key = DomKey::FINAL_MODE; | |
236 return true; | |
237 case VKEY_HANJA: | |
238 // Windows conflates 'HanjaMode' and 'KanjiMode' | |
239 *dom_key = DomKey::HANJA_MODE; | |
240 return true; | |
241 case VKEY_CONVERT: | |
242 *dom_key = DomKey::CONVERT; | |
243 return true; | |
244 case VKEY_NONCONVERT: | |
245 *dom_key = DomKey::NON_CONVERT; | |
246 return true; | |
247 case VKEY_ACCEPT: | |
248 *dom_key = DomKey::ACCEPT; | |
249 return true; | |
250 case VKEY_MODECHANGE: | |
251 *dom_key = DomKey::MODE_CHANGE; | |
252 return true; | |
253 case VKEY_PRIOR: | |
254 *dom_key = DomKey::PAGE_UP; | |
255 return true; | |
256 case VKEY_NEXT: | |
257 *dom_key = DomKey::PAGE_DOWN; | |
258 return true; | |
259 case VKEY_END: | |
260 *dom_key = DomKey::END; | |
261 return true; | |
262 case VKEY_HOME: | |
263 *dom_key = DomKey::HOME; | |
264 return true; | |
265 case VKEY_LEFT: | |
266 *dom_key = DomKey::ARROW_LEFT; | |
267 return true; | |
268 case VKEY_UP: | |
269 *dom_key = DomKey::ARROW_UP; | |
270 return true; | |
271 case VKEY_RIGHT: | |
272 *dom_key = DomKey::ARROW_RIGHT; | |
273 return true; | |
274 case VKEY_DOWN: | |
275 *dom_key = DomKey::ARROW_DOWN; | |
276 return true; | |
277 case VKEY_SELECT: | |
278 *dom_key = DomKey::SELECT; | |
279 return true; | |
280 case VKEY_PRINT: | |
281 *dom_key = DomKey::PRINT; | |
282 return true; | |
283 case VKEY_EXECUTE: | |
284 *dom_key = DomKey::EXECUTE; | |
285 return true; | |
286 case VKEY_SNAPSHOT: | |
287 *dom_key = DomKey::PRINT_SCREEN; | |
288 return true; | |
289 case VKEY_INSERT: | |
290 *dom_key = DomKey::INSERT; | |
291 return true; | |
292 case VKEY_DELETE: | |
293 *dom_key = DomKey::DEL; | |
294 return true; | |
295 case VKEY_HELP: | |
296 *dom_key = DomKey::HELP; | |
297 return true; | |
298 case VKEY_LWIN: | |
299 case VKEY_RWIN: | |
300 *dom_key = DomKey::OS; | |
301 return true; | |
302 case VKEY_APPS: | |
303 *dom_key = DomKey::MEDIA_APPS; | |
304 return true; | |
305 case VKEY_NUMLOCK: | |
306 *dom_key = DomKey::NUM_LOCK; | |
307 return true; | |
308 case VKEY_SCROLL: | |
309 *dom_key = DomKey::SCROLL_LOCK; | |
310 return true; | |
311 case VKEY_LSHIFT: | |
312 case VKEY_RSHIFT: | |
313 *dom_key = DomKey::SHIFT; | |
314 return true; | |
315 case VKEY_LCONTROL: | |
316 case VKEY_RCONTROL: | |
317 *dom_key = DomKey::CONTROL; | |
318 return true; | |
319 case VKEY_LMENU: | |
320 case VKEY_RMENU: | |
321 *dom_key = DomKey::ALT; | |
322 return true; | |
323 case VKEY_BROWSER_BACK: | |
324 *dom_key = DomKey::BROWSER_BACK; | |
325 return true; | |
326 case VKEY_BROWSER_FORWARD: | |
327 *dom_key = DomKey::BROWSER_FORWARD; | |
328 return true; | |
329 case VKEY_BROWSER_REFRESH: | |
330 *dom_key = DomKey::BROWSER_REFRESH; | |
331 return true; | |
332 case VKEY_BROWSER_STOP: | |
333 *dom_key = DomKey::BROWSER_STOP; | |
334 return true; | |
335 case VKEY_BROWSER_SEARCH: | |
336 *dom_key = DomKey::BROWSER_SEARCH; | |
337 return true; | |
338 case VKEY_BROWSER_FAVORITES: | |
339 *dom_key = DomKey::BROWSER_FAVORITES; | |
340 return true; | |
341 case VKEY_BROWSER_HOME: | |
342 *dom_key = DomKey::BROWSER_HOME; | |
343 return true; | |
344 case VKEY_VOLUME_MUTE: | |
345 *dom_key = DomKey::VOLUME_MUTE; | |
346 return true; | |
347 case VKEY_VOLUME_DOWN: | |
348 *dom_key = DomKey::VOLUME_DOWN; | |
349 return true; | |
350 case VKEY_VOLUME_UP: | |
351 *dom_key = DomKey::VOLUME_UP; | |
352 return true; | |
353 case VKEY_MEDIA_NEXT_TRACK: | |
354 *dom_key = DomKey::MEDIA_TRACK_NEXT; | |
355 return true; | |
356 case VKEY_MEDIA_PREV_TRACK: | |
357 *dom_key = DomKey::MEDIA_TRACK_PREVIOUS; | |
358 return true; | |
359 case VKEY_MEDIA_STOP: | |
360 *dom_key = DomKey::MEDIA_STOP; | |
361 return true; | |
362 case VKEY_MEDIA_PLAY_PAUSE: | |
363 *dom_key = DomKey::MEDIA_PLAY_PAUSE; | |
364 return true; | |
365 case VKEY_MEDIA_LAUNCH_MAIL: | |
366 *dom_key = DomKey::LAUNCH_MAIL; | |
367 return true; | |
368 case VKEY_MEDIA_LAUNCH_MEDIA_SELECT: | |
369 *dom_key = DomKey::LAUNCH_MEDIA_PLAYER; | |
370 return true; | |
371 case VKEY_MEDIA_LAUNCH_APP1: | |
372 *dom_key = DomKey::LAUNCH_MY_COMPUTER; | |
373 return true; | |
374 case VKEY_MEDIA_LAUNCH_APP2: | |
375 *dom_key = DomKey::LAUNCH_CALCULATOR; | |
376 return true; | |
377 case VKEY_OEM_8: | |
378 // ISO Level 5 Shift in ChromeOS | |
379 *dom_key = DomKey::SUPER; | |
380 return true; | |
381 #if defined(OS_POSIX) | |
382 case VKEY_OEM_103: | |
383 *dom_key = DomKey::MEDIA_REWIND; | |
384 return true; | |
385 case VKEY_OEM_104: | |
386 *dom_key = DomKey::MEDIA_FAST_FORWARD; | |
387 return true; | |
388 #endif | |
389 case VKEY_PROCESSKEY: | |
390 *dom_key = DomKey::PROCESS; | |
391 return true; | |
392 case VKEY_DBE_SBCSCHAR: | |
393 *dom_key = DomKey::HANKAKU; | |
394 return true; | |
395 case VKEY_DBE_DBCSCHAR: | |
396 *dom_key = DomKey::ZENKAKU; | |
397 return true; | |
398 case VKEY_ATTN: | |
399 *dom_key = DomKey::ATTN; | |
400 return true; | |
401 case VKEY_CRSEL: | |
402 *dom_key = DomKey::CR_SEL; | |
403 return true; | |
404 case VKEY_EXSEL: | |
405 *dom_key = DomKey::EX_SEL; | |
406 return true; | |
407 case VKEY_EREOF: | |
408 *dom_key = DomKey::ERASE_EOF; | |
409 return true; | |
410 case VKEY_PLAY: | |
411 *dom_key = DomKey::MEDIA_PLAY; | |
412 return true; | |
413 case VKEY_ZOOM: | |
414 *dom_key = DomKey::ZOOM_TOGGLE; | |
415 return true; | |
416 case VKEY_OEM_CLEAR: | |
417 *dom_key = DomKey::CLEAR; | |
418 return true; | |
419 #if defined(OS_POSIX) | |
420 case VKEY_POWER: | |
421 *dom_key = DomKey::POWER; | |
422 return true; | |
423 case VKEY_BRIGHTNESS_DOWN: | |
424 *dom_key = DomKey::BRIGHTNESS_DOWN; | |
425 return true; | |
426 case VKEY_BRIGHTNESS_UP: | |
427 *dom_key = DomKey::BRIGHTNESS_UP; | |
428 return true; | |
429 #endif | |
430 case VKEY_ALTGR: | |
431 *dom_key = DomKey::ALT_GRAPH; | |
432 return true; | |
433 #if defined(OS_POSIX) | |
434 case VKEY_COMPOSE: | |
435 *dom_key = DomKey::COMPOSE; | |
436 return true; | |
437 #endif | |
438 // case VKEY_BACKTAB: | |
439 // case VKEY_SLEEP: | |
440 // case VKEY_PACKET: | |
441 // case VKEY_NONAME: | |
442 // case VKEY_PA1: | |
443 // case VKEY_WLAN: // Toggle wifi in ChromeOS | |
444 // case VKEY_KBD_BRIGHTNESS_DOWN: | |
445 // case VKEY_KBD_BRIGHTNESS_UP: | |
112 default: | 446 default: |
113 return 0; | 447 *dom_key = DomKey::UNIDENTIFIED; |
448 return false; | |
114 } | 449 } |
115 } | 450 } |
116 | 451 |
117 } // namespace ui | 452 } // namespace ui |
OLD | NEW |