Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: ui/events/platform/x11/keyboard_code_conversion_x11.cc

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW
« no previous file with comments | « ui/events/platform/x11/keyboard_code_conversion_x11.h ('k') | ui/events/platform/x11/keysym_to_unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698