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.
4
5#include "chrome/browser/extensions/key_identifier_conversion_views.h"
6
7#include <string.h>
8
9#include "base/basictypes.h"
10#include "base/hash_tables.h"
11#include "content/browser/browser_thread.h"
12#include "ui/base/keycodes/keyboard_codes.h"
13#include "views/events/event.h"
14
15namespace {
16
17static const int kNumIdentifierTypes = 3;
18
19typedef 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// TODO(bryeung): keycodes could be wrong: I took the keydown code only
33static 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_FAVORITES, 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, 0 },
199  { {"", "B", "U+0042"}, ui::VKEY_B, 0 },
200  { {"", "C", "U+0043"}, ui::VKEY_C, 0 },
201  { {"", "D", "U+0044"}, ui::VKEY_D, 0 },
202  { {"", "E", "U+0045"}, ui::VKEY_E, 0 },
203  { {"", "F", "U+0046"}, ui::VKEY_F, 0 },
204  { {"", "G", "U+0047"}, ui::VKEY_G, 0 },
205  { {"", "H", "U+0048"}, ui::VKEY_H, 0 },
206  { {"", "I", "U+0049"}, ui::VKEY_I, 0 },
207  { {"", "J", "U+004A"}, ui::VKEY_J, 0 },
208  { {"", "K", "U+004B"}, ui::VKEY_K, 0 },
209  { {"", "L", "U+004C"}, ui::VKEY_L, 0 },
210  { {"", "M", "U+004D"}, ui::VKEY_M, 0 },
211  { {"", "N", "U+004E"}, ui::VKEY_N, 0 },
212  { {"", "O", "U+004F"}, ui::VKEY_O, 0 },
213  { {"", "P", "U+0050"}, ui::VKEY_P, 0 },
214  { {"", "Q", "U+0051"}, ui::VKEY_Q, 0 },
215  { {"", "R", "U+0052"}, ui::VKEY_R, 0 },
216  { {"", "S", "U+0053"}, ui::VKEY_S, 0 },
217  { {"", "T", "U+0054"}, ui::VKEY_T, 0 },
218  { {"", "U", "U+0055"}, ui::VKEY_U, 0 },
219  { {"", "V", "U+0056"}, ui::VKEY_V, 0 },
220  { {"", "W", "U+0057"}, ui::VKEY_W, 0 },
221  { {"", "X", "U+0058"}, ui::VKEY_X, 0 },
222  { {"", "Y", "U+0059"}, ui::VKEY_Y, 0 },
223  { {"", "Z", "U+005A"}, ui::VKEY_Z, 0 },
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
284static const int kNumKeyIdentifiers = arraysize(kKeyIdentifiers);
285
286typedef base::hash_map<std::string, const views::KeyEvent*> IdentifierMap;
287typedef std::pair<std::string, const views::KeyEvent*> IdentifierPair;
288static IdentifierMap* identifierMaps[kNumIdentifierTypes] = { NULL };
289
290static views::KeyEvent* kUnknownKeyEvent = NULL;
291
292static void InitializeMaps() {
293  if (identifierMaps[0])
294    return;
295
296  kUnknownKeyEvent = new views::KeyEvent(
297    ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN, 0);
298
299  for (int i = 0; i < kNumIdentifierTypes; ++i)
300    identifierMaps[i] = new IdentifierMap;
301
302  for (int i = 0; i < kNumKeyIdentifiers; ++i) {
303    const KeyIdentifier& key = kKeyIdentifiers[i];
304
305    views::KeyEvent* event = new views::KeyEvent(
306        ui::ET_KEY_PRESSED, key.key_code, key.event_flags);
307
308    for (int j = 0; j < kNumIdentifierTypes; ++j) {
309      if (key.identifiers[j][0] != '\0') {
310        std::pair<IdentifierMap::iterator, bool> result =
311            identifierMaps[j]->insert(
312                IdentifierPair(key.identifiers[j], event));
313        DCHECK(result.second);
314      }
315    }
316  }
317}
318
319}  // namespace
320
321
322const views::KeyEvent& KeyEventFromKeyIdentifier(
323    const std::string& key_identifier) {
324  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
325  InitializeMaps();
326
327  for (int i = 0; i < kNumIdentifierTypes; ++i) {
328    const IdentifierMap& map = *identifierMaps[i];
329
330    IdentifierMap::const_iterator iter = map.find(key_identifier);
331    if (iter != map.end())
332      return *iter->second;
333  }
334
335  return *kUnknownKeyEvent;
336}
337