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/events/platform/x11/keyboard_code_conversion_x11.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #define XK_3270 // for XK_3270_BackTab | |
10 #include <X11/extensions/XInput2.h> | |
11 #include <X11/keysym.h> | |
12 #include <X11/XF86keysym.h> | |
13 #include <X11/Xlib.h> | |
14 #include <X11/Xutil.h> | |
15 | |
16 #include "base/basictypes.h" | |
17 #include "base/logging.h" | |
18 #include "base/strings/stringprintf.h" | |
19 #include "base/strings/sys_string_conversions.h" | |
20 #include "base/strings/utf_string_conversions.h" | |
21 #include "ui/events/keycodes/dom4/keycode_converter.h" | |
22 #include "ui/events/platform/x11/keysym_to_unicode.h" | |
23 | |
24 #define VKEY_UNSUPPORTED VKEY_UNKNOWN | |
25 | |
26 namespace ui { | |
27 | |
28 namespace { | |
29 | |
30 // MAP0 - MAP3: | |
31 // These are the generated VKEY code maps for all possible Latin keyboard | |
32 // layouts in Windows. And the maps are only for special letter keys excluding | |
33 // [a-z] & [0-9]. | |
34 // | |
35 // ch0: the keysym without modifier states. | |
36 // ch1: the keysym with shift state. | |
37 // ch2: the keysym with altgr state. | |
38 // sc: the hardware keycode (in Windows, it's called scan code). | |
39 // vk: the VKEY code. | |
40 // | |
41 // MAP0: maps from ch0 to vk. | |
42 // MAP1: maps from ch0+sc to vk. | |
43 // MAP2: maps from ch0+ch1+sc to vk. | |
44 // MAP3: maps from ch0+ch1+ch2+sc to vk. | |
45 // MAP0 - MAP3 are all sorted, so that finding VK can be binary search. | |
46 // | |
47 // Reason for creating these maps is because a hard-coded mapping in | |
48 // KeyboardCodeFromXKeysym() doesn't support non-US keyboard layouts. | |
49 // e.g. in UK keyboard, the key between Quote and Enter keys has the VKEY code | |
50 // VKEY_OEM_5 instead of VKEY_3. | |
51 // | |
52 // The key symbols which are not [a-zA-Z0-9] and functional/extend keys (e.g. | |
53 // TAB, ENTER, BS, Arrow keys, modifier keys, F1-F12, media/app keys, etc.) | |
54 // should go through these maps for correct VKEY codes. | |
55 // | |
56 // Please refer to crbug.com/386066. | |
57 // | |
58 const struct MAP0 { | |
59 KeySym ch0; | |
60 uint8 vk; | |
61 bool operator()(const MAP0& m1, const MAP0& m2) const { | |
62 return m1.ch0 < m2.ch0; | |
63 } | |
64 } map0[] = { | |
65 {0x0025, 0x35}, // XK_percent: VKEY_5 | |
66 {0x0026, 0x31}, // XK_ampersand: VKEY_1 | |
67 {0x003C, 0xDC}, // XK_less: VKEY_OEM_5 | |
68 {0x007B, 0xDE}, // XK_braceleft: VKEY_OEM_7 | |
69 {0x007C, 0xDC}, // XK_bar: VKEY_OEM_5 | |
70 {0x007D, 0xBF}, // XK_braceright: VKEY_OEM_2 | |
71 {0x007E, 0xDC}, // XK_asciitilde: VKEY_OEM_5 | |
72 {0x00A1, 0xDD}, // XK_exclamdown: VKEY_OEM_6 | |
73 {0x00AD, 0xC0}, // XK_hyphen: VKEY_OEM_3 | |
74 {0x00B2, 0xDE}, // XK_twosuperior: VKEY_OEM_7 | |
75 {0x00B5, 0xDC}, // XK_mu: VKEY_OEM_5 | |
76 {0x00BB, 0x39}, // XK_guillemotright: VKEY_9 | |
77 {0x00BD, 0xDC}, // XK_onehalf: VKEY_OEM_5 | |
78 {0x00BF, 0xDD}, // XK_questiondown: VKEY_OEM_6 | |
79 {0x00DF, 0xDB}, // XK_ssharp: VKEY_OEM_4 | |
80 {0x00E5, 0xDD}, // XK_aring: VKEY_OEM_6 | |
81 {0x00EA, 0x33}, // XK_ecircumflex: VKEY_3 | |
82 {0x00EB, 0xBA}, // XK_ediaeresis: VKEY_OEM_1 | |
83 {0x00EC, 0xDD}, // XK_igrave: VKEY_OEM_6 | |
84 {0x00EE, 0xDD}, // XK_icircumflex: VKEY_OEM_6 | |
85 {0x00F1, 0xC0}, // XK_ntilde: VKEY_OEM_3 | |
86 {0x00F2, 0xC0}, // XK_ograve: VKEY_OEM_3 | |
87 {0x00F5, 0xDB}, // XK_otilde: VKEY_OEM_4 | |
88 {0x00F7, 0xDD}, // XK_division: VKEY_OEM_6 | |
89 {0x00FD, 0x37}, // XK_yacute: VKEY_7 | |
90 {0x00FE, 0xBD}, // XK_thorn: VKEY_OEM_MINUS | |
91 {0x01A1, 0xDD}, // XK_ohorn: VKEY_OEM_6 | |
92 {0x01B0, 0xDB}, // XK_uhorn: VKEY_OEM_4 | |
93 {0x01B5, 0x32}, // XK_lcaron: VKEY_2 | |
94 {0x01B6, 0xDD}, // XK_zstroke: VKEY_OEM_6 | |
95 {0x01BB, 0x35}, // XK_tcaron: VKEY_5 | |
96 {0x01E6, 0xDE}, // XK_cacute: VKEY_OEM_7 | |
97 {0x01EC, 0x32}, // XK_ecaron: VKEY_2 | |
98 {0x01F2, 0xDC}, // XK_ncaron: VKEY_OEM_5 | |
99 {0x01F5, 0xDB}, // XK_odoubleacute: VKEY_OEM_4 | |
100 {0x01F8, 0x35}, // XK_rcaron: VKEY_5 | |
101 {0x01F9, 0xBA}, // XK_uring: VKEY_OEM_1 | |
102 {0x01FB, 0xDC}, // XK_udoubleacute: VKEY_OEM_5 | |
103 {0x01FE, 0xDE}, // XK_tcedilla: VKEY_OEM_7 | |
104 {0x0259, 0xC0}, // XK_schwa: VKEY_OEM_3 | |
105 {0x02B1, 0xDD}, // XK_hstroke: VKEY_OEM_6 | |
106 {0x02B9, 0xBA}, // XK_idotless: VKEY_OEM_1 | |
107 {0x02BB, 0xDD}, // XK_gbreve: VKEY_OEM_6 | |
108 {0x02E5, 0xC0}, // XK_cabovedot: VKEY_OEM_3 | |
109 {0x02F5, 0xDB}, // XK_gabovedot: VKEY_OEM_4 | |
110 {0x03B6, 0xBF}, // XK_lcedilla: VKEY_OEM_2 | |
111 {0x03BA, 0x57}, // XK_emacron: VKEY_W | |
112 {0x03E0, 0xDF}, // XK_amacron: VKEY_OEM_8 | |
113 {0x03EF, 0xDD}, // XK_imacron: VKEY_OEM_6 | |
114 {0x03F1, 0xDB}, // XK_ncedilla: VKEY_OEM_4 | |
115 {0x03F3, 0xDC}, // XK_kcedilla: VKEY_OEM_5 | |
116 }; | |
117 | |
118 const struct MAP1 { | |
119 KeySym ch0; | |
120 unsigned sc; | |
121 uint8 vk; | |
122 bool operator()(const MAP1& m1, const MAP1& m2) const { | |
123 if (m1.ch0 == m2.ch0) | |
124 return m1.sc < m2.sc; | |
125 return m1.ch0 < m2.ch0; | |
126 } | |
127 } map1[] = { | |
128 {0x0021, 0x0A, 0x31}, // XK_exclam+AE01: VKEY_1 | |
129 {0x0021, 0x11, 0x38}, // XK_exclam+AE08: VKEY_8 | |
130 {0x0021, 0x3D, 0xDF}, // XK_exclam+AB10: VKEY_OEM_8 | |
131 {0x0022, 0x0B, 0x32}, // XK_quotedbl+AE02: VKEY_2 | |
132 {0x0022, 0x0C, 0x33}, // XK_quotedbl+AE03: VKEY_3 | |
133 {0x0023, 0x31, 0xDE}, // XK_numbersign+TLDE: VKEY_OEM_7 | |
134 {0x0024, 0x23, 0xBA}, // XK_dollar+AD12: VKEY_OEM_1 | |
135 {0x0024, 0x33, 0xDF}, // XK_dollar+BKSL: VKEY_OEM_8 | |
136 {0x0027, 0x0D, 0x34}, // XK_quoteright+AE04: VKEY_4 | |
137 {0x0027, 0x18, 0xDE}, // XK_quoteright+AD01: VKEY_OEM_7 | |
138 {0x0027, 0x23, 0xBA}, // XK_quoteright+AD12: VKEY_OEM_1 | |
139 {0x0027, 0x3D, 0xDE}, // XK_quoteright+AB10: VKEY_OEM_7 | |
140 {0x0028, 0x0E, 0x35}, // XK_parenleft+AE05: VKEY_5 | |
141 {0x0028, 0x12, 0x39}, // XK_parenleft+AE09: VKEY_9 | |
142 {0x0028, 0x33, 0xDC}, // XK_parenleft+BKSL: VKEY_OEM_5 | |
143 {0x0029, 0x13, 0x30}, // XK_parenright+AE10: VKEY_0 | |
144 {0x0029, 0x14, 0xDB}, // XK_parenright+AE11: VKEY_OEM_4 | |
145 {0x0029, 0x23, 0xDD}, // XK_parenright+AD12: VKEY_OEM_6 | |
146 {0x002A, 0x23, 0xBA}, // XK_asterisk+AD12: VKEY_OEM_1 | |
147 {0x002A, 0x33, 0xDC}, // XK_asterisk+BKSL: VKEY_OEM_5 | |
148 {0x002B, 0x0A, 0x31}, // XK_plus+AE01: VKEY_1 | |
149 {0x002B, 0x15, 0xBB}, // XK_plus+AE12: VKEY_OEM_PLUS | |
150 {0x002B, 0x22, 0xBB}, // XK_plus+AD11: VKEY_OEM_PLUS | |
151 {0x002B, 0x23, 0xBB}, // XK_plus+AD12: VKEY_OEM_PLUS | |
152 {0x002B, 0x2F, 0xBB}, // XK_plus+AC10: VKEY_OEM_PLUS | |
153 {0x002B, 0x33, 0xBF}, // XK_plus+BKSL: VKEY_OEM_2 | |
154 {0x002C, 0x0C, 0x33}, // XK_comma+AE03: VKEY_3 | |
155 {0x002C, 0x0E, 0x35}, // XK_comma+AE05: VKEY_5 | |
156 {0x002C, 0x0F, 0x36}, // XK_comma+AE06: VKEY_6 | |
157 {0x002C, 0x12, 0x39}, // XK_comma+AE09: VKEY_9 | |
158 {0x002C, 0x19, 0xBC}, // XK_comma+AD02: VKEY_OEM_COMMA | |
159 {0x002C, 0x37, 0xBC}, // XK_comma+AB04: VKEY_OEM_COMMA | |
160 {0x002C, 0x3A, 0xBC}, // XK_comma+AB07: VKEY_OEM_COMMA | |
161 {0x002C, 0x3B, 0xBC}, // XK_comma+AB08: VKEY_OEM_COMMA | |
162 {0x002D, 0x0B, 0x32}, // XK_minus+AE02: VKEY_2 | |
163 {0x002D, 0x0F, 0x36}, // XK_minus+AE06: VKEY_6 | |
164 {0x002D, 0x14, 0xBD}, // XK_minus+AE11: VKEY_OEM_MINUS | |
165 {0x002D, 0x26, 0xBD}, // XK_minus+AC01: VKEY_OEM_MINUS | |
166 {0x002D, 0x30, 0xBD}, // XK_minus+AC11: VKEY_OEM_MINUS | |
167 {0x002E, 0x10, 0x37}, // XK_period+AE07: VKEY_7 | |
168 {0x002E, 0x11, 0x38}, // XK_period+AE08: VKEY_8 | |
169 {0x002E, 0x1A, 0xBE}, // XK_period+AD03: VKEY_OEM_PERIOD | |
170 {0x002E, 0x1B, 0xBE}, // XK_period+AD04: VKEY_OEM_PERIOD | |
171 {0x002E, 0x20, 0xBE}, // XK_period+AD09: VKEY_OEM_PERIOD | |
172 {0x002E, 0x30, 0xDE}, // XK_period+AC11: VKEY_OEM_7 | |
173 {0x002E, 0x3C, 0xBE}, // XK_period+AB09: VKEY_OEM_PERIOD | |
174 {0x002E, 0x3D, 0xBF}, // XK_period+AB10: VKEY_OEM_2 | |
175 {0x002F, 0x14, 0xDB}, // XK_slash+AE11: VKEY_OEM_4 | |
176 {0x002F, 0x22, 0xBF}, // XK_slash+AD11: VKEY_OEM_2 | |
177 {0x002F, 0x31, 0xDE}, // XK_slash+TLDE: VKEY_OEM_7 | |
178 {0x002F, 0x33, 0xDC}, // XK_slash+BKSL: VKEY_OEM_5 | |
179 {0x002F, 0x3D, 0xBF}, // XK_slash+AB10: VKEY_OEM_2 | |
180 {0x003A, 0x0A, 0x31}, // XK_colon+AE01: VKEY_1 | |
181 {0x003A, 0x0E, 0x35}, // XK_colon+AE05: VKEY_5 | |
182 {0x003A, 0x0F, 0x36}, // XK_colon+AE06: VKEY_6 | |
183 {0x003A, 0x3C, 0xBF}, // XK_colon+AB09: VKEY_OEM_2 | |
184 {0x003B, 0x0D, 0x34}, // XK_semicolon+AE04: VKEY_4 | |
185 {0x003B, 0x11, 0x38}, // XK_semicolon+AE08: VKEY_8 | |
186 {0x003B, 0x18, 0xBA}, // XK_semicolon+AD01: VKEY_OEM_1 | |
187 {0x003B, 0x22, 0xBA}, // XK_semicolon+AD11: VKEY_OEM_1 | |
188 {0x003B, 0x23, 0xDD}, // XK_semicolon+AD12: VKEY_OEM_6 | |
189 {0x003B, 0x2F, 0xBA}, // XK_semicolon+AC10: VKEY_OEM_1 | |
190 {0x003B, 0x31, 0xC0}, // XK_semicolon+TLDE: VKEY_OEM_3 | |
191 {0x003B, 0x34, 0xBA}, // XK_semicolon+AB01: VKEY_OEM_1 | |
192 {0x003B, 0x3B, 0xBE}, // XK_semicolon+AB08: VKEY_OEM_PERIOD | |
193 {0x003B, 0x3D, 0xBF}, // XK_semicolon+AB10: VKEY_OEM_2 | |
194 {0x003D, 0x11, 0x38}, // XK_equal+AE08: VKEY_8 | |
195 {0x003D, 0x15, 0xBB}, // XK_equal+AE12: VKEY_OEM_PLUS | |
196 {0x003D, 0x23, 0xBB}, // XK_equal+AD12: VKEY_OEM_PLUS | |
197 {0x003F, 0x0B, 0x32}, // XK_question+AE02: VKEY_2 | |
198 {0x003F, 0x10, 0x37}, // XK_question+AE07: VKEY_7 | |
199 {0x003F, 0x11, 0x38}, // XK_question+AE08: VKEY_8 | |
200 {0x003F, 0x14, 0xBB}, // XK_question+AE11: VKEY_OEM_PLUS | |
201 {0x0040, 0x23, 0xDD}, // XK_at+AD12: VKEY_OEM_6 | |
202 {0x0040, 0x31, 0xDE}, // XK_at+TLDE: VKEY_OEM_7 | |
203 {0x005B, 0x0A, 0xDB}, // XK_bracketleft+AE01: VKEY_OEM_4 | |
204 {0x005B, 0x14, 0xDB}, // XK_bracketleft+AE11: VKEY_OEM_4 | |
205 {0x005B, 0x22, 0xDB}, // XK_bracketleft+AD11: VKEY_OEM_4 | |
206 {0x005B, 0x23, 0xDD}, // XK_bracketleft+AD12: VKEY_OEM_6 | |
207 {0x005B, 0x30, 0xDE}, // XK_bracketleft+AC11: VKEY_OEM_7 | |
208 {0x005C, 0x15, 0xDB}, // XK_backslash+AE12: VKEY_OEM_4 | |
209 {0x005D, 0x0B, 0xDD}, // XK_bracketright+AE02: VKEY_OEM_6 | |
210 {0x005D, 0x15, 0xDD}, // XK_bracketright+AE12: VKEY_OEM_6 | |
211 {0x005D, 0x23, 0xDD}, // XK_bracketright+AD12: VKEY_OEM_6 | |
212 {0x005D, 0x31, 0xC0}, // XK_bracketright+TLDE: VKEY_OEM_3 | |
213 {0x005D, 0x33, 0xDC}, // XK_bracketright+BKSL: VKEY_OEM_5 | |
214 {0x005F, 0x11, 0x38}, // XK_underscore+AE08: VKEY_8 | |
215 {0x005F, 0x14, 0xBD}, // XK_underscore+AE11: VKEY_OEM_MINUS | |
216 {0x00A7, 0x0D, 0x34}, // XK_section+AE04: VKEY_4 | |
217 {0x00A7, 0x0F, 0x36}, // XK_section+AE06: VKEY_6 | |
218 {0x00A7, 0x30, 0xDE}, // XK_section+AC11: VKEY_OEM_7 | |
219 {0x00AB, 0x11, 0x38}, // XK_guillemotleft+AE08: VKEY_8 | |
220 {0x00AB, 0x15, 0xDD}, // XK_guillemotleft+AE12: VKEY_OEM_6 | |
221 {0x00B0, 0x15, 0xBF}, // XK_degree+AE12: VKEY_OEM_2 | |
222 {0x00B0, 0x31, 0xDE}, // XK_degree+TLDE: VKEY_OEM_7 | |
223 {0x00BA, 0x30, 0xDE}, // XK_masculine+AC11: VKEY_OEM_7 | |
224 {0x00BA, 0x31, 0xDC}, // XK_masculine+TLDE: VKEY_OEM_5 | |
225 {0x00E0, 0x13, 0x30}, // XK_agrave+AE10: VKEY_0 | |
226 {0x00E0, 0x33, 0xDC}, // XK_agrave+BKSL: VKEY_OEM_5 | |
227 {0x00E1, 0x11, 0x38}, // XK_aacute+AE08: VKEY_8 | |
228 {0x00E1, 0x30, 0xDE}, // XK_aacute+AC11: VKEY_OEM_7 | |
229 {0x00E2, 0x0B, 0x32}, // XK_acircumflex+AE02: VKEY_2 | |
230 {0x00E2, 0x33, 0xDC}, // XK_acircumflex+BKSL: VKEY_OEM_5 | |
231 {0x00E4, 0x23, 0xDD}, // XK_adiaeresis+AD12: VKEY_OEM_6 | |
232 {0x00E6, 0x2F, 0xC0}, // XK_ae+AC10: VKEY_OEM_3 | |
233 {0x00E6, 0x30, 0xDE}, // XK_ae+AC11: VKEY_OEM_7 | |
234 {0x00E7, 0x12, 0x39}, // XK_ccedilla+AE09: VKEY_9 | |
235 {0x00E7, 0x22, 0xDB}, // XK_ccedilla+AD11: VKEY_OEM_4 | |
236 {0x00E7, 0x23, 0xDD}, // XK_ccedilla+AD12: VKEY_OEM_6 | |
237 {0x00E7, 0x30, 0xDE}, // XK_ccedilla+AC11: VKEY_OEM_7 | |
238 {0x00E7, 0x33, 0xBF}, // XK_ccedilla+BKSL: VKEY_OEM_2 | |
239 {0x00E7, 0x3B, 0xBC}, // XK_ccedilla+AB08: VKEY_OEM_COMMA | |
240 {0x00E8, 0x10, 0x37}, // XK_egrave+AE07: VKEY_7 | |
241 {0x00E8, 0x22, 0xBA}, // XK_egrave+AD11: VKEY_OEM_1 | |
242 {0x00E8, 0x30, 0xC0}, // XK_egrave+AC11: VKEY_OEM_3 | |
243 {0x00E9, 0x0B, 0x32}, // XK_eacute+AE02: VKEY_2 | |
244 {0x00E9, 0x13, 0x30}, // XK_eacute+AE10: VKEY_0 | |
245 {0x00E9, 0x3D, 0xBF}, // XK_eacute+AB10: VKEY_OEM_2 | |
246 {0x00ED, 0x12, 0x39}, // XK_iacute+AE09: VKEY_9 | |
247 {0x00ED, 0x31, 0x30}, // XK_iacute+TLDE: VKEY_0 | |
248 {0x00F0, 0x22, 0xDD}, // XK_eth+AD11: VKEY_OEM_6 | |
249 {0x00F0, 0x23, 0xBA}, // XK_eth+AD12: VKEY_OEM_1 | |
250 {0x00F3, 0x15, 0xBB}, // XK_oacute+AE12: VKEY_OEM_PLUS | |
251 {0x00F3, 0x33, 0xDC}, // XK_oacute+BKSL: VKEY_OEM_5 | |
252 {0x00F4, 0x0D, 0x34}, // XK_ocircumflex+AE04: VKEY_4 | |
253 {0x00F4, 0x2F, 0xBA}, // XK_ocircumflex+AC10: VKEY_OEM_1 | |
254 {0x00F6, 0x13, 0xC0}, // XK_odiaeresis+AE10: VKEY_OEM_3 | |
255 {0x00F6, 0x14, 0xBB}, // XK_odiaeresis+AE11: VKEY_OEM_PLUS | |
256 {0x00F6, 0x22, 0xDB}, // XK_odiaeresis+AD11: VKEY_OEM_4 | |
257 {0x00F8, 0x2F, 0xC0}, // XK_oslash+AC10: VKEY_OEM_3 | |
258 {0x00F8, 0x30, 0xDE}, // XK_oslash+AC11: VKEY_OEM_7 | |
259 {0x00F9, 0x30, 0xC0}, // XK_ugrave+AC11: VKEY_OEM_3 | |
260 {0x00F9, 0x33, 0xBF}, // XK_ugrave+BKSL: VKEY_OEM_2 | |
261 {0x00FA, 0x22, 0xDB}, // XK_uacute+AD11: VKEY_OEM_4 | |
262 {0x00FA, 0x23, 0xDD}, // XK_uacute+AD12: VKEY_OEM_6 | |
263 {0x00FC, 0x19, 0x57}, // XK_udiaeresis+AD02: VKEY_W | |
264 {0x01B1, 0x0A, 0x31}, // XK_aogonek+AE01: VKEY_1 | |
265 {0x01B1, 0x18, 0x51}, // XK_aogonek+AD01: VKEY_Q | |
266 {0x01B1, 0x30, 0xDE}, // XK_aogonek+AC11: VKEY_OEM_7 | |
267 {0x01B3, 0x2F, 0xBA}, // XK_lstroke+AC10: VKEY_OEM_1 | |
268 {0x01B3, 0x33, 0xBF}, // XK_lstroke+BKSL: VKEY_OEM_2 | |
269 {0x01B9, 0x0C, 0x33}, // XK_scaron+AE03: VKEY_3 | |
270 {0x01B9, 0x0F, 0x36}, // XK_scaron+AE06: VKEY_6 | |
271 {0x01B9, 0x22, 0xDB}, // XK_scaron+AD11: VKEY_OEM_4 | |
272 {0x01B9, 0x26, 0xBA}, // XK_scaron+AC01: VKEY_OEM_1 | |
273 {0x01B9, 0x29, 0x46}, // XK_scaron+AC04: VKEY_F | |
274 {0x01B9, 0x3C, 0xBE}, // XK_scaron+AB09: VKEY_OEM_PERIOD | |
275 {0x01BA, 0x2F, 0xBA}, // XK_scedilla+AC10: VKEY_OEM_1 | |
276 {0x01BA, 0x3C, 0xBE}, // XK_scedilla+AB09: VKEY_OEM_PERIOD | |
277 {0x01BE, 0x0F, 0x36}, // XK_zcaron+AE06: VKEY_6 | |
278 {0x01BE, 0x15, 0xBB}, // XK_zcaron+AE12: VKEY_OEM_PLUS | |
279 {0x01BE, 0x19, 0x57}, // XK_zcaron+AD02: VKEY_W | |
280 {0x01BE, 0x22, 0x59}, // XK_zcaron+AD11: VKEY_Y | |
281 {0x01BE, 0x33, 0xDC}, // XK_zcaron+BKSL: VKEY_OEM_5 | |
282 {0x01BF, 0x22, 0xDB}, // XK_zabovedot+AD11: VKEY_OEM_4 | |
283 {0x01BF, 0x33, 0xDC}, // XK_zabovedot+BKSL: VKEY_OEM_5 | |
284 {0x01E3, 0x0A, 0x31}, // XK_abreve+AE01: VKEY_1 | |
285 {0x01E3, 0x22, 0xDB}, // XK_abreve+AD11: VKEY_OEM_4 | |
286 {0x01E8, 0x0B, 0x32}, // XK_ccaron+AE02: VKEY_2 | |
287 {0x01E8, 0x0D, 0x34}, // XK_ccaron+AE04: VKEY_4 | |
288 {0x01E8, 0x21, 0x58}, // XK_ccaron+AD10: VKEY_X | |
289 {0x01E8, 0x2F, 0xBA}, // XK_ccaron+AC10: VKEY_OEM_1 | |
290 {0x01E8, 0x3B, 0xBC}, // XK_ccaron+AB08: VKEY_OEM_COMMA | |
291 {0x01EA, 0x0C, 0x33}, // XK_eogonek+AE03: VKEY_3 | |
292 {0x01F0, 0x13, 0x30}, // XK_dstroke+AE10: VKEY_0 | |
293 {0x01F0, 0x23, 0xDD}, // XK_dstroke+AD12: VKEY_OEM_6 | |
294 {0x03E7, 0x0E, 0x35}, // XK_iogonek+AE05: VKEY_5 | |
295 {0x03EC, 0x0D, 0x34}, // XK_eabovedot+AE04: VKEY_4 | |
296 {0x03EC, 0x30, 0xDE}, // XK_eabovedot+AC11: VKEY_OEM_7 | |
297 {0x03F9, 0x10, 0x37}, // XK_uogonek+AE07: VKEY_7 | |
298 {0x03FE, 0x11, 0x38}, // XK_umacron+AE08: VKEY_8 | |
299 {0x03FE, 0x18, 0x51}, // XK_umacron+AD01: VKEY_Q | |
300 {0x03FE, 0x35, 0x58}, // XK_umacron+AB02: VKEY_X | |
301 }; | |
302 | |
303 const struct MAP2 { | |
304 KeySym ch0; | |
305 unsigned sc; | |
306 KeySym ch1; | |
307 uint8 vk; | |
308 bool operator()(const MAP2& m1, const MAP2& m2) const { | |
309 if (m1.ch0 == m2.ch0 && m1.sc == m2.sc) | |
310 return m1.ch1 < m2.ch1; | |
311 if (m1.ch0 == m2.ch0) | |
312 return m1.sc < m2.sc; | |
313 return m1.ch0 < m2.ch0; | |
314 } | |
315 } map2[] = { | |
316 {0x0023, | |
317 0x33, | |
318 0x0027, | |
319 0xBF}, // XK_numbersign+BKSL+XK_quoteright: VKEY_OEM_2 | |
320 {0x0027, 0x30, 0x0022, 0xDE}, // XK_quoteright+AC11+XK_quotedbl: VKEY_OEM_7 | |
321 {0x0027, 0x31, 0x0022, 0xC0}, // XK_quoteright+TLDE+XK_quotedbl: VKEY_OEM_3 | |
322 {0x0027, | |
323 0x31, | |
324 0x00B7, | |
325 0xDC}, // XK_quoteright+TLDE+XK_periodcentered: VKEY_OEM_5 | |
326 {0x0027, 0x33, 0x0000, 0xDC}, // XK_quoteright+BKSL+NoSymbol: VKEY_OEM_5 | |
327 {0x002D, 0x3D, 0x003D, 0xBD}, // XK_minus+AB10+XK_equal: VKEY_OEM_MINUS | |
328 {0x002F, 0x0C, 0x0033, 0x33}, // XK_slash+AE03+XK_3: VKEY_3 | |
329 {0x002F, 0x0C, 0x003F, 0xBF}, // XK_slash+AE03+XK_question: VKEY_OEM_2 | |
330 {0x002F, 0x13, 0x0030, 0x30}, // XK_slash+AE10+XK_0: VKEY_0 | |
331 {0x002F, 0x13, 0x003F, 0xBF}, // XK_slash+AE10+XK_question: VKEY_OEM_2 | |
332 {0x003D, 0x3D, 0x0025, 0xDF}, // XK_equal+AB10+XK_percent: VKEY_OEM_8 | |
333 {0x003D, 0x3D, 0x002B, 0xBB}, // XK_equal+AB10+XK_plus: VKEY_OEM_PLUS | |
334 {0x005C, 0x33, 0x002F, 0xDE}, // XK_backslash+BKSL+XK_slash: VKEY_OEM_7 | |
335 {0x005C, 0x33, 0x007C, 0xDC}, // XK_backslash+BKSL+XK_bar: VKEY_OEM_5 | |
336 {0x0060, 0x31, 0x0000, 0xC0}, // XK_quoteleft+TLDE+NoSymbol: VKEY_OEM_3 | |
337 {0x0060, 0x31, 0x00AC, 0xDF}, // XK_quoteleft+TLDE+XK_notsign: VKEY_OEM_8 | |
338 {0x00A7, 0x31, 0x00B0, 0xBF}, // XK_section+TLDE+XK_degree: VKEY_OEM_2 | |
339 {0x00A7, 0x31, 0x00BD, 0xDC}, // XK_section+TLDE+XK_onehalf: VKEY_OEM_5 | |
340 {0x00E0, 0x30, 0x00B0, 0xDE}, // XK_agrave+AC11+XK_degree: VKEY_OEM_7 | |
341 {0x00E0, 0x30, 0x00E4, 0xDC}, // XK_agrave+AC11+XK_adiaeresis: VKEY_OEM_5 | |
342 {0x00E4, 0x30, 0x00E0, 0xDC}, // XK_adiaeresis+AC11+XK_agrave: VKEY_OEM_5 | |
343 {0x00E9, 0x2F, 0x00C9, 0xBA}, // XK_eacute+AC10+XK_Eacute: VKEY_OEM_1 | |
344 {0x00E9, 0x2F, 0x00F6, 0xDE}, // XK_eacute+AC10+XK_odiaeresis: VKEY_OEM_7 | |
345 {0x00F6, 0x2F, 0x00E9, 0xDE}, // XK_odiaeresis+AC10+XK_eacute: VKEY_OEM_7 | |
346 {0x00FC, 0x22, 0x00E8, 0xBA}, // XK_udiaeresis+AD11+XK_egrave: VKEY_OEM_1 | |
347 }; | |
348 | |
349 const struct MAP3 { | |
350 KeySym ch0; | |
351 unsigned sc; | |
352 KeySym ch1; | |
353 KeySym ch2; | |
354 uint8 vk; | |
355 bool operator()(const MAP3& m1, const MAP3& m2) const { | |
356 if (m1.ch0 == m2.ch0 && m1.sc == m2.sc && m1.ch1 == m2.ch1) | |
357 return m1.ch2 < m2.ch2; | |
358 if (m1.ch0 == m2.ch0 && m1.sc == m2.sc) | |
359 return m1.ch1 < m2.ch1; | |
360 if (m1.ch0 == m2.ch0) | |
361 return m1.sc < m2.sc; | |
362 return m1.ch0 < m2.ch0; | |
363 } | |
364 } map3[] = { | |
365 {0x0023, | |
366 0x33, | |
367 0x007E, | |
368 0x0000, | |
369 0xDE}, // XK_numbersign+BKSL+XK_asciitilde+NoSymbol: VKEY_OEM_7 | |
370 {0x0027, | |
371 0x14, | |
372 0x003F, | |
373 0x0000, | |
374 0xDB}, // XK_quoteright+AE11+XK_question+NoSymbol: VKEY_OEM_4 | |
375 {0x0027, | |
376 0x14, | |
377 0x003F, | |
378 0x00DD, | |
379 0xDB}, // XK_quoteright+AE11+XK_question+XK_Yacute: VKEY_OEM_4 | |
380 {0x0027, | |
381 0x15, | |
382 0x002A, | |
383 0x0000, | |
384 0xBB}, // XK_quoteright+AE12+XK_asterisk+NoSymbol: VKEY_OEM_PLUS | |
385 {0x0027, | |
386 0x30, | |
387 0x0040, | |
388 0x0000, | |
389 0xC0}, // XK_quoteright+AC11+XK_at+NoSymbol: VKEY_OEM_3 | |
390 {0x0027, | |
391 0x33, | |
392 0x002A, | |
393 0x0000, | |
394 0xBF}, // XK_quoteright+BKSL+XK_asterisk+NoSymbol: VKEY_OEM_2 | |
395 {0x0027, | |
396 0x33, | |
397 0x002A, | |
398 0x00BD, | |
399 0xDC}, // XK_quoteright+BKSL+XK_asterisk+XK_onehalf: VKEY_OEM_5 | |
400 {0x0027, | |
401 0x33, | |
402 0x002A, | |
403 0x01A3, | |
404 0xBF}, // XK_quoteright+BKSL+XK_asterisk+XK_Lstroke: VKEY_OEM_2 | |
405 {0x0027, | |
406 0x34, | |
407 0x0022, | |
408 0x0000, | |
409 0x5A}, // XK_quoteright+AB01+XK_quotedbl+NoSymbol: VKEY_Z | |
410 {0x0027, | |
411 0x34, | |
412 0x0022, | |
413 0x01D8, | |
414 0xDE}, // XK_quoteright+AB01+XK_quotedbl+XK_Rcaron: VKEY_OEM_7 | |
415 {0x002B, | |
416 0x14, | |
417 0x003F, | |
418 0x0000, | |
419 0xBB}, // XK_plus+AE11+XK_question+NoSymbol: VKEY_OEM_PLUS | |
420 {0x002B, | |
421 0x14, | |
422 0x003F, | |
423 0x005C, | |
424 0xBD}, // XK_plus+AE11+XK_question+XK_backslash: VKEY_OEM_MINUS | |
425 {0x002B, | |
426 0x14, | |
427 0x003F, | |
428 0x01F5, | |
429 0xBB}, // XK_plus+AE11+XK_question+XK_odoubleacute: VKEY_OEM_PLUS | |
430 {0x002D, | |
431 0x15, | |
432 0x005F, | |
433 0x0000, | |
434 0xBD}, // XK_minus+AE12+XK_underscore+NoSymbol: VKEY_OEM_MINUS | |
435 {0x002D, | |
436 0x15, | |
437 0x005F, | |
438 0x03B3, | |
439 0xDB}, // XK_minus+AE12+XK_underscore+XK_rcedilla: VKEY_OEM_4 | |
440 {0x002D, | |
441 0x3D, | |
442 0x005F, | |
443 0x0000, | |
444 0xBD}, // XK_minus+AB10+XK_underscore+NoSymbol: VKEY_OEM_MINUS | |
445 {0x002D, | |
446 0x3D, | |
447 0x005F, | |
448 0x002A, | |
449 0xBD}, // XK_minus+AB10+XK_underscore+XK_asterisk: VKEY_OEM_MINUS | |
450 {0x002D, | |
451 0x3D, | |
452 0x005F, | |
453 0x002F, | |
454 0xBF}, // XK_minus+AB10+XK_underscore+XK_slash: VKEY_OEM_2 | |
455 {0x002D, | |
456 0x3D, | |
457 0x005F, | |
458 0x006E, | |
459 0xBD}, // XK_minus+AB10+XK_underscore+XK_n: VKEY_OEM_MINUS | |
460 {0x003D, | |
461 0x14, | |
462 0x0025, | |
463 0x0000, | |
464 0xBB}, // XK_equal+AE11+XK_percent+NoSymbol: VKEY_OEM_PLUS | |
465 {0x003D, | |
466 0x14, | |
467 0x0025, | |
468 0x002D, | |
469 0xBD}, // XK_equal+AE11+XK_percent+XK_minus: VKEY_OEM_MINUS | |
470 {0x005C, | |
471 0x31, | |
472 0x007C, | |
473 0x0031, | |
474 0xDC}, // XK_backslash+TLDE+XK_bar+XK_1: VKEY_OEM_5 | |
475 {0x005C, | |
476 0x31, | |
477 0x007C, | |
478 0x03D1, | |
479 0xC0}, // XK_backslash+TLDE+XK_bar+XK_Ncedilla: VKEY_OEM_3 | |
480 {0x0060, | |
481 0x31, | |
482 0x007E, | |
483 0x0000, | |
484 0xC0}, // XK_quoteleft+TLDE+XK_asciitilde+NoSymbol: VKEY_OEM_3 | |
485 {0x0060, | |
486 0x31, | |
487 0x007E, | |
488 0x0031, | |
489 0xC0}, // XK_quoteleft+TLDE+XK_asciitilde+XK_1: VKEY_OEM_3 | |
490 {0x0060, | |
491 0x31, | |
492 0x007E, | |
493 0x003B, | |
494 0xC0}, // XK_quoteleft+TLDE+XK_asciitilde+XK_semicolon: VKEY_OEM_3 | |
495 {0x0060, | |
496 0x31, | |
497 0x007E, | |
498 0x0060, | |
499 0xC0}, // XK_quoteleft+TLDE+XK_asciitilde+XK_quoteleft: VKEY_OEM_3 | |
500 {0x0060, | |
501 0x31, | |
502 0x007E, | |
503 0x00BF, | |
504 0xC0}, // XK_quoteleft+TLDE+XK_asciitilde+XK_questiondown: VKEY_OEM_3 | |
505 {0x0060, | |
506 0x31, | |
507 0x007E, | |
508 0x01F5, | |
509 0xC0}, // XK_quoteleft+TLDE+XK_asciitilde+XK_odoubleacute: VKEY_OEM_3 | |
510 {0x00E4, | |
511 0x30, | |
512 0x00C4, | |
513 0x0000, | |
514 0xDE}, // XK_adiaeresis+AC11+XK_Adiaeresis+NoSymbol: VKEY_OEM_7 | |
515 {0x00E4, | |
516 0x30, | |
517 0x00C4, | |
518 0x01A6, | |
519 0xDE}, // XK_adiaeresis+AC11+XK_Adiaeresis+XK_Sacute: VKEY_OEM_7 | |
520 {0x00E4, | |
521 0x30, | |
522 0x00C4, | |
523 0x01F8, | |
524 0xDE}, // XK_adiaeresis+AC11+XK_Adiaeresis+XK_rcaron: VKEY_OEM_7 | |
525 {0x00E7, | |
526 0x2F, | |
527 0x00C7, | |
528 0x0000, | |
529 0xBA}, // XK_ccedilla+AC10+XK_Ccedilla+NoSymbol: VKEY_OEM_1 | |
530 {0x00E7, | |
531 0x2F, | |
532 0x00C7, | |
533 0x00DE, | |
534 0xC0}, // XK_ccedilla+AC10+XK_Ccedilla+XK_Thorn: VKEY_OEM_3 | |
535 {0x00F6, | |
536 0x2F, | |
537 0x00D6, | |
538 0x0000, | |
539 0xC0}, // XK_odiaeresis+AC10+XK_Odiaeresis+NoSymbol: VKEY_OEM_3 | |
540 {0x00F6, | |
541 0x2F, | |
542 0x00D6, | |
543 0x01DE, | |
544 0xC0}, // XK_odiaeresis+AC10+XK_Odiaeresis+XK_Tcedilla: VKEY_OEM_3 | |
545 {0x00FC, | |
546 0x14, | |
547 0x00DC, | |
548 0x0000, | |
549 0xBF}, // XK_udiaeresis+AE11+XK_Udiaeresis+NoSymbol: VKEY_OEM_2 | |
550 {0x00FC, | |
551 0x22, | |
552 0x00DC, | |
553 0x0000, | |
554 0xBA}, // XK_udiaeresis+AD11+XK_Udiaeresis+NoSymbol: VKEY_OEM_1 | |
555 {0x00FC, | |
556 0x22, | |
557 0x00DC, | |
558 0x01A3, | |
559 0xC0}, // XK_udiaeresis+AD11+XK_Udiaeresis+XK_Lstroke: VKEY_OEM_3 | |
560 {0x01EA, | |
561 0x3D, | |
562 0x01CA, | |
563 0x0000, | |
564 0xBD}, // XK_eogonek+AB10+XK_Eogonek+NoSymbol: VKEY_OEM_MINUS | |
565 {0x01EA, | |
566 0x3D, | |
567 0x01CA, | |
568 0x006E, | |
569 0xBF}, // XK_eogonek+AB10+XK_Eogonek+XK_n: VKEY_OEM_2 | |
570 {0x03E7, | |
571 0x22, | |
572 0x03C7, | |
573 0x0000, | |
574 0xDB}, // XK_iogonek+AD11+XK_Iogonek+NoSymbol: VKEY_OEM_4 | |
575 {0x03F9, | |
576 0x2F, | |
577 0x03D9, | |
578 0x0000, | |
579 0xC0}, // XK_uogonek+AC10+XK_Uogonek+NoSymbol: VKEY_OEM_3 | |
580 {0x03F9, | |
581 0x2F, | |
582 0x03D9, | |
583 0x01DE, | |
584 0xBA}, // XK_uogonek+AC10+XK_Uogonek+XK_Tcedilla: VKEY_OEM_1 | |
585 }; | |
586 | |
587 template <class T_MAP> | |
588 KeyboardCode FindVK(const T_MAP& key, const T_MAP* map, size_t size) { | |
589 T_MAP comp = {0}; | |
590 const T_MAP* p = std::lower_bound(map, map + size, key, comp); | |
591 if (p != map + size && !comp(*p, key) && !comp(key, *p)) | |
592 return static_cast<KeyboardCode>(p->vk); | |
593 return VKEY_UNKNOWN; | |
594 } | |
595 | |
596 } // namespace | |
597 | |
598 // Get an ui::KeyboardCode from an X keyevent | |
599 KeyboardCode KeyboardCodeFromXKeyEvent(const XEvent* xev) { | |
600 // Gets correct VKEY code from XEvent is performed as the following steps: | |
601 // 1. Gets the keysym without modifier states. | |
602 // 2. For [a-z] & [0-9] cases, returns the VKEY code accordingly. | |
603 // 3. Find keysym in map0. | |
604 // 4. If not found, fallback to find keysym + hardware_code in map1. | |
605 // 5. If not found, fallback to find keysym + keysym_shift + hardware_code | |
606 // in map2. | |
607 // 6. If not found, fallback to find keysym + keysym_shift + keysym_altgr + | |
608 // hardware_code in map3. | |
609 // 7. If not found, fallback to find in KeyboardCodeFromXKeysym(), which | |
610 // mainly for non-letter keys. | |
611 // 8. If not found, fallback to find with the hardware code in US layout. | |
612 | |
613 KeySym keysym = NoSymbol; | |
614 XEvent xkeyevent = {0}; | |
615 if (xev->type == GenericEvent) { | |
616 // Convert the XI2 key event into a core key event so that we can | |
617 // continue to use XLookupString() until crbug.com/367732 is complete. | |
618 InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent); | |
619 } else { | |
620 xkeyevent.xkey = xev->xkey; | |
621 } | |
622 KeyboardCode keycode = VKEY_UNKNOWN; | |
623 XKeyEvent* xkey = &xkeyevent.xkey; | |
624 // XLookupKeysym does not take into consideration the state of the lock/shift | |
625 // etc. keys. So it is necessary to use XLookupString instead. | |
626 XLookupString(xkey, NULL, 0, &keysym, NULL); | |
627 if (IsKeypadKey(keysym) || IsPrivateKeypadKey(keysym) || | |
628 IsCursorKey(keysym) || IsPFKey(keysym) || IsFunctionKey(keysym) || | |
629 IsModifierKey(keysym)) { | |
630 return KeyboardCodeFromXKeysym(keysym); | |
631 } | |
632 | |
633 // If |xkey| has modifiers set, other than NumLock, then determine the | |
634 // un-modified KeySym and use that to map, so that e.g. Ctrl+D correctly | |
635 // generates VKEY_D. | |
636 if (xkey->state & 0xFF & ~Mod2Mask) { | |
637 xkey->state &= (~0xFF | Mod2Mask); | |
638 XLookupString(xkey, NULL, 0, &keysym, NULL); | |
639 } | |
640 | |
641 // [a-z] cases. | |
642 if (keysym >= XK_a && keysym <= XK_z) | |
643 return static_cast<KeyboardCode>(VKEY_A + keysym - XK_a); | |
644 | |
645 // [0-9] cases. | |
646 if (keysym >= XK_0 && keysym <= XK_9) | |
647 return static_cast<KeyboardCode>(VKEY_0 + keysym - XK_0); | |
648 | |
649 if (!IsKeypadKey(keysym) && !IsPrivateKeypadKey(keysym) && | |
650 !IsCursorKey(keysym) && !IsPFKey(keysym) && !IsFunctionKey(keysym) && | |
651 !IsModifierKey(keysym)) { | |
652 MAP0 key0 = {keysym & 0xFFFF, 0}; | |
653 keycode = FindVK(key0, map0, arraysize(map0)); | |
654 if (keycode != VKEY_UNKNOWN) | |
655 return keycode; | |
656 | |
657 MAP1 key1 = {keysym & 0xFFFF, xkey->keycode, 0}; | |
658 keycode = FindVK(key1, map1, arraysize(map1)); | |
659 if (keycode != VKEY_UNKNOWN) | |
660 return keycode; | |
661 | |
662 KeySym keysym_shift = NoSymbol; | |
663 xkey->state |= ShiftMask; | |
664 XLookupString(xkey, NULL, 0, &keysym_shift, NULL); | |
665 MAP2 key2 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0}; | |
666 keycode = FindVK(key2, map2, arraysize(map2)); | |
667 if (keycode != VKEY_UNKNOWN) | |
668 return keycode; | |
669 | |
670 KeySym keysym_altgr = NoSymbol; | |
671 xkey->state &= ~ShiftMask; | |
672 xkey->state |= Mod1Mask; | |
673 XLookupString(xkey, NULL, 0, &keysym_altgr, NULL); | |
674 MAP3 key3 = {keysym & 0xFFFF, | |
675 xkey->keycode, | |
676 keysym_shift & 0xFFFF, | |
677 keysym_altgr & 0xFFFF, | |
678 0}; | |
679 keycode = FindVK(key3, map3, arraysize(map3)); | |
680 if (keycode != VKEY_UNKNOWN) | |
681 return keycode; | |
682 | |
683 // On Linux some keys has AltGr char but not on Windows. | |
684 // So if cannot find VKEY with (ch0+sc+ch1+ch2) in map3, tries to fallback | |
685 // to just find VKEY with (ch0+sc+ch1). This is the best we could do. | |
686 MAP3 key4 = {keysym & 0xFFFF, xkey->keycode, keysym_shift & 0xFFFF, 0, 0}; | |
687 const MAP3* p = | |
688 std::lower_bound(map3, map3 + arraysize(map3), key4, MAP3()); | |
689 if (p != map3 + arraysize(map3) && p->ch0 == key4.ch0 && p->sc == key4.sc && | |
690 p->ch1 == key4.ch1) | |
691 return static_cast<KeyboardCode>(p->vk); | |
692 } | |
693 | |
694 keycode = KeyboardCodeFromXKeysym(keysym); | |
695 if (keycode == VKEY_UNKNOWN && !IsModifierKey(keysym)) { | |
696 // Modifier keys should not fall back to the hardware-keycode-based US | |
697 // layout. See crbug.com/402320 | |
698 keycode = DefaultKeyboardCodeFromHardwareKeycode(xkey->keycode); | |
699 } | |
700 | |
701 return keycode; | |
702 } | |
703 | |
704 KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { | |
705 // TODO(sad): Have |keysym| go through the X map list? | |
706 | |
707 switch (keysym) { | |
708 case XK_BackSpace: | |
709 return VKEY_BACK; | |
710 case XK_Delete: | |
711 case XK_KP_Delete: | |
712 return VKEY_DELETE; | |
713 case XK_Tab: | |
714 case XK_KP_Tab: | |
715 case XK_ISO_Left_Tab: | |
716 case XK_3270_BackTab: | |
717 return VKEY_TAB; | |
718 case XK_Linefeed: | |
719 case XK_Return: | |
720 case XK_KP_Enter: | |
721 case XK_ISO_Enter: | |
722 return VKEY_RETURN; | |
723 case XK_Clear: | |
724 case XK_KP_Begin: // NumPad 5 without Num Lock, for crosbug.com/29169. | |
725 return VKEY_CLEAR; | |
726 case XK_KP_Space: | |
727 case XK_space: | |
728 return VKEY_SPACE; | |
729 case XK_Home: | |
730 case XK_KP_Home: | |
731 return VKEY_HOME; | |
732 case XK_End: | |
733 case XK_KP_End: | |
734 return VKEY_END; | |
735 case XK_Page_Up: | |
736 case XK_KP_Page_Up: // aka XK_KP_Prior | |
737 return VKEY_PRIOR; | |
738 case XK_Page_Down: | |
739 case XK_KP_Page_Down: // aka XK_KP_Next | |
740 return VKEY_NEXT; | |
741 case XK_Left: | |
742 case XK_KP_Left: | |
743 return VKEY_LEFT; | |
744 case XK_Right: | |
745 case XK_KP_Right: | |
746 return VKEY_RIGHT; | |
747 case XK_Down: | |
748 case XK_KP_Down: | |
749 return VKEY_DOWN; | |
750 case XK_Up: | |
751 case XK_KP_Up: | |
752 return VKEY_UP; | |
753 case XK_Escape: | |
754 return VKEY_ESCAPE; | |
755 case XK_Kana_Lock: | |
756 case XK_Kana_Shift: | |
757 return VKEY_KANA; | |
758 case XK_Hangul: | |
759 return VKEY_HANGUL; | |
760 case XK_Hangul_Hanja: | |
761 return VKEY_HANJA; | |
762 case XK_Kanji: | |
763 return VKEY_KANJI; | |
764 case XK_Henkan: | |
765 return VKEY_CONVERT; | |
766 case XK_Muhenkan: | |
767 return VKEY_NONCONVERT; | |
768 case XK_Zenkaku_Hankaku: | |
769 return VKEY_DBE_DBCSCHAR; | |
770 | |
771 case XK_KP_0: | |
772 case XK_KP_1: | |
773 case XK_KP_2: | |
774 case XK_KP_3: | |
775 case XK_KP_4: | |
776 case XK_KP_5: | |
777 case XK_KP_6: | |
778 case XK_KP_7: | |
779 case XK_KP_8: | |
780 case XK_KP_9: | |
781 return static_cast<KeyboardCode>(VKEY_NUMPAD0 + (keysym - XK_KP_0)); | |
782 | |
783 case XK_multiply: | |
784 case XK_KP_Multiply: | |
785 return VKEY_MULTIPLY; | |
786 case XK_KP_Add: | |
787 return VKEY_ADD; | |
788 case XK_KP_Separator: | |
789 return VKEY_SEPARATOR; | |
790 case XK_KP_Subtract: | |
791 return VKEY_SUBTRACT; | |
792 case XK_KP_Decimal: | |
793 return VKEY_DECIMAL; | |
794 case XK_KP_Divide: | |
795 return VKEY_DIVIDE; | |
796 case XK_KP_Equal: | |
797 case XK_equal: | |
798 case XK_plus: | |
799 return VKEY_OEM_PLUS; | |
800 case XK_comma: | |
801 case XK_less: | |
802 return VKEY_OEM_COMMA; | |
803 case XK_minus: | |
804 case XK_underscore: | |
805 return VKEY_OEM_MINUS; | |
806 case XK_greater: | |
807 case XK_period: | |
808 return VKEY_OEM_PERIOD; | |
809 case XK_colon: | |
810 case XK_semicolon: | |
811 return VKEY_OEM_1; | |
812 case XK_question: | |
813 case XK_slash: | |
814 return VKEY_OEM_2; | |
815 case XK_asciitilde: | |
816 case XK_quoteleft: | |
817 return VKEY_OEM_3; | |
818 case XK_bracketleft: | |
819 case XK_braceleft: | |
820 return VKEY_OEM_4; | |
821 case XK_backslash: | |
822 case XK_bar: | |
823 return VKEY_OEM_5; | |
824 case XK_bracketright: | |
825 case XK_braceright: | |
826 return VKEY_OEM_6; | |
827 case XK_quoteright: | |
828 case XK_quotedbl: | |
829 return VKEY_OEM_7; | |
830 case XK_ISO_Level5_Shift: | |
831 return VKEY_OEM_8; | |
832 case XK_Shift_L: | |
833 case XK_Shift_R: | |
834 return VKEY_SHIFT; | |
835 case XK_Control_L: | |
836 case XK_Control_R: | |
837 return VKEY_CONTROL; | |
838 case XK_Meta_L: | |
839 case XK_Meta_R: | |
840 case XK_Alt_L: | |
841 case XK_Alt_R: | |
842 return VKEY_MENU; | |
843 case XK_ISO_Level3_Shift: | |
844 case XK_Mode_switch: | |
845 return VKEY_ALTGR; | |
846 case XK_Multi_key: | |
847 return VKEY_COMPOSE; | |
848 case XK_Pause: | |
849 return VKEY_PAUSE; | |
850 case XK_Caps_Lock: | |
851 return VKEY_CAPITAL; | |
852 case XK_Num_Lock: | |
853 return VKEY_NUMLOCK; | |
854 case XK_Scroll_Lock: | |
855 return VKEY_SCROLL; | |
856 case XK_Select: | |
857 return VKEY_SELECT; | |
858 case XK_Print: | |
859 return VKEY_PRINT; | |
860 case XK_Execute: | |
861 return VKEY_EXECUTE; | |
862 case XK_Insert: | |
863 case XK_KP_Insert: | |
864 return VKEY_INSERT; | |
865 case XK_Help: | |
866 return VKEY_HELP; | |
867 case XK_Super_L: | |
868 return VKEY_LWIN; | |
869 case XK_Super_R: | |
870 return VKEY_RWIN; | |
871 case XK_Menu: | |
872 return VKEY_APPS; | |
873 case XK_F1: | |
874 case XK_F2: | |
875 case XK_F3: | |
876 case XK_F4: | |
877 case XK_F5: | |
878 case XK_F6: | |
879 case XK_F7: | |
880 case XK_F8: | |
881 case XK_F9: | |
882 case XK_F10: | |
883 case XK_F11: | |
884 case XK_F12: | |
885 case XK_F13: | |
886 case XK_F14: | |
887 case XK_F15: | |
888 case XK_F16: | |
889 case XK_F17: | |
890 case XK_F18: | |
891 case XK_F19: | |
892 case XK_F20: | |
893 case XK_F21: | |
894 case XK_F22: | |
895 case XK_F23: | |
896 case XK_F24: | |
897 return static_cast<KeyboardCode>(VKEY_F1 + (keysym - XK_F1)); | |
898 case XK_KP_F1: | |
899 case XK_KP_F2: | |
900 case XK_KP_F3: | |
901 case XK_KP_F4: | |
902 return static_cast<KeyboardCode>(VKEY_F1 + (keysym - XK_KP_F1)); | |
903 | |
904 case XK_guillemotleft: | |
905 case XK_guillemotright: | |
906 case XK_degree: | |
907 // In the case of canadian multilingual keyboard layout, VKEY_OEM_102 is | |
908 // assigned to ugrave key. | |
909 case XK_ugrave: | |
910 case XK_Ugrave: | |
911 case XK_brokenbar: | |
912 return VKEY_OEM_102; // international backslash key in 102 keyboard. | |
913 | |
914 // When evdev is in use, /usr/share/X11/xkb/symbols/inet maps F13-18 keys | |
915 // to the special XF86XK symbols to support Microsoft Ergonomic keyboards: | |
916 // https://bugs.freedesktop.org/show_bug.cgi?id=5783 | |
917 // In Chrome, we map these X key symbols back to F13-18 since we don't have | |
918 // VKEYs for these XF86XK symbols. | |
919 case XF86XK_Tools: | |
920 return VKEY_F13; | |
921 case XF86XK_Launch5: | |
922 return VKEY_F14; | |
923 case XF86XK_Launch6: | |
924 return VKEY_F15; | |
925 case XF86XK_Launch7: | |
926 return VKEY_F16; | |
927 case XF86XK_Launch8: | |
928 return VKEY_F17; | |
929 case XF86XK_Launch9: | |
930 return VKEY_F18; | |
931 | |
932 // For supporting multimedia buttons on a USB keyboard. | |
933 case XF86XK_Back: | |
934 return VKEY_BROWSER_BACK; | |
935 case XF86XK_Forward: | |
936 return VKEY_BROWSER_FORWARD; | |
937 case XF86XK_Reload: | |
938 return VKEY_BROWSER_REFRESH; | |
939 case XF86XK_Stop: | |
940 return VKEY_BROWSER_STOP; | |
941 case XF86XK_Search: | |
942 return VKEY_BROWSER_SEARCH; | |
943 case XF86XK_Favorites: | |
944 return VKEY_BROWSER_FAVORITES; | |
945 case XF86XK_HomePage: | |
946 return VKEY_BROWSER_HOME; | |
947 case XF86XK_AudioMute: | |
948 return VKEY_VOLUME_MUTE; | |
949 case XF86XK_AudioLowerVolume: | |
950 return VKEY_VOLUME_DOWN; | |
951 case XF86XK_AudioRaiseVolume: | |
952 return VKEY_VOLUME_UP; | |
953 case XF86XK_AudioNext: | |
954 return VKEY_MEDIA_NEXT_TRACK; | |
955 case XF86XK_AudioPrev: | |
956 return VKEY_MEDIA_PREV_TRACK; | |
957 case XF86XK_AudioStop: | |
958 return VKEY_MEDIA_STOP; | |
959 case XF86XK_AudioPlay: | |
960 return VKEY_MEDIA_PLAY_PAUSE; | |
961 case XF86XK_Mail: | |
962 return VKEY_MEDIA_LAUNCH_MAIL; | |
963 case XF86XK_LaunchA: // F3 on an Apple keyboard. | |
964 return VKEY_MEDIA_LAUNCH_APP1; | |
965 case XF86XK_LaunchB: // F4 on an Apple keyboard. | |
966 case XF86XK_Calculator: | |
967 return VKEY_MEDIA_LAUNCH_APP2; | |
968 case XF86XK_WLAN: | |
969 return VKEY_WLAN; | |
970 case XF86XK_PowerOff: | |
971 return VKEY_POWER; | |
972 case XF86XK_Sleep: | |
973 return VKEY_SLEEP; | |
974 case XF86XK_MonBrightnessDown: | |
975 return VKEY_BRIGHTNESS_DOWN; | |
976 case XF86XK_MonBrightnessUp: | |
977 return VKEY_BRIGHTNESS_UP; | |
978 case XF86XK_KbdBrightnessDown: | |
979 return VKEY_KBD_BRIGHTNESS_DOWN; | |
980 case XF86XK_KbdBrightnessUp: | |
981 return VKEY_KBD_BRIGHTNESS_UP; | |
982 | |
983 // TODO(sad): some keycodes are still missing. | |
984 } | |
985 DVLOG(1) << "Unknown keysym: " << base::StringPrintf("0x%x", keysym); | |
986 return VKEY_UNKNOWN; | |
987 } | |
988 | |
989 const char* CodeFromXEvent(const XEvent* xev) { | |
990 int keycode = (xev->type == GenericEvent) | |
991 ? static_cast<XIDeviceEvent*>(xev->xcookie.data)->detail | |
992 : xev->xkey.keycode; | |
993 return ui::KeycodeConverter::NativeKeycodeToCode(keycode); | |
994 } | |
995 | |
996 uint16 GetCharacterFromXEvent(const XEvent* xev) { | |
997 XEvent xkeyevent = {0}; | |
998 const XKeyEvent* xkey = NULL; | |
999 if (xev->type == GenericEvent) { | |
1000 // Convert the XI2 key event into a core key event so that we can | |
1001 // continue to use XLookupString() until crbug.com/367732 is complete. | |
1002 InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent); | |
1003 xkey = &xkeyevent.xkey; | |
1004 } else { | |
1005 xkey = &xev->xkey; | |
1006 } | |
1007 KeySym keysym = XK_VoidSymbol; | |
1008 XLookupString(const_cast<XKeyEvent*>(xkey), NULL, 0, &keysym, NULL); | |
1009 return GetUnicodeCharacterFromXKeySym(keysym); | |
1010 } | |
1011 | |
1012 KeyboardCode DefaultKeyboardCodeFromHardwareKeycode( | |
1013 unsigned int hardware_code) { | |
1014 // This function assumes that X11 is using evdev-based keycodes. | |
1015 static const KeyboardCode kHardwareKeycodeMap[] = { | |
1016 // Please refer to below links for the table content: | |
1017 // http://www.w3.org/TR/DOM-Level-3-Events-code/#keyboard-101 | |
1018 // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode | |
1019 // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-92
3143f3456c/translate.pdf | |
1020 VKEY_UNKNOWN, // 0x00: | |
1021 VKEY_UNKNOWN, // 0x01: | |
1022 VKEY_UNKNOWN, // 0x02: | |
1023 VKEY_UNKNOWN, // 0x03: | |
1024 VKEY_UNKNOWN, // 0x04: | |
1025 VKEY_UNKNOWN, // 0x05: | |
1026 VKEY_UNKNOWN, // 0x06: | |
1027 VKEY_UNKNOWN, // XKB evdev (XKB - 8) X KeySym | |
1028 VKEY_UNKNOWN, // === =============== ====== | |
1029 VKEY_ESCAPE, // 0x09: KEY_ESC Escape | |
1030 VKEY_1, // 0x0A: KEY_1 1 | |
1031 VKEY_2, // 0x0B: KEY_2 2 | |
1032 VKEY_3, // 0x0C: KEY_3 3 | |
1033 VKEY_4, // 0x0D: KEY_4 4 | |
1034 VKEY_5, // 0x0E: KEY_5 5 | |
1035 VKEY_6, // 0x0F: KEY_6 6 | |
1036 VKEY_7, // 0x10: KEY_7 7 | |
1037 VKEY_8, // 0x11: KEY_8 8 | |
1038 VKEY_9, // 0x12: KEY_9 9 | |
1039 VKEY_0, // 0x13: KEY_0 0 | |
1040 VKEY_OEM_MINUS, // 0x14: KEY_MINUS minus | |
1041 VKEY_OEM_PLUS, // 0x15: KEY_EQUAL equal | |
1042 VKEY_BACK, // 0x16: KEY_BACKSPACE BackSpace | |
1043 VKEY_TAB, // 0x17: KEY_TAB Tab | |
1044 VKEY_Q, // 0x18: KEY_Q q | |
1045 VKEY_W, // 0x19: KEY_W w | |
1046 VKEY_E, // 0x1A: KEY_E e | |
1047 VKEY_R, // 0x1B: KEY_R r | |
1048 VKEY_T, // 0x1C: KEY_T t | |
1049 VKEY_Y, // 0x1D: KEY_Y y | |
1050 VKEY_U, // 0x1E: KEY_U u | |
1051 VKEY_I, // 0x1F: KEY_I i | |
1052 VKEY_O, // 0x20: KEY_O o | |
1053 VKEY_P, // 0x21: KEY_P p | |
1054 VKEY_OEM_4, // 0x22: KEY_LEFTBRACE bracketleft | |
1055 VKEY_OEM_6, // 0x23: KEY_RIGHTBRACE bracketright | |
1056 VKEY_RETURN, // 0x24: KEY_ENTER Return | |
1057 VKEY_LCONTROL, // 0x25: KEY_LEFTCTRL Control_L | |
1058 VKEY_A, // 0x26: KEY_A a | |
1059 VKEY_S, // 0x27: KEY_S s | |
1060 VKEY_D, // 0x28: KEY_D d | |
1061 VKEY_F, // 0x29: KEY_F f | |
1062 VKEY_G, // 0x2A: KEY_G g | |
1063 VKEY_H, // 0x2B: KEY_H h | |
1064 VKEY_J, // 0x2C: KEY_J j | |
1065 VKEY_K, // 0x2D: KEY_K k | |
1066 VKEY_L, // 0x2E: KEY_L l | |
1067 VKEY_OEM_1, // 0x2F: KEY_SEMICOLON semicolon | |
1068 VKEY_OEM_7, // 0x30: KEY_APOSTROPHE apostrophe | |
1069 VKEY_OEM_3, // 0x31: KEY_GRAVE grave | |
1070 VKEY_LSHIFT, // 0x32: KEY_LEFTSHIFT Shift_L | |
1071 VKEY_OEM_5, // 0x33: KEY_BACKSLASH backslash | |
1072 VKEY_Z, // 0x34: KEY_Z z | |
1073 VKEY_X, // 0x35: KEY_X x | |
1074 VKEY_C, // 0x36: KEY_C c | |
1075 VKEY_V, // 0x37: KEY_V v | |
1076 VKEY_B, // 0x38: KEY_B b | |
1077 VKEY_N, // 0x39: KEY_N n | |
1078 VKEY_M, // 0x3A: KEY_M m | |
1079 VKEY_OEM_COMMA, // 0x3B: KEY_COMMA comma | |
1080 VKEY_OEM_PERIOD, // 0x3C: KEY_DOT period | |
1081 VKEY_OEM_2, // 0x3D: KEY_SLASH slash | |
1082 VKEY_RSHIFT, // 0x3E: KEY_RIGHTSHIFT Shift_R | |
1083 VKEY_MULTIPLY, // 0x3F: KEY_KPASTERISK KP_Multiply | |
1084 VKEY_LMENU, // 0x40: KEY_LEFTALT Alt_L | |
1085 VKEY_SPACE, // 0x41: KEY_SPACE space | |
1086 VKEY_CAPITAL, // 0x42: KEY_CAPSLOCK Caps_Lock | |
1087 VKEY_F1, // 0x43: KEY_F1 F1 | |
1088 VKEY_F2, // 0x44: KEY_F2 F2 | |
1089 VKEY_F3, // 0x45: KEY_F3 F3 | |
1090 VKEY_F4, // 0x46: KEY_F4 F4 | |
1091 VKEY_F5, // 0x47: KEY_F5 F5 | |
1092 VKEY_F6, // 0x48: KEY_F6 F6 | |
1093 VKEY_F7, // 0x49: KEY_F7 F7 | |
1094 VKEY_F8, // 0x4A: KEY_F8 F8 | |
1095 VKEY_F9, // 0x4B: KEY_F9 F9 | |
1096 VKEY_F10, // 0x4C: KEY_F10 F10 | |
1097 VKEY_NUMLOCK, // 0x4D: KEY_NUMLOCK Num_Lock | |
1098 VKEY_SCROLL, // 0x4E: KEY_SCROLLLOCK Scroll_Lock | |
1099 VKEY_NUMPAD7, // 0x4F: KEY_KP7 KP_7 | |
1100 VKEY_NUMPAD8, // 0x50: KEY_KP8 KP_8 | |
1101 VKEY_NUMPAD9, // 0x51: KEY_KP9 KP_9 | |
1102 VKEY_SUBTRACT, // 0x52: KEY_KPMINUS KP_Subtract | |
1103 VKEY_NUMPAD4, // 0x53: KEY_KP4 KP_4 | |
1104 VKEY_NUMPAD5, // 0x54: KEY_KP5 KP_5 | |
1105 VKEY_NUMPAD6, // 0x55: KEY_KP6 KP_6 | |
1106 VKEY_ADD, // 0x56: KEY_KPPLUS KP_Add | |
1107 VKEY_NUMPAD1, // 0x57: KEY_KP1 KP_1 | |
1108 VKEY_NUMPAD2, // 0x58: KEY_KP2 KP_2 | |
1109 VKEY_NUMPAD3, // 0x59: KEY_KP3 KP_3 | |
1110 VKEY_NUMPAD0, // 0x5A: KEY_KP0 KP_0 | |
1111 VKEY_DECIMAL, // 0x5B: KEY_KPDOT KP_Decimal | |
1112 VKEY_UNKNOWN, // 0x5C: | |
1113 VKEY_DBE_DBCSCHAR, // 0x5D: KEY_ZENKAKUHANKAKU Zenkaku_Hankaku | |
1114 VKEY_OEM_5, // 0x5E: KEY_102ND backslash | |
1115 VKEY_F11, // 0x5F: KEY_F11 F11 | |
1116 VKEY_F12, // 0x60: KEY_F12 F12 | |
1117 VKEY_OEM_102, // 0x61: KEY_RO Romaji | |
1118 VKEY_UNSUPPORTED, // 0x62: KEY_KATAKANA Katakana | |
1119 VKEY_UNSUPPORTED, // 0x63: KEY_HIRAGANA Hiragana | |
1120 VKEY_CONVERT, // 0x64: KEY_HENKAN Henkan | |
1121 VKEY_UNSUPPORTED, // 0x65: KEY_KATAKANAHIRAGANA Hiragana_Katakana | |
1122 VKEY_NONCONVERT, // 0x66: KEY_MUHENKAN Muhenkan | |
1123 VKEY_SEPARATOR, // 0x67: KEY_KPJPCOMMA KP_Separator | |
1124 VKEY_RETURN, // 0x68: KEY_KPENTER KP_Enter | |
1125 VKEY_RCONTROL, // 0x69: KEY_RIGHTCTRL Control_R | |
1126 VKEY_DIVIDE, // 0x6A: KEY_KPSLASH KP_Divide | |
1127 VKEY_PRINT, // 0x6B: KEY_SYSRQ Print | |
1128 VKEY_RMENU, // 0x6C: KEY_RIGHTALT Alt_R | |
1129 VKEY_RETURN, // 0x6D: KEY_LINEFEED Linefeed | |
1130 VKEY_HOME, // 0x6E: KEY_HOME Home | |
1131 VKEY_UP, // 0x6F: KEY_UP Up | |
1132 VKEY_PRIOR, // 0x70: KEY_PAGEUP Page_Up | |
1133 VKEY_LEFT, // 0x71: KEY_LEFT Left | |
1134 VKEY_RIGHT, // 0x72: KEY_RIGHT Right | |
1135 VKEY_END, // 0x73: KEY_END End | |
1136 VKEY_DOWN, // 0x74: KEY_DOWN Down | |
1137 VKEY_NEXT, // 0x75: KEY_PAGEDOWN Page_Down | |
1138 VKEY_INSERT, // 0x76: KEY_INSERT Insert | |
1139 VKEY_DELETE, // 0x77: KEY_DELETE Delete | |
1140 VKEY_UNSUPPORTED, // 0x78: KEY_MACRO | |
1141 VKEY_VOLUME_MUTE, // 0x79: KEY_MUTE XF86AudioMute | |
1142 VKEY_VOLUME_DOWN, // 0x7A: KEY_VOLUMEDOWN XF86AudioLowerVolume | |
1143 VKEY_VOLUME_UP, // 0x7B: KEY_VOLUMEUP XF86AudioRaiseVolume | |
1144 VKEY_POWER, // 0x7C: KEY_POWER XF86PowerOff | |
1145 VKEY_OEM_PLUS, // 0x7D: KEY_KPEQUAL KP_Equal | |
1146 VKEY_UNSUPPORTED, // 0x7E: KEY_KPPLUSMINUS plusminus | |
1147 VKEY_PAUSE, // 0x7F: KEY_PAUSE Pause | |
1148 VKEY_MEDIA_LAUNCH_APP1, // 0x80: KEY_SCALE XF86LaunchA | |
1149 VKEY_DECIMAL, // 0x81: KEY_KPCOMMA KP_Decimal | |
1150 VKEY_HANGUL, // 0x82: KEY_HANGUEL Hangul | |
1151 VKEY_HANJA, // 0x83: KEY_HANJA Hangul_Hanja | |
1152 VKEY_OEM_5, // 0x84: KEY_YEN yen | |
1153 VKEY_LWIN, // 0x85: KEY_LEFTMETA Super_L | |
1154 VKEY_RWIN, // 0x86: KEY_RIGHTMETA Super_R | |
1155 VKEY_COMPOSE, // 0x87: KEY_COMPOSE Menu | |
1156 }; | |
1157 | |
1158 if (hardware_code >= arraysize(kHardwareKeycodeMap)) { | |
1159 // Additional keycodes used by the Chrome OS top row special function keys. | |
1160 switch (hardware_code) { | |
1161 case 0xA6: // KEY_BACK | |
1162 return VKEY_BACK; | |
1163 case 0xA7: // KEY_FORWARD | |
1164 return VKEY_BROWSER_FORWARD; | |
1165 case 0xB5: // KEY_REFRESH | |
1166 return VKEY_BROWSER_REFRESH; | |
1167 case 0xD4: // KEY_DASHBOARD | |
1168 return VKEY_MEDIA_LAUNCH_APP2; | |
1169 case 0xE8: // KEY_BRIGHTNESSDOWN | |
1170 return VKEY_BRIGHTNESS_DOWN; | |
1171 case 0xE9: // KEY_BRIGHTNESSUP | |
1172 return VKEY_BRIGHTNESS_UP; | |
1173 } | |
1174 return VKEY_UNKNOWN; | |
1175 } | |
1176 return kHardwareKeycodeMap[hardware_code]; | |
1177 } | |
1178 | |
1179 // TODO(jcampan): this method might be incomplete. | |
1180 int XKeysymForWindowsKeyCode(KeyboardCode keycode, bool shift) { | |
1181 switch (keycode) { | |
1182 case VKEY_NUMPAD0: | |
1183 return XK_KP_0; | |
1184 case VKEY_NUMPAD1: | |
1185 return XK_KP_1; | |
1186 case VKEY_NUMPAD2: | |
1187 return XK_KP_2; | |
1188 case VKEY_NUMPAD3: | |
1189 return XK_KP_3; | |
1190 case VKEY_NUMPAD4: | |
1191 return XK_KP_4; | |
1192 case VKEY_NUMPAD5: | |
1193 return XK_KP_5; | |
1194 case VKEY_NUMPAD6: | |
1195 return XK_KP_6; | |
1196 case VKEY_NUMPAD7: | |
1197 return XK_KP_7; | |
1198 case VKEY_NUMPAD8: | |
1199 return XK_KP_8; | |
1200 case VKEY_NUMPAD9: | |
1201 return XK_KP_9; | |
1202 case VKEY_MULTIPLY: | |
1203 return XK_KP_Multiply; | |
1204 case VKEY_ADD: | |
1205 return XK_KP_Add; | |
1206 case VKEY_SUBTRACT: | |
1207 return XK_KP_Subtract; | |
1208 case VKEY_DECIMAL: | |
1209 return XK_KP_Decimal; | |
1210 case VKEY_DIVIDE: | |
1211 return XK_KP_Divide; | |
1212 | |
1213 case VKEY_BACK: | |
1214 return XK_BackSpace; | |
1215 case VKEY_TAB: | |
1216 return shift ? XK_ISO_Left_Tab : XK_Tab; | |
1217 case VKEY_CLEAR: | |
1218 return XK_Clear; | |
1219 case VKEY_RETURN: | |
1220 return XK_Return; | |
1221 case VKEY_SHIFT: | |
1222 return XK_Shift_L; | |
1223 case VKEY_CONTROL: | |
1224 return XK_Control_L; | |
1225 case VKEY_MENU: | |
1226 return XK_Alt_L; | |
1227 case VKEY_APPS: | |
1228 return XK_Menu; | |
1229 case VKEY_ALTGR: | |
1230 return XK_ISO_Level3_Shift; | |
1231 case VKEY_COMPOSE: | |
1232 return XK_Multi_key; | |
1233 | |
1234 case VKEY_PAUSE: | |
1235 return XK_Pause; | |
1236 case VKEY_CAPITAL: | |
1237 return XK_Caps_Lock; | |
1238 case VKEY_KANA: | |
1239 return XK_Kana_Lock; | |
1240 case VKEY_HANJA: | |
1241 return XK_Hangul_Hanja; | |
1242 case VKEY_CONVERT: | |
1243 return XK_Henkan; | |
1244 case VKEY_NONCONVERT: | |
1245 return XK_Muhenkan; | |
1246 case VKEY_DBE_SBCSCHAR: | |
1247 return XK_Zenkaku_Hankaku; | |
1248 case VKEY_DBE_DBCSCHAR: | |
1249 return XK_Zenkaku_Hankaku; | |
1250 case VKEY_ESCAPE: | |
1251 return XK_Escape; | |
1252 case VKEY_SPACE: | |
1253 return XK_space; | |
1254 case VKEY_PRIOR: | |
1255 return XK_Page_Up; | |
1256 case VKEY_NEXT: | |
1257 return XK_Page_Down; | |
1258 case VKEY_END: | |
1259 return XK_End; | |
1260 case VKEY_HOME: | |
1261 return XK_Home; | |
1262 case VKEY_LEFT: | |
1263 return XK_Left; | |
1264 case VKEY_UP: | |
1265 return XK_Up; | |
1266 case VKEY_RIGHT: | |
1267 return XK_Right; | |
1268 case VKEY_DOWN: | |
1269 return XK_Down; | |
1270 case VKEY_SELECT: | |
1271 return XK_Select; | |
1272 case VKEY_PRINT: | |
1273 return XK_Print; | |
1274 case VKEY_EXECUTE: | |
1275 return XK_Execute; | |
1276 case VKEY_INSERT: | |
1277 return XK_Insert; | |
1278 case VKEY_DELETE: | |
1279 return XK_Delete; | |
1280 case VKEY_HELP: | |
1281 return XK_Help; | |
1282 case VKEY_0: | |
1283 return shift ? XK_parenright : XK_0; | |
1284 case VKEY_1: | |
1285 return shift ? XK_exclam : XK_1; | |
1286 case VKEY_2: | |
1287 return shift ? XK_at : XK_2; | |
1288 case VKEY_3: | |
1289 return shift ? XK_numbersign : XK_3; | |
1290 case VKEY_4: | |
1291 return shift ? XK_dollar : XK_4; | |
1292 case VKEY_5: | |
1293 return shift ? XK_percent : XK_5; | |
1294 case VKEY_6: | |
1295 return shift ? XK_asciicircum : XK_6; | |
1296 case VKEY_7: | |
1297 return shift ? XK_ampersand : XK_7; | |
1298 case VKEY_8: | |
1299 return shift ? XK_asterisk : XK_8; | |
1300 case VKEY_9: | |
1301 return shift ? XK_parenleft : XK_9; | |
1302 | |
1303 case VKEY_A: | |
1304 case VKEY_B: | |
1305 case VKEY_C: | |
1306 case VKEY_D: | |
1307 case VKEY_E: | |
1308 case VKEY_F: | |
1309 case VKEY_G: | |
1310 case VKEY_H: | |
1311 case VKEY_I: | |
1312 case VKEY_J: | |
1313 case VKEY_K: | |
1314 case VKEY_L: | |
1315 case VKEY_M: | |
1316 case VKEY_N: | |
1317 case VKEY_O: | |
1318 case VKEY_P: | |
1319 case VKEY_Q: | |
1320 case VKEY_R: | |
1321 case VKEY_S: | |
1322 case VKEY_T: | |
1323 case VKEY_U: | |
1324 case VKEY_V: | |
1325 case VKEY_W: | |
1326 case VKEY_X: | |
1327 case VKEY_Y: | |
1328 case VKEY_Z: | |
1329 return (shift ? XK_A : XK_a) + (keycode - VKEY_A); | |
1330 | |
1331 case VKEY_LWIN: | |
1332 return XK_Super_L; | |
1333 case VKEY_RWIN: | |
1334 return XK_Super_R; | |
1335 | |
1336 case VKEY_NUMLOCK: | |
1337 return XK_Num_Lock; | |
1338 | |
1339 case VKEY_SCROLL: | |
1340 return XK_Scroll_Lock; | |
1341 | |
1342 case VKEY_OEM_1: | |
1343 return shift ? XK_colon : XK_semicolon; | |
1344 case VKEY_OEM_PLUS: | |
1345 return shift ? XK_plus : XK_equal; | |
1346 case VKEY_OEM_COMMA: | |
1347 return shift ? XK_less : XK_comma; | |
1348 case VKEY_OEM_MINUS: | |
1349 return shift ? XK_underscore : XK_minus; | |
1350 case VKEY_OEM_PERIOD: | |
1351 return shift ? XK_greater : XK_period; | |
1352 case VKEY_OEM_2: | |
1353 return shift ? XK_question : XK_slash; | |
1354 case VKEY_OEM_3: | |
1355 return shift ? XK_asciitilde : XK_quoteleft; | |
1356 case VKEY_OEM_4: | |
1357 return shift ? XK_braceleft : XK_bracketleft; | |
1358 case VKEY_OEM_5: | |
1359 return shift ? XK_bar : XK_backslash; | |
1360 case VKEY_OEM_6: | |
1361 return shift ? XK_braceright : XK_bracketright; | |
1362 case VKEY_OEM_7: | |
1363 return shift ? XK_quotedbl : XK_quoteright; | |
1364 case VKEY_OEM_8: | |
1365 return XK_ISO_Level5_Shift; | |
1366 case VKEY_OEM_102: | |
1367 return shift ? XK_guillemotleft : XK_guillemotright; | |
1368 | |
1369 case VKEY_F1: | |
1370 case VKEY_F2: | |
1371 case VKEY_F3: | |
1372 case VKEY_F4: | |
1373 case VKEY_F5: | |
1374 case VKEY_F6: | |
1375 case VKEY_F7: | |
1376 case VKEY_F8: | |
1377 case VKEY_F9: | |
1378 case VKEY_F10: | |
1379 case VKEY_F11: | |
1380 case VKEY_F12: | |
1381 case VKEY_F13: | |
1382 case VKEY_F14: | |
1383 case VKEY_F15: | |
1384 case VKEY_F16: | |
1385 case VKEY_F17: | |
1386 case VKEY_F18: | |
1387 case VKEY_F19: | |
1388 case VKEY_F20: | |
1389 case VKEY_F21: | |
1390 case VKEY_F22: | |
1391 case VKEY_F23: | |
1392 case VKEY_F24: | |
1393 return XK_F1 + (keycode - VKEY_F1); | |
1394 | |
1395 case VKEY_BROWSER_BACK: | |
1396 return XF86XK_Back; | |
1397 case VKEY_BROWSER_FORWARD: | |
1398 return XF86XK_Forward; | |
1399 case VKEY_BROWSER_REFRESH: | |
1400 return XF86XK_Reload; | |
1401 case VKEY_BROWSER_STOP: | |
1402 return XF86XK_Stop; | |
1403 case VKEY_BROWSER_SEARCH: | |
1404 return XF86XK_Search; | |
1405 case VKEY_BROWSER_FAVORITES: | |
1406 return XF86XK_Favorites; | |
1407 case VKEY_BROWSER_HOME: | |
1408 return XF86XK_HomePage; | |
1409 case VKEY_VOLUME_MUTE: | |
1410 return XF86XK_AudioMute; | |
1411 case VKEY_VOLUME_DOWN: | |
1412 return XF86XK_AudioLowerVolume; | |
1413 case VKEY_VOLUME_UP: | |
1414 return XF86XK_AudioRaiseVolume; | |
1415 case VKEY_MEDIA_NEXT_TRACK: | |
1416 return XF86XK_AudioNext; | |
1417 case VKEY_MEDIA_PREV_TRACK: | |
1418 return XF86XK_AudioPrev; | |
1419 case VKEY_MEDIA_STOP: | |
1420 return XF86XK_AudioStop; | |
1421 case VKEY_MEDIA_PLAY_PAUSE: | |
1422 return XF86XK_AudioPlay; | |
1423 case VKEY_MEDIA_LAUNCH_MAIL: | |
1424 return XF86XK_Mail; | |
1425 case VKEY_MEDIA_LAUNCH_APP1: | |
1426 return XF86XK_LaunchA; | |
1427 case VKEY_MEDIA_LAUNCH_APP2: | |
1428 return XF86XK_LaunchB; | |
1429 case VKEY_WLAN: | |
1430 return XF86XK_WLAN; | |
1431 case VKEY_POWER: | |
1432 return XF86XK_PowerOff; | |
1433 case VKEY_BRIGHTNESS_DOWN: | |
1434 return XF86XK_MonBrightnessDown; | |
1435 case VKEY_BRIGHTNESS_UP: | |
1436 return XF86XK_MonBrightnessUp; | |
1437 case VKEY_KBD_BRIGHTNESS_DOWN: | |
1438 return XF86XK_KbdBrightnessDown; | |
1439 case VKEY_KBD_BRIGHTNESS_UP: | |
1440 return XF86XK_KbdBrightnessUp; | |
1441 | |
1442 default: | |
1443 LOG(WARNING) << "Unknown keycode:" << keycode; | |
1444 return 0; | |
1445 } | |
1446 } | |
1447 | |
1448 void InitXKeyEventFromXIDeviceEvent(const XEvent& src, XEvent* xkeyevent) { | |
1449 DCHECK(src.type == GenericEvent); | |
1450 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(src.xcookie.data); | |
1451 switch (xievent->evtype) { | |
1452 case XI_KeyPress: | |
1453 xkeyevent->type = KeyPress; | |
1454 break; | |
1455 case XI_KeyRelease: | |
1456 xkeyevent->type = KeyRelease; | |
1457 break; | |
1458 default: | |
1459 NOTREACHED(); | |
1460 } | |
1461 xkeyevent->xkey.serial = xievent->serial; | |
1462 xkeyevent->xkey.send_event = xievent->send_event; | |
1463 xkeyevent->xkey.display = xievent->display; | |
1464 xkeyevent->xkey.window = xievent->event; | |
1465 xkeyevent->xkey.root = xievent->root; | |
1466 xkeyevent->xkey.subwindow = xievent->child; | |
1467 xkeyevent->xkey.time = xievent->time; | |
1468 xkeyevent->xkey.x = xievent->event_x; | |
1469 xkeyevent->xkey.y = xievent->event_y; | |
1470 xkeyevent->xkey.x_root = xievent->root_x; | |
1471 xkeyevent->xkey.y_root = xievent->root_y; | |
1472 xkeyevent->xkey.state = xievent->mods.effective; | |
1473 xkeyevent->xkey.keycode = xievent->detail; | |
1474 xkeyevent->xkey.same_screen = 1; | |
1475 } | |
1476 | |
1477 unsigned int XKeyCodeForWindowsKeyCode(ui::KeyboardCode key_code, | |
1478 int flags, | |
1479 XDisplay* display) { | |
1480 // SHIFT state is ignored in the call to XKeysymForWindowsKeyCode() here | |
1481 // because we map the XKeysym back to a keycode, i.e. a physical key position. | |
1482 // Using a SHIFT-modified XKeysym would sometimes yield X keycodes that, | |
1483 // while technically valid, may be surprising in that they do not match | |
1484 // the keycode of the original press, and conflict with assumptions in | |
1485 // other code. | |
1486 // | |
1487 // For example, in a US layout, Shift-9 has the interpretation XK_parenleft, | |
1488 // but the keycode KEY_9 alone does not map to XK_parenleft; instead, | |
1489 // XKeysymToKeycode() returns KEY_KPLEFTPAREN (keypad left parenthesis) | |
1490 // which does map to XK_parenleft -- notwithstanding that keyboards with | |
1491 // dedicated number pad parenthesis keys are currently uncommon. | |
1492 // | |
1493 // Similarly, Shift-Comma has the interpretation XK_less, but KEY_COMMA | |
1494 // alone does not map to XK_less; XKeysymToKeycode() returns KEY_102ND | |
1495 // (the '<>' key between Shift and Z on 105-key keyboards) which does. | |
1496 // | |
1497 // crbug.com/386066 and crbug.com/390263 are examples of problems | |
1498 // associated with this. | |
1499 // | |
1500 return XKeysymToKeycode(display, XKeysymForWindowsKeyCode(key_code, false)); | |
1501 } | |
1502 | |
1503 } // namespace ui | |
OLD | NEW |