Chromium Code Reviews| Index: ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc |
| diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc |
| index 9090c442c6be7320de80cee28d2a81bb5b5e7c24..325ccbafc3497457da3877ccddd11e9cba7afe4b 100644 |
| --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc |
| +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc |
| @@ -1,3 +1,4 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @@ -7,6 +8,7 @@ |
| #include "base/logging.h" |
| #include "ui/events/event_constants.h" |
| +#include "ui/events/keycodes/dom3/dom_code.h" |
| #include "ui/events/keycodes/dom3/dom_key.h" |
| #include "ui/events/keycodes/dom4/keycode_converter.h" |
| #include "ui/events/ozone/layout/layout_util.h" |
| @@ -204,15 +206,585 @@ DomKey CharacterToDomKey(base::char16 character) { |
| } |
| } |
| -KeyboardCode DifficultKeyboardCode(DomCode dom_code, |
| - int flags, |
| - DomKey dom_key, |
| - base::char16 character) { |
| - // TODO(kpschoedel): correct key_code for non-US layouts along the lines |
| - // of KeyboardCodeFromXKeyEvent() |
| - return DomCodeToKeyboardCode(dom_code); |
| +KeyboardCode AlphanumericKeyboardCode(base::char16 character) { |
| + // Plain ASCII letters and digits map directly to VKEY values. |
| + if ((character >= '0') && (character <= '9')) |
| + return static_cast<KeyboardCode>(VKEY_0 + character - '0'); |
| + if ((character >= 'a') && (character <= 'z')) |
| + return static_cast<KeyboardCode>(VKEY_A + character - 'a'); |
| + if ((character >= 'A') && (character <= 'Z')) |
| + return static_cast<KeyboardCode>(VKEY_A + character - 'A'); |
| + return VKEY_UNKNOWN; |
| } |
| +// These tables map layout-dependent printable characters/codes |
| +// to legacy Windows-based VKEY values. |
| +// |
| +// VKEYs are determined by the character produced from a DomCode without |
| +// any modifiers, plus zero or more of the DomCode itself, the character |
| +// produced with the Shift modifier, and the character produced with the |
| +// AltGr modifier. |
| + |
| +// A table of one or more PrintableSubEntry cases applies when the VKEY is |
| +// not determined by the unmodified character value alone. Each such table |
| +// corresponds to one unmodified character value. For an entry to match, |
| +// the dom_code must match, and, if test_X is set, then the character for |
| +// the key plus modifier X must also match. |
| +struct PrintableSubEntry { |
| + DomCode dom_code; |
| + bool test_shift : 1; |
| + bool test_altgr : 1; |
| + base::char16 shift_character; |
| + base::char16 altgr_character; |
| + KeyboardCode key_code; |
| +}; |
| + |
| +// U+0021 exclamation mark |
| +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.
|
| + {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_8}}; |
| + |
| +// U+0022 quote |
| +const PrintableSubEntry u0022[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, |
| + {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}}; |
| + |
| +// U+0023 number sign |
| +const PrintableSubEntry u0023[] = { |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::BACKSLASH, 1, 0, 0x0027, 0xFFFF, VKEY_OEM_2}, // apostrophe |
| + {DomCode::BACKSLASH, 1, 1, 0x007E, 0x0000, VKEY_OEM_7}}; // ~, NUL |
| + |
| +// U+0024 dollar sign |
| +const PrintableSubEntry u0024[] = { |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_8}}; |
| + |
| +// U+0027 apostrophe |
| +const PrintableSubEntry u0027[] = { |
| + {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, |
| + {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::QUOTE, 1, 0, 0x0022, 0xFFFF, VKEY_OEM_7}, // quote |
| + {DomCode::BACKQUOTE, 1, 0, 0x0022, 0xFFFF, VKEY_OEM_3}, // quote |
| + {DomCode::BACKQUOTE, 1, 0, 0x00B7, 0xFFFF, VKEY_OEM_5}, // middle dot |
| + {DomCode::BACKSLASH, 1, 0, 0x0000, 0xFFFF, VKEY_OEM_5}, // NUL |
| + {DomCode::MINUS, 1, 1, 0x003F, 0x0000, VKEY_OEM_4}, // ?, NUL |
| + {DomCode::MINUS, 1, 1, 0x003F, 0x00DD, VKEY_OEM_4}, // ?, Y acute |
| + {DomCode::EQUAL, 1, 1, 0x002A, 0x0000, VKEY_OEM_PLUS}, // *, NUL |
| + {DomCode::QUOTE, 1, 1, 0x0040, 0x0000, VKEY_OEM_3}, // @, NUL |
| + {DomCode::BACKSLASH, 1, 1, 0x002A, 0x0000, VKEY_OEM_2}, // *, NUL |
| + {DomCode::BACKSLASH, 1, 1, 0x002A, 0x00BD, VKEY_OEM_5}, // *, one half |
| + {DomCode::BACKSLASH, 1, 1, 0x002A, 0x0141, VKEY_OEM_2}, // *, L stroke |
| + {DomCode::KEY_Z, 1, 1, 0x0022, 0x0000, VKEY_Z}, // quote, NUL |
| + {DomCode::KEY_Z, 1, 1, 0x0022, 0x0158, VKEY_OEM_7}}; // quote, R caron |
| + |
| +// U+0028 left parenthesis |
| +const PrintableSubEntry u0028[] = { |
| + {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, |
| + {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+0029 right parenthesis |
| +const PrintableSubEntry u0029[] = { |
| + {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; |
| + |
| +// U+002A * |
| +const PrintableSubEntry u002A[] = { |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+002B plus sign |
| +const PrintableSubEntry u002B[] = { |
| + {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, |
| + {DomCode::MINUS, 1, 1, 0x003F, 0x0000, VKEY_OEM_PLUS}, // ?, NUL |
| + {DomCode::MINUS, 1, 1, 0x003F, 0x005C, VKEY_OEM_MINUS}, // ?, backslash |
| + {DomCode::MINUS, 1, 1, 0x003F, 0x0151, VKEY_OEM_PLUS}}; // ?, o'' |
| + |
| +// U+002C comma |
| +const PrintableSubEntry u002C[] = { |
| + {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}, |
| + {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, |
| + {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, |
| + {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, |
| + {DomCode::KEY_W, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, |
| + {DomCode::KEY_V, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, |
| + {DomCode::KEY_M, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, |
| + {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}}; |
| + |
| +// U+002D hyphen-minus |
| +const PrintableSubEntry u002D[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, |
| + {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}, |
| + {DomCode::KEY_A, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}, |
| + {DomCode::SLASH, 1, 0, 0x003D, 0xFFFF, VKEY_OEM_MINUS}, // = |
| + {DomCode::EQUAL, 1, 1, 0x005F, 0x0000, VKEY_OEM_MINUS}, // _, NUL |
| + {DomCode::EQUAL, 1, 1, 0x005F, 0x0157, VKEY_OEM_4}, // _, r cedilla |
| + {DomCode::SLASH, 1, 1, 0x005F, 0x0000, VKEY_OEM_MINUS}, // _, NUL |
| + {DomCode::SLASH, 1, 1, 0x005F, 0x002A, VKEY_OEM_MINUS}, // _, * |
| + {DomCode::SLASH, 1, 1, 0x005F, 0x002F, VKEY_OEM_2}, // _, / |
| + {DomCode::SLASH, 1, 1, 0x005F, 0x006E, VKEY_OEM_MINUS}}; // _, n |
| + |
| +// U+002E full stop |
| +const PrintableSubEntry u002E[] = { |
| + {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::KEY_E, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, |
| + {DomCode::KEY_R, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, |
| + {DomCode::KEY_O, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, |
| + {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; |
| + |
| +// U+002F / |
| +const PrintableSubEntry u002F[] = { |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}, |
| + {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, |
| + {DomCode::DIGIT3, 1, 0, 0x0033, 0xFFFF, VKEY_3}, // 3 |
| + {DomCode::DIGIT3, 1, 0, 0x003F, 0xFFFF, VKEY_OEM_2}, // ? |
| + {DomCode::DIGIT0, 1, 0, 0x0030, 0xFFFF, VKEY_0}, // 0 |
| + {DomCode::DIGIT0, 1, 0, 0x003F, 0xFFFF, VKEY_OEM_2}}; // ? |
| + |
| +// U+003A colon |
| +const PrintableSubEntry u003A[] = { |
| + {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, |
| + {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, |
| + {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, |
| + {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; |
| + |
| +// U+003B semicolon |
| +const PrintableSubEntry u003B[] = { |
| + {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, |
| + {DomCode::KEY_Z, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}, |
| + {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; |
| + |
| +// U+003D = |
| +const PrintableSubEntry u003D[] = { |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::SLASH, 1, 0, 0x0025, 0xFFFF, VKEY_OEM_8}, // % |
| + {DomCode::SLASH, 1, 0, 0x002B, 0xFFFF, VKEY_OEM_PLUS}, // + |
| + {DomCode::MINUS, 1, 1, 0x0025, 0x0000, VKEY_OEM_PLUS}, // %, NUL |
| + {DomCode::MINUS, 1, 1, 0x0025, 0x002D, VKEY_OEM_MINUS}}; // %, - |
| + |
| +// U+003F ? |
| +const PrintableSubEntry u003F[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, |
| + {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}}; |
| + |
| +// U+0040 @ |
| +const PrintableSubEntry u0040[] = { |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+005B left square bracket |
| +const PrintableSubEntry u005B[] = { |
| + {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+005C backslash |
| +const PrintableSubEntry u005C[] = { |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BACKSLASH, 1, 0, 0x002F, 0xFFFF, VKEY_OEM_7}, // / |
| + {DomCode::BACKSLASH, 1, 0, 0x007C, 0xFFFF, VKEY_OEM_5}, // | |
| + {DomCode::BACKQUOTE, 1, 1, 0x007C, 0x0031, VKEY_OEM_5}, // |, 1 |
| + {DomCode::BACKQUOTE, 1, 1, 0x007C, 0x0145, VKEY_OEM_3}}; // |, N cedilla |
| + |
| +// U+005D right square bracket |
| +const PrintableSubEntry u005D[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+005F _ |
| +const PrintableSubEntry u005F[] = { |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_MINUS}}; |
| + |
| +// U+0060 grave accent |
| +const PrintableSubEntry u0060[] = { |
| + {DomCode::BACKQUOTE, 1, 0, 0x0000, 0xFFFF, VKEY_OEM_3}, // NUL |
| + {DomCode::BACKQUOTE, 1, 0, 0x00AC, 0xFFFF, VKEY_OEM_8}, // not |
| + {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0000, VKEY_OEM_3}, // ~, NUL |
| + {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0031, VKEY_OEM_3}, // ~, 1 |
| + {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x003B, VKEY_OEM_3}, // ~, ; |
| + {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0060, VKEY_OEM_3}, // ~, ` |
| + {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x00BF, VKEY_OEM_3}, // ~, inverted ? |
| + {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0151, VKEY_OEM_3}}; // ~, o'' |
| + |
| +// U+00A7 section |
| +const PrintableSubEntry u00A7[] = { |
| + {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, |
| + {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::BACKQUOTE, 1, 0, 0x00B0, 0xFFFF, VKEY_OEM_2}, // degree |
| + {DomCode::BACKQUOTE, 1, 0, 0x00BD, 0xFFFF, VKEY_OEM_5}}; // one half |
| + |
| +// U+00AB left-pointing double angle quote |
| +const PrintableSubEntry u00AB[] = { |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; |
| + |
| +// U+00B0 degree |
| +const PrintableSubEntry u00B0[] = { |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+00BA masculine ordinal indicator |
| +const PrintableSubEntry u00BA[] = { |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+00E0 a grave |
| +const PrintableSubEntry u00E0[] = { |
| + {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}, |
| + {DomCode::QUOTE, 1, 0, 0x00B0, 0xFFFF, VKEY_OEM_7}, // degree |
| + {DomCode::QUOTE, 1, 0, 0x00E4, 0xFFFF, VKEY_OEM_5}}; // a diaeresis |
| + |
| +// U+00E1 a acute |
| +const PrintableSubEntry u00E1[] = { |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+00E2 a circumflex |
| +const PrintableSubEntry u00E2[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+00E4 a diaeresis |
| +const PrintableSubEntry u00E4[] = { |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::QUOTE, 1, 0, 0x00E0, 0xFFFF, VKEY_OEM_5}, // a grave |
| + {DomCode::QUOTE, 1, 1, 0x00C4, 0x0000, VKEY_OEM_7}, // A dia., NUL |
| + {DomCode::QUOTE, 1, 1, 0x00C4, 0x015A, VKEY_OEM_7}, // A dia., S acute |
| + {DomCode::QUOTE, 1, 1, 0x00C4, 0x0159, VKEY_OEM_7}}; // A dia., r caron |
| + |
| +// U+00E6 ae |
| +const PrintableSubEntry u00E6[] = { |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+00E7 c cedilla |
| +const PrintableSubEntry u00E7[] = { |
| + {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, |
| + {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}, |
| + {DomCode::SEMICOLON, 1, 1, 0x00C7, 0x0000, VKEY_OEM_1}, // C ced., NUL |
| + {DomCode::SEMICOLON, 1, 1, 0x00C7, 0x00DE, VKEY_OEM_3}}; // C ced., Thorn |
| + |
| +// U+00E8 e grave |
| +const PrintableSubEntry u00E8[] = { |
| + {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}}; |
| + |
| +// U+00E9 e acute |
| +const PrintableSubEntry u00E9[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, |
| + {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, |
| + {DomCode::SLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}, |
| + {DomCode::SEMICOLON, 1, 0, 0x00C9, 0xFFFF, VKEY_OEM_1}, // E acute |
| + {DomCode::SEMICOLON, 1, 0, 0x00F6, 0xFFFF, VKEY_OEM_7}}; // o diaeresis |
| + |
| +// U+00ED i acute |
| +const PrintableSubEntry u00ED[] = { |
| + {DomCode::DIGIT9, 0, 0, 0xFFFF, 0xFFFF, VKEY_9}, |
| + {DomCode::BACKQUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}}; |
| + |
| +// U+00F0 eth |
| +const PrintableSubEntry u00F0[] = { |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}}; |
| + |
| +// U+00F3 o acute |
| +const PrintableSubEntry u00F3[] = { |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+00F4 o circumflex |
| +const PrintableSubEntry u00F4[] = { |
| + {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}}; |
| + |
| +// U+00F6 o diaeresis |
| +const PrintableSubEntry u00F6[] = { |
| + {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, |
| + {DomCode::MINUS, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::SEMICOLON, 1, 0, 0x00E9, 0xFFFF, VKEY_OEM_7}, // e acute |
| + {DomCode::SEMICOLON, 1, 1, 0x00D6, 0x0000, VKEY_OEM_3}, // O dia., NUL |
| + {DomCode::SEMICOLON, 1, 1, 0x00D6, 0x0162, VKEY_OEM_3}}; // O dia., T ced. |
| + |
| +// U+00F8 o stroke |
| +const PrintableSubEntry u00F8[] = { |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+00F9 u grave |
| +const PrintableSubEntry u00F9[] = { |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_3}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; |
| + |
| +// U+00FA u acute |
| +const PrintableSubEntry u00FA[] = { |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; |
| + |
| +// U+00FC u diaeresis |
| +const PrintableSubEntry u00FC[] = { |
| + {DomCode::KEY_W, 0, 0, 0xFFFF, 0xFFFF, VKEY_W}, |
| + {DomCode::BRACKET_LEFT, 1, 0, 0x00E8, 0xFFFF, VKEY_OEM_1}, // e grave |
| + {DomCode::MINUS, 1, 1, 0x00DC, 0x0000, VKEY_OEM_2}, // U dia., NUL |
| + {DomCode::BRACKET_LEFT, 1, 1, 0x00DC, 0x0000, VKEY_OEM_1}, // U dia., NUL |
| + {DomCode::BRACKET_LEFT, 1, 1, 0x00DC, 0x0141, VKEY_OEM_3}}; // U dia., L- |
| + |
| +// U+0103 a breve |
| +const PrintableSubEntry u0103[] = { |
| + {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}}; |
| + |
| +// U+0105 a ogonek |
| +const PrintableSubEntry u0105[] = { |
| + {DomCode::DIGIT1, 0, 0, 0xFFFF, 0xFFFF, VKEY_1}, |
| + {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_Q}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+010D c caron |
| +const PrintableSubEntry u010D[] = { |
| + {DomCode::DIGIT2, 0, 0, 0xFFFF, 0xFFFF, VKEY_2}, |
| + {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, |
| + {DomCode::KEY_P, 0, 0, 0xFFFF, 0xFFFF, VKEY_X}, |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::COMMA, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_COMMA}}; |
| + |
| +// U+0111 d stroke |
| +const PrintableSubEntry u0111[] = { |
| + {DomCode::DIGIT0, 0, 0, 0xFFFF, 0xFFFF, VKEY_0}, |
| + {DomCode::BRACKET_RIGHT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_6}}; |
| + |
| +// U+0117 e dot above |
| +const PrintableSubEntry u0117[] = { |
| + {DomCode::DIGIT4, 0, 0, 0xFFFF, 0xFFFF, VKEY_4}, |
| + {DomCode::QUOTE, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_7}}; |
| + |
| +// U+0119 e ogonek |
| +const PrintableSubEntry u0119[] = { |
| + {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}, |
| + {DomCode::SLASH, 1, 1, 0x0118, 0x0000, VKEY_OEM_MINUS}, // E ogonek, NUL |
| + {DomCode::SLASH, 1, 1, 0x0118, 0x006E, VKEY_OEM_2}}; // E ogonek, n |
| + |
| +// U+012F i ogonek |
| +const PrintableSubEntry u012F[] = { |
| + {DomCode::DIGIT5, 0, 0, 0xFFFF, 0xFFFF, VKEY_5}, |
| + {DomCode::BRACKET_LEFT, 1, 1, 0x012E, 0x0000, VKEY_OEM_4}}; // Iogonek, NUL |
| + |
| +// U+0142 l stroke |
| +const PrintableSubEntry u0142[] = { |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_2}}; |
| + |
| +// U+015F s cedilla |
| +const PrintableSubEntry u015F[] = { |
| + {DomCode::SEMICOLON, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}}; |
| + |
| +// U+0161 s caron |
| +const PrintableSubEntry u0161[] = { |
| + {DomCode::DIGIT3, 0, 0, 0xFFFF, 0xFFFF, VKEY_3}, |
| + {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::KEY_A, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_1}, |
| + {DomCode::KEY_F, 0, 0, 0xFFFF, 0xFFFF, VKEY_F}, |
| + {DomCode::PERIOD, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PERIOD}}; |
| + |
| +// U+016B u macron |
| +const PrintableSubEntry u016B[] = { |
| + {DomCode::DIGIT8, 0, 0, 0xFFFF, 0xFFFF, VKEY_8}, |
| + {DomCode::KEY_Q, 0, 0, 0xFFFF, 0xFFFF, VKEY_Q}, |
| + {DomCode::KEY_X, 0, 0, 0xFFFF, 0xFFFF, VKEY_X}}; |
| + |
| +// U+0173 u ogonek |
| +const PrintableSubEntry u0173[] = { |
| + {DomCode::DIGIT7, 0, 0, 0xFFFF, 0xFFFF, VKEY_7}, |
| + {DomCode::SEMICOLON, 1, 1, 0x0172, 0x0000, VKEY_OEM_3}, // U ogo., NUL |
| + {DomCode::SEMICOLON, 1, 1, 0x0172, 0x0162, VKEY_OEM_1}}; // U ogo., T ced. |
| + |
| +// U+017C z dot above |
| +const PrintableSubEntry u017C[] = { |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_4}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// U+017E z caron |
| +const PrintableSubEntry u017E[] = { |
| + {DomCode::DIGIT6, 0, 0, 0xFFFF, 0xFFFF, VKEY_6}, |
| + {DomCode::EQUAL, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_PLUS}, |
| + {DomCode::KEY_W, 0, 0, 0xFFFF, 0xFFFF, VKEY_W}, |
| + {DomCode::BRACKET_LEFT, 0, 0, 0xFFFF, 0xFFFF, VKEY_Y}, |
| + {DomCode::BACKSLASH, 0, 0, 0xFFFF, 0xFFFF, VKEY_OEM_5}}; |
| + |
| +// Table mapping unshifted characters to PrintableSubEntry tables. |
| +struct PrintableMultiEntry { |
| + base::char16 plain_character; |
| + const PrintableSubEntry* subtable; |
| + size_t subtable_size; |
| +}; |
| + |
| +// Entries are ordered by character value. |
| +const PrintableMultiEntry multi_map[] = { |
| + {0x0021, u0021, arraysize(u0021)}, // exclamation mark |
| + {0x0022, u0022, arraysize(u0022)}, // quotation mark |
| + {0x0023, u0023, arraysize(u0023)}, // number sign |
| + {0x0024, u0024, arraysize(u0024)}, // dollar sign |
| + {0x0027, u0027, arraysize(u0027)}, // apostrophe |
| + {0x0028, u0028, arraysize(u0028)}, // left parenthesis |
| + {0x0029, u0029, arraysize(u0029)}, // right parenthesis |
| + {0x002A, u002A, arraysize(u002A)}, // asterisk |
| + {0x002B, u002B, arraysize(u002B)}, // plus sign |
| + {0x002C, u002C, arraysize(u002C)}, // comma |
| + {0x002D, u002D, arraysize(u002D)}, // hyphen-minus |
| + {0x002E, u002E, arraysize(u002E)}, // full stop |
| + {0x002F, u002F, arraysize(u002F)}, // solidus |
| + {0x003A, u003A, arraysize(u003A)}, // colon |
| + {0x003B, u003B, arraysize(u003B)}, // semicolon |
| + {0x003D, u003D, arraysize(u003D)}, // equals sign |
| + {0x003F, u003F, arraysize(u003F)}, // question mark |
| + {0x0040, u0040, arraysize(u0040)}, // commercial at |
| + {0x005B, u005B, arraysize(u005B)}, // left square bracket |
| + {0x005C, u005C, arraysize(u005C)}, // reverse solidus |
| + {0x005D, u005D, arraysize(u005D)}, // right square bracket |
| + {0x005F, u005F, arraysize(u005F)}, // low line |
| + {0x0060, u0060, arraysize(u0060)}, // grave accent |
| + {0x00A7, u00A7, arraysize(u00A7)}, // section sign |
| + {0x00AB, u00AB, arraysize(u00AB)}, // left double angle quotation mark |
| + {0x00B0, u00B0, arraysize(u00B0)}, // degree sign |
| + {0x00BA, u00BA, arraysize(u00BA)}, // masculine ordinal indicator |
| + {0x00E0, u00E0, arraysize(u00E0)}, // a grave |
| + {0x00E1, u00E1, arraysize(u00E1)}, // a acute |
| + {0x00E2, u00E2, arraysize(u00E2)}, // a circumflex |
| + {0x00E4, u00E4, arraysize(u00E4)}, // a diaeresis |
| + {0x00E6, u00E6, arraysize(u00E6)}, // ae |
| + {0x00E7, u00E7, arraysize(u00E7)}, // c cedilla |
| + {0x00E8, u00E8, arraysize(u00E8)}, // e grave |
| + {0x00E9, u00E9, arraysize(u00E9)}, // e acute |
| + {0x00ED, u00ED, arraysize(u00ED)}, // i acute |
| + {0x00F0, u00F0, arraysize(u00F0)}, // eth |
| + {0x00F3, u00F3, arraysize(u00F3)}, // o acute |
| + {0x00F4, u00F4, arraysize(u00F4)}, // o circumflex |
| + {0x00F6, u00F6, arraysize(u00F6)}, // o diaeresis |
| + {0x00F8, u00F8, arraysize(u00F8)}, // o stroke |
| + {0x00F9, u00F9, arraysize(u00F9)}, // u grave |
| + {0x00FA, u00FA, arraysize(u00FA)}, // u acute |
| + {0x00FC, u00FC, arraysize(u00FC)}, // u diaeresis |
| + {0x0103, u0103, arraysize(u0103)}, // a breve |
| + {0x0105, u0105, arraysize(u0105)}, // a ogonek |
| + {0x010D, u010D, arraysize(u010D)}, // c caron |
| + {0x0111, u0111, arraysize(u0111)}, // d stroke |
| + {0x0117, u0117, arraysize(u0117)}, // e dot above |
| + {0x0119, u0119, arraysize(u0119)}, // e ogonek |
| + {0x012F, u012F, arraysize(u012F)}, // i ogonek |
| + {0x0142, u0142, arraysize(u0142)}, // l stroke |
| + {0x015F, u015F, arraysize(u015F)}, // s cedilla |
| + {0x0161, u0161, arraysize(u0161)}, // s caron |
| + {0x016B, u016B, arraysize(u016B)}, // u macron |
| + {0x0173, u0173, arraysize(u0173)}, // u ogonek |
| + {0x017C, u017C, arraysize(u017C)}, // z dot above |
| + {0x017E, u017E, arraysize(u017E)}, // z caron |
| +}; |
| + |
| +// Table mapping unshifted characters to VKEY values. |
| +struct PrintableSimpleEntry { |
| + base::char16 plain_character; |
| + KeyboardCode key_code; |
| +}; |
| + |
| +// Entries are ordered by character value. |
| +const PrintableSimpleEntry simple_map[] = { |
| + {0x0025, VKEY_5}, // percent sign |
| + {0x0026, VKEY_1}, // ampersand |
| + {0x003C, VKEY_OEM_5}, // less-than sign |
| + {0x007B, VKEY_OEM_7}, // left curly bracket |
| + {0x007C, VKEY_OEM_5}, // vertical line |
| + {0x007D, VKEY_OEM_2}, // right curly bracket |
| + {0x007E, VKEY_OEM_5}, // tilde |
| + {0x00A1, VKEY_OEM_6}, // inverted exclamation mark |
| + {0x00AD, VKEY_OEM_3}, // soft hyphen |
| + {0x00B2, VKEY_OEM_7}, // superscript two |
| + {0x00B5, VKEY_OEM_5}, // micro sign |
| + {0x00BB, VKEY_9}, // right-pointing double angle quotation mark |
| + {0x00BD, VKEY_OEM_5}, // vulgar fraction one half |
| + {0x00BF, VKEY_OEM_6}, // inverted question mark |
| + {0x00DF, VKEY_OEM_4}, // sharp s |
| + {0x00E5, VKEY_OEM_6}, // a ring above |
| + {0x00EA, VKEY_3}, // e circumflex |
| + {0x00EB, VKEY_OEM_1}, // e diaeresis |
| + {0x00EC, VKEY_OEM_6}, // i grave |
| + {0x00EE, VKEY_OEM_6}, // i circumflex |
| + {0x00F1, VKEY_OEM_3}, // n tilde |
| + {0x00F2, VKEY_OEM_3}, // o grave |
| + {0x00F5, VKEY_OEM_4}, // o tilde |
| + {0x00F7, VKEY_OEM_6}, // division sign |
| + {0x00FD, VKEY_7}, // y acute |
| + {0x00FE, VKEY_OEM_MINUS}, // thorn |
| + {0x0101, VKEY_OEM_8}, // a macron |
| + {0x0107, VKEY_OEM_7}, // c acute |
| + {0x010B, VKEY_OEM_3}, // c dot above |
| + {0x0113, VKEY_W}, // e macron |
| + {0x011B, VKEY_2}, // e caron |
| + {0x011F, VKEY_OEM_6}, // g breve |
| + {0x0121, VKEY_OEM_4}, // g dot above |
| + {0x0127, VKEY_OEM_6}, // h stroke |
| + {0x012B, VKEY_OEM_6}, // i macron |
| + {0x0131, VKEY_OEM_1}, // dotless i |
| + {0x0137, VKEY_OEM_5}, // k cedilla |
| + {0x013C, VKEY_OEM_2}, // l cedilla |
| + {0x013E, VKEY_2}, // l caron |
| + {0x0146, VKEY_OEM_4}, // n cedilla |
| + {0x0148, VKEY_OEM_5}, // n caron |
| + {0x0151, VKEY_OEM_4}, // o double acute |
| + {0x0159, VKEY_5}, // r caron |
| + {0x0163, VKEY_OEM_7}, // t cedilla |
| + {0x0165, VKEY_5}, // t caron |
| + {0x016F, VKEY_OEM_1}, // u ring above |
| + {0x0171, VKEY_OEM_5}, // u double acute |
| + {0x01A1, VKEY_OEM_6}, // o horn |
| + {0x01B0, VKEY_OEM_4}, // u horn |
| + {0x01B6, VKEY_OEM_6}, // z stroke |
| + {0x0259, VKEY_OEM_3}, // schwa |
| +}; |
| + |
| } // anonymous namespace |
| XkbKeyCodeConverter::XkbKeyCodeConverter() { |
| @@ -272,6 +844,7 @@ bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, |
| DomKey* dom_key, |
| base::char16* character, |
| KeyboardCode* key_code) const { |
| + // Convert DOM physical key to XKB representation. |
| xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code); |
| if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) { |
| LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex |
| @@ -280,20 +853,28 @@ bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, |
| return false; |
| } |
| xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags); |
| + // Obtain keysym and character. |
| xkb_keysym_t xkb_keysym; |
| if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, character)) |
| return false; |
| - *dom_key = XkbKeySymToDomKey(xkb_keysym); |
| + // Classify the keysym and convert to DOM and VKEY representations. |
| + *dom_key = NonPrintableXkbKeySymToDomKey(xkb_keysym); |
| if (*dom_key == DomKey::NONE) { |
| *dom_key = CharacterToDomKey(*character); |
| - *key_code = DifficultKeyboardCode(dom_code, flags, *dom_key, *character); |
| + *key_code = AlphanumericKeyboardCode(*character); |
| + if (*key_code == VKEY_UNKNOWN) { |
| + *key_code = DifficultKeyboardCode(dom_code, flags, xkb_keycode, xkb_flags, |
| + xkb_keysym, *dom_key, *character); |
| + if (*key_code == VKEY_UNKNOWN) |
| + *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); |
| + } |
| } else if (*dom_key == DomKey::DEAD) { |
| - *character = XkbKeySymDeadKey(xkb_keysym); |
| - *key_code = DomCodeToKeyboardCode(dom_code); |
| + *character = DeadXkbKeySymToCombiningCharacter(xkb_keysym); |
| + *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); |
| } else { |
| *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); |
| if (*key_code == VKEY_UNKNOWN) |
| - *key_code = DomCodeToKeyboardCode(dom_code); |
| + *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); |
| } |
| return true; |
| } |
| @@ -354,4 +935,90 @@ bool XkbKeyboardLayoutEngine::XkbLookup(xkb_keycode_t xkb_keycode, |
| return true; |
| } |
| +KeyboardCode XkbKeyboardLayoutEngine::DifficultKeyboardCode( |
| + DomCode dom_code, |
| + int ui_flags, |
| + xkb_keycode_t xkb_keycode, |
| + xkb_mod_mask_t xkb_flags, |
| + xkb_keysym_t xkb_keysym, |
| + DomKey dom_key, |
| + base::char16 character) const { |
| + // Get the layout interpretation without modifiers, so that |
| + // e.g. Ctrl+D correctly generates VKEY_D. |
| + xkb_keysym_t plain_keysym; |
| + base::char16 plain_character; |
| + if (!XkbLookup(xkb_keycode, 0, &plain_keysym, &plain_character)) |
| + return VKEY_UNKNOWN; |
| + |
| + // If the plain key is non-printable, that determines the VKEY. |
| + DomKey plain_key = NonPrintableXkbKeySymToDomKey(plain_keysym); |
| + if (plain_key != ui::DomKey::NONE) |
| + return NonPrintableDomKeyToKeyboardCode(dom_key); |
| + |
| + // Plain ASCII letters and digits map directly to VKEY values. |
| + KeyboardCode key_code = AlphanumericKeyboardCode(plain_character); |
| + if (key_code != VKEY_UNKNOWN) |
| + return key_code; |
| + |
| + // Check the multi-character tables. |
| + const PrintableMultiEntry* multi_end = multi_map + arraysize(multi_map); |
| + const PrintableMultiEntry* multi = |
| + std::lower_bound(multi_map, multi_end, plain_character, |
| + [](const PrintableMultiEntry& e, base::char16 c) { |
| + return e.plain_character < c; |
| + }); |
| + if ((multi != multi_end) && (multi->plain_character == plain_character)) { |
| + const base::char16 kNonCharacter = 0xFFFFu; |
| + base::char16 shift_character = kNonCharacter; |
| + base::char16 altgr_character = kNonCharacter; |
| + for (size_t i = 0; i < multi->subtable_size; ++i) { |
| + if (multi->subtable[i].dom_code != dom_code) |
| + continue; |
| + if (multi->subtable[i].test_shift) { |
| + if (shift_character == kNonCharacter) { |
| + shift_character = XkbSubCharacter(xkb_keycode, xkb_flags, character, |
| + ui::EF_SHIFT_DOWN); |
| + } |
| + if (shift_character != multi->subtable[i].shift_character) |
| + continue; |
| + } |
| + if (multi->subtable[i].test_altgr) { |
| + if (altgr_character == kNonCharacter) { |
| + altgr_character = XkbSubCharacter(xkb_keycode, xkb_flags, character, |
| + ui::EF_ALTGR_DOWN); |
| + } |
| + if (altgr_character != multi->subtable[i].altgr_character) |
| + continue; |
| + } |
| + return multi->subtable[i].key_code; |
| + } |
| + } |
| + |
| + // Check the simple character table. |
| + const PrintableSimpleEntry* simple_end = simple_map + arraysize(simple_map); |
| + const PrintableSimpleEntry* simple = |
| + std::lower_bound(simple_map, simple_end, plain_character, |
| + [](const PrintableSimpleEntry& e, base::char16 c) { |
| + return e.plain_character < c; |
| + }); |
| + if ((simple != simple_end) && (simple->plain_character == plain_character)) |
| + return simple->key_code; |
| + |
| + return VKEY_UNKNOWN; |
| +} |
| + |
| +base::char16 XkbKeyboardLayoutEngine::XkbSubCharacter( |
| + xkb_keycode_t xkb_keycode, |
| + xkb_mod_mask_t base_flags, |
| + base::char16 base_character, |
| + int ui_flags) const { |
| + xkb_mod_mask_t flags = EventFlagsToXkbFlags(ui_flags); |
| + if (flags == base_flags) |
| + return base_character; |
| + xkb_keysym_t keysym; |
| + base::char16 character = 0; |
| + 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
|
| + return character; |
| +} |
| + |
| } // namespace ui |