Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 1 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 2 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 3 | 4 |
| 4 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h" | 5 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h" |
| 5 | 6 |
| 6 #include <xkbcommon/xkbcommon-names.h> | 7 #include <xkbcommon/xkbcommon-names.h> |
| 7 | 8 |
| 8 #include "base/logging.h" | 9 #include "base/logging.h" |
| 9 #include "ui/events/event_constants.h" | 10 #include "ui/events/event_constants.h" |
| 11 #include "ui/events/keycodes/dom3/dom_code.h" | |
| 10 #include "ui/events/keycodes/dom3/dom_key.h" | 12 #include "ui/events/keycodes/dom3/dom_key.h" |
| 11 #include "ui/events/keycodes/dom4/keycode_converter.h" | 13 #include "ui/events/keycodes/dom4/keycode_converter.h" |
| 12 #include "ui/events/ozone/layout/layout_util.h" | 14 #include "ui/events/ozone/layout/layout_util.h" |
| 13 #include "ui/events/ozone/layout/xkb/xkb_keyboard_code_conversion.h" | 15 #include "ui/events/ozone/layout/xkb/xkb_keyboard_code_conversion.h" |
| 14 | 16 |
| 15 namespace ui { | 17 namespace ui { |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 19 // Temporarily hard-code an initial layout to test libxkbcommon. | 21 // Temporarily hard-code an initial layout to test libxkbcommon. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 case 0x0A: | 199 case 0x0A: |
| 198 case 0x0D: | 200 case 0x0D: |
| 199 return DomKey::ENTER; | 201 return DomKey::ENTER; |
| 200 case 0x1B: | 202 case 0x1B: |
| 201 return DomKey::ESCAPE; | 203 return DomKey::ESCAPE; |
| 202 default: | 204 default: |
| 203 return DomKey::CHARACTER; | 205 return DomKey::CHARACTER; |
| 204 } | 206 } |
| 205 } | 207 } |
| 206 | 208 |
| 207 KeyboardCode DifficultKeyboardCode(DomCode dom_code, | 209 KeyboardCode AlphanumericKeyboardCode(base::char16 character) { |
| 208 int flags, | 210 // Plain ASCII letters and digits map directly to VKEY values. |
| 209 DomKey dom_key, | 211 if ((character >= '0') && (character <= '9')) |
| 210 base::char16 character) { | 212 return static_cast<KeyboardCode>(VKEY_0 + character - '0'); |
| 211 // TODO(kpschoedel): correct key_code for non-US layouts along the lines | 213 if ((character >= 'a') && (character <= 'z')) |
| 212 // of KeyboardCodeFromXKeyEvent() | 214 return static_cast<KeyboardCode>(VKEY_A + character - 'a'); |
| 213 return DomCodeToKeyboardCode(dom_code); | 215 if ((character >= 'A') && (character <= 'Z')) |
| 216 return static_cast<KeyboardCode>(VKEY_A + character - 'A'); | |
| 217 return VKEY_UNKNOWN; | |
| 214 } | 218 } |
| 215 | 219 |
| 220 // These tables map layout-dependent printable characters/codes | |
| 221 // to legacy Windows-based VKEY values. | |
| 222 // | |
| 223 // VKEYs are determined by the character produced from a DomCode without | |
| 224 // any modifiers, plus zero or more of the DomCode itself, the character | |
| 225 // produced with the Shift modifier, and the character produced with the | |
| 226 // AltGr modifier. | |
| 227 | |
| 228 // A table of one or more PrintableSubEntry cases applies when the VKEY is | |
| 229 // not determined by the unmodified character value alone. Each such table | |
| 230 // corresponds to one unmodified character value. For an entry to match, | |
| 231 // the dom_code must match, and, if test_X is set, then the character for | |
| 232 // the key plus modifier X must also match. | |
| 233 struct PrintableSubEntry { | |
| 234 DomCode dom_code; | |
| 235 bool test_shift : 1; | |
| 236 bool test_altgr : 1; | |
| 237 base::char16 shift_character; | |
| 238 base::char16 altgr_character; | |
| 239 KeyboardCode key_code; | |
| 240 }; | |
| 241 | |
| 242 // U+0021 exclamation mark | |
| 243 const PrintableSubEntry u0021[] = { | |
|
spang
2014/12/08 23:07:30
These identifiers should start with 'k' as in kons
kpschoedel
2014/12/09 00:32:37
Done.
| |
| 244 {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, | |
| 245 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 246 {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_8}}; | |
| 247 | |
| 248 // U+0022 quote | |
| 249 const PrintableSubEntry u0022[] = { | |
| 250 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, | |
| 251 {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}}; | |
| 252 | |
| 253 // U+0023 number sign | |
| 254 const PrintableSubEntry u0023[] = { | |
| 255 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 256 {DomCode::BACKSLASH, 1, 0, 0x0027, 0xFFFF, VKEY_OEM_2}, // apostrophe | |
| 257 {DomCode::BACKSLASH, 1, 1, 0x007E, 0x0000, VKEY_OEM_7}}; // ~, NUL | |
| 258 | |
| 259 // U+0024 dollar sign | |
| 260 const PrintableSubEntry u0024[] = { | |
| 261 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 262 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_8}}; | |
| 263 | |
| 264 // U+0027 apostrophe | |
| 265 const PrintableSubEntry u0027[] = { | |
| 266 {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, | |
| 267 {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 268 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 269 {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 270 {DomCode::QUOTE, 1, 0, 0x0022, 0xFFFF, VKEY_OEM_7}, // quote | |
| 271 {DomCode::BACKQUOTE, 1, 0, 0x0022, 0xFFFF, VKEY_OEM_3}, // quote | |
| 272 {DomCode::BACKQUOTE, 1, 0, 0x00B7, 0xFFFF, VKEY_OEM_5}, // middle dot | |
| 273 {DomCode::BACKSLASH, 1, 0, 0x0000, 0xFFFF, VKEY_OEM_5}, // NUL | |
| 274 {DomCode::MINUS, 1, 1, 0x003F, 0x0000, VKEY_OEM_4}, // ?, NUL | |
| 275 {DomCode::MINUS, 1, 1, 0x003F, 0x00DD, VKEY_OEM_4}, // ?, Y acute | |
| 276 {DomCode::EQUAL, 1, 1, 0x002A, 0x0000, VKEY_OEM_PLUS}, // *, NUL | |
| 277 {DomCode::QUOTE, 1, 1, 0x0040, 0x0000, VKEY_OEM_3}, // @, NUL | |
| 278 {DomCode::BACKSLASH, 1, 1, 0x002A, 0x0000, VKEY_OEM_2}, // *, NUL | |
| 279 {DomCode::BACKSLASH, 1, 1, 0x002A, 0x00BD, VKEY_OEM_5}, // *, one half | |
| 280 {DomCode::BACKSLASH, 1, 1, 0x002A, 0x0141, VKEY_OEM_2}, // *, L stroke | |
| 281 {DomCode::KEY_Z, 1, 1, 0x0022, 0x0000, VKEY_Z}, // quote, NUL | |
| 282 {DomCode::KEY_Z, 1, 1, 0x0022, 0x0158, VKEY_OEM_7}}; // quote, R caron | |
| 283 | |
| 284 // U+0028 left parenthesis | |
| 285 const PrintableSubEntry u0028[] = { | |
| 286 {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, | |
| 287 {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, | |
| 288 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 289 | |
| 290 // U+0029 right parenthesis | |
| 291 const PrintableSubEntry u0029[] = { | |
| 292 {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, | |
| 293 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 294 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; | |
| 295 | |
| 296 // U+002A * | |
| 297 const PrintableSubEntry u002A[] = { | |
| 298 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 299 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 300 | |
| 301 // U+002B plus sign | |
| 302 const PrintableSubEntry u002B[] = { | |
| 303 {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, | |
| 304 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 305 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 306 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 307 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 308 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, | |
| 309 {DomCode::MINUS, 1, 1, 0x003F, 0x0000, VKEY_OEM_PLUS}, // ?, NUL | |
| 310 {DomCode::MINUS, 1, 1, 0x003F, 0x005C, VKEY_OEM_MINUS}, // ?, backslash | |
| 311 {DomCode::MINUS, 1, 1, 0x003F, 0x0151, VKEY_OEM_PLUS}}; // ?, o'' | |
| 312 | |
| 313 // U+002C comma | |
| 314 const PrintableSubEntry u002C[] = { | |
| 315 {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}, | |
| 316 {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, | |
| 317 {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, | |
| 318 {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, | |
| 319 {DomCode::KEY_W, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, | |
| 320 {DomCode::KEY_V, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, | |
| 321 {DomCode::KEY_M, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, | |
| 322 {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}}; | |
| 323 | |
| 324 // U+002D hyphen-minus | |
| 325 const PrintableSubEntry u002D[] = { | |
| 326 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, | |
| 327 {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, | |
| 328 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}, | |
| 329 {DomCode::KEY_A, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}, | |
| 330 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}, | |
| 331 {DomCode::SLASH, 1, 0, 0x003D, 0xFFFF, VKEY_OEM_MINUS}, // = | |
| 332 {DomCode::EQUAL, 1, 1, 0x005F, 0x0000, VKEY_OEM_MINUS}, // _, NUL | |
| 333 {DomCode::EQUAL, 1, 1, 0x005F, 0x0157, VKEY_OEM_4}, // _, r cedilla | |
| 334 {DomCode::SLASH, 1, 1, 0x005F, 0x0000, VKEY_OEM_MINUS}, // _, NUL | |
| 335 {DomCode::SLASH, 1, 1, 0x005F, 0x002A, VKEY_OEM_MINUS}, // _, * | |
| 336 {DomCode::SLASH, 1, 1, 0x005F, 0x002F, VKEY_OEM_2}, // _, / | |
| 337 {DomCode::SLASH, 1, 1, 0x005F, 0x006E, VKEY_OEM_MINUS}}; // _, n | |
| 338 | |
| 339 // U+002E full stop | |
| 340 const PrintableSubEntry u002E[] = { | |
| 341 {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, | |
| 342 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 343 {DomCode::KEY_E, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, | |
| 344 {DomCode::KEY_R, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, | |
| 345 {DomCode::KEY_O, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, | |
| 346 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 347 {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, | |
| 348 {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; | |
| 349 | |
| 350 // U+002F / | |
| 351 const PrintableSubEntry u002F[] = { | |
| 352 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 353 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, | |
| 354 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 355 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}, | |
| 356 {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, | |
| 357 {DomCode::DIGIT3, 1, 0, 0x0033, 0xFFFF, VKEY_3}, // 3 | |
| 358 {DomCode::DIGIT3, 1, 0, 0x003F, 0xFFFF, VKEY_OEM_2}, // ? | |
| 359 {DomCode::DIGIT0, 1, 0, 0x0030, 0xFFFF, VKEY_0}, // 0 | |
| 360 {DomCode::DIGIT0, 1, 0, 0x003F, 0xFFFF, VKEY_OEM_2}}; // ? | |
| 361 | |
| 362 // U+003A colon | |
| 363 const PrintableSubEntry u003A[] = { | |
| 364 {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, | |
| 365 {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, | |
| 366 {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, | |
| 367 {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; | |
| 368 | |
| 369 // U+003B semicolon | |
| 370 const PrintableSubEntry u003B[] = { | |
| 371 {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, | |
| 372 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 373 {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 374 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 375 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 376 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 377 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, | |
| 378 {DomCode::KEY_Z, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 379 {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, | |
| 380 {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; | |
| 381 | |
| 382 // U+003D = | |
| 383 const PrintableSubEntry u003D[] = { | |
| 384 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 385 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 386 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 387 {DomCode::SLASH, 1, 0, 0x0025, 0xFFFF, VKEY_OEM_8}, // % | |
| 388 {DomCode::SLASH, 1, 0, 0x002B, 0xFFFF, VKEY_OEM_PLUS}, // + | |
| 389 {DomCode::MINUS, 1, 1, 0x0025, 0x0000, VKEY_OEM_PLUS}, // %, NUL | |
| 390 {DomCode::MINUS, 1, 1, 0x0025, 0x002D, VKEY_OEM_MINUS}}; // %, - | |
| 391 | |
| 392 // U+003F ? | |
| 393 const PrintableSubEntry u003F[] = { | |
| 394 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, | |
| 395 {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, | |
| 396 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 397 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}}; | |
| 398 | |
| 399 // U+0040 @ | |
| 400 const PrintableSubEntry u0040[] = { | |
| 401 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 402 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 403 | |
| 404 // U+005B left square bracket | |
| 405 const PrintableSubEntry u005B[] = { | |
| 406 {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 407 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 408 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 409 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 410 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 411 | |
| 412 // U+005C backslash | |
| 413 const PrintableSubEntry u005C[] = { | |
| 414 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 415 {DomCode::BACKSLASH, 1, 0, 0x002F, 0xFFFF, VKEY_OEM_7}, // / | |
| 416 {DomCode::BACKSLASH, 1, 0, 0x007C, 0xFFFF, VKEY_OEM_5}, // | | |
| 417 {DomCode::BACKQUOTE, 1, 1, 0x007C, 0x0031, VKEY_OEM_5}, // |, 1 | |
| 418 {DomCode::BACKQUOTE, 1, 1, 0x007C, 0x0145, VKEY_OEM_3}}; // |, N cedilla | |
| 419 | |
| 420 // U+005D right square bracket | |
| 421 const PrintableSubEntry u005D[] = { | |
| 422 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 423 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 424 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 425 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, | |
| 426 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 427 | |
| 428 // U+005F _ | |
| 429 const PrintableSubEntry u005F[] = { | |
| 430 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 431 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}}; | |
| 432 | |
| 433 // U+0060 grave accent | |
| 434 const PrintableSubEntry u0060[] = { | |
| 435 {DomCode::BACKQUOTE, 1, 0, 0x0000, 0xFFFF, VKEY_OEM_3}, // NUL | |
| 436 {DomCode::BACKQUOTE, 1, 0, 0x00AC, 0xFFFF, VKEY_OEM_8}, // not | |
| 437 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0000, VKEY_OEM_3}, // ~, NUL | |
| 438 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0031, VKEY_OEM_3}, // ~, 1 | |
| 439 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x003B, VKEY_OEM_3}, // ~, ; | |
| 440 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0060, VKEY_OEM_3}, // ~, ` | |
| 441 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x00BF, VKEY_OEM_3}, // ~, inverted ? | |
| 442 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0151, VKEY_OEM_3}}; // ~, o'' | |
| 443 | |
| 444 // U+00A7 section | |
| 445 const PrintableSubEntry u00A7[] = { | |
| 446 {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, | |
| 447 {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, | |
| 448 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 449 {DomCode::BACKQUOTE, 1, 0, 0x00B0, 0xFFFF, VKEY_OEM_2}, // degree | |
| 450 {DomCode::BACKQUOTE, 1, 0, 0x00BD, 0xFFFF, VKEY_OEM_5}}; // one half | |
| 451 | |
| 452 // U+00AB left-pointing double angle quote | |
| 453 const PrintableSubEntry u00AB[] = { | |
| 454 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 455 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; | |
| 456 | |
| 457 // U+00B0 degree | |
| 458 const PrintableSubEntry u00B0[] = { | |
| 459 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, | |
| 460 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 461 | |
| 462 // U+00BA masculine ordinal indicator | |
| 463 const PrintableSubEntry u00BA[] = { | |
| 464 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 465 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 466 | |
| 467 // U+00E0 a grave | |
| 468 const PrintableSubEntry u00E0[] = { | |
| 469 {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, | |
| 470 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}, | |
| 471 {DomCode::QUOTE, 1, 0, 0x00B0, 0xFFFF, VKEY_OEM_7}, // degree | |
| 472 {DomCode::QUOTE, 1, 0, 0x00E4, 0xFFFF, VKEY_OEM_5}}; // a diaeresis | |
| 473 | |
| 474 // U+00E1 a acute | |
| 475 const PrintableSubEntry u00E1[] = { | |
| 476 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 477 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 478 | |
| 479 // U+00E2 a circumflex | |
| 480 const PrintableSubEntry u00E2[] = { | |
| 481 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, | |
| 482 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 483 | |
| 484 // U+00E4 a diaeresis | |
| 485 const PrintableSubEntry u00E4[] = { | |
| 486 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 487 {DomCode::QUOTE, 1, 0, 0x00E0, 0xFFFF, VKEY_OEM_5}, // a grave | |
| 488 {DomCode::QUOTE, 1, 1, 0x00C4, 0x0000, VKEY_OEM_7}, // A dia., NUL | |
| 489 {DomCode::QUOTE, 1, 1, 0x00C4, 0x015A, VKEY_OEM_7}, // A dia., S acute | |
| 490 {DomCode::QUOTE, 1, 1, 0x00C4, 0x0159, VKEY_OEM_7}}; // A dia., r caron | |
| 491 | |
| 492 // U+00E6 ae | |
| 493 const PrintableSubEntry u00E6[] = { | |
| 494 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, | |
| 495 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 496 | |
| 497 // U+00E7 c cedilla | |
| 498 const PrintableSubEntry u00E7[] = { | |
| 499 {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, | |
| 500 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 501 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 502 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, | |
| 503 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, | |
| 504 {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, | |
| 505 {DomCode::SEMICOLON, 1, 1, 0x00C7, 0x0000, VKEY_OEM_1}, // C ced., NUL | |
| 506 {DomCode::SEMICOLON, 1, 1, 0x00C7, 0x00DE, VKEY_OEM_3}}; // C ced., Thorn | |
| 507 | |
| 508 // U+00E8 e grave | |
| 509 const PrintableSubEntry u00E8[] = { | |
| 510 {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, | |
| 511 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 512 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}}; | |
| 513 | |
| 514 // U+00E9 e acute | |
| 515 const PrintableSubEntry u00E9[] = { | |
| 516 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, | |
| 517 {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, | |
| 518 {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, | |
| 519 {DomCode::SEMICOLON, 1, 0, 0x00C9, 0xFFFF, VKEY_OEM_1}, // E acute | |
| 520 {DomCode::SEMICOLON, 1, 0, 0x00F6, 0xFFFF, VKEY_OEM_7}}; // o diaeresis | |
| 521 | |
| 522 // U+00ED i acute | |
| 523 const PrintableSubEntry u00ED[] = { | |
| 524 {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, | |
| 525 {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}}; | |
| 526 | |
| 527 // U+00F0 eth | |
| 528 const PrintableSubEntry u00F0[] = { | |
| 529 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, | |
| 530 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}}; | |
| 531 | |
| 532 // U+00F3 o acute | |
| 533 const PrintableSubEntry u00F3[] = { | |
| 534 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 535 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 536 | |
| 537 // U+00F4 o circumflex | |
| 538 const PrintableSubEntry u00F4[] = { | |
| 539 {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, | |
| 540 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}}; | |
| 541 | |
| 542 // U+00F6 o diaeresis | |
| 543 const PrintableSubEntry u00F6[] = { | |
| 544 {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, | |
| 545 {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 546 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 547 {DomCode::SEMICOLON, 1, 0, 0x00E9, 0xFFFF, VKEY_OEM_7}, // e acute | |
| 548 {DomCode::SEMICOLON, 1, 1, 0x00D6, 0x0000, VKEY_OEM_3}, // O dia., NUL | |
| 549 {DomCode::SEMICOLON, 1, 1, 0x00D6, 0x0162, VKEY_OEM_3}}; // O dia., T ced. | |
| 550 | |
| 551 // U+00F8 o stroke | |
| 552 const PrintableSubEntry u00F8[] = { | |
| 553 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, | |
| 554 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 555 | |
| 556 // U+00F9 u grave | |
| 557 const PrintableSubEntry u00F9[] = { | |
| 558 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, | |
| 559 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; | |
| 560 | |
| 561 // U+00FA u acute | |
| 562 const PrintableSubEntry u00FA[] = { | |
| 563 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 564 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; | |
| 565 | |
| 566 // U+00FC u diaeresis | |
| 567 const PrintableSubEntry u00FC[] = { | |
| 568 {DomCode::KEY_W, 0, 0, 0xFFFF, 0xFFFF, VKEY_W}, | |
| 569 {DomCode::BRACKET_LEFT, 1, 0, 0x00E8, 0xFFFF, VKEY_OEM_1}, // e grave | |
| 570 {DomCode::MINUS, 1, 1, 0x00DC, 0x0000, VKEY_OEM_2}, // U dia., NUL | |
| 571 {DomCode::BRACKET_LEFT, 1, 1, 0x00DC, 0x0000, VKEY_OEM_1}, // U dia., NUL | |
| 572 {DomCode::BRACKET_LEFT, 1, 1, 0x00DC, 0x0141, VKEY_OEM_3}}; // U dia., L- | |
| 573 | |
| 574 // U+0103 a breve | |
| 575 const PrintableSubEntry u0103[] = { | |
| 576 {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, | |
| 577 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}}; | |
| 578 | |
| 579 // U+0105 a ogonek | |
| 580 const PrintableSubEntry u0105[] = { | |
| 581 {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, | |
| 582 {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_Q}, | |
| 583 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 584 | |
| 585 // U+010D c caron | |
| 586 const PrintableSubEntry u010D[] = { | |
| 587 {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, | |
| 588 {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, | |
| 589 {DomCode::KEY_P, 0, 0, 0xFFFF, 0xFFFF, VKEY_X}, | |
| 590 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 591 {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}}; | |
| 592 | |
| 593 // U+0111 d stroke | |
| 594 const PrintableSubEntry u0111[] = { | |
| 595 {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, | |
| 596 {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; | |
| 597 | |
| 598 // U+0117 e dot above | |
| 599 const PrintableSubEntry u0117[] = { | |
| 600 {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, | |
| 601 {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; | |
| 602 | |
| 603 // U+0119 e ogonek | |
| 604 const PrintableSubEntry u0119[] = { | |
| 605 {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}, | |
| 606 {DomCode::SLASH, 1, 1, 0x0118, 0x0000, VKEY_OEM_MINUS}, // E ogonek, NUL | |
| 607 {DomCode::SLASH, 1, 1, 0x0118, 0x006E, VKEY_OEM_2}}; // E ogonek, n | |
| 608 | |
| 609 // U+012F i ogonek | |
| 610 const PrintableSubEntry u012F[] = { | |
| 611 {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, | |
| 612 {DomCode::BRACKET_LEFT, 1, 1, 0x012E, 0x0000, VKEY_OEM_4}}; // Iogonek, NUL | |
| 613 | |
| 614 // U+0142 l stroke | |
| 615 const PrintableSubEntry u0142[] = { | |
| 616 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 617 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; | |
| 618 | |
| 619 // U+015F s cedilla | |
| 620 const PrintableSubEntry u015F[] = { | |
| 621 {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 622 {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}}; | |
| 623 | |
| 624 // U+0161 s caron | |
| 625 const PrintableSubEntry u0161[] = { | |
| 626 {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}, | |
| 627 {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, | |
| 628 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 629 {DomCode::KEY_A, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, | |
| 630 {DomCode::KEY_F, 0, 0, 0xFFFF, 0xFFFF, VKEY_F}, | |
| 631 {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}}; | |
| 632 | |
| 633 // U+016B u macron | |
| 634 const PrintableSubEntry u016B[] = { | |
| 635 {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, | |
| 636 {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_Q}, | |
| 637 {DomCode::KEY_X, 0, 0, 0xFFFF, 0xFFFF, VKEY_X}}; | |
| 638 | |
| 639 // U+0173 u ogonek | |
| 640 const PrintableSubEntry u0173[] = { | |
| 641 {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, | |
| 642 {DomCode::SEMICOLON, 1, 1, 0x0172, 0x0000, VKEY_OEM_3}, // U ogo., NUL | |
| 643 {DomCode::SEMICOLON, 1, 1, 0x0172, 0x0162, VKEY_OEM_1}}; // U ogo., T ced. | |
| 644 | |
| 645 // U+017C z dot above | |
| 646 const PrintableSubEntry u017C[] = { | |
| 647 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, | |
| 648 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 649 | |
| 650 // U+017E z caron | |
| 651 const PrintableSubEntry u017E[] = { | |
| 652 {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, | |
| 653 {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, | |
| 654 {DomCode::KEY_W, 0, 0, 0xFFFF, 0xFFFF, VKEY_W}, | |
| 655 {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_Y}, | |
| 656 {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; | |
| 657 | |
| 658 // Table mapping unshifted characters to PrintableSubEntry tables. | |
| 659 struct PrintableMultiEntry { | |
| 660 base::char16 plain_character; | |
| 661 const PrintableSubEntry* subtable; | |
| 662 size_t subtable_size; | |
| 663 }; | |
| 664 | |
| 665 // Entries are ordered by character value. | |
| 666 const PrintableMultiEntry multi_map[] = { | |
| 667 {0x0021, u0021, arraysize(u0021)}, // exclamation mark | |
| 668 {0x0022, u0022, arraysize(u0022)}, // quotation mark | |
| 669 {0x0023, u0023, arraysize(u0023)}, // number sign | |
| 670 {0x0024, u0024, arraysize(u0024)}, // dollar sign | |
| 671 {0x0027, u0027, arraysize(u0027)}, // apostrophe | |
| 672 {0x0028, u0028, arraysize(u0028)}, // left parenthesis | |
| 673 {0x0029, u0029, arraysize(u0029)}, // right parenthesis | |
| 674 {0x002A, u002A, arraysize(u002A)}, // asterisk | |
| 675 {0x002B, u002B, arraysize(u002B)}, // plus sign | |
| 676 {0x002C, u002C, arraysize(u002C)}, // comma | |
| 677 {0x002D, u002D, arraysize(u002D)}, // hyphen-minus | |
| 678 {0x002E, u002E, arraysize(u002E)}, // full stop | |
| 679 {0x002F, u002F, arraysize(u002F)}, // solidus | |
| 680 {0x003A, u003A, arraysize(u003A)}, // colon | |
| 681 {0x003B, u003B, arraysize(u003B)}, // semicolon | |
| 682 {0x003D, u003D, arraysize(u003D)}, // equals sign | |
| 683 {0x003F, u003F, arraysize(u003F)}, // question mark | |
| 684 {0x0040, u0040, arraysize(u0040)}, // commercial at | |
| 685 {0x005B, u005B, arraysize(u005B)}, // left square bracket | |
| 686 {0x005C, u005C, arraysize(u005C)}, // reverse solidus | |
| 687 {0x005D, u005D, arraysize(u005D)}, // right square bracket | |
| 688 {0x005F, u005F, arraysize(u005F)}, // low line | |
| 689 {0x0060, u0060, arraysize(u0060)}, // grave accent | |
| 690 {0x00A7, u00A7, arraysize(u00A7)}, // section sign | |
| 691 {0x00AB, u00AB, arraysize(u00AB)}, // left double angle quotation mark | |
| 692 {0x00B0, u00B0, arraysize(u00B0)}, // degree sign | |
| 693 {0x00BA, u00BA, arraysize(u00BA)}, // masculine ordinal indicator | |
| 694 {0x00E0, u00E0, arraysize(u00E0)}, // a grave | |
| 695 {0x00E1, u00E1, arraysize(u00E1)}, // a acute | |
| 696 {0x00E2, u00E2, arraysize(u00E2)}, // a circumflex | |
| 697 {0x00E4, u00E4, arraysize(u00E4)}, // a diaeresis | |
| 698 {0x00E6, u00E6, arraysize(u00E6)}, // ae | |
| 699 {0x00E7, u00E7, arraysize(u00E7)}, // c cedilla | |
| 700 {0x00E8, u00E8, arraysize(u00E8)}, // e grave | |
| 701 {0x00E9, u00E9, arraysize(u00E9)}, // e acute | |
| 702 {0x00ED, u00ED, arraysize(u00ED)}, // i acute | |
| 703 {0x00F0, u00F0, arraysize(u00F0)}, // eth | |
| 704 {0x00F3, u00F3, arraysize(u00F3)}, // o acute | |
| 705 {0x00F4, u00F4, arraysize(u00F4)}, // o circumflex | |
| 706 {0x00F6, u00F6, arraysize(u00F6)}, // o diaeresis | |
| 707 {0x00F8, u00F8, arraysize(u00F8)}, // o stroke | |
| 708 {0x00F9, u00F9, arraysize(u00F9)}, // u grave | |
| 709 {0x00FA, u00FA, arraysize(u00FA)}, // u acute | |
| 710 {0x00FC, u00FC, arraysize(u00FC)}, // u diaeresis | |
| 711 {0x0103, u0103, arraysize(u0103)}, // a breve | |
| 712 {0x0105, u0105, arraysize(u0105)}, // a ogonek | |
| 713 {0x010D, u010D, arraysize(u010D)}, // c caron | |
| 714 {0x0111, u0111, arraysize(u0111)}, // d stroke | |
| 715 {0x0117, u0117, arraysize(u0117)}, // e dot above | |
| 716 {0x0119, u0119, arraysize(u0119)}, // e ogonek | |
| 717 {0x012F, u012F, arraysize(u012F)}, // i ogonek | |
| 718 {0x0142, u0142, arraysize(u0142)}, // l stroke | |
| 719 {0x015F, u015F, arraysize(u015F)}, // s cedilla | |
| 720 {0x0161, u0161, arraysize(u0161)}, // s caron | |
| 721 {0x016B, u016B, arraysize(u016B)}, // u macron | |
| 722 {0x0173, u0173, arraysize(u0173)}, // u ogonek | |
| 723 {0x017C, u017C, arraysize(u017C)}, // z dot above | |
| 724 {0x017E, u017E, arraysize(u017E)}, // z caron | |
| 725 }; | |
| 726 | |
| 727 // Table mapping unshifted characters to VKEY values. | |
| 728 struct PrintableSimpleEntry { | |
| 729 base::char16 plain_character; | |
| 730 KeyboardCode key_code; | |
| 731 }; | |
| 732 | |
| 733 // Entries are ordered by character value. | |
| 734 const PrintableSimpleEntry simple_map[] = { | |
| 735 {0x0025, VKEY_5}, // percent sign | |
| 736 {0x0026, VKEY_1}, // ampersand | |
| 737 {0x003C, VKEY_OEM_5}, // less-than sign | |
| 738 {0x007B, VKEY_OEM_7}, // left curly bracket | |
| 739 {0x007C, VKEY_OEM_5}, // vertical line | |
| 740 {0x007D, VKEY_OEM_2}, // right curly bracket | |
| 741 {0x007E, VKEY_OEM_5}, // tilde | |
| 742 {0x00A1, VKEY_OEM_6}, // inverted exclamation mark | |
| 743 {0x00AD, VKEY_OEM_3}, // soft hyphen | |
| 744 {0x00B2, VKEY_OEM_7}, // superscript two | |
| 745 {0x00B5, VKEY_OEM_5}, // micro sign | |
| 746 {0x00BB, VKEY_9}, // right-pointing double angle quotation mark | |
| 747 {0x00BD, VKEY_OEM_5}, // vulgar fraction one half | |
| 748 {0x00BF, VKEY_OEM_6}, // inverted question mark | |
| 749 {0x00DF, VKEY_OEM_4}, // sharp s | |
| 750 {0x00E5, VKEY_OEM_6}, // a ring above | |
| 751 {0x00EA, VKEY_3}, // e circumflex | |
| 752 {0x00EB, VKEY_OEM_1}, // e diaeresis | |
| 753 {0x00EC, VKEY_OEM_6}, // i grave | |
| 754 {0x00EE, VKEY_OEM_6}, // i circumflex | |
| 755 {0x00F1, VKEY_OEM_3}, // n tilde | |
| 756 {0x00F2, VKEY_OEM_3}, // o grave | |
| 757 {0x00F5, VKEY_OEM_4}, // o tilde | |
| 758 {0x00F7, VKEY_OEM_6}, // division sign | |
| 759 {0x00FD, VKEY_7}, // y acute | |
| 760 {0x00FE, VKEY_OEM_MINUS}, // thorn | |
| 761 {0x0101, VKEY_OEM_8}, // a macron | |
| 762 {0x0107, VKEY_OEM_7}, // c acute | |
| 763 {0x010B, VKEY_OEM_3}, // c dot above | |
| 764 {0x0113, VKEY_W}, // e macron | |
| 765 {0x011B, VKEY_2}, // e caron | |
| 766 {0x011F, VKEY_OEM_6}, // g breve | |
| 767 {0x0121, VKEY_OEM_4}, // g dot above | |
| 768 {0x0127, VKEY_OEM_6}, // h stroke | |
| 769 {0x012B, VKEY_OEM_6}, // i macron | |
| 770 {0x0131, VKEY_OEM_1}, // dotless i | |
| 771 {0x0137, VKEY_OEM_5}, // k cedilla | |
| 772 {0x013C, VKEY_OEM_2}, // l cedilla | |
| 773 {0x013E, VKEY_2}, // l caron | |
| 774 {0x0146, VKEY_OEM_4}, // n cedilla | |
| 775 {0x0148, VKEY_OEM_5}, // n caron | |
| 776 {0x0151, VKEY_OEM_4}, // o double acute | |
| 777 {0x0159, VKEY_5}, // r caron | |
| 778 {0x0163, VKEY_OEM_7}, // t cedilla | |
| 779 {0x0165, VKEY_5}, // t caron | |
| 780 {0x016F, VKEY_OEM_1}, // u ring above | |
| 781 {0x0171, VKEY_OEM_5}, // u double acute | |
| 782 {0x01A1, VKEY_OEM_6}, // o horn | |
| 783 {0x01B0, VKEY_OEM_4}, // u horn | |
| 784 {0x01B6, VKEY_OEM_6}, // z stroke | |
| 785 {0x0259, VKEY_OEM_3}, // schwa | |
| 786 }; | |
| 787 | |
| 216 } // anonymous namespace | 788 } // anonymous namespace |
| 217 | 789 |
| 218 XkbKeyCodeConverter::XkbKeyCodeConverter() { | 790 XkbKeyCodeConverter::XkbKeyCodeConverter() { |
| 219 } | 791 } |
| 220 | 792 |
| 221 XkbKeyCodeConverter::~XkbKeyCodeConverter() { | 793 XkbKeyCodeConverter::~XkbKeyCodeConverter() { |
| 222 } | 794 } |
| 223 | 795 |
| 224 XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( | 796 XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( |
| 225 const XkbKeyCodeConverter& converter) | 797 const XkbKeyCodeConverter& converter) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 bool XkbKeyboardLayoutEngine::UsesAltGr() const { | 837 bool XkbKeyboardLayoutEngine::UsesAltGr() const { |
| 266 // NOTIMPLEMENTED(); | 838 // NOTIMPLEMENTED(); |
| 267 return false; | 839 return false; |
| 268 } | 840 } |
| 269 | 841 |
| 270 bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, | 842 bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, |
| 271 int flags, | 843 int flags, |
| 272 DomKey* dom_key, | 844 DomKey* dom_key, |
| 273 base::char16* character, | 845 base::char16* character, |
| 274 KeyboardCode* key_code) const { | 846 KeyboardCode* key_code) const { |
| 847 // Convert DOM physical key to XKB representation. | |
| 275 xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code); | 848 xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code); |
| 276 if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) { | 849 if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) { |
| 277 LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex | 850 LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex |
| 278 << static_cast<int>(dom_code) << " '" | 851 << static_cast<int>(dom_code) << " '" |
| 279 << KeycodeConverter::DomCodeToCodeString(dom_code) << "'"; | 852 << KeycodeConverter::DomCodeToCodeString(dom_code) << "'"; |
| 280 return false; | 853 return false; |
| 281 } | 854 } |
| 282 xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags); | 855 xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags); |
| 856 // Obtain keysym and character. | |
| 283 xkb_keysym_t xkb_keysym; | 857 xkb_keysym_t xkb_keysym; |
| 284 if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, character)) | 858 if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, character)) |
| 285 return false; | 859 return false; |
| 286 *dom_key = XkbKeySymToDomKey(xkb_keysym); | 860 // Classify the keysym and convert to DOM and VKEY representations. |
| 861 *dom_key = NonPrintableXkbKeySymToDomKey(xkb_keysym); | |
| 287 if (*dom_key == DomKey::NONE) { | 862 if (*dom_key == DomKey::NONE) { |
| 288 *dom_key = CharacterToDomKey(*character); | 863 *dom_key = CharacterToDomKey(*character); |
| 289 *key_code = DifficultKeyboardCode(dom_code, flags, *dom_key, *character); | 864 *key_code = AlphanumericKeyboardCode(*character); |
| 865 if (*key_code == VKEY_UNKNOWN) { | |
| 866 *key_code = DifficultKeyboardCode(dom_code, flags, xkb_keycode, xkb_flags, | |
| 867 xkb_keysym, *dom_key, *character); | |
| 868 if (*key_code == VKEY_UNKNOWN) | |
| 869 *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); | |
| 870 } | |
| 290 } else if (*dom_key == DomKey::DEAD) { | 871 } else if (*dom_key == DomKey::DEAD) { |
| 291 *character = XkbKeySymDeadKey(xkb_keysym); | 872 *character = DeadXkbKeySymToCombiningCharacter(xkb_keysym); |
| 292 *key_code = DomCodeToKeyboardCode(dom_code); | 873 *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); |
| 293 } else { | 874 } else { |
| 294 *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); | 875 *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); |
| 295 if (*key_code == VKEY_UNKNOWN) | 876 if (*key_code == VKEY_UNKNOWN) |
| 296 *key_code = DomCodeToKeyboardCode(dom_code); | 877 *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); |
| 297 } | 878 } |
| 298 return true; | 879 return true; |
| 299 } | 880 } |
| 300 | 881 |
| 301 void XkbKeyboardLayoutEngine::SetKeymap(xkb_keymap* keymap) { | 882 void XkbKeyboardLayoutEngine::SetKeymap(xkb_keymap* keymap) { |
| 302 xkb_state_.reset(xkb_state_new(keymap)); | 883 xkb_state_.reset(xkb_state_new(keymap)); |
| 303 // Update flag map. | 884 // Update flag map. |
| 304 static struct { | 885 static struct { |
| 305 int ui_flag; | 886 int ui_flag; |
| 306 const char* xkb_name; | 887 const char* xkb_name; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 xkb_state_update_mask(xkb_state_.get(), xkb_flags, 0, 0, 0, 0, 0); | 928 xkb_state_update_mask(xkb_state_.get(), xkb_flags, 0, 0, 0, 0, 0); |
| 348 *xkb_keysym = xkb_state_key_get_one_sym(xkb_state_.get(), xkb_keycode); | 929 *xkb_keysym = xkb_state_key_get_one_sym(xkb_state_.get(), xkb_keycode); |
| 349 if (*xkb_keysym == XKB_KEY_NoSymbol) | 930 if (*xkb_keysym == XKB_KEY_NoSymbol) |
| 350 return false; | 931 return false; |
| 351 uint32_t c = xkb_state_key_get_utf32(xkb_state_.get(), xkb_keycode); | 932 uint32_t c = xkb_state_key_get_utf32(xkb_state_.get(), xkb_keycode); |
| 352 DLOG_IF(ERROR, c != (c & 0xFFFF)) << "Non-BMP character:" << c; | 933 DLOG_IF(ERROR, c != (c & 0xFFFF)) << "Non-BMP character:" << c; |
| 353 *character = static_cast<base::char16>(c); | 934 *character = static_cast<base::char16>(c); |
| 354 return true; | 935 return true; |
| 355 } | 936 } |
| 356 | 937 |
| 938 KeyboardCode XkbKeyboardLayoutEngine::DifficultKeyboardCode( | |
| 939 DomCode dom_code, | |
| 940 int ui_flags, | |
| 941 xkb_keycode_t xkb_keycode, | |
| 942 xkb_mod_mask_t xkb_flags, | |
| 943 xkb_keysym_t xkb_keysym, | |
| 944 DomKey dom_key, | |
| 945 base::char16 character) const { | |
| 946 // Get the layout interpretation without modifiers, so that | |
| 947 // e.g. Ctrl+D correctly generates VKEY_D. | |
| 948 xkb_keysym_t plain_keysym; | |
| 949 base::char16 plain_character; | |
| 950 if (!XkbLookup(xkb_keycode, 0, &plain_keysym, &plain_character)) | |
| 951 return VKEY_UNKNOWN; | |
| 952 | |
| 953 // If the plain key is non-printable, that determines the VKEY. | |
| 954 DomKey plain_key = NonPrintableXkbKeySymToDomKey(plain_keysym); | |
| 955 if (plain_key != ui::DomKey::NONE) | |
| 956 return NonPrintableDomKeyToKeyboardCode(dom_key); | |
| 957 | |
| 958 // Plain ASCII letters and digits map directly to VKEY values. | |
| 959 KeyboardCode key_code = AlphanumericKeyboardCode(plain_character); | |
| 960 if (key_code != VKEY_UNKNOWN) | |
| 961 return key_code; | |
| 962 | |
| 963 // Check the multi-character tables. | |
| 964 const PrintableMultiEntry* multi_end = multi_map + arraysize(multi_map); | |
| 965 const PrintableMultiEntry* multi = | |
| 966 std::lower_bound(multi_map, multi_end, plain_character, | |
| 967 [](const PrintableMultiEntry& e, base::char16 c) { | |
| 968 return e.plain_character < c; | |
| 969 }); | |
| 970 if ((multi != multi_end) && (multi->plain_character == plain_character)) { | |
| 971 const base::char16 kNonCharacter = 0xFFFFu; | |
| 972 base::char16 shift_character = kNonCharacter; | |
| 973 base::char16 altgr_character = kNonCharacter; | |
| 974 for (size_t i = 0; i < multi->subtable_size; ++i) { | |
| 975 if (multi->subtable[i].dom_code != dom_code) | |
| 976 continue; | |
| 977 if (multi->subtable[i].test_shift) { | |
| 978 if (shift_character == kNonCharacter) { | |
| 979 shift_character = XkbSubCharacter(xkb_keycode, xkb_flags, character, | |
| 980 ui::EF_SHIFT_DOWN); | |
| 981 } | |
| 982 if (shift_character != multi->subtable[i].shift_character) | |
| 983 continue; | |
| 984 } | |
| 985 if (multi->subtable[i].test_altgr) { | |
| 986 if (altgr_character == kNonCharacter) { | |
| 987 altgr_character = XkbSubCharacter(xkb_keycode, xkb_flags, character, | |
| 988 ui::EF_ALTGR_DOWN); | |
| 989 } | |
| 990 if (altgr_character != multi->subtable[i].altgr_character) | |
| 991 continue; | |
| 992 } | |
| 993 return multi->subtable[i].key_code; | |
| 994 } | |
| 995 } | |
| 996 | |
| 997 // Check the simple character table. | |
| 998 const PrintableSimpleEntry* simple_end = simple_map + arraysize(simple_map); | |
| 999 const PrintableSimpleEntry* simple = | |
| 1000 std::lower_bound(simple_map, simple_end, plain_character, | |
| 1001 [](const PrintableSimpleEntry& e, base::char16 c) { | |
| 1002 return e.plain_character < c; | |
| 1003 }); | |
| 1004 if ((simple != simple_end) && (simple->plain_character == plain_character)) | |
| 1005 return simple->key_code; | |
| 1006 | |
| 1007 return VKEY_UNKNOWN; | |
| 1008 } | |
| 1009 | |
| 1010 base::char16 XkbKeyboardLayoutEngine::XkbSubCharacter( | |
| 1011 xkb_keycode_t xkb_keycode, | |
| 1012 xkb_mod_mask_t base_flags, | |
| 1013 base::char16 base_character, | |
| 1014 int ui_flags) const { | |
| 1015 xkb_mod_mask_t flags = EventFlagsToXkbFlags(ui_flags); | |
| 1016 if (flags == base_flags) | |
| 1017 return base_character; | |
| 1018 xkb_keysym_t keysym; | |
| 1019 base::char16 character = 0; | |
| 1020 XkbLookup(xkb_keycode, flags, &keysym, &character); | |
|
spang
2014/12/08 23:07:30
What if lookup fails?
kpschoedel
2014/12/09 00:32:37
It would have worked, because no relevant keymap h
| |
| 1021 return character; | |
| 1022 } | |
| 1023 | |
| 357 } // namespace ui | 1024 } // namespace ui |
| OLD | NEW |