| 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 |