OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/base/events/key_identifier_conversion.h" | |
6 | |
7 #include <string.h> | |
8 #include <utility> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/containers/hash_tables.h" | |
12 #include "ui/base/events/event.h" | |
13 #include "ui/base/keycodes/keyboard_codes.h" | |
14 | |
15 namespace { | |
16 | |
17 const int kNumIdentifierTypes = 3; | |
18 | |
19 typedef struct KeyIdentifier { | |
20 // In order: key identifier, character and unicode codepoint. They are | |
21 // searched in that order as well. | |
22 // These are all placed into a single array as they are treated uniformly and | |
23 // we never refer to a specific type of identifier. This reduces code | |
24 // duplication below. | |
25 const char* identifiers[kNumIdentifierTypes]; | |
26 const ui::KeyboardCode key_code; | |
27 const int event_flags; | |
28 } KeyIdentifier; | |
29 | |
30 // Taken from Section 6.3.3 here: | |
31 // http://www.w3.org/TR/DOM-Level-3-Events/#keyset-keyidentifiers | |
32 // WARNING: keycodes could be wrong, as they are based soley on keydown | |
33 const KeyIdentifier kKeyIdentifiers[] = { | |
34 { {"Accept", "", ""}, ui::VKEY_ACCEPT, 0 }, | |
35 { {"Add", "", ""}, ui::VKEY_ADD, 0 }, | |
36 { {"Again", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
37 { {"AllCandidates", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
38 { {"Alphanumeric", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
39 { {"Alt", "", ""}, ui::VKEY_MENU, 0 }, | |
40 { {"AltGraph", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
41 { {"Apps", "", ""}, ui::VKEY_APPS, 0 }, | |
42 { {"Attn", "", ""}, ui::VKEY_ATTN, 0 }, | |
43 { {"BrowserBack", "", ""}, ui::VKEY_BROWSER_BACK, 0 }, | |
44 { {"BrowserFavorites", "", ""}, ui::VKEY_BROWSER_FAVORITES, 0 }, | |
45 { {"BrowserForward", "", ""}, ui::VKEY_BROWSER_FORWARD, 0 }, | |
46 { {"BrowserHome", "", ""}, ui::VKEY_BROWSER_HOME, 0 }, | |
47 { {"BrowserRefresh", "", ""}, ui::VKEY_BROWSER_REFRESH, 0 }, | |
48 { {"BrowserSearch", "", ""}, ui::VKEY_BROWSER_SEARCH, 0 }, | |
49 { {"BrowserStop", "", ""}, ui::VKEY_BROWSER_STOP, 0 }, | |
50 { {"CapsLock", "", ""}, ui::VKEY_CAPITAL, 0 }, | |
51 { {"Clear", "", ""}, ui::VKEY_OEM_CLEAR, 0 }, | |
52 { {"CodeInput", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
53 { {"Compose", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
54 { {"Control", "", ""}, ui::VKEY_CONTROL, 0 }, | |
55 { {"Crsel", "", ""}, ui::VKEY_CRSEL, 0 }, | |
56 { {"Convert", "", ""}, ui::VKEY_CONVERT, 0 }, | |
57 { {"Copy", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
58 { {"Cut", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
59 { {"Decimal", "", ""}, ui::VKEY_DECIMAL, 0 }, | |
60 { {"Divide", "", ""}, ui::VKEY_DIVIDE, 0 }, | |
61 { {"Down", "", ""}, ui::VKEY_DOWN, 0 }, | |
62 { {"DownLeft", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
63 { {"DownRight", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
64 { {"End", "", ""}, ui::VKEY_END, 0 }, | |
65 { {"Enter", "", ""}, ui::VKEY_RETURN, 0 }, | |
66 { {"EraseEof", "", ""}, ui::VKEY_EREOF, 0 }, | |
67 { {"Execute", "", ""}, ui::VKEY_EXECUTE, 0 }, | |
68 { {"Exsel", "", ""}, ui::VKEY_EXSEL, 0 }, | |
69 { {"Fn", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
70 { {"F1", "", ""}, ui::VKEY_F1, 0 }, | |
71 { {"F2", "", ""}, ui::VKEY_F2, 0 }, | |
72 { {"F3", "", ""}, ui::VKEY_F3, 0 }, | |
73 { {"F4", "", ""}, ui::VKEY_F4, 0 }, | |
74 { {"F5", "", ""}, ui::VKEY_F5, 0 }, | |
75 { {"F6", "", ""}, ui::VKEY_F6, 0 }, | |
76 { {"F7", "", ""}, ui::VKEY_F7, 0 }, | |
77 { {"F8", "", ""}, ui::VKEY_F8, 0 }, | |
78 { {"F9", "", ""}, ui::VKEY_F9, 0 }, | |
79 { {"F10", "", ""}, ui::VKEY_F10, 0 }, | |
80 { {"F11", "", ""}, ui::VKEY_F11, 0 }, | |
81 { {"F12", "", ""}, ui::VKEY_F12, 0 }, | |
82 { {"F13", "", ""}, ui::VKEY_F13, 0 }, | |
83 { {"F14", "", ""}, ui::VKEY_F14, 0 }, | |
84 { {"F15", "", ""}, ui::VKEY_F15, 0 }, | |
85 { {"F16", "", ""}, ui::VKEY_F16, 0 }, | |
86 { {"F17", "", ""}, ui::VKEY_F17, 0 }, | |
87 { {"F18", "", ""}, ui::VKEY_F18, 0 }, | |
88 { {"F19", "", ""}, ui::VKEY_F19, 0 }, | |
89 { {"F20", "", ""}, ui::VKEY_F20, 0 }, | |
90 { {"F21", "", ""}, ui::VKEY_F21, 0 }, | |
91 { {"F22", "", ""}, ui::VKEY_F22, 0 }, | |
92 { {"F23", "", ""}, ui::VKEY_F23, 0 }, | |
93 { {"F24", "", ""}, ui::VKEY_F24, 0 }, | |
94 { {"FinalMode", "", ""}, ui::VKEY_FINAL, 0 }, | |
95 { {"Find", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
96 { {"FullWidth", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
97 { {"HalfWidth", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
98 { {"HangulMode", "", ""}, ui::VKEY_HANGUL, 0 }, | |
99 { {"HanjaMode", "", ""}, ui::VKEY_HANJA, 0 }, | |
100 { {"Help", "", ""}, ui::VKEY_HELP, 0 }, | |
101 { {"Hiragana", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
102 { {"Home", "", ""}, ui::VKEY_HOME, 0 }, | |
103 { {"Insert", "", ""}, ui::VKEY_INSERT, 0 }, | |
104 { {"JapaneseHiragana", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
105 { {"JapaneseKatakana", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
106 { {"JapaneseRomaji", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
107 { {"JunjaMode", "", ""}, ui::VKEY_JUNJA, 0 }, | |
108 { {"KanaMode", "", ""}, ui::VKEY_KANA, 0 }, | |
109 { {"KanjiMode", "", ""}, ui::VKEY_KANJI, 0 }, | |
110 { {"Katakana", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
111 { {"LaunchApplication1", "", ""}, ui::VKEY_MEDIA_LAUNCH_APP1, 0 }, | |
112 { {"LaunchApplication2", "", ""}, ui::VKEY_MEDIA_LAUNCH_APP2, 0 }, | |
113 { {"LaunchMail", "", ""}, ui::VKEY_MEDIA_LAUNCH_MAIL, 0 }, | |
114 { {"Left", "", ""}, ui::VKEY_LEFT, 0 }, | |
115 { {"Menu", "", ""}, ui::VKEY_MENU, 0 }, | |
116 { {"Meta", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
117 { {"MediaNextTrack", "", ""}, ui::VKEY_MEDIA_NEXT_TRACK, 0 }, | |
118 { {"MediaPlayPause", "", ""}, ui::VKEY_MEDIA_PLAY_PAUSE, 0 }, | |
119 { {"MediaPreviousTrack", "", ""}, ui::VKEY_MEDIA_PREV_TRACK, 0 }, | |
120 { {"MediaStop", "", ""}, ui::VKEY_MEDIA_STOP, 0 }, | |
121 { {"ModeChange", "", ""}, ui::VKEY_MODECHANGE, 0 }, | |
122 { {"Multiply", "", ""}, ui::VKEY_MULTIPLY, 0 }, | |
123 { {"NextCandidate", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
124 { {"Nonconvert", "", ""}, ui::VKEY_NONCONVERT, 0 }, | |
125 { {"NumLock", "", ""}, ui::VKEY_NUMLOCK, 0 }, | |
126 { {"PageDown", "", ""}, ui::VKEY_NEXT, 0 }, | |
127 { {"PageUp", "", ""}, ui::VKEY_PRIOR, 0 }, | |
128 { {"Paste", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
129 { {"Pause", "", ""}, ui::VKEY_PAUSE, 0 }, | |
130 { {"Play", "", ""}, ui::VKEY_PLAY, 0 }, | |
131 { {"PreviousCandidate", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
132 { {"PrintScreen", "", ""}, ui::VKEY_SNAPSHOT, 0 }, | |
133 { {"Process", "", ""}, ui::VKEY_PROCESSKEY, 0 }, | |
134 { {"Props", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
135 { {"Right", "", ""}, ui::VKEY_RIGHT, 0 }, | |
136 { {"RomanCharacters", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
137 { {"Scroll", "", ""}, ui::VKEY_SCROLL, 0 }, | |
138 { {"Select", "", ""}, ui::VKEY_SELECT, 0 }, | |
139 { {"SelectMedia", "", ""}, ui::VKEY_MEDIA_LAUNCH_MEDIA_SELECT, 0 }, | |
140 { {"Separator", "", ""}, ui::VKEY_SEPARATOR, 0 }, | |
141 { {"Shift", "", ""}, ui::VKEY_SHIFT, 0 }, | |
142 { {"Soft1", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
143 { {"Soft2", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
144 { {"Soft3", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
145 { {"Soft4", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
146 { {"Stop", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
147 { {"Subtract", "", ""}, ui::VKEY_SUBTRACT, 0 }, | |
148 { {"Up", "", ""}, ui::VKEY_UP, 0 }, | |
149 { {"UpLeft", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
150 { {"UpRight", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
151 { {"Undo", "", ""}, ui::VKEY_UNKNOWN, 0 }, | |
152 { {"VolumeDown", "", ""}, ui::VKEY_VOLUME_DOWN, 0 }, | |
153 { {"VolumeMute", "", ""}, ui::VKEY_VOLUME_MUTE, 0 }, | |
154 { {"VolumeUp", "", ""}, ui::VKEY_VOLUME_UP, 0 }, | |
155 { {"Win", "", ""}, ui::VKEY_LWIN, 0 }, | |
156 { {"Zoom", "", ""}, ui::VKEY_ZOOM, 0 }, | |
157 { {"Backspace", "", "U+0008"}, ui::VKEY_BACK, 0 }, | |
158 { {"Tab", "", "U+0009"}, ui::VKEY_TAB, 0 }, | |
159 { {"Cancel", "", "U+0018"}, ui::VKEY_UNKNOWN, 0 }, | |
160 { {"Esc", "", "U+001B"}, ui::VKEY_ESCAPE, 0 }, | |
161 { {"Spacebar", " ", "U+0020"}, ui::VKEY_SPACE, 0 }, | |
162 { {"Exclamation", "!", "U+0021"}, ui::VKEY_1, ui::EF_SHIFT_DOWN }, | |
163 { {"DoubleQuote", "\"", "U+0022"}, | |
164 ui::VKEY_OEM_7, ui::EF_SHIFT_DOWN }, | |
165 { {"Hash", "#", "U+0023"}, ui::VKEY_3, ui::EF_SHIFT_DOWN }, | |
166 { {"Dollar", "$", "U+0024"}, ui::VKEY_4, ui::EF_SHIFT_DOWN }, | |
167 { {"Ampersand", "&", "U+0026"}, ui::VKEY_7, ui::EF_SHIFT_DOWN }, | |
168 { {"Apostrophe", "\'", "U+0027"}, ui::VKEY_OEM_7, 0 }, | |
169 { {"LeftParen", "(", "U+0028"}, ui::VKEY_9, ui::EF_SHIFT_DOWN }, | |
170 { {"RightParen", ")", "U+0029"}, ui::VKEY_0, ui::EF_SHIFT_DOWN }, | |
171 { {"Asterisk", "*", "U+002A"}, ui::VKEY_8, ui::EF_SHIFT_DOWN }, | |
172 { {"Plus", "+", "U+002B"}, ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN }, | |
173 { {"Percent", "%", "U+0025"}, ui::VKEY_5, ui::EF_SHIFT_DOWN }, | |
174 { {"Comma", ",", "U+002C"}, ui::VKEY_OEM_COMMA, 0 }, | |
175 { {"HyphenMinus", "-", "U+002D"}, ui::VKEY_OEM_MINUS, 0 }, | |
176 { {"Period", ".", "U+002E"}, ui::VKEY_OEM_PERIOD, 0 }, | |
177 { {"Solidus", "/", "U+002F"}, ui::VKEY_OEM_2, 0 }, | |
178 { {"", "0", "U+0030"}, ui::VKEY_0, 0 }, | |
179 { {"", "1", "U+0031"}, ui::VKEY_1, 0 }, | |
180 { {"", "2", "U+0032"}, ui::VKEY_2, 0 }, | |
181 { {"", "3", "U+0033"}, ui::VKEY_3, 0 }, | |
182 { {"", "4", "U+0034"}, ui::VKEY_4, 0 }, | |
183 { {"", "5", "U+0035"}, ui::VKEY_5, 0 }, | |
184 { {"", "6", "U+0036"}, ui::VKEY_6, 0 }, | |
185 { {"", "7", "U+0037"}, ui::VKEY_7, 0 }, | |
186 { {"", "8", "U+0038"}, ui::VKEY_8, 0 }, | |
187 { {"", "9", "U+0039"}, ui::VKEY_9, 0 }, | |
188 { {"Colon", ":", "U+003A"}, ui::VKEY_OEM_1, ui::EF_SHIFT_DOWN }, | |
189 { {"Semicolon", ";", "U+003B"}, ui::VKEY_OEM_1, 0 }, | |
190 { {"LessThan", "<", "U+003C"}, | |
191 ui::VKEY_OEM_COMMA, ui::EF_SHIFT_DOWN }, | |
192 { {"Equals", "=", "U+003D"}, ui::VKEY_OEM_PLUS, 0 }, | |
193 { {"GreaterThan", ">", "U+003E"}, | |
194 ui::VKEY_OEM_PERIOD, ui::EF_SHIFT_DOWN }, | |
195 { {"QuestionMark", "?", "U+003F"}, | |
196 ui::VKEY_OEM_2, ui::EF_SHIFT_DOWN }, | |
197 { {"At", "@", "U+0040"}, ui::VKEY_2, ui::EF_SHIFT_DOWN }, | |
198 { {"", "A", "U+0041"}, ui::VKEY_A, ui::EF_SHIFT_DOWN }, | |
199 { {"", "B", "U+0042"}, ui::VKEY_B, ui::EF_SHIFT_DOWN }, | |
200 { {"", "C", "U+0043"}, ui::VKEY_C, ui::EF_SHIFT_DOWN }, | |
201 { {"", "D", "U+0044"}, ui::VKEY_D, ui::EF_SHIFT_DOWN }, | |
202 { {"", "E", "U+0045"}, ui::VKEY_E, ui::EF_SHIFT_DOWN }, | |
203 { {"", "F", "U+0046"}, ui::VKEY_F, ui::EF_SHIFT_DOWN }, | |
204 { {"", "G", "U+0047"}, ui::VKEY_G, ui::EF_SHIFT_DOWN }, | |
205 { {"", "H", "U+0048"}, ui::VKEY_H, ui::EF_SHIFT_DOWN }, | |
206 { {"", "I", "U+0049"}, ui::VKEY_I, ui::EF_SHIFT_DOWN }, | |
207 { {"", "J", "U+004A"}, ui::VKEY_J, ui::EF_SHIFT_DOWN }, | |
208 { {"", "K", "U+004B"}, ui::VKEY_K, ui::EF_SHIFT_DOWN }, | |
209 { {"", "L", "U+004C"}, ui::VKEY_L, ui::EF_SHIFT_DOWN }, | |
210 { {"", "M", "U+004D"}, ui::VKEY_M, ui::EF_SHIFT_DOWN }, | |
211 { {"", "N", "U+004E"}, ui::VKEY_N, ui::EF_SHIFT_DOWN }, | |
212 { {"", "O", "U+004F"}, ui::VKEY_O, ui::EF_SHIFT_DOWN }, | |
213 { {"", "P", "U+0050"}, ui::VKEY_P, ui::EF_SHIFT_DOWN }, | |
214 { {"", "Q", "U+0051"}, ui::VKEY_Q, ui::EF_SHIFT_DOWN }, | |
215 { {"", "R", "U+0052"}, ui::VKEY_R, ui::EF_SHIFT_DOWN }, | |
216 { {"", "S", "U+0053"}, ui::VKEY_S, ui::EF_SHIFT_DOWN }, | |
217 { {"", "T", "U+0054"}, ui::VKEY_T, ui::EF_SHIFT_DOWN }, | |
218 { {"", "U", "U+0055"}, ui::VKEY_U, ui::EF_SHIFT_DOWN }, | |
219 { {"", "V", "U+0056"}, ui::VKEY_V, ui::EF_SHIFT_DOWN }, | |
220 { {"", "W", "U+0057"}, ui::VKEY_W, ui::EF_SHIFT_DOWN }, | |
221 { {"", "X", "U+0058"}, ui::VKEY_X, ui::EF_SHIFT_DOWN }, | |
222 { {"", "Y", "U+0059"}, ui::VKEY_Y, ui::EF_SHIFT_DOWN }, | |
223 { {"", "Z", "U+005A"}, ui::VKEY_Z, ui::EF_SHIFT_DOWN }, | |
224 { {"", "a", "U+0061"}, ui::VKEY_A, 0 }, | |
225 { {"", "b", "U+0062"}, ui::VKEY_B, 0 }, | |
226 { {"", "c", "U+0063"}, ui::VKEY_C, 0 }, | |
227 { {"", "d", "U+0064"}, ui::VKEY_D, 0 }, | |
228 { {"", "e", "U+0065"}, ui::VKEY_E, 0 }, | |
229 { {"", "f", "U+0066"}, ui::VKEY_F, 0 }, | |
230 { {"", "g", "U+0067"}, ui::VKEY_G, 0 }, | |
231 { {"", "h", "U+0068"}, ui::VKEY_H, 0 }, | |
232 { {"", "i", "U+0069"}, ui::VKEY_I, 0 }, | |
233 { {"", "j", "U+006A"}, ui::VKEY_J, 0 }, | |
234 { {"", "k", "U+006B"}, ui::VKEY_K, 0 }, | |
235 { {"", "l", "U+006C"}, ui::VKEY_L, 0 }, | |
236 { {"", "m", "U+006D"}, ui::VKEY_M, 0 }, | |
237 { {"", "n", "U+006E"}, ui::VKEY_N, 0 }, | |
238 { {"", "o", "U+006F"}, ui::VKEY_O, 0 }, | |
239 { {"", "p", "U+0070"}, ui::VKEY_P, 0 }, | |
240 { {"", "q", "U+0071"}, ui::VKEY_Q, 0 }, | |
241 { {"", "r", "U+0072"}, ui::VKEY_R, 0 }, | |
242 { {"", "s", "U+0073"}, ui::VKEY_S, 0 }, | |
243 { {"", "t", "U+0074"}, ui::VKEY_T, 0 }, | |
244 { {"", "u", "U+0075"}, ui::VKEY_U, 0 }, | |
245 { {"", "v", "U+0076"}, ui::VKEY_V, 0 }, | |
246 { {"", "w", "U+0077"}, ui::VKEY_W, 0 }, | |
247 { {"", "x", "U+0078"}, ui::VKEY_X, 0 }, | |
248 { {"", "y", "U+0079"}, ui::VKEY_Y, 0 }, | |
249 { {"", "z", "U+007A"}, ui::VKEY_Z, 0 }, | |
250 { {"LeftSquareBracket", "[", "U+005B"}, ui::VKEY_OEM_4, 0 }, | |
251 { {"Backslash", "\\", "U+005C"}, ui::VKEY_OEM_5, 0 }, | |
252 { {"RightSquareBracket", "]", "U+005D"}, ui::VKEY_OEM_6, 0 }, | |
253 { {"Circumflex", "^", "U+005E"}, ui::VKEY_6, ui::EF_SHIFT_DOWN }, | |
254 { {"Underscore", "_", "U+005F"}, | |
255 ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN }, | |
256 { {"Grave", "`", "U+0060"}, ui::VKEY_OEM_3, 0 }, | |
257 { {"Tilde", "~", "U+007E"}, ui::VKEY_OEM_3, ui::EF_SHIFT_DOWN }, | |
258 { {"LeftCurlyBracket", "{", "U+007B"}, | |
259 ui::VKEY_OEM_4, ui::EF_SHIFT_DOWN }, | |
260 { {"Pipe", "|", "U+007C"}, ui::VKEY_OEM_5, ui::EF_SHIFT_DOWN }, | |
261 { {"RightCurlyBracket", "}", "U+007D"}, | |
262 ui::VKEY_OEM_6, ui::EF_SHIFT_DOWN }, | |
263 { {"Del", "", "U+007F"}, ui::VKEY_DELETE, 0 }, | |
264 { {"InvertedExclamation", "", "U+00A1"}, ui::VKEY_UNKNOWN, 0 }, | |
265 { {"DeadGrave", "", "U+0300"}, ui::VKEY_UNKNOWN, 0 }, | |
266 { {"DeadEacute", "", "U+0301"}, ui::VKEY_UNKNOWN, 0 }, | |
267 { {"DeadCircumflex", "", "U+0302"}, ui::VKEY_UNKNOWN, 0 }, | |
268 { {"DeadTilde", "", "U+0303"}, ui::VKEY_UNKNOWN, 0 }, | |
269 { {"DeadMacron", "", "U+0304"}, ui::VKEY_UNKNOWN, 0 }, | |
270 { {"DeadBreve", "", "U+0306"}, ui::VKEY_UNKNOWN, 0 }, | |
271 { {"DeadAboveDot", "", "U+0307"}, ui::VKEY_UNKNOWN, 0 }, | |
272 { {"DeadUmlaut", "", "U+0308"}, ui::VKEY_UNKNOWN, 0 }, | |
273 { {"DeadAboveRing", "", "U+030A"}, ui::VKEY_UNKNOWN, 0 }, | |
274 { {"DeadDoubleacute", "", "U+030B"}, ui::VKEY_UNKNOWN, 0 }, | |
275 { {"DeadCaron", "", "U+030C"}, ui::VKEY_UNKNOWN, 0 }, | |
276 { {"DeadCedilla", "", "U+0327"}, ui::VKEY_UNKNOWN, 0 }, | |
277 { {"DeadOgonek", "", "U+0328"}, ui::VKEY_UNKNOWN, 0 }, | |
278 { {"DeadIota", "", "U+0345"}, ui::VKEY_UNKNOWN, 0 }, | |
279 { {"Euro", "", "U+20AC"}, ui::VKEY_UNKNOWN, 0 }, | |
280 { {"DeadVoicedSound", "", "U+3099"}, ui::VKEY_UNKNOWN, 0 }, | |
281 { {"DeadSemivoicedSound", "", "U+309A"}, ui::VKEY_UNKNOWN, 0 } | |
282 }; | |
283 | |
284 const int kNumKeyIdentifiers = arraysize(kKeyIdentifiers); | |
285 | |
286 typedef base::hash_map<std::string, const ui::KeyEvent*> IdentifierMap; | |
287 typedef std::pair<std::string, const ui::KeyEvent*> IdentifierPair; | |
288 IdentifierMap* identifierMaps[kNumIdentifierTypes] = { NULL }; | |
289 | |
290 ui::KeyEvent* kUnknownKeyEvent = NULL; | |
291 | |
292 void InitializeMaps() { | |
293 if (identifierMaps[0]) | |
294 return; | |
295 | |
296 kUnknownKeyEvent = new ui::KeyEvent(ui::ET_KEY_PRESSED, | |
297 ui::VKEY_UNKNOWN, | |
298 0, | |
299 false); | |
300 | |
301 for (int i = 0; i < kNumIdentifierTypes; ++i) | |
302 identifierMaps[i] = new IdentifierMap; | |
303 | |
304 for (int i = 0; i < kNumKeyIdentifiers; ++i) { | |
305 const KeyIdentifier& key = kKeyIdentifiers[i]; | |
306 | |
307 ui::KeyEvent* event = new ui::KeyEvent(ui::ET_KEY_PRESSED, | |
308 key.key_code, | |
309 key.event_flags, | |
310 false); | |
311 for (int j = 0; j < kNumIdentifierTypes; ++j) { | |
312 if (key.identifiers[j][0] != '\0') { | |
313 std::pair<IdentifierMap::iterator, bool> result = | |
314 identifierMaps[j]->insert( | |
315 IdentifierPair(key.identifiers[j], event)); | |
316 DCHECK(result.second); | |
317 } | |
318 } | |
319 } | |
320 } | |
321 | |
322 } // namespace | |
323 | |
324 namespace ui { | |
325 | |
326 const ui::KeyEvent& KeyEventFromKeyIdentifier( | |
327 const std::string& key_identifier) { | |
328 // This lazily initializes lookup tables for the conversion. To prevent | |
329 // races, it should only ever be called from a single thread. | |
330 InitializeMaps(); | |
331 | |
332 for (int i = 0; i < kNumIdentifierTypes; ++i) { | |
333 const IdentifierMap& map = *identifierMaps[i]; | |
334 | |
335 IdentifierMap::const_iterator iter = map.find(key_identifier); | |
336 if (iter != map.end()) | |
337 return *iter->second; | |
338 } | |
339 | |
340 return *kUnknownKeyEvent; | |
341 } | |
342 | |
343 } // namespace ui | |
OLD | NEW |