diff options
author | kpschoedel <kpschoedel@chromium.org> | 2015-04-21 13:58:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-21 20:59:07 +0000 |
commit | 4675e7cbedf99fcc18ae9bfcf19225740fed9387 (patch) | |
tree | ed602ea300dd5b11ae50a1bdfa0354fb9fb28418 | |
parent | 73360dd269e417b1dc8aa8022ae5d2274fe70e89 (diff) | |
download | chromium_src-4675e7cbedf99fcc18ae9bfcf19225740fed9387.zip chromium_src-4675e7cbedf99fcc18ae9bfcf19225740fed9387.tar.gz chromium_src-4675e7cbedf99fcc18ae9bfcf19225740fed9387.tar.bz2 |
Use DOM- rather than Windows-based key code for non-layout cases.
BUG=444048
Review URL: https://codereview.chromium.org/841263005
Cr-Commit-Position: refs/heads/master@{#326111}
22 files changed, 1518 insertions, 917 deletions
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index 22f49b6..208cc18 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn @@ -33,6 +33,7 @@ component("events_base") { "gesture_event_details.h", "gestures/fling_curve.cc", "gestures/fling_curve.h", + "keycodes/dom_us_layout_data.h", "keycodes/keyboard_code_conversion.cc", "keycodes/keyboard_code_conversion.h", "keycodes/keyboard_code_conversion_android.cc", @@ -297,6 +298,7 @@ test("events_unittests") { "gestures/blink/web_gesture_curve_impl_unittest.cc", "gestures/fling_curve_unittest.cc", "keycodes/dom4/keycode_converter_unittest.cc", + "keycodes/keyboard_code_conversion_unittest.cc", "latency_info_unittest.cc", "platform/platform_event_source_unittest.cc", "x/events_x_unittest.cc", diff --git a/ui/events/event.cc b/ui/events/event.cc index 5444019..4649e24 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc @@ -697,7 +697,7 @@ KeyEvent::KeyEvent(EventType type, int flags) : Event(type, EventTimeForNow(), flags), key_code_(key_code), - code_(DomCode::NONE), + code_(UsLayoutKeyboardCodeToDomCode(key_code)), is_char_(false), platform_keycode_(0), key_(DomKey::NONE), @@ -786,34 +786,49 @@ void KeyEvent::ApplyLayout() const { key_ = DomKey::UNIDENTIFIED; return; } + ui::DomCode code = code_; + if (code == DomCode::NONE) { + // Catch old code that tries to do layout without a physical key, and try + // to recover using the KeyboardCode. Once key events are fully defined + // on construction (see TODO in event.h) this will go away. + LOG(WARNING) << "DomCode::NONE keycode=" << key_code_; + code = UsLayoutKeyboardCodeToDomCode(key_code_); + if (code == DomCode::NONE) { + key_ = DomKey::UNIDENTIFIED; + return; + } + } + KeyboardCode dummy_key_code; #if defined(OS_WIN) - // Native Windows character events always have is_char_ == true, - // so this is a synthetic or native keystroke event. - // Therefore, perform only the fallback action. - GetMeaningFromKeyCode(key_code_, flags(), &key_, &character_); +// Native Windows character events always have is_char_ == true, +// so this is a synthetic or native keystroke event. +// Therefore, perform only the fallback action. #elif defined(USE_X11) // When a control key is held, prefer ASCII characters to non ASCII // characters in order to use it for shortcut keys. GetCharacterFromKeyCode // returns 'a' for VKEY_A even if the key is actually bound to 'à' in X11. // GetCharacterFromXEvent returns 'à' in that case. - character_ = (IsControlDown() || !native_event()) ? - GetCharacterFromKeyCode(key_code_, flags()) : - GetCharacterFromXEvent(native_event()); - // TODO(kpschoedel): set key_ field for X11. + if (!IsControlDown() && native_event()) { + character_ = GetCharacterFromXEvent(native_event()); + // TODO(kpschoedel): set key_ field for X11. + return; + } #elif defined(USE_OZONE) - KeyboardCode key_code; - if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup( - code_, flags(), &key_, &character_, &key_code, &platform_keycode_)) { - GetMeaningFromKeyCode(key_code_, flags(), &key_, &character_); + if (KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup( + code, flags(), &key_, &character_, &dummy_key_code, + &platform_keycode_)) { + return; } #else if (native_event()) { DCHECK(EventTypeFromNative(native_event()) == ET_KEY_PRESSED || EventTypeFromNative(native_event()) == ET_KEY_RELEASED); } - // TODO(kpschoedel): revise to use DOM code_ instead of Windows key_code_ - GetMeaningFromKeyCode(key_code_, flags(), &key_, &character_); #endif + if (!DomCodeToUsLayoutMeaning(code, flags(), &key_, &character_, + &dummy_key_code)) { + key_ = DomKey::UNIDENTIFIED; + } } DomKey KeyEvent::GetDomKey() const { @@ -832,9 +847,11 @@ base::char16 KeyEvent::GetCharacter() const { base::char16 KeyEvent::GetText() const { if ((flags() & EF_CONTROL_DOWN) != 0) { - // TODO(kpschoedel): revise to use DOM code_ instead of Windows key_code_ - return GetControlCharacterForKeycode(key_code_, - (flags() & EF_SHIFT_DOWN) != 0); + base::char16 character; + ui::DomKey key; + ui::KeyboardCode key_code; + if (DomCodeToControlCharacter(code_, flags(), &key, &character, &key_code)) + return character; } return GetUnmodifiedText(); } diff --git a/ui/events/event.h b/ui/events/event.h index 6a27b0e..349ed55 100644 --- a/ui/events/event.h +++ b/ui/events/event.h @@ -779,7 +779,7 @@ class EVENTS_EXPORT KeyEvent : public Event { // TODO(kpschoedel): refactor so that key_ and character_ are not mutable. // This requires defining the KeyEvent completely at construction rather // than lazily under GetCharacter(), which likely also means removing - // the two 'incomplete' constructors. + // the two 'incomplete' constructors. crbug.com/444045 // // DOM KeyboardEvent |key| // http://www.w3.org/TR/DOM-Level-3-Events-key/ diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc index 1297f30..6d94812 100644 --- a/ui/events/event_unittest.cc +++ b/ui/events/event_unittest.cc @@ -367,11 +367,10 @@ TEST(EventTest, KeyEventCode) { EXPECT_EQ(kCodeForSpace, key.GetCodeString()); } { - // If the synthetic event is initialized without code, it returns - // an empty string. - // TODO(komatsu): Fill a fallback value assuming the US keyboard layout. + // If the synthetic event is initialized without code, the code is + // determined from the KeyboardCode assuming a US keyboard layout. KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE); - EXPECT_TRUE(key.GetCodeString().empty()); + EXPECT_EQ(kCodeForSpace, key.GetCodeString()); } #if defined(USE_X11) { diff --git a/ui/events/event_utils.cc b/ui/events/event_utils.cc index 2e3517e..021ac27 100644 --- a/ui/events/event_utils.cc +++ b/ui/events/event_utils.cc @@ -63,51 +63,6 @@ scoped_ptr<Event> EventFromNative(const base::NativeEvent& native_event) { return event.Pass(); } -// From third_party/WebKit/Source/web/gtk/WebInputEventFactory.cpp: -base::char16 GetControlCharacterForKeycode(int windows_key_code, bool shift) { - if (windows_key_code >= ui::VKEY_A && - windows_key_code <= ui::VKEY_Z) { - // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A - return windows_key_code - ui::VKEY_A + 1; - } - if (shift) { - // following graphics chars require shift key to input. - switch (windows_key_code) { - // ctrl-@ maps to \x00 (Null byte) - case ui::VKEY_2: - return 0; - // ctrl-^ maps to \x1E (Record separator, Information separator two) - case ui::VKEY_6: - return 0x1E; - // ctrl-_ maps to \x1F (Unit separator, Information separator one) - case ui::VKEY_OEM_MINUS: - return 0x1F; - // Returns 0 for all other keys to avoid inputting unexpected chars. - default: - break; - } - } else { - switch (windows_key_code) { - // ctrl-[ maps to \x1B (Escape) - case ui::VKEY_OEM_4: - return 0x1B; - // ctrl-\ maps to \x1C (File separator, Information separator four) - case ui::VKEY_OEM_5: - return 0x1C; - // ctrl-] maps to \x1D (Group separator, Information separator three) - case ui::VKEY_OEM_6: - return 0x1D; - // ctrl-Enter maps to \x0A (Line feed) - case ui::VKEY_RETURN: - return 0x0A; - // Returns 0 for all other keys to avoid inputting unexpected chars. - default: - break; - } - } - return 0; -} - int RegisterCustomEventType() { return ++g_custom_event_types; } diff --git a/ui/events/event_utils.h b/ui/events/event_utils.h index 1649bd7..e9c9093 100644 --- a/ui/events/event_utils.h +++ b/ui/events/event_utils.h @@ -84,14 +84,11 @@ EVENTS_EXPORT KeyboardCode KeyboardCodeFromNative( // keyboard) from a native event. EVENTS_EXPORT DomCode CodeFromNative(const base::NativeEvent& native_event); -// Returns the platform related key code. For X11, it is xksym value. +// Returns the platform related key code (interpretation, not scan code). +// For X11 and xkbcommon, this is the KeySym value. EVENTS_EXPORT uint32 PlatformKeycodeFromNative( const base::NativeEvent& native_event); -// Returns a control character sequences from a |windows_key_code|. -EVENTS_EXPORT base::char16 GetControlCharacterForKeycode(int windows_key_code, - bool shift); - // Returns true if the keyboard event is a character event rather than // a keystroke event. EVENTS_EXPORT bool IsCharFromNative(const base::NativeEvent& native_event); diff --git a/ui/events/events.gyp b/ui/events/events.gyp index 9e63434b..2f5757b 100644 --- a/ui/events/events.gyp +++ b/ui/events/events.gyp @@ -52,6 +52,7 @@ 'gesture_event_details.h', 'gestures/fling_curve.cc', 'gestures/fling_curve.h', + 'keycodes/dom_us_layout_data.h', 'keycodes/keyboard_code_conversion.cc', 'keycodes/keyboard_code_conversion.h', 'keycodes/keyboard_code_conversion_android.cc', @@ -373,6 +374,7 @@ 'gestures/gesture_provider_aura_unittest.cc', 'gestures/motion_event_aura_unittest.cc', 'keycodes/dom4/keycode_converter_unittest.cc', + 'keycodes/keyboard_code_conversion_unittest.cc', 'latency_info_unittest.cc', 'platform/platform_event_source_unittest.cc', 'x/events_x_unittest.cc', diff --git a/ui/events/keycodes/dom4/keycode_converter.cc b/ui/events/keycodes/dom4/keycode_converter.cc index 7c81862..d9a26a2 100644 --- a/ui/events/keycodes/dom4/keycode_converter.cc +++ b/ui/events/keycodes/dom4/keycode_converter.cc @@ -4,6 +4,7 @@ #include "ui/events/keycodes/dom4/keycode_converter.h" +#include "base/logging.h" #include "ui/events/keycodes/dom3/dom_code.h" #include "ui/events/keycodes/dom3/dom_key.h" @@ -118,14 +119,17 @@ int KeycodeConverter::DomCodeToNativeKeycode(DomCode code) { // static DomCode KeycodeConverter::CodeStringToDomCode(const char* code) { - if (!code || !*code) + if (!code || !*code) { + LOG(WARNING) << "empty code string"; return DomCode::NONE; + } for (size_t i = 0; i < kKeycodeMapEntries; ++i) { if (usb_keycode_map[i].code && strcmp(usb_keycode_map[i].code, code) == 0) { return static_cast<DomCode>(usb_keycode_map[i].usb_keycode); } } + LOG(WARNING) << "unrecognized code string '" << code << "'"; return DomCode::NONE; } diff --git a/ui/events/keycodes/dom4/keycode_converter_data.h b/ui/events/keycodes/dom4/keycode_converter_data.h index 0d9fccd..2f7712e 100644 --- a/ui/events/keycodes/dom4/keycode_converter_data.h +++ b/ui/events/keycodes/dom4/keycode_converter_data.h @@ -399,6 +399,12 @@ USB_KEYMAP_DECLARATION { USB_KEYMAP(0x0c0075, 0x00fc, 0x0000, 0xffff, NULL, BRIGHTNESS_AUTO), // USB XKB Win Mac + //USB_KEYMAP(0x0c00b0, 0x00d7, 0x????, 0x????, "MediaPlay", MEDIA_PLAY), + //USB_KEYMAP(0x0c00b1, 0x007f, 0x????, 0x????, "MediaPause", MEDIA_PAUSE), + //USB_KEYMAP(0x0c00b2, 0x00af, 0x????, 0x????, "MediaRecord", MEDIA_RECORD), + //USB_KEYMAP(0x0c00b3, 0x00d8, 0x????, 0x????, "MediaFastForward", + // MEDIA_FAST_FORWARD), + //USB_KEYMAP(0x0c00b4, 0x00b0, 0x????, 0x????, "MediaRewind", MEDIA_REWIND), USB_KEYMAP(0x0c00b5, 0x0000, 0xe019, 0xffff, "MediaTrackNext", MEDIA_TRACK_NEXT), USB_KEYMAP(0x0c00b6, 0x0000, 0xe010, 0xffff, "MediaTrackPrevious", @@ -441,6 +447,8 @@ USB_KEYMAP_DECLARATION { USB_KEYMAP(0x0c01b4, 0x0098, 0x0000, 0xffff, NULL, LAUNCH_FILE_BROWSER), // USB#0x0c01b7: AL Audio Browser //USB_KEYMAP(0x0c01b7, 0x0190, 0x0000, 0xffff, NULL, LAUNCH_AUDIO_BROWSER), + // USB#0x0c0208: AC Print + //USB_KEYMAP(0x0c0208, 0x00da, 0x0000, 0xffff, NULL, PRINT), // USB#0x0c0221: AC_Search USB_KEYMAP(0x0c0221, 0x0000, 0xe065, 0xffff, "BrowserSearch", BROWSER_SEARCH), // USB#0x0c0223: AC_Home diff --git a/ui/events/keycodes/dom_us_layout_data.h b/ui/events/keycodes/dom_us_layout_data.h new file mode 100644 index 0000000..c85aef2 --- /dev/null +++ b/ui/events/keycodes/dom_us_layout_data.h @@ -0,0 +1,624 @@ +// Copyright (c) 2015 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. + +#ifndef UI_EVENTS_KEYCODES_DOM_US_LAYOUT_DATA_H_ +#define UI_EVENTS_KEYCODES_DOM_US_LAYOUT_DATA_H_ + +namespace ui { + +// This table maps a DomCode to a printable character, assuming US layout. +const struct PrintableCodeEntry { + DomCode dom_code; + base::char16 character[2]; // normal, shift +} kPrintableCodeMap[] = { + {DomCode::KEY_A, {'a', 'A'}}, + {DomCode::KEY_B, {'b', 'B'}}, + {DomCode::KEY_C, {'c', 'C'}}, + {DomCode::KEY_D, {'d', 'D'}}, + {DomCode::KEY_E, {'e', 'E'}}, + {DomCode::KEY_F, {'f', 'F'}}, + {DomCode::KEY_G, {'g', 'G'}}, + {DomCode::KEY_H, {'h', 'H'}}, + {DomCode::KEY_I, {'i', 'I'}}, + {DomCode::KEY_J, {'j', 'J'}}, + {DomCode::KEY_K, {'k', 'K'}}, + {DomCode::KEY_L, {'l', 'L'}}, + {DomCode::KEY_M, {'m', 'M'}}, + {DomCode::KEY_N, {'n', 'N'}}, + {DomCode::KEY_O, {'o', 'O'}}, + {DomCode::KEY_P, {'p', 'P'}}, + {DomCode::KEY_Q, {'q', 'Q'}}, + {DomCode::KEY_R, {'r', 'R'}}, + {DomCode::KEY_S, {'s', 'S'}}, + {DomCode::KEY_T, {'t', 'T'}}, + {DomCode::KEY_U, {'u', 'U'}}, + {DomCode::KEY_V, {'v', 'V'}}, + {DomCode::KEY_W, {'w', 'W'}}, + {DomCode::KEY_X, {'x', 'X'}}, + {DomCode::KEY_Y, {'y', 'Y'}}, + {DomCode::KEY_Z, {'z', 'Z'}}, + {DomCode::DIGIT1, {'1', '!'}}, + {DomCode::DIGIT2, {'2', '@'}}, + {DomCode::DIGIT3, {'3', '#'}}, + {DomCode::DIGIT4, {'4', '$'}}, + {DomCode::DIGIT5, {'5', '%'}}, + {DomCode::DIGIT6, {'6', '^'}}, + {DomCode::DIGIT7, {'7', '&'}}, + {DomCode::DIGIT8, {'8', '*'}}, + {DomCode::DIGIT9, {'9', '('}}, + {DomCode::DIGIT0, {'0', ')'}}, + {DomCode::SPACE, {' ', ' '}}, + {DomCode::MINUS, {'-', '_'}}, + {DomCode::EQUAL, {'=', '+'}}, + {DomCode::BRACKET_LEFT, {'[', '{'}}, + {DomCode::BRACKET_RIGHT, {']', '}'}}, + {DomCode::BACKSLASH, {'\\', '|'}}, + {DomCode::SEMICOLON, {';', ':'}}, + {DomCode::QUOTE, {'\'', '"'}}, + {DomCode::BACKQUOTE, {'`', '~'}}, + {DomCode::COMMA, {',', '<'}}, + {DomCode::PERIOD, {'.', '>'}}, + {DomCode::SLASH, {'/', '?'}}, + {DomCode::INTL_BACKSLASH, {'\\', '|'}}, + {DomCode::INTL_YEN, {0x00A5, '|'}}, + {DomCode::NUMPAD_DIVIDE, {'/', '/'}}, + {DomCode::NUMPAD_MULTIPLY, {'*', '*'}}, + {DomCode::NUMPAD_SUBTRACT, {'-', '-'}}, + {DomCode::NUMPAD_ADD, {'+', '+'}}, + {DomCode::NUMPAD1, {'1', '1'}}, + {DomCode::NUMPAD2, {'2', '2'}}, + {DomCode::NUMPAD3, {'3', '3'}}, + {DomCode::NUMPAD4, {'4', '4'}}, + {DomCode::NUMPAD5, {'5', '5'}}, + {DomCode::NUMPAD6, {'6', '6'}}, + {DomCode::NUMPAD7, {'7', '7'}}, + {DomCode::NUMPAD8, {'8', '8'}}, + {DomCode::NUMPAD9, {'9', '9'}}, + {DomCode::NUMPAD0, {'0', '0'}}, + {DomCode::NUMPAD_DECIMAL, {'.', '.'}}, + {DomCode::NUMPAD_EQUAL, {'=', '='}}, + {DomCode::NUMPAD_COMMA, {',', ','}}, + {DomCode::NUMPAD_PAREN_LEFT, {'(', '('}}, + {DomCode::NUMPAD_PAREN_RIGHT, {')', ')'}}, + {DomCode::NUMPAD_SIGN_CHANGE, {0x00B1, 0x00B1}}, +}; + +// This table maps a DomCode to a DomKey, assuming US keyboard layout. +const struct NonPrintableCodeEntry { + DomCode dom_code; + DomKey dom_key; + base::char16 character; +} kNonPrintableCodeMap[] = { + {DomCode::ABORT, DomKey::CANCEL}, + {DomCode::AGAIN, DomKey::AGAIN}, + {DomCode::ALT_LEFT, DomKey::ALT}, + {DomCode::ALT_RIGHT, DomKey::ALT}, + {DomCode::ARROW_DOWN, DomKey::ARROW_DOWN}, + {DomCode::ARROW_LEFT, DomKey::ARROW_LEFT}, + {DomCode::ARROW_RIGHT, DomKey::ARROW_RIGHT}, + {DomCode::ARROW_UP, DomKey::ARROW_UP}, + {DomCode::BACKSPACE, DomKey::BACKSPACE, 0x0008}, + {DomCode::BRIGHTNESS_DOWN, DomKey::BRIGHTNESS_DOWN}, + {DomCode::BRIGHTNESS_UP, DomKey::BRIGHTNESS_UP}, + // {DomCode::BRIGHTNESS_AUTO, DomKey::_} + // {DomCode::BRIGHTNESS_MAXIMUM, DomKey::_} + // {DomCode::BRIGHTNESS_MINIMIUM, DomKey::_} + // {DomCode::BRIGHTNESS_TOGGLE, DomKey::_} + {DomCode::BROWSER_BACK, DomKey::BROWSER_BACK}, + {DomCode::BROWSER_FAVORITES, DomKey::BROWSER_FAVORITES}, + {DomCode::BROWSER_FORWARD, DomKey::BROWSER_FORWARD}, + {DomCode::BROWSER_HOME, DomKey::BROWSER_HOME}, + {DomCode::BROWSER_REFRESH, DomKey::BROWSER_REFRESH}, + {DomCode::BROWSER_SEARCH, DomKey::BROWSER_SEARCH}, + {DomCode::BROWSER_STOP, DomKey::BROWSER_STOP}, + {DomCode::CAPS_LOCK, DomKey::CAPS_LOCK}, + {DomCode::CONTEXT_MENU, DomKey::CONTEXT_MENU}, + {DomCode::CONTROL_LEFT, DomKey::CONTROL}, + {DomCode::CONTROL_RIGHT, DomKey::CONTROL}, + {DomCode::CONVERT, DomKey::CONVERT}, + {DomCode::COPY, DomKey::COPY}, + {DomCode::CUT, DomKey::CUT}, + {DomCode::DEL, DomKey::DEL, 0x007F}, + {DomCode::EJECT, DomKey::EJECT}, + {DomCode::END, DomKey::END}, + {DomCode::ENTER, DomKey::ENTER, 0x000D}, + {DomCode::ESCAPE, DomKey::ESCAPE, 0x001B}, + {DomCode::F1, DomKey::F1}, + {DomCode::F2, DomKey::F2}, + {DomCode::F3, DomKey::F3}, + {DomCode::F4, DomKey::F4}, + {DomCode::F5, DomKey::F5}, + {DomCode::F6, DomKey::F6}, + {DomCode::F7, DomKey::F7}, + {DomCode::F8, DomKey::F8}, + {DomCode::F9, DomKey::F9}, + {DomCode::F10, DomKey::F10}, + {DomCode::F11, DomKey::F11}, + {DomCode::F12, DomKey::F12}, + {DomCode::F13, DomKey::F13}, + {DomCode::F14, DomKey::F14}, + {DomCode::F15, DomKey::F15}, + {DomCode::F16, DomKey::F16}, + {DomCode::F17, DomKey::F17}, + {DomCode::F18, DomKey::F18}, + {DomCode::F19, DomKey::F19}, + {DomCode::F20, DomKey::F20}, + {DomCode::F21, DomKey::F21}, + {DomCode::F22, DomKey::F22}, + {DomCode::F23, DomKey::F23}, + {DomCode::F24, DomKey::F24}, + {DomCode::FIND, DomKey::FIND}, + {DomCode::FN, DomKey::FN}, + {DomCode::FN_LOCK, DomKey::FN_LOCK}, + {DomCode::HELP, DomKey::HELP}, + {DomCode::HOME, DomKey::HOME}, + {DomCode::HYPER, DomKey::HYPER}, + {DomCode::INSERT, DomKey::INSERT}, + // {DomCode::INTL_RO, DomKey::_} + {DomCode::KANA_MODE, DomKey::KANA_MODE}, + {DomCode::LANG1, DomKey::HANGUL_MODE}, + {DomCode::LANG2, DomKey::HANJA_MODE}, + {DomCode::LANG3, DomKey::KATAKANA}, + {DomCode::LANG4, DomKey::HIRAGANA}, + {DomCode::LANG5, DomKey::ZENKAKU_HANKAKU}, + {DomCode::LAUNCH_APP1, DomKey::LAUNCH_MY_COMPUTER}, + {DomCode::LAUNCH_APP2, DomKey::LAUNCH_CALCULATOR}, + {DomCode::LAUNCH_MAIL, DomKey::LAUNCH_MAIL}, + {DomCode::LAUNCH_SCREEN_SAVER, DomKey::LAUNCH_SCREEN_SAVER}, + // {DomCode::LAUNCH_DOCUMENTS, DomKey::_} + // {DomCode::LAUNCH_FILE_BROWSER, DomKey::_} + // {DomCode::LAUNCH_KEYBOARD_LAYOUT, DomKey::_} + {DomCode::LOCK_SCREEN, DomKey::LAUNCH_SCREEN_SAVER}, + {DomCode::MAIL_FORWARD, DomKey::MAIL_FORWARD}, + {DomCode::MAIL_REPLY, DomKey::MAIL_REPLY}, + {DomCode::MAIL_SEND, DomKey::MAIL_SEND}, + {DomCode::MEDIA_PLAY_PAUSE, DomKey::MEDIA_PLAY_PAUSE}, + {DomCode::MEDIA_SELECT, DomKey::MEDIA_SELECT}, + {DomCode::MEDIA_STOP, DomKey::MEDIA_STOP}, + {DomCode::MEDIA_TRACK_NEXT, DomKey::MEDIA_TRACK_NEXT}, + {DomCode::MEDIA_TRACK_PREVIOUS, DomKey::MEDIA_TRACK_PREVIOUS}, + // {DomCode::MENU, DomKey::_} + {DomCode::NON_CONVERT, DomKey::NON_CONVERT}, + {DomCode::NUM_LOCK, DomKey::NUM_LOCK}, + {DomCode::NUMPAD_BACKSPACE, DomKey::BACKSPACE, 0x0008}, + {DomCode::NUMPAD_CLEAR, DomKey::CLEAR}, + {DomCode::NUMPAD_ENTER, DomKey::ENTER, 0x000D}, + // {DomCode::NUMPAD_CLEAR_ENTRY, DomKey::_} + // {DomCode::NUMPAD_MEMORY_ADD, DomKey::_} + // {DomCode::NUMPAD_MEMORY_CLEAR, DomKey::_} + // {DomCode::NUMPAD_MEMORY_RECALL, DomKey::_} + // {DomCode::NUMPAD_MEMORY_STORE, DomKey::_} + // {DomCode::NUMPAD_MEMORY_SUBTRACT, DomKey::_} + {DomCode::OPEN, DomKey::OPEN}, + {DomCode::OS_LEFT, DomKey::OS}, + {DomCode::OS_RIGHT, DomKey::OS}, + {DomCode::PAGE_DOWN, DomKey::PAGE_DOWN}, + {DomCode::PAGE_UP, DomKey::PAGE_UP}, + {DomCode::PASTE, DomKey::PASTE}, + {DomCode::PAUSE, DomKey::PAUSE}, + {DomCode::POWER, DomKey::POWER}, + {DomCode::PRINT_SCREEN, DomKey::PRINT_SCREEN}, + {DomCode::PROPS, DomKey::PROPS}, + {DomCode::SCROLL_LOCK, DomKey::SCROLL_LOCK}, + {DomCode::SELECT, DomKey::SELECT}, + // {DomCode::SELECT_TASK, DomKey::_} + {DomCode::SHIFT_LEFT, DomKey::SHIFT}, + {DomCode::SHIFT_RIGHT, DomKey::SHIFT}, + {DomCode::SUPER, DomKey::SUPER}, + {DomCode::TAB, DomKey::TAB, 0x0009}, + {DomCode::UNDO, DomKey::UNDO}, + // {DomCode::VOICE_COMMAND, DomKey::_} + {DomCode::VOLUME_DOWN, DomKey::VOLUME_DOWN}, + {DomCode::VOLUME_MUTE, DomKey::VOLUME_MUTE}, + {DomCode::VOLUME_UP, DomKey::VOLUME_UP}, + {DomCode::WAKE_UP, DomKey::WAKE_UP}, + {DomCode::ZOOM_TOGGLE, DomKey::ZOOM_TOGGLE}, +}; + +// This table maps a DomKey to a non-located KeyboardCode. +const struct DomKeyToKeyboardCodeEntry { + DomKey dom_key; + KeyboardCode key_code; +} kDomKeyToKeyboardCodeMap[] = { + // No value. + {DomKey::NONE, VKEY_UNKNOWN}, + // Special Key Values + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-special + {DomKey::UNIDENTIFIED, VKEY_UNKNOWN}, + // Modifier Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-modifier + {DomKey::ALT, VKEY_MENU}, + {DomKey::ALT_GRAPH, VKEY_ALTGR}, + {DomKey::CAPS_LOCK, VKEY_CAPITAL}, + {DomKey::CONTROL, VKEY_CONTROL}, + {DomKey::NUM_LOCK, VKEY_NUMLOCK}, + {DomKey::OS, VKEY_LWIN}, + {DomKey::SCROLL_LOCK, VKEY_SCROLL}, + {DomKey::SHIFT, VKEY_SHIFT}, + // Whitespace Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-whitespace + {DomKey::ENTER, VKEY_RETURN}, + {DomKey::SEPARATOR, VKEY_SEPARATOR}, + {DomKey::TAB, VKEY_TAB}, + // Navigation Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-navigation + {DomKey::ARROW_DOWN, VKEY_DOWN}, + {DomKey::ARROW_LEFT, VKEY_LEFT}, + {DomKey::ARROW_RIGHT, VKEY_RIGHT}, + {DomKey::ARROW_UP, VKEY_UP}, + {DomKey::END, VKEY_END}, + {DomKey::HOME, VKEY_HOME}, + {DomKey::PAGE_DOWN, VKEY_NEXT}, + {DomKey::PAGE_UP, VKEY_PRIOR}, + // Editing Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-editing + {DomKey::BACKSPACE, VKEY_BACK}, + {DomKey::CLEAR, VKEY_CLEAR}, + {DomKey::CR_SEL, VKEY_CRSEL}, + {DomKey::DEL, VKEY_DELETE}, + {DomKey::ERASE_EOF, VKEY_EREOF}, + {DomKey::EX_SEL, VKEY_EXSEL}, + {DomKey::INSERT, VKEY_INSERT}, + // UI Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-ui + {DomKey::ACCEPT, VKEY_ACCEPT}, + {DomKey::ATTN, VKEY_ATTN}, + {DomKey::CONTEXT_MENU, VKEY_APPS}, + {DomKey::ESCAPE, VKEY_ESCAPE}, + {DomKey::EXECUTE, VKEY_EXECUTE}, + {DomKey::HELP, VKEY_HELP}, + {DomKey::PAUSE, VKEY_PAUSE}, + {DomKey::PLAY, VKEY_PLAY}, + {DomKey::SELECT, VKEY_SELECT}, + // Device Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-device +#if defined(OS_POSIX) + {DomKey::BRIGHTNESS_DOWN, VKEY_BRIGHTNESS_DOWN}, + {DomKey::BRIGHTNESS_UP, VKEY_BRIGHTNESS_UP}, + {DomKey::POWER, VKEY_POWER}, +#endif + {DomKey::PRINT_SCREEN, VKEY_SNAPSHOT}, +// IME and Composition Keys +// http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-composition +#if defined(OS_POSIX) + {DomKey::COMPOSE, VKEY_COMPOSE}, +#endif + {DomKey::CONVERT, VKEY_CONVERT}, + {DomKey::FINAL_MODE, VKEY_FINAL}, + {DomKey::MODE_CHANGE, VKEY_MODECHANGE}, + {DomKey::NON_CONVERT, VKEY_NONCONVERT}, + {DomKey::PROCESS, VKEY_PROCESSKEY}, + // Keys specific to Korean keyboards + {DomKey::HANGUL_MODE, VKEY_HANGUL}, + {DomKey::HANJA_MODE, VKEY_HANJA}, + {DomKey::JUNJA_MODE, VKEY_JUNJA}, + // Keys specific to Japanese keyboards + {DomKey::HANKAKU, VKEY_DBE_SBCSCHAR}, + {DomKey::KANA_MODE, VKEY_KANA}, + {DomKey::KANJI_MODE, VKEY_KANJI}, + {DomKey::ZENKAKU, VKEY_DBE_DBCSCHAR}, + {DomKey::ZENKAKU_HANKAKU, VKEY_DBE_DBCSCHAR}, + // General-Purpose Function Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-function + {DomKey::F1, VKEY_F1}, + {DomKey::F2, VKEY_F2}, + {DomKey::F3, VKEY_F3}, + {DomKey::F4, VKEY_F4}, + {DomKey::F5, VKEY_F5}, + {DomKey::F6, VKEY_F6}, + {DomKey::F7, VKEY_F7}, + {DomKey::F8, VKEY_F8}, + {DomKey::F9, VKEY_F9}, + {DomKey::F10, VKEY_F10}, + {DomKey::F11, VKEY_F11}, + {DomKey::F12, VKEY_F12}, + {DomKey::F13, VKEY_F13}, + {DomKey::F14, VKEY_F14}, + {DomKey::F15, VKEY_F15}, + {DomKey::F16, VKEY_F16}, + {DomKey::F17, VKEY_F17}, + {DomKey::F18, VKEY_F18}, + {DomKey::F19, VKEY_F19}, + {DomKey::F20, VKEY_F20}, + {DomKey::F21, VKEY_F21}, + {DomKey::F22, VKEY_F22}, + {DomKey::F23, VKEY_F23}, + {DomKey::F24, VKEY_F24}, + // Multimedia Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-multimedia + {DomKey::MEDIA_PLAY_PAUSE, VKEY_MEDIA_PLAY_PAUSE}, + {DomKey::MEDIA_SELECT, VKEY_MEDIA_LAUNCH_MEDIA_SELECT}, + {DomKey::MEDIA_STOP, VKEY_MEDIA_STOP}, + {DomKey::MEDIA_TRACK_NEXT, VKEY_MEDIA_NEXT_TRACK}, + {DomKey::MEDIA_TRACK_PREVIOUS, VKEY_MEDIA_PREV_TRACK}, + {DomKey::PRINT, VKEY_PRINT}, + {DomKey::VOLUME_DOWN, VKEY_VOLUME_DOWN}, + {DomKey::VOLUME_MUTE, VKEY_VOLUME_MUTE}, + {DomKey::VOLUME_UP, VKEY_VOLUME_UP}, + // Application Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-apps + {DomKey::LAUNCH_CALCULATOR, VKEY_MEDIA_LAUNCH_APP2}, + {DomKey::LAUNCH_MAIL, VKEY_MEDIA_LAUNCH_MAIL}, + {DomKey::LAUNCH_MY_COMPUTER, VKEY_MEDIA_LAUNCH_APP1}, + // Browser Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-browser + {DomKey::BROWSER_BACK, VKEY_BROWSER_BACK}, + {DomKey::BROWSER_FAVORITES, VKEY_BROWSER_FAVORITES}, + {DomKey::BROWSER_FORWARD, VKEY_BROWSER_FORWARD}, + {DomKey::BROWSER_HOME, VKEY_BROWSER_HOME}, + {DomKey::BROWSER_REFRESH, VKEY_BROWSER_REFRESH}, + {DomKey::BROWSER_SEARCH, VKEY_BROWSER_SEARCH}, + {DomKey::BROWSER_STOP, VKEY_BROWSER_STOP}, + // Media Controller Keys + // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-media-controller +#if defined(OS_POSIX) + {DomKey::MEDIA_FAST_FORWARD, VKEY_OEM_104}, +#endif + {DomKey::MEDIA_PLAY, VKEY_PLAY}, +#if defined(OS_POSIX) + {DomKey::MEDIA_REWIND, VKEY_OEM_103}, +#endif + {DomKey::ZOOM_TOGGLE, VKEY_ZOOM}, +}; + +// This table, used by DomCodeToUsLayoutKeyboardCode() and +// UsLayoutKeyboardCodeToDomCode(), maps between DOM Level 3 .code values +// and legacy Windows-based VKEY values, where the VKEYs are interpreted +// positionally (located) following a base US English layout. +const struct DomCodeToKeyboardCodeEntry { + DomCode dom_code; + KeyboardCode key_code; +} kDomCodeToKeyboardCodeMap[] = { + // Entries are ordered by numeric value of the DomCode enum, + // which is the USB physical key code. + // DomCode::HYPER 0x000010 Hyper + // DomCode::SUPER 0x000011 Super + // DomCode::FN 0x000012 Fn + // DomCode::FN_LOCK 0x000013 FLock + // DomCode::SUSPEND 0x000014 Suspend + // DomCode::RESUME 0x000015 Resume + // DomCode::TURBO 0x000016 Turbo + {DomCode::SLEEP, VKEY_SLEEP}, // 0x010082 Sleep + // DomCode::WAKE_UP 0x010083 WakeUp + {DomCode::KEY_A, VKEY_A}, // 0x070004 KeyA + {DomCode::KEY_B, VKEY_B}, // 0x070005 KeyB + {DomCode::KEY_C, VKEY_C}, // 0x070006 KeyC + {DomCode::KEY_D, VKEY_D}, // 0x070007 KeyD + {DomCode::KEY_E, VKEY_E}, // 0x070008 KeyE + {DomCode::KEY_F, VKEY_F}, // 0x070009 KeyF + {DomCode::KEY_G, VKEY_G}, // 0x07000A KeyG + {DomCode::KEY_H, VKEY_H}, // 0x07000B KeyH + {DomCode::KEY_I, VKEY_I}, // 0x07000C KeyI + {DomCode::KEY_J, VKEY_J}, // 0x07000D KeyJ + {DomCode::KEY_K, VKEY_K}, // 0x07000E KeyK + {DomCode::KEY_L, VKEY_L}, // 0x07000F KeyL + {DomCode::KEY_M, VKEY_M}, // 0x070010 KeyM + {DomCode::KEY_N, VKEY_N}, // 0x070011 KeyN + {DomCode::KEY_O, VKEY_O}, // 0x070012 KeyO + {DomCode::KEY_P, VKEY_P}, // 0x070013 KeyP + {DomCode::KEY_Q, VKEY_Q}, // 0x070014 KeyQ + {DomCode::KEY_R, VKEY_R}, // 0x070015 KeyR + {DomCode::KEY_S, VKEY_S}, // 0x070016 KeyS + {DomCode::KEY_T, VKEY_T}, // 0x070017 KeyT + {DomCode::KEY_U, VKEY_U}, // 0x070018 KeyU + {DomCode::KEY_V, VKEY_V}, // 0x070019 KeyV + {DomCode::KEY_W, VKEY_W}, // 0x07001A KeyW + {DomCode::KEY_X, VKEY_X}, // 0x07001B KeyX + {DomCode::KEY_Y, VKEY_Y}, // 0x07001C KeyY + {DomCode::KEY_Z, VKEY_Z}, // 0x07001D KeyZ + {DomCode::DIGIT1, VKEY_1}, // 0x07001E Digit1 + {DomCode::DIGIT2, VKEY_2}, // 0x07001F Digit2 + {DomCode::DIGIT3, VKEY_3}, // 0x070020 Digit3 + {DomCode::DIGIT4, VKEY_4}, // 0x070021 Digit4 + {DomCode::DIGIT5, VKEY_5}, // 0x070022 Digit5 + {DomCode::DIGIT6, VKEY_6}, // 0x070023 Digit6 + {DomCode::DIGIT7, VKEY_7}, // 0x070024 Digit7 + {DomCode::DIGIT8, VKEY_8}, // 0x070025 Digit8 + {DomCode::DIGIT9, VKEY_9}, // 0x070026 Digit9 + {DomCode::DIGIT0, VKEY_0}, // 0x070027 Digit0 + {DomCode::ENTER, VKEY_RETURN}, // 0x070028 Enter + {DomCode::ESCAPE, VKEY_ESCAPE}, // 0x070029 Escape + {DomCode::BACKSPACE, VKEY_BACK}, // 0x07002A Backspace + {DomCode::TAB, VKEY_TAB}, // 0x07002B Tab + {DomCode::SPACE, VKEY_SPACE}, // 0x07002C Space + {DomCode::MINUS, VKEY_OEM_MINUS}, // 0x07002D Minus + {DomCode::EQUAL, VKEY_OEM_PLUS}, // 0x07002E Equal + {DomCode::BRACKET_LEFT, VKEY_OEM_4}, // 0x07002F BracketLeft + {DomCode::BRACKET_RIGHT, VKEY_OEM_6}, // 0x070030 BracketRight + {DomCode::BACKSLASH, VKEY_OEM_5}, // 0x070031 Backslash + // DomCode::INTL_HASH, VKEY_OEM_5 // 0x070032 IntlHash + {DomCode::SEMICOLON, VKEY_OEM_1}, // 0x070033 Semicolon + {DomCode::QUOTE, VKEY_OEM_7}, // 0x070034 Quote + {DomCode::BACKQUOTE, VKEY_OEM_3}, // 0x070035 Backquote + {DomCode::COMMA, VKEY_OEM_COMMA}, // 0x070036 Comma + {DomCode::PERIOD, VKEY_OEM_PERIOD}, // 0x070037 Period + {DomCode::SLASH, VKEY_OEM_2}, // 0x070038 Slash + {DomCode::CAPS_LOCK, VKEY_CAPITAL}, // 0x070039 CapsLock + {DomCode::F1, VKEY_F1}, // 0x07003A F1 + {DomCode::F2, VKEY_F2}, // 0x07003B F2 + {DomCode::F3, VKEY_F3}, // 0x07003C F3 + {DomCode::F4, VKEY_F4}, // 0x07003D F4 + {DomCode::F5, VKEY_F5}, // 0x07003E F5 + {DomCode::F6, VKEY_F6}, // 0x07003F F6 + {DomCode::F7, VKEY_F7}, // 0x070040 F7 + {DomCode::F8, VKEY_F8}, // 0x070041 F8 + {DomCode::F9, VKEY_F9}, // 0x070042 F9 + {DomCode::F10, VKEY_F10}, // 0x070043 F10 + {DomCode::F11, VKEY_F11}, // 0x070044 F11 + {DomCode::F12, VKEY_F12}, // 0x070045 F12 + {DomCode::PRINT_SCREEN, VKEY_SNAPSHOT}, // 0x070046 PrintScreen + {DomCode::SCROLL_LOCK, VKEY_SCROLL}, // 0x070047 ScrollLock + {DomCode::PAUSE, VKEY_PAUSE}, // 0x070048 Pause + {DomCode::INSERT, VKEY_INSERT}, // 0x070049 Insert + {DomCode::HOME, VKEY_HOME}, // 0x07004A Home + {DomCode::PAGE_UP, VKEY_PRIOR}, // 0x07004B PageUp + {DomCode::DEL, VKEY_DELETE}, // 0x07004C Delete + {DomCode::END, VKEY_END}, // 0x07004D End + {DomCode::PAGE_DOWN, VKEY_NEXT}, // 0x07004E PageDown + {DomCode::ARROW_RIGHT, VKEY_RIGHT}, // 0x07004F ArrowRight + {DomCode::ARROW_LEFT, VKEY_LEFT}, // 0x070050 ArrowLeft + {DomCode::ARROW_DOWN, VKEY_DOWN}, // 0x070051 ArrowDown + {DomCode::ARROW_UP, VKEY_UP}, // 0x070052 ArrowUp + {DomCode::NUM_LOCK, VKEY_NUMLOCK}, // 0x070053 NumLock + {DomCode::NUMPAD_DIVIDE, VKEY_DIVIDE}, // 0x070054 NumpadDivide + {DomCode::NUMPAD_MULTIPLY, VKEY_MULTIPLY}, // 0x070055 NumpadMultiply + {DomCode::NUMPAD_SUBTRACT, VKEY_SUBTRACT}, // 0x070056 NumpadSubtract + {DomCode::NUMPAD_ADD, VKEY_ADD}, // 0x070057 NumpadAdd + {DomCode::NUMPAD_ENTER, VKEY_RETURN}, // 0x070058 NumpadEnter + {DomCode::NUMPAD1, VKEY_NUMPAD1}, // 0x070059 Numpad1 + {DomCode::NUMPAD2, VKEY_NUMPAD2}, // 0x07005A Numpad2 + {DomCode::NUMPAD3, VKEY_NUMPAD3}, // 0x07005B Numpad3 + {DomCode::NUMPAD4, VKEY_NUMPAD4}, // 0x07005C Numpad4 + {DomCode::NUMPAD5, VKEY_NUMPAD5}, // 0x07005D Numpad5 + {DomCode::NUMPAD6, VKEY_NUMPAD6}, // 0x07005E Numpad6 + {DomCode::NUMPAD7, VKEY_NUMPAD7}, // 0x07005F Numpad7 + {DomCode::NUMPAD8, VKEY_NUMPAD8}, // 0x070060 Numpad8 + {DomCode::NUMPAD9, VKEY_NUMPAD9}, // 0x070061 Numpad9 + {DomCode::NUMPAD0, VKEY_NUMPAD0}, // 0x070062 Numpad0 + {DomCode::NUMPAD_DECIMAL, VKEY_DECIMAL}, // 0x070063 NumpadDecimal + {DomCode::INTL_BACKSLASH, VKEY_OEM_102}, // 0x070064 IntlBackslash + {DomCode::CONTEXT_MENU, VKEY_APPS}, // 0x070065 ContextMenu +#if defined(OS_POSIX) + {DomCode::POWER, VKEY_POWER}, // 0x070066 Power +#endif + // DomCode::NUMPAD_EQUAL 0x070067 NumpadEqual + {DomCode::F13, VKEY_F13}, // 0x070068 F13 + {DomCode::F14, VKEY_F14}, // 0x070069 F14 + {DomCode::F15, VKEY_F15}, // 0x07006A F15 + {DomCode::F16, VKEY_F16}, // 0x07006B F16 + {DomCode::F17, VKEY_F17}, // 0x07006C F17 + {DomCode::F18, VKEY_F18}, // 0x07006D F18 + {DomCode::F19, VKEY_F19}, // 0x07006E F19 + {DomCode::F20, VKEY_F20}, // 0x07006F F20 + {DomCode::F21, VKEY_F21}, // 0x070070 F21 + {DomCode::F22, VKEY_F22}, // 0x070071 F22 + {DomCode::F23, VKEY_F23}, // 0x070072 F23 + {DomCode::F24, VKEY_F24}, // 0x070073 F24 + {DomCode::OPEN, VKEY_EXECUTE}, // 0x070074 Open + {DomCode::HELP, VKEY_HELP}, // 0x070075 Help + {DomCode::SELECT, VKEY_SELECT}, // 0x070077 Select + // DomCode::AGAIN 0x070079 Again + // DomCode::UNDO 0x07007A Undo + // DomCode::CUT 0x07007B Cut + // DomCode::COPY 0x07007C Copy + // DomCode::PASTE 0x07007D Paste + // DomCode::FIND 0x07007E Find + {DomCode::VOLUME_MUTE, VKEY_VOLUME_MUTE}, // 0x07007F VolumeMute + {DomCode::VOLUME_UP, VKEY_VOLUME_UP}, // 0x070080 VolumeUp + {DomCode::VOLUME_DOWN, VKEY_VOLUME_DOWN}, // 0x070081 VolumeDown + {DomCode::NUMPAD_COMMA, VKEY_OEM_COMMA}, // 0x070085 NumpadComma + {DomCode::INTL_RO, VKEY_OEM_102}, // 0x070087 IntlRo + {DomCode::KANA_MODE, VKEY_KANA}, // 0x070088 KanaMode + {DomCode::INTL_YEN, VKEY_OEM_5}, // 0x070089 IntlYen + {DomCode::CONVERT, VKEY_CONVERT}, // 0x07008A Convert + {DomCode::NON_CONVERT, VKEY_NONCONVERT}, // 0x07008B NonConvert + {DomCode::LANG1, VKEY_KANA}, // 0x070090 Lang1 + {DomCode::LANG2, VKEY_KANJI}, // 0x070091 Lang2 + // DomCode::LANG3 0x070092 Lang3 + // DomCode::LANG4 0x070093 Lang4 + // DomCode::LANG5 0x070094 Lang5 + // DomCode::ABORT 0x07009B Abort + // DomCode::PROPS 0x0700A3 Props + // DomCode::NUMPAD_PAREN_LEFT 0x0700B6 NumpadParenLeft + // DomCode::NUMPAD_PAREN_RIGHT 0x0700B7 NumpadParenRight + {DomCode::NUMPAD_BACKSPACE, VKEY_BACK}, // 0x0700BB NumpadBackspace + // DomCode::NUMPAD_MEMORY_STORE 0x0700D0 NumpadMemoryStore + // DomCode::NUMPAD_MEMORY_RECALL 0x0700D1 NumpadMemoryRecall + // DomCode::NUMPAD_MEMORY_CLEAR 0x0700D2 NumpadMemoryClear + // DomCode::NUMPAD_MEMORY_ADD 0x0700D3 NumpadMemoryAdd + // DomCode::NUMPAD_MEMORY_SUBTRACT 0x0700D4 NumpadMemorySubtract + {DomCode::NUMPAD_CLEAR, VKEY_CLEAR}, // 0x0700D8 NumpadClear + {DomCode::NUMPAD_CLEAR_ENTRY, VKEY_CLEAR}, // 0x0700D9 NumpadClearEntry + {DomCode::CONTROL_LEFT, VKEY_LCONTROL}, // 0x0700E0 ControlLeft + {DomCode::SHIFT_LEFT, VKEY_LSHIFT}, // 0x0700E1 ShiftLeft + {DomCode::ALT_LEFT, VKEY_LMENU}, // 0x0700E2 AltLeft + {DomCode::OS_LEFT, VKEY_LWIN}, // 0x0700E3 OSLeft + {DomCode::CONTROL_RIGHT, VKEY_RCONTROL}, // 0x0700E4 ControlRight + {DomCode::SHIFT_RIGHT, VKEY_RSHIFT}, // 0x0700E5 ShiftRight + {DomCode::ALT_RIGHT, VKEY_RMENU}, // 0x0700E6 AltRight + {DomCode::OS_RIGHT, VKEY_RWIN}, // 0x0700E7 OSRight +#if defined(OS_POSIX) + {DomCode::BRIGHTNESS_UP, + VKEY_BRIGHTNESS_UP}, // 0x0C006F BrightnessUp + {DomCode::BRIGHTNESS_DOWN, + VKEY_BRIGHTNESS_DOWN}, // 0x0C0070 BrightnessDown +#endif + {DomCode::MEDIA_TRACK_NEXT, + VKEY_MEDIA_NEXT_TRACK}, // 0x0C00B5 MediaTrackNext + {DomCode::MEDIA_TRACK_PREVIOUS, + VKEY_MEDIA_PREV_TRACK}, // 0x0C00B6 MediaTrackPrevious + {DomCode::MEDIA_STOP, VKEY_MEDIA_STOP}, // 0x0C00B7 MediaStop + // DomCode::EJECT 0x0C00B8 Eject + {DomCode::MEDIA_PLAY_PAUSE, + VKEY_MEDIA_PLAY_PAUSE}, // 0x0C00CD MediaPlayPause + {DomCode::MEDIA_SELECT, + VKEY_MEDIA_LAUNCH_MEDIA_SELECT}, // 0x0C0183 MediaSelect + {DomCode::LAUNCH_MAIL, + VKEY_MEDIA_LAUNCH_MAIL}, // 0x0C018A LaunchMail + {DomCode::LAUNCH_APP2, + VKEY_MEDIA_LAUNCH_APP2}, // 0x0C0192 LaunchApp2 + {DomCode::LAUNCH_APP1, + VKEY_MEDIA_LAUNCH_APP1}, // 0x0C0194 LaunchApp1 + {DomCode::BROWSER_SEARCH, + VKEY_BROWSER_SEARCH}, // 0x0C0221 BrowserSearch + {DomCode::BROWSER_HOME, VKEY_BROWSER_HOME}, // 0x0C0223 BrowserHome + {DomCode::BROWSER_BACK, VKEY_BROWSER_BACK}, // 0x0C0224 BrowserBack + {DomCode::BROWSER_FORWARD, + VKEY_BROWSER_FORWARD}, // 0x0C0225 BrowserForward + {DomCode::BROWSER_STOP, VKEY_BROWSER_STOP}, // 0x0C0226 BrowserStop + {DomCode::BROWSER_REFRESH, + VKEY_BROWSER_REFRESH}, // 0x0C0227 BrowserRefresh + {DomCode::BROWSER_FAVORITES, + VKEY_BROWSER_FAVORITES}, // 0x0C022A BrowserFavorites + {DomCode::ZOOM_TOGGLE, VKEY_ZOOM}, // 0x0C0232 ZoomToggle +}; + +// This table, used by UsLayoutKeyboardCodeToDomCode(), maps legacy +// Windows-based VKEY values that are not part of kDomCodeToKeyboardCodeMap[] +// to suitable DomCode values, where practical. +const DomCodeToKeyboardCodeEntry kFallbackKeyboardCodeToDomCodeMap[] = { + {DomCode::ALT_LEFT, VKEY_MENU}, + {DomCode::ALT_RIGHT, VKEY_ALTGR}, + {DomCode::BACKQUOTE, VKEY_DBE_SBCSCHAR}, +#if defined(OS_POSIX) + {DomCode::CONTEXT_MENU, VKEY_COMPOSE}, +#endif + {DomCode::CONTROL_LEFT, VKEY_CONTROL}, + {DomCode::LANG1, VKEY_HANGUL}, + {DomCode::LANG2, VKEY_HANJA}, + {DomCode::LANG5, VKEY_DBE_DBCSCHAR}, + {DomCode::NUMPAD_CLEAR, VKEY_OEM_CLEAR}, + {DomCode::PROPS, VKEY_CRSEL}, + {DomCode::SHIFT_LEFT, VKEY_SHIFT}, + {DomCode::SUPER, VKEY_OEM_8}, + // + // VKEYs with no existing corresponding DomCode, but a USB usage code: + // {DomCode::SYS_REQ, VKEY_ATTN}, // 0x07009A SysReq + // {DomCode::SEPARATOR, VKEY_SEPARATOR}, // 0x07009F Separator + // {DomCode::EX_SEL, VKEY_EXSEL}, // 0x0700A4 ExSel + // {DomCode::PRINT, VKEY_PRINT}, // 0x0C0208 AC Print + // {DomCode::MEDIA_PLAY, VKEY_PLAY}, // 0x0C00B0 MediaPlay + // {DomCode::MEDIA_REWIND, VKEY_OEM_103}, // 0x0C00B4 MediaRewind + // {DomCode::MEDIA_FAST_FORWARD, VKEY_OEM_104}, + // // 0x0C00B3 MediaFastForward + // + // VKEYs with no corresponding DomCode and no obvious USB usage code: + // VKEY_ACCEPT + // VKEY_BACKTAB + // VKEY_EREOF + // VKEY_FINAL + // VKEY_JUNJA + // VKEY_KBD_BRIGHTNESS_DOWN + // VKEY_KBD_BRIGHTNESS_UP + // VKEY_MODECHANGE + // VKEY_NONAME + // VKEY_PA1 + // VKEY_PACKET + // VKEY_PROCESSKEY + // VKEY_WLAN +}; + +} // namespace ui + +#endif // UI_EVENTS_KEYCODES_DOM_US_LAYOUT_DATA_H_ diff --git a/ui/events/keycodes/keyboard_code_conversion.cc b/ui/events/keycodes/keyboard_code_conversion.cc index b71dd6f..e31512b 100644 --- a/ui/events/keycodes/keyboard_code_conversion.cc +++ b/ui/events/keycodes/keyboard_code_conversion.cc @@ -4,9 +4,12 @@ #include "ui/events/keycodes/keyboard_code_conversion.h" +#include <algorithm> + #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/dom_us_layout_data.h" namespace ui { @@ -130,6 +133,29 @@ bool IsRightSideDomCode(DomCode code) { (code == DomCode::ALT_RIGHT) || (code == DomCode::OS_RIGHT); } +bool IsModifierDomCode(DomCode code) { + return (code == DomCode::CONTROL_LEFT) || (code == DomCode::CONTROL_RIGHT) || + (code == DomCode::SHIFT_LEFT) || (code == DomCode::SHIFT_RIGHT) || + (code == DomCode::ALT_LEFT) || (code == DomCode::ALT_RIGHT) || + (code == DomCode::OS_LEFT) || (code == DomCode::OS_RIGHT); +} + +// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|, +// assuming a base US English layout. The returned VKEY is located +// (e.g. VKEY_LSHIFT). +KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code) { + const DomCodeToKeyboardCodeEntry* end = + kDomCodeToKeyboardCodeMap + arraysize(kDomCodeToKeyboardCodeMap); + const DomCodeToKeyboardCodeEntry* found = + std::lower_bound(kDomCodeToKeyboardCodeMap, end, dom_code, + [](const DomCodeToKeyboardCodeEntry& a, DomCode b) { + return static_cast<int>(a.dom_code) < static_cast<int>(b); + }); + if ((found != end) && (found->dom_code == dom_code)) + return found->key_code; + return VKEY_UNKNOWN; +} + } // anonymous namespace base::char16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags) { @@ -267,6 +293,151 @@ bool GetMeaningFromKeyCode(KeyboardCode key_code, return false; } +bool DomCodeToUsLayoutMeaning(DomCode dom_code, + int flags, + DomKey* out_dom_key, + base::char16* out_character, + KeyboardCode* out_key_code) { + if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) { + if (DomCodeToControlCharacter(dom_code, flags, out_dom_key, out_character, + out_key_code)) { + return true; + } + if (!IsModifierDomCode(dom_code)) { + *out_dom_key = DomKey::UNIDENTIFIED; + *out_character = 0; + *out_key_code = LocatedToNonLocatedKeyboardCode( + DomCodeToUsLayoutKeyboardCode(dom_code)); + return true; + } + } else { + for (const auto& it : kPrintableCodeMap) { + if (it.dom_code == dom_code) { + int state = ((flags & EF_SHIFT_DOWN) == EF_SHIFT_DOWN); + base::char16 ch = it.character[state]; + *out_dom_key = DomKey::CHARACTER; + *out_character = ch; + if ((flags & EF_CAPS_LOCK_DOWN) == EF_CAPS_LOCK_DOWN) { + ch |= 0x20; + if ((ch >= 'a') && (ch <= 'z')) + *out_character = it.character[state ^ 1]; + } + *out_key_code = LocatedToNonLocatedKeyboardCode( + DomCodeToUsLayoutKeyboardCode(dom_code)); + return true; + } + } + } + for (const auto& it : kNonPrintableCodeMap) { + if (it.dom_code == dom_code) { + *out_dom_key = it.dom_key; + *out_character = it.character; + *out_key_code = NonPrintableDomKeyToKeyboardCode(it.dom_key); + return true; + } + } + return false; +} + +bool DomCodeToControlCharacter(DomCode dom_code, + int flags, + DomKey* dom_key, + base::char16* character, + KeyboardCode* key_code) { + if ((flags & EF_CONTROL_DOWN) == 0) + return false; + + int code = static_cast<int>(dom_code); + const int kKeyA = static_cast<int>(DomCode::KEY_A); + // Control-A - Control-Z map to 0x01 - 0x1A. + if (code >= kKeyA && code <= static_cast<int>(DomCode::KEY_Z)) { + *character = static_cast<base::char16>(code - kKeyA + 1); + switch (dom_code) { + case DomCode::KEY_H: + *dom_key = DomKey::BACKSPACE; + *key_code = VKEY_BACK; + break; + case DomCode::KEY_I: + *dom_key = DomKey::TAB; + *key_code = VKEY_TAB; + break; + case DomCode::KEY_M: + *dom_key = DomKey::ENTER; + *key_code = VKEY_RETURN; + break; + default: + *dom_key = DomKey::CHARACTER; + *key_code = static_cast<KeyboardCode>(code - kKeyA + VKEY_A); + break; + } + return true; + } + + if (flags & EF_SHIFT_DOWN) { + switch (dom_code) { + case DomCode::DIGIT2: + // NUL + *character = 0; + *dom_key = DomKey::CHARACTER; + *key_code = VKEY_2; + return true; + case DomCode::DIGIT6: + // RS + *character = 0x1E; + *dom_key = DomKey::CHARACTER; + *key_code = VKEY_6; + return true; + case DomCode::MINUS: + // US + *character = 0x1F; + *dom_key = DomKey::CHARACTER; + *key_code = VKEY_OEM_MINUS; + return true; + default: + return false; + } + } + + switch (dom_code) { + case DomCode::ENTER: + // NL + *character = 0x0A; + *dom_key = DomKey::CHARACTER; + *key_code = VKEY_RETURN; + return true; + case DomCode::BRACKET_LEFT: + // ESC + *character = 0x1B; + *dom_key = DomKey::ESCAPE; + *key_code = VKEY_OEM_4; + return true; + case DomCode::BACKSLASH: + // FS + *character = 0x1C; + *dom_key = DomKey::CHARACTER; + *key_code = VKEY_OEM_5; + return true; + case DomCode::BRACKET_RIGHT: + // GS + *character = 0x1D; + *dom_key = DomKey::CHARACTER; + *key_code = VKEY_OEM_6; + return true; + default: + return false; + } +} + +// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. +// The returned VKEY is non-positional (e.g. VKEY_SHIFT). +KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) { + for (const auto& it : kDomKeyToKeyboardCodeMap) { + if (it.dom_key == dom_key) + return it.key_code; + } + return VKEY_UNKNOWN; +} + // Determine the non-located VKEY corresponding to a located VKEY. KeyboardCode LocatedToNonLocatedKeyboardCode(KeyboardCode key_code) { switch (key_code) { @@ -343,4 +514,17 @@ KeyboardCode NonLocatedToLocatedKeyboardCode(KeyboardCode key_code, } } +DomCode UsLayoutKeyboardCodeToDomCode(KeyboardCode key_code) { + key_code = NonLocatedToLocatedKeyboardCode(key_code, DomCode::NONE); + for (const auto& it : kDomCodeToKeyboardCodeMap) { + if (it.key_code == key_code) + return it.dom_code; + } + for (const auto& it : kFallbackKeyboardCodeToDomCodeMap) { + if (it.key_code == key_code) + return it.dom_code; + } + return DomCode::NONE; +} + } // namespace ui diff --git a/ui/events/keycodes/keyboard_code_conversion.h b/ui/events/keycodes/keyboard_code_conversion.h index 0c14ed74..8b92ba1 100644 --- a/ui/events/keycodes/keyboard_code_conversion.h +++ b/ui/events/keycodes/keyboard_code_conversion.h @@ -5,6 +5,7 @@ #ifndef UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_ #define UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_ +#include "base/compiler_specific.h" #include "base/strings/string16.h" #include "ui/events/events_base_export.h" #include "ui/events/keycodes/keyboard_codes.h" @@ -18,22 +19,20 @@ enum class DomKey; // platform independent way. It supports control characters as well. // It assumes a US keyboard layout is used, so it may only be used when there // is no native event or no better way to get the character. +// // For example, if a virtual keyboard implementation can only generate key // events with key_code and flags information, then there is no way for us to // determine the actual character that should be generate by the key. Because // a key_code only represents a physical key on the keyboard, it has nothing // to do with the actual character printed on that key. In such case, the only // thing we can do is to assume that we are using a US keyboard and get the -// character according to US keyboard layout definition. -// If a virtual keyboard implementation wants to support other keyboard -// layouts, that may generate different text for a certain key than on a US -// keyboard, a special native event object should be introduced to carry extra -// information to help determine the correct character. -// Take XKeyEvent as an example, it contains not only keycode and modifier -// flags but also group and other extra XKB information to help determine the -// correct character. That's why we can use XLookupString() function to get -// the correct text generated by a X key event (See how is GetCharacter() -// implemented in event_x.cc). +// character according to US keyboard layout definition. Preferably, such +// events should be created using a full KeyEvent constructor, explicitly +// specifying the character and DOM 3 values as well as the legacy VKEY. +// +// TODO(kpschoedel): replace remaining uses of the ...FromKeyCode() functions +// and remove them, to avoid future creation of underspecified key events. +// crbug.com/444045 EVENTS_BASE_EXPORT base::char16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags); EVENTS_BASE_EXPORT bool GetMeaningFromKeyCode(KeyboardCode key_code, @@ -41,6 +40,41 @@ EVENTS_BASE_EXPORT bool GetMeaningFromKeyCode(KeyboardCode key_code, DomKey* dom_key, base::char16* character); +// Helper function to map a physical key state (dom_code and flags) +// to a meaning (dom_key and character, together corresponding to the +// DOM keyboard event |key| value), along with a corresponding Windows-based +// key_code. +// +// This follows a US keyboard layout, so it should only be used when there +// is no other better way to obtain the meaning (e.g. actual keyboard layout). +// Returns true and sets the output parameters if the (dom_code, flags) pair +// has an interpretation in the US English layout; otherwise the output +// parameters are untouched. +EVENTS_BASE_EXPORT bool DomCodeToUsLayoutMeaning(DomCode dom_code, + int flags, + DomKey* dom_key, + base::char16* character, + KeyboardCode* key_code) + WARN_UNUSED_RESULT; + +// Obtains the control character corresponding to a physical key; +// that is, the meaning of the physical key state (dom_code, and flags +// containing EF_CONTROL_DOWN) under the base US English layout. +// Returns true and sets the output parameters if the (dom_code, flags) pair +// is interpreted as a control character; otherwise the output parameters +// are untouched. +EVENTS_BASE_EXPORT bool DomCodeToControlCharacter(DomCode dom_code, + int flags, + DomKey* dom_key, + base::char16* character, + KeyboardCode* key_code) + WARN_UNUSED_RESULT; + +// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. +// The returned VKEY is non-located (e.g. VKEY_SHIFT). +EVENTS_BASE_EXPORT KeyboardCode +NonPrintableDomKeyToKeyboardCode(DomKey dom_key); + // Determine the non-located VKEY corresponding to a located VKEY. // Most modifier keys have two kinds of KeyboardCode: located (e.g. // VKEY_LSHIFT and VKEY_RSHIFT), that indentify one of two specific @@ -53,6 +87,12 @@ LocatedToNonLocatedKeyboardCode(KeyboardCode key_code); EVENTS_BASE_EXPORT KeyboardCode NonLocatedToLocatedKeyboardCode(KeyboardCode key_code, DomCode dom_code); +// Returns a DOM Level 3 |code| from a Windows-based VKEY value. +// This assumes a US layout and should only be used when |code| cannot be +// determined from a physical scan code, for example when a key event was +// generated synthetically by JavaScript with only a VKEY value supplied. +EVENTS_BASE_EXPORT DomCode UsLayoutKeyboardCodeToDomCode(KeyboardCode key_code); + } // namespace ui #endif // UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_ diff --git a/ui/events/keycodes/keyboard_code_conversion_unittest.cc b/ui/events/keycodes/keyboard_code_conversion_unittest.cc new file mode 100644 index 0000000..e22208a --- /dev/null +++ b/ui/events/keycodes/keyboard_code_conversion_unittest.cc @@ -0,0 +1,523 @@ +// Copyright 2015 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. + +#include "ui/events/keycodes/keyboard_code_conversion.h" + +#include "base/basictypes.h" +#include "base/strings/stringprintf.h" +#include "testing/gtest/include/gtest/gtest.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/keycodes/keyboard_codes.h" + +namespace { + +struct Meaning { + bool defined; + ui::DomKey dom_key; + base::char16 character; + ui::KeyboardCode legacy_key_code; +}; + +const Meaning kUndefined = {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}; + +void CheckDomCodeToMeaning(const char* label, + bool f(ui::DomCode dom_code, + int flags, + ui::DomKey* out_dom_key, + base::char16* out_character, + ui::KeyboardCode* out_key_code), + ui::DomCode dom_code, + int event_flags, + const Meaning& result) { + ui::DomKey result_dom_key = ui::DomKey::NONE; + base::char16 result_character = 0; + ui::KeyboardCode result_legacy_key_code = ui::VKEY_UNKNOWN; + bool success = f(dom_code, event_flags, &result_dom_key, &result_character, + &result_legacy_key_code); + SCOPED_TRACE( + base::StringPrintf("%s %s %06X:%04X", label, + ui::KeycodeConverter::DomCodeToCodeString(dom_code), + static_cast<int>(dom_code), event_flags)); + EXPECT_EQ(result.defined, success); + if (success) { + EXPECT_EQ(result.dom_key, result_dom_key); + EXPECT_EQ(result.character, result_character); + EXPECT_EQ(result.legacy_key_code, result_legacy_key_code); + } else { + // Should not have touched output parameters. + EXPECT_EQ(ui::DomKey::NONE, result_dom_key); + EXPECT_EQ(0, result_character); + EXPECT_EQ(ui::VKEY_UNKNOWN, result_legacy_key_code); + } +} + +TEST(KeyboardCodeConversion, ControlCharacters) { + // The codes in this table are handled by |DomCodeToControlCharacter()|. + static const struct { + ui::DomCode dom_code; + Meaning control; + Meaning control_shift; + } kControlCharacters[] = { + {ui::DomCode::KEY_A, + {true, ui::DomKey::CHARACTER, 0x01, ui::VKEY_A}, + {true, ui::DomKey::CHARACTER, 0x01, ui::VKEY_A}}, + {ui::DomCode::KEY_B, + {true, ui::DomKey::CHARACTER, 0x02, ui::VKEY_B}, + {true, ui::DomKey::CHARACTER, 0x02, ui::VKEY_B}}, + {ui::DomCode::KEY_C, + {true, ui::DomKey::CHARACTER, 0x03, ui::VKEY_C}, + {true, ui::DomKey::CHARACTER, 0x03, ui::VKEY_C}}, + {ui::DomCode::KEY_D, + {true, ui::DomKey::CHARACTER, 0x04, ui::VKEY_D}, + {true, ui::DomKey::CHARACTER, 0x04, ui::VKEY_D}}, + {ui::DomCode::KEY_E, + {true, ui::DomKey::CHARACTER, 0x05, ui::VKEY_E}, + {true, ui::DomKey::CHARACTER, 0x05, ui::VKEY_E}}, + {ui::DomCode::KEY_F, + {true, ui::DomKey::CHARACTER, 0x06, ui::VKEY_F}, + {true, ui::DomKey::CHARACTER, 0x06, ui::VKEY_F}}, + {ui::DomCode::KEY_G, + {true, ui::DomKey::CHARACTER, 0x07, ui::VKEY_G}, + {true, ui::DomKey::CHARACTER, 0x07, ui::VKEY_G}}, + {ui::DomCode::KEY_H, + {true, ui::DomKey::BACKSPACE, 0x08, ui::VKEY_BACK}, + {true, ui::DomKey::BACKSPACE, 0x08, ui::VKEY_BACK}}, + {ui::DomCode::KEY_I, + {true, ui::DomKey::TAB, 0x09, ui::VKEY_TAB}, + {true, ui::DomKey::TAB, 0x09, ui::VKEY_TAB}}, + {ui::DomCode::KEY_J, + {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_J}, + {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_J}}, + {ui::DomCode::KEY_K, + {true, ui::DomKey::CHARACTER, 0x0B, ui::VKEY_K}, + {true, ui::DomKey::CHARACTER, 0x0B, ui::VKEY_K}}, + {ui::DomCode::KEY_L, + {true, ui::DomKey::CHARACTER, 0x0C, ui::VKEY_L}, + {true, ui::DomKey::CHARACTER, 0x0C, ui::VKEY_L}}, + {ui::DomCode::KEY_M, + {true, ui::DomKey::ENTER, 0x0D, ui::VKEY_RETURN}, + {true, ui::DomKey::ENTER, 0x0D, ui::VKEY_RETURN}}, + {ui::DomCode::KEY_N, + {true, ui::DomKey::CHARACTER, 0x0E, ui::VKEY_N}, + {true, ui::DomKey::CHARACTER, 0x0E, ui::VKEY_N}}, + {ui::DomCode::KEY_O, + {true, ui::DomKey::CHARACTER, 0x0F, ui::VKEY_O}, + {true, ui::DomKey::CHARACTER, 0x0F, ui::VKEY_O}}, + {ui::DomCode::KEY_P, + {true, ui::DomKey::CHARACTER, 0x10, ui::VKEY_P}, + {true, ui::DomKey::CHARACTER, 0x10, ui::VKEY_P}}, + {ui::DomCode::KEY_Q, + {true, ui::DomKey::CHARACTER, 0x11, ui::VKEY_Q}, + {true, ui::DomKey::CHARACTER, 0x11, ui::VKEY_Q}}, + {ui::DomCode::KEY_R, + {true, ui::DomKey::CHARACTER, 0x12, ui::VKEY_R}, + {true, ui::DomKey::CHARACTER, 0x12, ui::VKEY_R}}, + {ui::DomCode::KEY_S, + {true, ui::DomKey::CHARACTER, 0x13, ui::VKEY_S}, + {true, ui::DomKey::CHARACTER, 0x13, ui::VKEY_S}}, + {ui::DomCode::KEY_T, + {true, ui::DomKey::CHARACTER, 0x14, ui::VKEY_T}, + {true, ui::DomKey::CHARACTER, 0x14, ui::VKEY_T}}, + {ui::DomCode::KEY_U, + {true, ui::DomKey::CHARACTER, 0x15, ui::VKEY_U}, + {true, ui::DomKey::CHARACTER, 0x15, ui::VKEY_U}}, + {ui::DomCode::KEY_V, + {true, ui::DomKey::CHARACTER, 0x16, ui::VKEY_V}, + {true, ui::DomKey::CHARACTER, 0x16, ui::VKEY_V}}, + {ui::DomCode::KEY_W, + {true, ui::DomKey::CHARACTER, 0x17, ui::VKEY_W}, + {true, ui::DomKey::CHARACTER, 0x17, ui::VKEY_W}}, + {ui::DomCode::KEY_X, + {true, ui::DomKey::CHARACTER, 0x18, ui::VKEY_X}, + {true, ui::DomKey::CHARACTER, 0x18, ui::VKEY_X}}, + {ui::DomCode::KEY_Y, + {true, ui::DomKey::CHARACTER, 0x19, ui::VKEY_Y}, + {true, ui::DomKey::CHARACTER, 0x19, ui::VKEY_Y}}, + {ui::DomCode::KEY_Z, + {true, ui::DomKey::CHARACTER, 0x1A, ui::VKEY_Z}, + {true, ui::DomKey::CHARACTER, 0x1A, ui::VKEY_Z}}, + }; + for (const auto& it : kControlCharacters) { + // Verify |DomCodeToControlCharacter()|. + CheckDomCodeToMeaning("c_cc_n", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_NONE, kUndefined); + CheckDomCodeToMeaning("c_cc_c", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_CONTROL_DOWN, it.control); + CheckDomCodeToMeaning("c_cc_cs", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, + it.control_shift); + // Verify |DomCodeToUsLayoutMeaning()|. + CheckDomCodeToMeaning("c_us_c", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_CONTROL_DOWN, it.control); + CheckDomCodeToMeaning("c_us_cs", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, + it.control_shift); + } + + // The codes in this table are sensitive to the Shift state, so they are + // handled differently by |DomCodeToControlCharacter()|, which returns false + // for unknown combinations, vs |DomCodeToUsLayoutMeaning()|, which returns + // true with DomKey::UNIDENTIFIED. + static const struct { + ui::DomCode dom_code; + Meaning cc_control; + Meaning cc_control_shift; + Meaning us_control; + Meaning us_control_shift; + } kShiftControlCharacters[] = { + {ui::DomCode::DIGIT2, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0, ui::VKEY_2}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_2}, + {true, ui::DomKey::CHARACTER, 0, ui::VKEY_2}}, + {ui::DomCode::DIGIT6, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0x1E, ui::VKEY_6}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_6}, + {true, ui::DomKey::CHARACTER, 0x1E, ui::VKEY_6}}, + {ui::DomCode::MINUS, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0x1F, ui::VKEY_OEM_MINUS}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_MINUS}, + {true, ui::DomKey::CHARACTER, 0x1F, ui::VKEY_OEM_MINUS}}, + {ui::DomCode::ENTER, + {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_RETURN}, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0x0A, ui::VKEY_RETURN}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_RETURN}}, + {ui::DomCode::BRACKET_LEFT, + {true, ui::DomKey::ESCAPE, 0x1B, ui::VKEY_OEM_4}, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::ESCAPE, 0x1B, ui::VKEY_OEM_4}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_4}}, + {ui::DomCode::BACKSLASH, + {true, ui::DomKey::CHARACTER, 0x1C, ui::VKEY_OEM_5}, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0x1C, ui::VKEY_OEM_5}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_5}}, + {ui::DomCode::BRACKET_RIGHT, + {true, ui::DomKey::CHARACTER, 0x1D, ui::VKEY_OEM_6}, + {false, ui::DomKey::NONE, 0, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0x1D, ui::VKEY_OEM_6}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_6}}, + }; + for (const auto& it : kShiftControlCharacters) { + // Verify |DomCodeToControlCharacter()|. + CheckDomCodeToMeaning("s_cc_n", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_NONE, kUndefined); + CheckDomCodeToMeaning("s_cc_c", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_CONTROL_DOWN, it.cc_control); + CheckDomCodeToMeaning("s_cc_cs", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, + it.cc_control_shift); + // Verify |DomCodeToUsLayoutMeaning()|. + CheckDomCodeToMeaning("s_us_c", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_CONTROL_DOWN, it.us_control); + CheckDomCodeToMeaning("s_us_cs", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, + it.us_control_shift); + } + + // These codes are not handled by |DomCodeToControlCharacter()| directly. + static const struct { + ui::DomCode dom_code; + Meaning normal; + Meaning control; + } kNonControlCharacters[] = { + // Modifiers are handled by |DomCodeToUsLayoutMeaning()| without regard + // to whether Control is down. + {ui::DomCode::CONTROL_LEFT, + {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL}, + {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL}}, + {ui::DomCode::CONTROL_RIGHT, + {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL}, + {true, ui::DomKey::CONTROL, 0, ui::VKEY_CONTROL}}, + {ui::DomCode::SHIFT_LEFT, + {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT}, + {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT}}, + {ui::DomCode::SHIFT_RIGHT, + {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT}, + {true, ui::DomKey::SHIFT, 0, ui::VKEY_SHIFT}}, + {ui::DomCode::ALT_LEFT, + {true, ui::DomKey::ALT, 0, ui::VKEY_MENU}, + {true, ui::DomKey::ALT, 0, ui::VKEY_MENU}}, + {ui::DomCode::ALT_RIGHT, + {true, ui::DomKey::ALT, 0, ui::VKEY_MENU}, + {true, ui::DomKey::ALT, 0, ui::VKEY_MENU}}, + {ui::DomCode::OS_LEFT, + {true, ui::DomKey::OS, 0, ui::VKEY_LWIN}, + {true, ui::DomKey::OS, 0, ui::VKEY_LWIN}}, + {ui::DomCode::OS_RIGHT, + {true, ui::DomKey::OS, 0, ui::VKEY_LWIN}, + {true, ui::DomKey::OS, 0, ui::VKEY_LWIN}}, + // Non-modifiers (a representative sample here) succeed with + // DomKey::UNIDENTIFIED when Control is down. + {ui::DomCode::DIGIT1, + {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_1}}, + {ui::DomCode::EQUAL, + {true, ui::DomKey::CHARACTER, '=', ui::VKEY_OEM_PLUS}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_OEM_PLUS}}, + {ui::DomCode::TAB, + {true, ui::DomKey::TAB, 9, ui::VKEY_TAB}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_TAB}}, + {ui::DomCode::F1, + {true, ui::DomKey::F1, 0, ui::VKEY_F1}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_F1}}, + {ui::DomCode::VOLUME_UP, + {true, ui::DomKey::VOLUME_UP, 0, ui::VKEY_VOLUME_UP}, + {true, ui::DomKey::UNIDENTIFIED, 0, ui::VKEY_VOLUME_UP}}, + }; + for (const auto& it : kNonControlCharacters) { + // Verify |DomCodeToControlCharacter()|. + CheckDomCodeToMeaning("n_cc_n", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_NONE, kUndefined); + CheckDomCodeToMeaning("n_cc_c", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_CONTROL_DOWN, kUndefined); + CheckDomCodeToMeaning("n_cc_cs", ui::DomCodeToControlCharacter, it.dom_code, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, kUndefined); + // Verify |DomCodeToUsLayoutMeaning()|. + CheckDomCodeToMeaning("n_us_n", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_NONE, it.normal); + CheckDomCodeToMeaning("n_us_c", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_CONTROL_DOWN, it.control); + CheckDomCodeToMeaning("n_us_cs", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, it.control); + } +} + +TEST(KeyboardCodeConversion, UsLayout) { + static const struct { + ui::DomCode dom_code; + Meaning normal; + Meaning shift; + } kPrintableUsLayout[] = { + {ui::DomCode::KEY_A, + {true, ui::DomKey::CHARACTER, 'a', ui::VKEY_A}, + {true, ui::DomKey::CHARACTER, 'A', ui::VKEY_A}}, + {ui::DomCode::KEY_B, + {true, ui::DomKey::CHARACTER, 'b', ui::VKEY_B}, + {true, ui::DomKey::CHARACTER, 'B', ui::VKEY_B}}, + {ui::DomCode::KEY_C, + {true, ui::DomKey::CHARACTER, 'c', ui::VKEY_C}, + {true, ui::DomKey::CHARACTER, 'C', ui::VKEY_C}}, + {ui::DomCode::KEY_D, + {true, ui::DomKey::CHARACTER, 'd', ui::VKEY_D}, + {true, ui::DomKey::CHARACTER, 'D', ui::VKEY_D}}, + {ui::DomCode::KEY_E, + {true, ui::DomKey::CHARACTER, 'e', ui::VKEY_E}, + {true, ui::DomKey::CHARACTER, 'E', ui::VKEY_E}}, + {ui::DomCode::KEY_F, + {true, ui::DomKey::CHARACTER, 'f', ui::VKEY_F}, + {true, ui::DomKey::CHARACTER, 'F', ui::VKEY_F}}, + {ui::DomCode::KEY_G, + {true, ui::DomKey::CHARACTER, 'g', ui::VKEY_G}, + {true, ui::DomKey::CHARACTER, 'G', ui::VKEY_G}}, + {ui::DomCode::KEY_H, + {true, ui::DomKey::CHARACTER, 'h', ui::VKEY_H}, + {true, ui::DomKey::CHARACTER, 'H', ui::VKEY_H}}, + {ui::DomCode::KEY_I, + {true, ui::DomKey::CHARACTER, 'i', ui::VKEY_I}, + {true, ui::DomKey::CHARACTER, 'I', ui::VKEY_I}}, + {ui::DomCode::KEY_J, + {true, ui::DomKey::CHARACTER, 'j', ui::VKEY_J}, + {true, ui::DomKey::CHARACTER, 'J', ui::VKEY_J}}, + {ui::DomCode::KEY_K, + {true, ui::DomKey::CHARACTER, 'k', ui::VKEY_K}, + {true, ui::DomKey::CHARACTER, 'K', ui::VKEY_K}}, + {ui::DomCode::KEY_L, + {true, ui::DomKey::CHARACTER, 'l', ui::VKEY_L}, + {true, ui::DomKey::CHARACTER, 'L', ui::VKEY_L}}, + {ui::DomCode::KEY_M, + {true, ui::DomKey::CHARACTER, 'm', ui::VKEY_M}, + {true, ui::DomKey::CHARACTER, 'M', ui::VKEY_M}}, + {ui::DomCode::KEY_N, + {true, ui::DomKey::CHARACTER, 'n', ui::VKEY_N}, + {true, ui::DomKey::CHARACTER, 'N', ui::VKEY_N}}, + {ui::DomCode::KEY_O, + {true, ui::DomKey::CHARACTER, 'o', ui::VKEY_O}, + {true, ui::DomKey::CHARACTER, 'O', ui::VKEY_O}}, + {ui::DomCode::KEY_P, + {true, ui::DomKey::CHARACTER, 'p', ui::VKEY_P}, + {true, ui::DomKey::CHARACTER, 'P', ui::VKEY_P}}, + {ui::DomCode::KEY_Q, + {true, ui::DomKey::CHARACTER, 'q', ui::VKEY_Q}, + {true, ui::DomKey::CHARACTER, 'Q', ui::VKEY_Q}}, + {ui::DomCode::KEY_R, + {true, ui::DomKey::CHARACTER, 'r', ui::VKEY_R}, + {true, ui::DomKey::CHARACTER, 'R', ui::VKEY_R}}, + {ui::DomCode::KEY_S, + {true, ui::DomKey::CHARACTER, 's', ui::VKEY_S}, + {true, ui::DomKey::CHARACTER, 'S', ui::VKEY_S}}, + {ui::DomCode::KEY_T, + {true, ui::DomKey::CHARACTER, 't', ui::VKEY_T}, + {true, ui::DomKey::CHARACTER, 'T', ui::VKEY_T}}, + {ui::DomCode::KEY_U, + {true, ui::DomKey::CHARACTER, 'u', ui::VKEY_U}, + {true, ui::DomKey::CHARACTER, 'U', ui::VKEY_U}}, + {ui::DomCode::KEY_V, + {true, ui::DomKey::CHARACTER, 'v', ui::VKEY_V}, + {true, ui::DomKey::CHARACTER, 'V', ui::VKEY_V}}, + {ui::DomCode::KEY_W, + {true, ui::DomKey::CHARACTER, 'w', ui::VKEY_W}, + {true, ui::DomKey::CHARACTER, 'W', ui::VKEY_W}}, + {ui::DomCode::KEY_X, + {true, ui::DomKey::CHARACTER, 'x', ui::VKEY_X}, + {true, ui::DomKey::CHARACTER, 'X', ui::VKEY_X}}, + {ui::DomCode::KEY_Y, + {true, ui::DomKey::CHARACTER, 'y', ui::VKEY_Y}, + {true, ui::DomKey::CHARACTER, 'Y', ui::VKEY_Y}}, + {ui::DomCode::KEY_Z, + {true, ui::DomKey::CHARACTER, 'z', ui::VKEY_Z}, + {true, ui::DomKey::CHARACTER, 'Z', ui::VKEY_Z}}, + {ui::DomCode::DIGIT1, + {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1}, + {true, ui::DomKey::CHARACTER, '!', ui::VKEY_1}}, + {ui::DomCode::DIGIT2, + {true, ui::DomKey::CHARACTER, '2', ui::VKEY_2}, + {true, ui::DomKey::CHARACTER, '@', ui::VKEY_2}}, + {ui::DomCode::DIGIT3, + {true, ui::DomKey::CHARACTER, '3', ui::VKEY_3}, + {true, ui::DomKey::CHARACTER, '#', ui::VKEY_3}}, + {ui::DomCode::DIGIT4, + {true, ui::DomKey::CHARACTER, '4', ui::VKEY_4}, + {true, ui::DomKey::CHARACTER, '$', ui::VKEY_4}}, + {ui::DomCode::DIGIT5, + {true, ui::DomKey::CHARACTER, '5', ui::VKEY_5}, + {true, ui::DomKey::CHARACTER, '%', ui::VKEY_5}}, + {ui::DomCode::DIGIT6, + {true, ui::DomKey::CHARACTER, '6', ui::VKEY_6}, + {true, ui::DomKey::CHARACTER, '^', ui::VKEY_6}}, + {ui::DomCode::DIGIT7, + {true, ui::DomKey::CHARACTER, '7', ui::VKEY_7}, + {true, ui::DomKey::CHARACTER, '&', ui::VKEY_7}}, + {ui::DomCode::DIGIT8, + {true, ui::DomKey::CHARACTER, '8', ui::VKEY_8}, + {true, ui::DomKey::CHARACTER, '*', ui::VKEY_8}}, + {ui::DomCode::DIGIT9, + {true, ui::DomKey::CHARACTER, '9', ui::VKEY_9}, + {true, ui::DomKey::CHARACTER, '(', ui::VKEY_9}}, + {ui::DomCode::DIGIT0, + {true, ui::DomKey::CHARACTER, '0', ui::VKEY_0}, + {true, ui::DomKey::CHARACTER, ')', ui::VKEY_0}}, + {ui::DomCode::SPACE, + {true, ui::DomKey::CHARACTER, ' ', ui::VKEY_SPACE}, + {true, ui::DomKey::CHARACTER, ' ', ui::VKEY_SPACE}}, + {ui::DomCode::MINUS, + {true, ui::DomKey::CHARACTER, '-', ui::VKEY_OEM_MINUS}, + {true, ui::DomKey::CHARACTER, '_', ui::VKEY_OEM_MINUS}}, + {ui::DomCode::EQUAL, + {true, ui::DomKey::CHARACTER, '=', ui::VKEY_OEM_PLUS}, + {true, ui::DomKey::CHARACTER, '+', ui::VKEY_OEM_PLUS}}, + {ui::DomCode::BRACKET_LEFT, + {true, ui::DomKey::CHARACTER, '[', ui::VKEY_OEM_4}, + {true, ui::DomKey::CHARACTER, '{', ui::VKEY_OEM_4}}, + {ui::DomCode::BRACKET_RIGHT, + {true, ui::DomKey::CHARACTER, ']', ui::VKEY_OEM_6}, + {true, ui::DomKey::CHARACTER, '}', ui::VKEY_OEM_6}}, + {ui::DomCode::BACKSLASH, + {true, ui::DomKey::CHARACTER, '\\', ui::VKEY_OEM_5}, + {true, ui::DomKey::CHARACTER, '|', ui::VKEY_OEM_5}}, + {ui::DomCode::SEMICOLON, + {true, ui::DomKey::CHARACTER, ';', ui::VKEY_OEM_1}, + {true, ui::DomKey::CHARACTER, ':', ui::VKEY_OEM_1}}, + {ui::DomCode::QUOTE, + {true, ui::DomKey::CHARACTER, '\'', ui::VKEY_OEM_7}, + {true, ui::DomKey::CHARACTER, '"', ui::VKEY_OEM_7}}, + {ui::DomCode::BACKQUOTE, + {true, ui::DomKey::CHARACTER, '`', ui::VKEY_OEM_3}, + {true, ui::DomKey::CHARACTER, '~', ui::VKEY_OEM_3}}, + {ui::DomCode::COMMA, + {true, ui::DomKey::CHARACTER, ',', ui::VKEY_OEM_COMMA}, + {true, ui::DomKey::CHARACTER, '<', ui::VKEY_OEM_COMMA}}, + {ui::DomCode::PERIOD, + {true, ui::DomKey::CHARACTER, '.', ui::VKEY_OEM_PERIOD}, + {true, ui::DomKey::CHARACTER, '>', ui::VKEY_OEM_PERIOD}}, + {ui::DomCode::SLASH, + {true, ui::DomKey::CHARACTER, '/', ui::VKEY_OEM_2}, + {true, ui::DomKey::CHARACTER, '?', ui::VKEY_OEM_2}}, + {ui::DomCode::INTL_BACKSLASH, + {true, ui::DomKey::CHARACTER, '\\', ui::VKEY_OEM_102}, + {true, ui::DomKey::CHARACTER, '|', ui::VKEY_OEM_102}}, + {ui::DomCode::INTL_YEN, + {true, ui::DomKey::CHARACTER, 0x00A5, ui::VKEY_OEM_5}, + {true, ui::DomKey::CHARACTER, '|', ui::VKEY_OEM_5}}, + {ui::DomCode::NUMPAD_DIVIDE, + {true, ui::DomKey::CHARACTER, '/', ui::VKEY_DIVIDE}, + {true, ui::DomKey::CHARACTER, '/', ui::VKEY_DIVIDE}}, + {ui::DomCode::NUMPAD_MULTIPLY, + {true, ui::DomKey::CHARACTER, '*', ui::VKEY_MULTIPLY}, + {true, ui::DomKey::CHARACTER, '*', ui::VKEY_MULTIPLY}}, + {ui::DomCode::NUMPAD_SUBTRACT, + {true, ui::DomKey::CHARACTER, '-', ui::VKEY_SUBTRACT}, + {true, ui::DomKey::CHARACTER, '-', ui::VKEY_SUBTRACT}}, + {ui::DomCode::NUMPAD_ADD, + {true, ui::DomKey::CHARACTER, '+', ui::VKEY_ADD}, + {true, ui::DomKey::CHARACTER, '+', ui::VKEY_ADD}}, + {ui::DomCode::NUMPAD1, + {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1}, + {true, ui::DomKey::CHARACTER, '1', ui::VKEY_1}}, + {ui::DomCode::NUMPAD2, + {true, ui::DomKey::CHARACTER, '2', ui::VKEY_2}, + {true, ui::DomKey::CHARACTER, '2', ui::VKEY_2}}, + {ui::DomCode::NUMPAD3, + {true, ui::DomKey::CHARACTER, '3', ui::VKEY_3}, + {true, ui::DomKey::CHARACTER, '3', ui::VKEY_3}}, + {ui::DomCode::NUMPAD4, + {true, ui::DomKey::CHARACTER, '4', ui::VKEY_4}, + {true, ui::DomKey::CHARACTER, '4', ui::VKEY_4}}, + {ui::DomCode::NUMPAD5, + {true, ui::DomKey::CHARACTER, '5', ui::VKEY_5}, + {true, ui::DomKey::CHARACTER, '5', ui::VKEY_5}}, + {ui::DomCode::NUMPAD6, + {true, ui::DomKey::CHARACTER, '6', ui::VKEY_6}, + {true, ui::DomKey::CHARACTER, '6', ui::VKEY_6}}, + {ui::DomCode::NUMPAD7, + {true, ui::DomKey::CHARACTER, '7', ui::VKEY_7}, + {true, ui::DomKey::CHARACTER, '7', ui::VKEY_7}}, + {ui::DomCode::NUMPAD8, + {true, ui::DomKey::CHARACTER, '8', ui::VKEY_8}, + {true, ui::DomKey::CHARACTER, '8', ui::VKEY_8}}, + {ui::DomCode::NUMPAD9, + {true, ui::DomKey::CHARACTER, '9', ui::VKEY_9}, + {true, ui::DomKey::CHARACTER, '9', ui::VKEY_9}}, + {ui::DomCode::NUMPAD0, + {true, ui::DomKey::CHARACTER, '0', ui::VKEY_0}, + {true, ui::DomKey::CHARACTER, '0', ui::VKEY_0}}, + {ui::DomCode::NUMPAD_DECIMAL, + {true, ui::DomKey::CHARACTER, '.', ui::VKEY_DECIMAL}, + {true, ui::DomKey::CHARACTER, '.', ui::VKEY_DECIMAL}}, + {ui::DomCode::NUMPAD_EQUAL, + {true, ui::DomKey::CHARACTER, '=', ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, '=', ui::VKEY_UNKNOWN}}, + {ui::DomCode::NUMPAD_COMMA, + {true, ui::DomKey::CHARACTER, ',', ui::VKEY_OEM_COMMA}, + {true, ui::DomKey::CHARACTER, ',', ui::VKEY_OEM_COMMA}}, + {ui::DomCode::NUMPAD_PAREN_LEFT, + {true, ui::DomKey::CHARACTER, '(', ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, '(', ui::VKEY_UNKNOWN}}, + {ui::DomCode::NUMPAD_PAREN_RIGHT, + {true, ui::DomKey::CHARACTER, ')', ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, ')', ui::VKEY_UNKNOWN}}, + {ui::DomCode::NUMPAD_SIGN_CHANGE, + {true, ui::DomKey::CHARACTER, 0xB1, ui::VKEY_UNKNOWN}, + {true, ui::DomKey::CHARACTER, 0xB1, ui::VKEY_UNKNOWN}}, + }; + + for (const auto& it : kPrintableUsLayout) { + CheckDomCodeToMeaning("p_us_n", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_NONE, it.normal); + CheckDomCodeToMeaning("p_us_s", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_SHIFT_DOWN, it.shift); + CheckDomCodeToMeaning("p_us_a", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_ALTGR_DOWN, it.normal); + CheckDomCodeToMeaning("p_us_a", ui::DomCodeToUsLayoutMeaning, it.dom_code, + ui::EF_ALTGR_DOWN|ui::EF_SHIFT_DOWN, it.shift); + } +} + +} // namespace diff --git a/ui/events/ozone/layout/layout_util.cc b/ui/events/ozone/layout/layout_util.cc index b36bf57..e19c22d 100644 --- a/ui/events/ozone/layout/layout_util.cc +++ b/ui/events/ozone/layout/layout_util.cc @@ -4,542 +4,11 @@ #include "ui/events/ozone/layout/layout_util.h" -#include <algorithm> - #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/keyboard_code_conversion.h" namespace ui { -namespace { - -// This table, used by DomKeyToKeyboardCode(), maps DOM Level 3 .code -// values to legacy Windows-based VKEY values, where the VKEYs are -// interpreted positionally. -const struct DomCodeToKeyboardCodeEntry { - DomCode dom_code; - KeyboardCode key_code; -} dom_code_to_keyboard_code[] = { - // Entries are ordered by numeric value of the DomCode enum, - // which is the USB physical key code. - // DomCode::HYPER 0x000010 Hyper - // DomCode::SUPER 0x000011 Super - // DomCode::FN 0x000012 Fn - // DomCode::FN_LOCK 0x000013 FLock - // DomCode::SUSPEND 0x000014 Suspend - // DomCode::RESUME 0x000015 Resume - // DomCode::TURBO 0x000016 Turbo - {DomCode::SLEEP, VKEY_SLEEP}, // 0x010082 Sleep - // DomCode::WAKE_UP 0x010083 WakeUp - {DomCode::KEY_A, VKEY_A}, // 0x070004 KeyA - {DomCode::KEY_B, VKEY_B}, // 0x070005 KeyB - {DomCode::KEY_C, VKEY_C}, // 0x070006 KeyC - {DomCode::KEY_D, VKEY_D}, // 0x070007 KeyD - {DomCode::KEY_E, VKEY_E}, // 0x070008 KeyE - {DomCode::KEY_F, VKEY_F}, // 0x070009 KeyF - {DomCode::KEY_G, VKEY_G}, // 0x07000A KeyG - {DomCode::KEY_H, VKEY_H}, // 0x07000B KeyH - {DomCode::KEY_I, VKEY_I}, // 0x07000C KeyI - {DomCode::KEY_J, VKEY_J}, // 0x07000D KeyJ - {DomCode::KEY_K, VKEY_K}, // 0x07000E KeyK - {DomCode::KEY_L, VKEY_L}, // 0x07000F KeyL - {DomCode::KEY_M, VKEY_M}, // 0x070010 KeyM - {DomCode::KEY_N, VKEY_N}, // 0x070011 KeyN - {DomCode::KEY_O, VKEY_O}, // 0x070012 KeyO - {DomCode::KEY_P, VKEY_P}, // 0x070013 KeyP - {DomCode::KEY_Q, VKEY_Q}, // 0x070014 KeyQ - {DomCode::KEY_R, VKEY_R}, // 0x070015 KeyR - {DomCode::KEY_S, VKEY_S}, // 0x070016 KeyS - {DomCode::KEY_T, VKEY_T}, // 0x070017 KeyT - {DomCode::KEY_U, VKEY_U}, // 0x070018 KeyU - {DomCode::KEY_V, VKEY_V}, // 0x070019 KeyV - {DomCode::KEY_W, VKEY_W}, // 0x07001A KeyW - {DomCode::KEY_X, VKEY_X}, // 0x07001B KeyX - {DomCode::KEY_Y, VKEY_Y}, // 0x07001C KeyY - {DomCode::KEY_Z, VKEY_Z}, // 0x07001D KeyZ - {DomCode::DIGIT1, VKEY_1}, // 0x07001E Digit1 - {DomCode::DIGIT2, VKEY_2}, // 0x07001F Digit2 - {DomCode::DIGIT3, VKEY_3}, // 0x070020 Digit3 - {DomCode::DIGIT4, VKEY_4}, // 0x070021 Digit4 - {DomCode::DIGIT5, VKEY_5}, // 0x070022 Digit5 - {DomCode::DIGIT6, VKEY_6}, // 0x070023 Digit6 - {DomCode::DIGIT7, VKEY_7}, // 0x070024 Digit7 - {DomCode::DIGIT8, VKEY_8}, // 0x070025 Digit8 - {DomCode::DIGIT9, VKEY_9}, // 0x070026 Digit9 - {DomCode::DIGIT0, VKEY_0}, // 0x070027 Digit0 - {DomCode::ENTER, VKEY_RETURN}, // 0x070028 Enter - {DomCode::ESCAPE, VKEY_ESCAPE}, // 0x070029 Escape - {DomCode::BACKSPACE, VKEY_BACK}, // 0x07002A Backspace - {DomCode::TAB, VKEY_TAB}, // 0x07002B Tab - {DomCode::SPACE, VKEY_SPACE}, // 0x07002C Space - {DomCode::MINUS, VKEY_OEM_MINUS}, // 0x07002D Minus - {DomCode::EQUAL, VKEY_OEM_PLUS}, // 0x07002E Equal - {DomCode::BRACKET_LEFT, VKEY_OEM_4}, // 0x07002F BracketLeft - {DomCode::BRACKET_RIGHT, VKEY_OEM_6}, // 0x070030 BracketRight - {DomCode::BACKSLASH, VKEY_OEM_5}, // 0x070031 Backslash - // DomCode::INTL_HASH, VKEY_OEM_5 // 0x070032 IntlHash - {DomCode::SEMICOLON, VKEY_OEM_1}, // 0x070033 Semicolon - {DomCode::QUOTE, VKEY_OEM_7}, // 0x070034 Quote - {DomCode::BACKQUOTE, VKEY_OEM_3}, // 0x070035 Backquote - {DomCode::COMMA, VKEY_OEM_COMMA}, // 0x070036 Comma - {DomCode::PERIOD, VKEY_OEM_PERIOD}, // 0x070037 Period - {DomCode::SLASH, VKEY_OEM_2}, // 0x070038 Slash - {DomCode::CAPS_LOCK, VKEY_CAPITAL}, // 0x070039 CapsLock - {DomCode::F1, VKEY_F1}, // 0x07003A F1 - {DomCode::F2, VKEY_F2}, // 0x07003B F2 - {DomCode::F3, VKEY_F3}, // 0x07003C F3 - {DomCode::F4, VKEY_F4}, // 0x07003D F4 - {DomCode::F5, VKEY_F5}, // 0x07003E F5 - {DomCode::F6, VKEY_F6}, // 0x07003F F6 - {DomCode::F7, VKEY_F7}, // 0x070040 F7 - {DomCode::F8, VKEY_F8}, // 0x070041 F8 - {DomCode::F9, VKEY_F9}, // 0x070042 F9 - {DomCode::F10, VKEY_F10}, // 0x070043 F10 - {DomCode::F11, VKEY_F11}, // 0x070044 F11 - {DomCode::F12, VKEY_F12}, // 0x070045 F12 - {DomCode::PRINT_SCREEN, VKEY_SNAPSHOT}, // 0x070046 PrintScreen - {DomCode::SCROLL_LOCK, VKEY_SCROLL}, // 0x070047 ScrollLock - {DomCode::PAUSE, VKEY_PAUSE}, // 0x070048 Pause - {DomCode::INSERT, VKEY_INSERT}, // 0x070049 Insert - {DomCode::HOME, VKEY_HOME}, // 0x07004A Home - {DomCode::PAGE_UP, VKEY_PRIOR}, // 0x07004B PageUp - {DomCode::DEL, VKEY_DELETE}, // 0x07004C Delete - {DomCode::END, VKEY_END}, // 0x07004D End - {DomCode::PAGE_DOWN, VKEY_NEXT}, // 0x07004E PageDown - {DomCode::ARROW_RIGHT, VKEY_RIGHT}, // 0x07004F ArrowRight - {DomCode::ARROW_LEFT, VKEY_LEFT}, // 0x070050 ArrowLeft - {DomCode::ARROW_DOWN, VKEY_DOWN}, // 0x070051 ArrowDown - {DomCode::ARROW_UP, VKEY_UP}, // 0x070052 ArrowUp - {DomCode::NUM_LOCK, VKEY_NUMLOCK}, // 0x070053 NumLock - {DomCode::NUMPAD_DIVIDE, VKEY_DIVIDE}, // 0x070054 NumpadDivide - {DomCode::NUMPAD_MULTIPLY, VKEY_MULTIPLY}, // 0x070055 NumpadMultiply - {DomCode::NUMPAD_SUBTRACT, VKEY_SUBTRACT}, // 0x070056 NumpadSubtract - {DomCode::NUMPAD_ADD, VKEY_ADD}, // 0x070057 NumpadAdd - {DomCode::NUMPAD_ENTER, VKEY_RETURN}, // 0x070058 NumpadEnter - {DomCode::NUMPAD1, VKEY_NUMPAD1}, // 0x070059 Numpad1 - {DomCode::NUMPAD2, VKEY_NUMPAD2}, // 0x07005A Numpad2 - {DomCode::NUMPAD3, VKEY_NUMPAD3}, // 0x07005B Numpad3 - {DomCode::NUMPAD4, VKEY_NUMPAD4}, // 0x07005C Numpad4 - {DomCode::NUMPAD5, VKEY_NUMPAD5}, // 0x07005D Numpad5 - {DomCode::NUMPAD6, VKEY_NUMPAD6}, // 0x07005E Numpad6 - {DomCode::NUMPAD7, VKEY_NUMPAD7}, // 0x07005F Numpad7 - {DomCode::NUMPAD8, VKEY_NUMPAD8}, // 0x070060 Numpad8 - {DomCode::NUMPAD9, VKEY_NUMPAD9}, // 0x070061 Numpad9 - {DomCode::NUMPAD0, VKEY_NUMPAD0}, // 0x070062 Numpad0 - {DomCode::NUMPAD_DECIMAL, VKEY_DECIMAL}, // 0x070063 NumpadDecimal - {DomCode::INTL_BACKSLASH, VKEY_OEM_102}, // 0x070064 IntlBackslash - {DomCode::CONTEXT_MENU, VKEY_APPS}, // 0x070065 ContextMenu - {DomCode::POWER, VKEY_POWER}, // 0x070066 Power - // DomCode::NUMPAD_EQUAL 0x070067 NumpadEqual - // DomCode::OPEN 0x070074 Open - {DomCode::HELP, VKEY_HELP}, // 0x070075 Help - {DomCode::SELECT, VKEY_SELECT}, // 0x070077 Select - // DomCode::AGAIN 0x070079 Again - // DomCode::UNDO 0x07007A Undo - // DomCode::CUT 0x07007B Cut - // DomCode::COPY 0x07007C Copy - // DomCode::PASTE 0x07007D Paste - // DomCode::FIND 0x07007E Find - {DomCode::VOLUME_MUTE, VKEY_VOLUME_MUTE}, // 0x07007F VolumeMute - {DomCode::VOLUME_UP, VKEY_VOLUME_UP}, // 0x070080 VolumeUp - {DomCode::VOLUME_DOWN, VKEY_VOLUME_DOWN}, // 0x070081 VolumeDown - {DomCode::NUMPAD_COMMA, VKEY_OEM_COMMA}, // 0x070085 NumpadComma - {DomCode::INTL_RO, VKEY_OEM_102}, // 0x070087 IntlRo - {DomCode::KANA_MODE, VKEY_KANA}, // 0x070088 KanaMode - {DomCode::INTL_YEN, VKEY_OEM_5}, // 0x070089 IntlYen - {DomCode::CONVERT, VKEY_CONVERT}, // 0x07008A Convert - {DomCode::NON_CONVERT, VKEY_NONCONVERT}, // 0x07008B NonConvert - {DomCode::LANG1, VKEY_KANA}, // 0x070090 Lang1 - {DomCode::LANG2, VKEY_KANJI}, // 0x070091 Lang2 - // DomCode::LANG3 0x070092 Lang3 - // DomCode::LANG4 0x070093 Lang4 - // DomCode::LANG5 0x070094 Lang5 - // DomCode::ABORT 0x07009B Abort - // DomCode::PROPS 0x0700A3 Props - // DomCode::NUMPAD_PAREN_LEFT 0x0700B6 NumpadParenLeft - // DomCode::NUMPAD_PAREN_RIGHT 0x0700B7 NumpadParenRight - {DomCode::NUMPAD_BACKSPACE, VKEY_BACK}, // 0x0700BB NumpadBackspace - // DomCode::NUMPAD_MEMORY_STORE 0x0700D0 NumpadMemoryStore - // DomCode::NUMPAD_MEMORY_RECALL 0x0700D1 NumpadMemoryRecall - // DomCode::NUMPAD_MEMORY_CLEAR 0x0700D2 NumpadMemoryClear - // DomCode::NUMPAD_MEMORY_ADD 0x0700D3 NumpadMemoryAdd - // DomCode::NUMPAD_MEMORY_SUBTRACT 0x0700D4 - // NumpadMemorySubtract - {DomCode::NUMPAD_CLEAR, VKEY_CLEAR}, // 0x0700D8 NumpadClear - {DomCode::NUMPAD_CLEAR_ENTRY, VKEY_CLEAR}, // 0x0700D9 NumpadClearEntry - {DomCode::CONTROL_LEFT, VKEY_LCONTROL}, // 0x0700E0 ControlLeft - {DomCode::SHIFT_LEFT, VKEY_LSHIFT}, // 0x0700E1 ShiftLeft - {DomCode::ALT_LEFT, VKEY_LMENU}, // 0x0700E2 AltLeft - {DomCode::OS_LEFT, VKEY_LWIN}, // 0x0700E3 OSLeft - {DomCode::CONTROL_RIGHT, VKEY_RCONTROL}, // 0x0700E4 ControlRight - {DomCode::SHIFT_RIGHT, VKEY_RSHIFT}, // 0x0700E5 ShiftRight - {DomCode::ALT_RIGHT, VKEY_RMENU}, // 0x0700E6 AltRight - {DomCode::OS_RIGHT, VKEY_RWIN}, // 0x0700E7 OSRight - {DomCode::MEDIA_TRACK_NEXT, - VKEY_MEDIA_NEXT_TRACK}, // 0x0C00B5 MediaTrackNext - {DomCode::MEDIA_TRACK_PREVIOUS, - VKEY_MEDIA_PREV_TRACK}, // 0x0C00B6 MediaTrackPrevious - {DomCode::MEDIA_STOP, VKEY_MEDIA_STOP}, // 0x0C00B7 MediaStop - // DomCode::EJECT 0x0C00B8 Eject - {DomCode::MEDIA_PLAY_PAUSE, - VKEY_MEDIA_PLAY_PAUSE}, // 0x0C00CD MediaPlayPause - {DomCode::MEDIA_SELECT, - VKEY_MEDIA_LAUNCH_MEDIA_SELECT}, // 0x0C0183 MediaSelect - {DomCode::LAUNCH_MAIL, VKEY_MEDIA_LAUNCH_MAIL}, // 0x0C018A LaunchMail - {DomCode::LAUNCH_APP2, VKEY_MEDIA_LAUNCH_APP2}, // 0x0C0192 LaunchApp2 - {DomCode::LAUNCH_APP1, VKEY_MEDIA_LAUNCH_APP1}, // 0x0C0194 LaunchApp1 - {DomCode::BROWSER_SEARCH, VKEY_BROWSER_SEARCH}, // 0x0C0221 BrowserSearch - {DomCode::BROWSER_HOME, VKEY_BROWSER_HOME}, // 0x0C0223 BrowserHome - {DomCode::BROWSER_BACK, VKEY_BROWSER_BACK}, // 0x0C0224 BrowserBack - {DomCode::BROWSER_FORWARD, - VKEY_BROWSER_FORWARD}, // 0x0C0225 BrowserForward - {DomCode::BROWSER_STOP, VKEY_BROWSER_STOP}, // 0x0C0226 BrowserStop - {DomCode::BROWSER_REFRESH, - VKEY_BROWSER_REFRESH}, // 0x0C0227 BrowserRefresh - {DomCode::BROWSER_FAVORITES, - VKEY_BROWSER_FAVORITES}, // 0x0C022A BrowserFavorites -}; - -} // anonymous namespace - -// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. -// The returned VKEY is non-positional (e.g. VKEY_SHIFT). -KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) { - switch (dom_key) { - // No value. - case DomKey::NONE: - return VKEY_UNKNOWN; - // Character values. - // Special Key Values - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-special - case DomKey::UNIDENTIFIED: - return VKEY_UNKNOWN; - // Modifier Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-modifier - case DomKey::ALT: - return VKEY_MENU; - case DomKey::ALT_GRAPH: - return VKEY_ALTGR; - case DomKey::CAPS_LOCK: - return VKEY_CAPITAL; - case DomKey::CONTROL: - return VKEY_CONTROL; - case DomKey::NUM_LOCK: - return VKEY_NUMLOCK; - case DomKey::OS: - return VKEY_LWIN; - case DomKey::SCROLL_LOCK: - return VKEY_SCROLL; - case DomKey::SHIFT: - return VKEY_SHIFT; - // Whitespace Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-whitespace - case DomKey::ENTER: - return VKEY_RETURN; - case DomKey::SEPARATOR: - return VKEY_SEPARATOR; - case DomKey::TAB: - return VKEY_TAB; - // Navigation Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-navigation - case DomKey::ARROW_DOWN: - return VKEY_DOWN; - case DomKey::ARROW_LEFT: - return VKEY_LEFT; - case DomKey::ARROW_RIGHT: - return VKEY_RIGHT; - case DomKey::ARROW_UP: - return VKEY_UP; - case DomKey::END: - return VKEY_END; - case DomKey::HOME: - return VKEY_HOME; - case DomKey::PAGE_DOWN: - return VKEY_NEXT; - case DomKey::PAGE_UP: - return VKEY_PRIOR; - // Editing Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-editing - case DomKey::BACKSPACE: - return VKEY_BACK; - case DomKey::CLEAR: - return VKEY_CLEAR; - case DomKey::CR_SEL: - return VKEY_CRSEL; - case DomKey::DEL: - return VKEY_DELETE; - case DomKey::ERASE_EOF: - return VKEY_EREOF; - case DomKey::EX_SEL: - return VKEY_EXSEL; - case DomKey::INSERT: - return VKEY_INSERT; - // UI Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-ui - case DomKey::ACCEPT: - return VKEY_ACCEPT; - case DomKey::ATTN: - return VKEY_ATTN; - case DomKey::CONTEXT_MENU: - return VKEY_APPS; - case DomKey::ESCAPE: - return VKEY_ESCAPE; - case DomKey::EXECUTE: - return VKEY_EXECUTE; - case DomKey::HELP: - return VKEY_HELP; - case DomKey::PAUSE: - return VKEY_PAUSE; - case DomKey::PLAY: - return VKEY_PLAY; - case DomKey::SELECT: - return VKEY_SELECT; - // Device Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-device - case DomKey::BRIGHTNESS_DOWN: - return VKEY_BRIGHTNESS_DOWN; - case DomKey::BRIGHTNESS_UP: - return VKEY_BRIGHTNESS_UP; - case DomKey::POWER: - return VKEY_POWER; - case DomKey::PRINT_SCREEN: - return VKEY_SNAPSHOT; -// IME and Composition Keys -// http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-composition -#if 0 // TODO(kpschoedel) - case DomKey::COMPOSE: - return VKEY_COMPOSE; -#endif - case DomKey::CONVERT: - return VKEY_CONVERT; - case DomKey::FINAL_MODE: - return VKEY_FINAL; - case DomKey::MODE_CHANGE: - return VKEY_MODECHANGE; - case DomKey::NON_CONVERT: - return VKEY_NONCONVERT; - case DomKey::PROCESS: - return VKEY_PROCESSKEY; - // Keys specific to Korean keyboards - case DomKey::HANGUL_MODE: - return VKEY_HANGUL; - case DomKey::HANJA_MODE: - return VKEY_HANJA; - case DomKey::JUNJA_MODE: - return VKEY_JUNJA; - // Keys specific to Japanese keyboards - case DomKey::HANKAKU: - return VKEY_DBE_SBCSCHAR; - case DomKey::KANA_MODE: - return VKEY_KANA; - case DomKey::KANJI_MODE: - return VKEY_KANJI; - case DomKey::ZENKAKU: - return VKEY_DBE_DBCSCHAR; - case DomKey::ZENKAKU_HANKAKU: - return VKEY_DBE_DBCSCHAR; - // General-Purpose Function Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-function - case DomKey::F1: - return VKEY_F1; - case DomKey::F2: - return VKEY_F2; - case DomKey::F3: - return VKEY_F3; - case DomKey::F4: - return VKEY_F4; - case DomKey::F5: - return VKEY_F5; - case DomKey::F6: - return VKEY_F6; - case DomKey::F7: - return VKEY_F7; - case DomKey::F8: - return VKEY_F8; - case DomKey::F9: - return VKEY_F9; - case DomKey::F10: - return VKEY_F10; - case DomKey::F11: - return VKEY_F11; - case DomKey::F12: - return VKEY_F12; - case DomKey::F13: - return VKEY_F13; - case DomKey::F14: - return VKEY_F14; - case DomKey::F15: - return VKEY_F15; - case DomKey::F16: - return VKEY_F16; - case DomKey::F17: - return VKEY_F17; - case DomKey::F18: - return VKEY_F18; - case DomKey::F19: - return VKEY_F19; - case DomKey::F20: - return VKEY_F20; - case DomKey::F21: - return VKEY_F21; - case DomKey::F22: - return VKEY_F22; - case DomKey::F23: - return VKEY_F23; - case DomKey::F24: - return VKEY_F24; - // Multimedia Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-multimedia - case DomKey::MEDIA_PLAY_PAUSE: - return VKEY_MEDIA_PLAY_PAUSE; - case DomKey::MEDIA_SELECT: - return VKEY_MEDIA_LAUNCH_MEDIA_SELECT; - case DomKey::MEDIA_STOP: - return VKEY_MEDIA_STOP; - case DomKey::MEDIA_TRACK_NEXT: - return VKEY_MEDIA_NEXT_TRACK; - case DomKey::MEDIA_TRACK_PREVIOUS: - return VKEY_MEDIA_PREV_TRACK; - case DomKey::PRINT: - return VKEY_PRINT; - case DomKey::VOLUME_DOWN: - return VKEY_VOLUME_DOWN; - case DomKey::VOLUME_MUTE: - return VKEY_VOLUME_MUTE; - case DomKey::VOLUME_UP: - return VKEY_VOLUME_UP; - // Application Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-apps - case DomKey::LAUNCH_CALCULATOR: - return VKEY_MEDIA_LAUNCH_APP2; - case DomKey::LAUNCH_MAIL: - return VKEY_MEDIA_LAUNCH_MAIL; - case DomKey::LAUNCH_MY_COMPUTER: - return VKEY_MEDIA_LAUNCH_APP1; - // Browser Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-browser - case DomKey::BROWSER_BACK: - return VKEY_BROWSER_BACK; - case DomKey::BROWSER_FAVORITES: - return VKEY_BROWSER_FAVORITES; - case DomKey::BROWSER_FORWARD: - return VKEY_BROWSER_FORWARD; - case DomKey::BROWSER_HOME: - return VKEY_BROWSER_HOME; - case DomKey::BROWSER_REFRESH: - return VKEY_BROWSER_REFRESH; - case DomKey::BROWSER_SEARCH: - return VKEY_BROWSER_SEARCH; - case DomKey::BROWSER_STOP: - return VKEY_BROWSER_STOP; - // Media Controller Keys - // http://www.w3.org/TR/DOM-Level-3-Events-key/#keys-media-controller - case DomKey::ZOOM_TOGGLE: - return VKEY_ZOOM; - // No value. - default: - return VKEY_UNKNOWN; - } -} - -// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|. -// The returned VKEY is located (e.g. VKEY_LSHIFT). -KeyboardCode DomCodeToKeyboardCode(DomCode dom_code) { - const DomCodeToKeyboardCodeEntry* end = - dom_code_to_keyboard_code + arraysize(dom_code_to_keyboard_code); - const DomCodeToKeyboardCodeEntry* found = - std::lower_bound(dom_code_to_keyboard_code, end, dom_code, - [](const DomCodeToKeyboardCodeEntry& a, DomCode b) { - return static_cast<int>(a.dom_code) < static_cast<int>(b); - }); - if ((found != end) && (found->dom_code == dom_code)) - return found->key_code; - return VKEY_UNKNOWN; -} - -// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|. -// The returned VKEY is non-located (e.g. VKEY_SHIFT). -KeyboardCode DomCodeToNonLocatedKeyboardCode(DomCode dom_code) { - return LocatedToNonLocatedKeyboardCode(DomCodeToKeyboardCode(dom_code)); -} - -bool LookupControlCharacter(DomCode dom_code, - int flags, - DomKey* dom_key, - base::char16* character, - KeyboardCode* key_code) { - if ((flags & EF_CONTROL_DOWN) == 0) - return false; - - int code = static_cast<int>(dom_code); - const int kKeyA = static_cast<int>(DomCode::KEY_A); - // Control-A - Control-Z map to 0x01 - 0x1A. - if (code >= kKeyA && code <= static_cast<int>(DomCode::KEY_Z)) { - *character = static_cast<base::char16>(code - kKeyA + 1); - *key_code = static_cast<KeyboardCode>(code - kKeyA + VKEY_A); - switch (dom_code) { - case DomCode::KEY_H: - *dom_key = DomKey::BACKSPACE; - case DomCode::KEY_I: - *dom_key = DomKey::TAB; - case DomCode::KEY_M: - *dom_key = DomKey::ENTER; - default: - *dom_key = DomKey::CHARACTER; - } - return true; - } - - switch (dom_code) { - case DomCode::DIGIT2: - // NUL - *character = 0; - *dom_key = DomKey::CHARACTER; - *key_code = VKEY_2; - return true; - case DomCode::ENTER: - // NL - *character = 0x0A; - *dom_key = DomKey::CHARACTER; - *key_code = VKEY_RETURN; - return true; - case DomCode::BRACKET_LEFT: - // ESC - *character = 0x1B; - *dom_key = DomKey::ESCAPE; - *key_code = VKEY_OEM_4; - return true; - case DomCode::BACKSLASH: - // FS - *character = 0x1C; - *dom_key = DomKey::CHARACTER; - *key_code = VKEY_OEM_5; - return true; - case DomCode::BRACKET_RIGHT: - // GS - *character = 0x1D; - *dom_key = DomKey::CHARACTER; - *key_code = VKEY_OEM_6; - return true; - case DomCode::DIGIT6: - // RS - *character = 0x1E; - *dom_key = DomKey::CHARACTER; - *key_code = VKEY_6; - return true; - case DomCode::MINUS: - // US - *character = 0x1F; - *dom_key = DomKey::CHARACTER; - *key_code = VKEY_OEM_MINUS; - return true; - default: - return false; - } -} - int ModifierDomKeyToEventFlag(DomKey key) { switch (key) { case DomKey::ALT: diff --git a/ui/events/ozone/layout/layout_util.h b/ui/events/ozone/layout/layout_util.h index 7eb8f77..84d9d1d 100644 --- a/ui/events/ozone/layout/layout_util.h +++ b/ui/events/ozone/layout/layout_util.h @@ -13,31 +13,8 @@ namespace ui { -enum class DomCode; enum class DomKey; -// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. -// The returned VKEY is non-located (e.g. VKEY_SHIFT). -EVENTS_OZONE_LAYOUT_EXPORT KeyboardCode -NonPrintableDomKeyToKeyboardCode(DomKey dom_key); - -// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|. -// The returned VKEY is located (e.g. VKEY_LSHIFT). -EVENTS_OZONE_LAYOUT_EXPORT KeyboardCode DomCodeToKeyboardCode(DomCode dom_code); - -// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|. -// The returned VKEY is non-located (e.g. VKEY_SHIFT). -EVENTS_OZONE_LAYOUT_EXPORT KeyboardCode -DomCodeToNonLocatedKeyboardCode(DomCode dom_code); - -// Returns true control character corresponding to a physical key. -// In some contexts this is used instead of the key layout. -EVENTS_OZONE_LAYOUT_EXPORT bool LookupControlCharacter(DomCode dom_code, - int flags, - DomKey* dom_key, - base::char16* character, - KeyboardCode* key_code); - // Returns the ui::EventFlags value associated with a modifier key, // or 0 (EF_NONE) if the key is not a modifier. EVENTS_OZONE_LAYOUT_EXPORT int ModifierDomKeyToEventFlag(DomKey key); diff --git a/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc b/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc index 4279901..9a522df 100644 --- a/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc +++ b/ui/events/ozone/layout/stub/stub_keyboard_layout_engine.cc @@ -15,221 +15,6 @@ namespace ui { -namespace { - -// All of the characters have low ordinals, so we use bit 15 to flag dead keys. -#define DK 0x8000 - -const struct PrintableCodeEntry { - DomCode dom_code; - base::char16 character[4]; -} printable_code_map[] = { - // Stub table based on X US international. - {DomCode::KEY_A, {'a', 'A', 0x00E1, 0x00C1}}, - {DomCode::KEY_B, {'b', 'B', 'b', 'B'}}, - {DomCode::KEY_C, {'c', 'C', 0x00A9, 0x00A2}}, - {DomCode::KEY_D, {'d', 'D', 0x00F0, 0x00D0}}, - {DomCode::KEY_E, {'e', 'E', 0x00E9, 0x00C9}}, - {DomCode::KEY_F, {'f', 'F', 'f', 'F'}}, - {DomCode::KEY_G, {'g', 'G', 'g', 'G'}}, - {DomCode::KEY_H, {'h', 'H', 'h', 'H'}}, - {DomCode::KEY_I, {'i', 'I', 0x00ED, 0x00CD}}, - {DomCode::KEY_J, {'j', 'J', 'j', 'J'}}, - {DomCode::KEY_K, {'k', 'K', 0x0153, 0x0152}}, - {DomCode::KEY_L, {'l', 'L', 0x00F8, 0x00D8}}, - {DomCode::KEY_M, {'m', 'M', 0x00B5, 0x00B5}}, - {DomCode::KEY_N, {'n', 'N', 0x00F1, 0x00D1}}, - {DomCode::KEY_O, {'o', 'O', 0x00F3, 0x00D3}}, - {DomCode::KEY_P, {'p', 'P', 0x00F6, 0x00D6}}, - {DomCode::KEY_Q, {'q', 'Q', 0x00E4, 0x00C4}}, - {DomCode::KEY_R, {'r', 'R', 0x00AE, 0x00AE}}, - {DomCode::KEY_S, {'s', 'S', 0x00DF, 0x00A7}}, - {DomCode::KEY_T, {'t', 'T', 0x00FE, 0x00DE}}, - {DomCode::KEY_U, {'u', 'U', 0x00FA, 0x00DA}}, - {DomCode::KEY_V, {'v', 'V', 'v', 'V'}}, - {DomCode::KEY_W, {'w', 'W', 0x00E5, 0x00C5}}, - {DomCode::KEY_X, {'x', 'X', 'x', 'X'}}, - {DomCode::KEY_Y, {'y', 'Y', 0x00FC, 0x00DC}}, - {DomCode::KEY_Z, {'z', 'Z', 0x00E6, 0x00C6}}, - {DomCode::DIGIT1, {'1', '!', 0x00A1, 0x00B9}}, - {DomCode::DIGIT2, {'2', '@', 0x00B2, DK|0x030B}}, - {DomCode::DIGIT3, {'3', '#', 0x00B3, DK|0x0304}}, - {DomCode::DIGIT4, {'4', '$', 0x00A4, 0x00A3}}, - {DomCode::DIGIT5, {'5', '%', 0x20AC, DK|0x0327}}, - {DomCode::DIGIT6, {'6', '^', DK|0x0302, 0x00BC}}, - {DomCode::DIGIT7, {'7', '&', 0x00BD, DK|0x031B}}, - {DomCode::DIGIT8, {'8', '*', 0x00BE, DK|0x0328}}, - {DomCode::DIGIT9, {'9', '(', 0x2018, DK|0x0306}}, - {DomCode::DIGIT0, {'0', ')', 0x2019, DK|0x030A}}, - {DomCode::SPACE, {' ', ' ', 0x00A0, 0x00A0}}, - {DomCode::MINUS, {'-', '_', 0x00A5, DK|0x0323}}, - {DomCode::EQUAL, {'=', '+', 0x00D7, 0x00F7}}, - {DomCode::BRACKET_LEFT, {'[', '{', 0x00AB, 0x201C}}, - {DomCode::BRACKET_RIGHT, {']', '}', 0x00BB, 0x201D}}, - {DomCode::BACKSLASH, {'\\', '|', 0x00AC, 0x00A6}}, - {DomCode::SEMICOLON, {';', ':', 0x00B6, 0x00B0}}, - {DomCode::QUOTE, {'\'', '"', DK|0x0301, DK|0x0308}}, - {DomCode::BACKQUOTE, {'`', '~', DK|0x0300, DK|0x0303}}, - {DomCode::COMMA, {',', '<', 0x00E7, 0x00C7}}, - {DomCode::PERIOD, {'.', '>', DK|0x0307, DK|0x030C}}, - {DomCode::SLASH, {'/', '?', 0x00BF, DK|0x0309}}, - {DomCode::INTL_BACKSLASH, {'\\', '|', '\\', '|'}}, - {DomCode::INTL_YEN, {0x00A5, '|', 0x00A5, '|'}}, - {DomCode::NUMPAD_DIVIDE, {'/', '/', '/', '/'}}, - {DomCode::NUMPAD_MULTIPLY, {'*', '*', '*', '*'}}, - {DomCode::NUMPAD_SUBTRACT, {'-', '-', '-', '-'}}, - {DomCode::NUMPAD_ADD, {'+', '+', '+', '+'}}, - {DomCode::NUMPAD1, {'1', '1', '1', '1'}}, - {DomCode::NUMPAD2, {'2', '2', '2', '2'}}, - {DomCode::NUMPAD3, {'3', '3', '3', '3'}}, - {DomCode::NUMPAD4, {'4', '4', '4', '4'}}, - {DomCode::NUMPAD5, {'5', '5', '5', '5'}}, - {DomCode::NUMPAD6, {'6', '6', '6', '6'}}, - {DomCode::NUMPAD7, {'7', '7', '7', '7'}}, - {DomCode::NUMPAD8, {'8', '8', '8', '8'}}, - {DomCode::NUMPAD9, {'9', '9', '9', '9'}}, - {DomCode::NUMPAD0, {'0', '0', '0', '0'}}, - {DomCode::NUMPAD_DECIMAL, {'.', '.', '.', '.'}}, - {DomCode::NUMPAD_EQUAL, {'=', '=', '=', '='}}, - {DomCode::NUMPAD_COMMA, {',', ',', ',', ','}}, - {DomCode::NUMPAD_PAREN_LEFT, {'(', '(', '(', '('}}, - {DomCode::NUMPAD_PAREN_RIGHT, {')', ')', ')', ')'}}, - {DomCode::NUMPAD_SIGN_CHANGE, {0x00B1, 0x00B1, 0x2213, 0x2213}}, -}; - -const struct NonPrintableCodeEntry { - DomCode dom_code; - DomKey dom_key; - base::char16 character; -} non_printable_code_map[] = { - {DomCode::ABORT, DomKey::CANCEL}, - {DomCode::AGAIN, DomKey::AGAIN}, - {DomCode::ALT_LEFT, DomKey::ALT}, - {DomCode::ALT_RIGHT, DomKey::ALT}, - {DomCode::ARROW_DOWN, DomKey::ARROW_DOWN}, - {DomCode::ARROW_LEFT, DomKey::ARROW_LEFT}, - {DomCode::ARROW_RIGHT, DomKey::ARROW_RIGHT}, - {DomCode::ARROW_UP, DomKey::ARROW_UP}, - {DomCode::BACKSPACE, DomKey::BACKSPACE, 0x0008}, - {DomCode::BRIGHTNESS_DOWN, DomKey::BRIGHTNESS_DOWN}, - {DomCode::BRIGHTNESS_UP, DomKey::BRIGHTNESS_UP}, - // {DomCode::BRIGHTNESS_AUTO, DomKey::_} - // {DomCode::BRIGHTNESS_MAXIMUM, DomKey::_} - // {DomCode::BRIGHTNESS_MINIMIUM, DomKey::_} - // {DomCode::BRIGHTNESS_TOGGLE, DomKey::_} - {DomCode::BROWSER_BACK, DomKey::BROWSER_BACK}, - {DomCode::BROWSER_FAVORITES, DomKey::BROWSER_FAVORITES}, - {DomCode::BROWSER_FORWARD, DomKey::BROWSER_FORWARD}, - {DomCode::BROWSER_HOME, DomKey::BROWSER_HOME}, - {DomCode::BROWSER_REFRESH, DomKey::BROWSER_REFRESH}, - {DomCode::BROWSER_SEARCH, DomKey::BROWSER_SEARCH}, - {DomCode::BROWSER_STOP, DomKey::BROWSER_STOP}, - {DomCode::CAPS_LOCK, DomKey::CAPS_LOCK}, - {DomCode::CONTEXT_MENU, DomKey::CONTEXT_MENU}, - {DomCode::CONTROL_LEFT, DomKey::CONTROL}, - {DomCode::CONTROL_RIGHT, DomKey::CONTROL}, - {DomCode::CONVERT, DomKey::CONVERT}, - {DomCode::COPY, DomKey::COPY}, - {DomCode::CUT, DomKey::CUT}, - {DomCode::DEL, DomKey::DEL, 0x007F}, - {DomCode::EJECT, DomKey::EJECT}, - {DomCode::END, DomKey::END}, - {DomCode::ENTER, DomKey::ENTER, 0x000D}, - {DomCode::ESCAPE, DomKey::ESCAPE, 0x001B}, - {DomCode::F1, DomKey::F1}, - {DomCode::F2, DomKey::F2}, - {DomCode::F3, DomKey::F3}, - {DomCode::F4, DomKey::F4}, - {DomCode::F5, DomKey::F5}, - {DomCode::F6, DomKey::F6}, - {DomCode::F7, DomKey::F7}, - {DomCode::F8, DomKey::F8}, - {DomCode::F9, DomKey::F9}, - {DomCode::F10, DomKey::F10}, - {DomCode::F11, DomKey::F11}, - {DomCode::F12, DomKey::F12}, - {DomCode::F13, DomKey::F13}, - {DomCode::F14, DomKey::F14}, - {DomCode::F15, DomKey::F15}, - {DomCode::F16, DomKey::F16}, - {DomCode::F17, DomKey::F17}, - {DomCode::F18, DomKey::F18}, - {DomCode::F19, DomKey::F19}, - {DomCode::F20, DomKey::F20}, - {DomCode::F21, DomKey::F21}, - {DomCode::F22, DomKey::F22}, - {DomCode::F23, DomKey::F23}, - {DomCode::F24, DomKey::F24}, - {DomCode::FIND, DomKey::FIND}, - {DomCode::FN, DomKey::FN}, - {DomCode::FN_LOCK, DomKey::FN_LOCK}, - {DomCode::HELP, DomKey::HELP}, - {DomCode::HOME, DomKey::HOME}, - {DomCode::HYPER, DomKey::HYPER}, - {DomCode::INSERT, DomKey::INSERT}, - // {DomCode::INTL_RO, DomKey::_} - {DomCode::KANA_MODE, DomKey::KANA_MODE}, - {DomCode::LANG1, DomKey::HANGUL_MODE}, - {DomCode::LANG2, DomKey::HANJA_MODE}, - {DomCode::LANG3, DomKey::KATAKANA}, - {DomCode::LANG4, DomKey::HIRAGANA}, - {DomCode::LANG5, DomKey::ZENKAKU_HANKAKU}, - {DomCode::LAUNCH_APP1, DomKey::LAUNCH_MY_COMPUTER}, - {DomCode::LAUNCH_APP2, DomKey::LAUNCH_CALCULATOR}, - {DomCode::LAUNCH_MAIL, DomKey::LAUNCH_MAIL}, - {DomCode::LAUNCH_SCREEN_SAVER, DomKey::LAUNCH_SCREEN_SAVER}, - // {DomCode::LAUNCH_DOCUMENTS, DomKey::_} - // {DomCode::LAUNCH_FILE_BROWSER, DomKey::_} - // {DomCode::LAUNCH_KEYBOARD_LAYOUT, DomKey::_} - {DomCode::LOCK_SCREEN, DomKey::LAUNCH_SCREEN_SAVER}, - {DomCode::MAIL_FORWARD, DomKey::MAIL_FORWARD}, - {DomCode::MAIL_REPLY, DomKey::MAIL_REPLY}, - {DomCode::MAIL_SEND, DomKey::MAIL_SEND}, - {DomCode::MEDIA_PLAY_PAUSE, DomKey::MEDIA_PLAY_PAUSE}, - {DomCode::MEDIA_SELECT, DomKey::MEDIA_SELECT}, - {DomCode::MEDIA_STOP, DomKey::MEDIA_STOP}, - {DomCode::MEDIA_TRACK_NEXT, DomKey::MEDIA_TRACK_NEXT}, - {DomCode::MEDIA_TRACK_PREVIOUS, DomKey::MEDIA_TRACK_PREVIOUS}, - // {DomCode::MENU, DomKey::_} - {DomCode::NON_CONVERT, DomKey::NON_CONVERT}, - {DomCode::NUM_LOCK, DomKey::NUM_LOCK}, - {DomCode::NUMPAD_BACKSPACE, DomKey::BACKSPACE, 0x0008}, - {DomCode::NUMPAD_CLEAR, DomKey::CLEAR}, - {DomCode::NUMPAD_ENTER, DomKey::ENTER, 0x000D}, - // {DomCode::NUMPAD_CLEAR_ENTRY, DomKey::_} - // {DomCode::NUMPAD_MEMORY_ADD, DomKey::_} - // {DomCode::NUMPAD_MEMORY_CLEAR, DomKey::_} - // {DomCode::NUMPAD_MEMORY_RECALL, DomKey::_} - // {DomCode::NUMPAD_MEMORY_STORE, DomKey::_} - // {DomCode::NUMPAD_MEMORY_SUBTRACT, DomKey::_} - {DomCode::OPEN, DomKey::OPEN}, - {DomCode::OS_LEFT, DomKey::OS}, - {DomCode::OS_RIGHT, DomKey::OS}, - {DomCode::PAGE_DOWN, DomKey::PAGE_DOWN}, - {DomCode::PAGE_UP, DomKey::PAGE_UP}, - {DomCode::PASTE, DomKey::PASTE}, - {DomCode::PAUSE, DomKey::PAUSE}, - {DomCode::POWER, DomKey::POWER}, - {DomCode::PRINT_SCREEN, DomKey::PRINT_SCREEN}, - {DomCode::PROPS, DomKey::PROPS}, - {DomCode::SCROLL_LOCK, DomKey::SCROLL_LOCK}, - {DomCode::SELECT, DomKey::SELECT}, - // {DomCode::SELECT_TASK, DomKey::_} - {DomCode::SHIFT_LEFT, DomKey::SHIFT}, - {DomCode::SHIFT_RIGHT, DomKey::SHIFT}, - {DomCode::SUPER, DomKey::SUPER}, - {DomCode::TAB, DomKey::TAB, 0x0009}, - {DomCode::UNDO, DomKey::UNDO}, - // {DomCode::VOICE_COMMAND, DomKey::_} - {DomCode::VOLUME_DOWN, DomKey::VOLUME_DOWN}, - {DomCode::VOLUME_MUTE, DomKey::VOLUME_MUTE}, - {DomCode::VOLUME_UP, DomKey::VOLUME_UP}, - {DomCode::WAKE_UP, DomKey::WAKE_UP}, - {DomCode::ZOOM_TOGGLE, DomKey::ZOOM_TOGGLE}, -}; - -} // anonymous namespace - StubKeyboardLayoutEngine::StubKeyboardLayoutEngine() { } @@ -259,42 +44,8 @@ bool StubKeyboardLayoutEngine::Lookup(DomCode dom_code, base::char16* out_character, KeyboardCode* out_key_code, uint32* platform_keycode) const { - if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) { - if (LookupControlCharacter(dom_code, flags, out_dom_key, out_character, - out_key_code)) { - return true; - } - } else { - for (size_t i = 0; i < arraysize(printable_code_map); ++i) { - const PrintableCodeEntry* e = &printable_code_map[i]; - if (e->dom_code == dom_code) { - int state = (((flags & EF_ALTGR_DOWN) == EF_ALTGR_DOWN) << 1) | - ((flags & EF_SHIFT_DOWN) == EF_SHIFT_DOWN); - base::char16 ch = e->character[state]; - *out_dom_key = (ch & DK) ? DomKey::DEAD : DomKey::CHARACTER; - *out_character = ch; - if ((flags & EF_CAPS_LOCK_DOWN) == EF_CAPS_LOCK_DOWN) { - ch = (ch & ~DK) | 0x20; - if ((ch >= 'a') && (ch <= 'z')) - *out_character = e->character[state ^ 1]; - } - *out_key_code = DomCodeToNonLocatedKeyboardCode(dom_code); - return true; - } - } - } - - for (size_t i = 0; i < arraysize(non_printable_code_map); ++i) { - const NonPrintableCodeEntry* e = &non_printable_code_map[i]; - if (e->dom_code == dom_code) { - *out_dom_key = e->dom_key; - *out_character = e->character; - *out_key_code = NonPrintableDomKeyToKeyboardCode(e->dom_key); - return true; - } - } - - return false; + return DomCodeToUsLayoutMeaning(dom_code, flags, out_dom_key, out_character, + out_key_code); } } // namespace ui 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 63b89fe..2d47caf 100644 --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc @@ -657,6 +657,17 @@ void LoadKeymap(const std::string& layout_name, } #endif +KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code) { + DomKey dummy_dom_key; + base::char16 dummy_character; + KeyboardCode key_code; + if (DomCodeToUsLayoutMeaning(dom_code, EF_NONE, &dummy_dom_key, + &dummy_character, &key_code)) { + return key_code; + } + return VKEY_UNKNOWN; +} + } // anonymous namespace XkbKeyCodeConverter::XkbKeyCodeConverter() { @@ -775,21 +786,21 @@ bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, *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); + *key_code = DomCodeToUsLayoutKeyboardCode(dom_code); } if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) { - // Use GetCharacterFromKeyCode() to set |character| to 0x0 for key codes - // that we do not care about. + // Use GetCharacterFromKeyCode() to set |character| to 0x0 for keys that + // are not part of the accepted set of Control+Key combinations. *character = GetCharacterFromKeyCode(*key_code, flags); } } else if (*dom_key == DomKey::DEAD) { *character = DeadXkbKeySymToCombiningCharacter(xkb_keysym); - *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); + *key_code = DomCodeToUsLayoutKeyboardCode(dom_code); } else { *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); if (*key_code == VKEY_UNKNOWN) - *key_code = DomCodeToNonLocatedKeyboardCode(dom_code); + *key_code = DomCodeToUsLayoutKeyboardCode(dom_code); } return true; } diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h index 382a9d3..099d7fd4 100644 --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h @@ -58,7 +58,8 @@ class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyboardLayoutEngine // Determines the Windows-based KeyboardCode (VKEY) for a character key, // accounting for non-US layouts. May return VKEY_UNKNOWN, in which case the - // caller should use |DomCodeToNonLocatedKeyboardCode()| as a last resort. + // caller should, as a last resort, obtain a KeyboardCode using + // |DomCodeToUsLayoutMeaning()|. KeyboardCode DifficultKeyboardCode(DomCode dom_code, int ui_flags, xkb_keycode_t xkb_keycode, diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc index 87b4c55..f5195d0 100644 --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc @@ -6,8 +6,8 @@ #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/keyboard_code_conversion.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" -#include "ui/events/ozone/layout/layout_util.h" #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h" namespace ui { @@ -72,16 +72,21 @@ class VkTestXkbKeyboardLayoutEngine : public XkbKeyboardLayoutEngine { KeyboardCode key_code = DifficultKeyboardCode( dom_code, flags, key_code_converter_.DomCodeToXkbKeyCode(dom_code), flags, CharacterToKeySym(character), DomKey::CHARACTER, character); - if (key_code == VKEY_UNKNOWN) - key_code = DomCodeToNonLocatedKeyboardCode(dom_code); + if (key_code == VKEY_UNKNOWN) { + DomKey dummy_dom_key; + base::char16 dummy_character; + // If this fails, key_code remains VKEY_UNKNOWN. + ignore_result(DomCodeToUsLayoutMeaning(dom_code, EF_NONE, &dummy_dom_key, + &dummy_character, &key_code)); + } return key_code; } // XkbKeyboardLayoutEngine overrides: bool XkbLookup(xkb_keycode_t xkb_keycode, - xkb_mod_mask_t xkb_flags, - xkb_keysym_t* xkb_keysym, - base::char16* character) const override { + xkb_mod_mask_t xkb_flags, + xkb_keysym_t* xkb_keysym, + base::char16* character) const override { if (!entry_ || (xkb_keycode != static_cast<xkb_keycode_t>(entry_->dom_code))) return false; @@ -731,14 +736,14 @@ TEST_F(XkbLayoutEngineVkTest, KeyboardCodeForPrintable) { if (e->shift_character) { // Test with predetermined shifted character. key_code = layout_engine_->GetKeyboardCode(e->dom_code, EF_SHIFT_DOWN, - e->shift_character); + e->shift_character); EXPECT_EQ(e->key_code, key_code); } if (e->altgr_character) { // Test with predetermined AltGr character. key_code = layout_engine_->GetKeyboardCode(e->dom_code, EF_ALTGR_DOWN, - e->altgr_character); + e->altgr_character); EXPECT_EQ(e->key_code, key_code); } diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn index 28f34f1..8f7c8a3 100644 --- a/ui/keyboard/BUILD.gn +++ b/ui/keyboard/BUILD.gn @@ -43,6 +43,7 @@ component("keyboard") { "//ui/compositor", "//ui/events", "//ui/events:dom4_keycode_converter", + "//ui/events:events_base", "//ui/gfx", "//ui/gfx/geometry", "//ui/wm", diff --git a/ui/keyboard/keyboard.gyp b/ui/keyboard/keyboard.gyp index 6570908..18069fa 100644 --- a/ui/keyboard/keyboard.gyp +++ b/ui/keyboard/keyboard.gyp @@ -59,6 +59,7 @@ '../compositor/compositor.gyp:compositor', '../events/events.gyp:dom4_keycode_converter', '../events/events.gyp:events', + '../events/events.gyp:events_base', '../gfx/gfx.gyp:gfx', '../gfx/gfx.gyp:gfx_geometry', '../wm/wm.gyp:wm', diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc index c234127..7b77b43 100644 --- a/ui/keyboard/keyboard_util.cc +++ b/ui/keyboard/keyboard_util.cc @@ -6,6 +6,7 @@ #include <string> +#include "base/basictypes.h" #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/logging.h" @@ -18,7 +19,11 @@ #include "ui/base/ime/input_method.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event_processor.h" +#include "ui/events/event_utils.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/keycodes/keyboard_code_conversion.h" #include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_controller_proxy.h" #include "ui/keyboard/keyboard_switches.h" @@ -31,7 +36,8 @@ const char kKeyUp[] = "keyup"; void SendProcessKeyEvent(ui::EventType type, aura::WindowTreeHost* host) { - ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::EF_NONE); + ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::DomCode::NONE, ui::EF_NONE, + ui::DomKey::PROCESS, 0, ui::EventTimeForNow()); event.SetTranslated(true); ui::EventDispatchDetails details = host->event_processor()->OnEventFromSource(&event); @@ -191,36 +197,54 @@ bool MoveCursor(int swipe_direction, aura::WindowTreeHost* host) { if (!host) return false; - ui::KeyboardCode codex = ui::VKEY_UNKNOWN; - ui::KeyboardCode codey = ui::VKEY_UNKNOWN; + ui::DomCode domcodex = ui::DomCode::NONE; + ui::DomCode domcodey = ui::DomCode::NONE; if (swipe_direction & kCursorMoveRight) - codex = ui::VKEY_RIGHT; + domcodex = ui::DomCode::ARROW_RIGHT; else if (swipe_direction & kCursorMoveLeft) - codex = ui::VKEY_LEFT; + domcodex = ui::DomCode::ARROW_LEFT; if (swipe_direction & kCursorMoveUp) - codey = ui::VKEY_UP; + domcodey = ui::DomCode::ARROW_UP; else if (swipe_direction & kCursorMoveDown) - codey = ui::VKEY_DOWN; + domcodey = ui::DomCode::ARROW_DOWN; // First deal with the x movement. - if (codex != ui::VKEY_UNKNOWN) { - ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags); + if (domcodex != ui::DomCode::NONE) { + ui::KeyboardCode codex = ui::VKEY_UNKNOWN; + ui::DomKey domkeyx = ui::DomKey::NONE; + base::char16 cx; + ignore_result(DomCodeToUsLayoutMeaning(domcodex, ui::EF_NONE, &domkeyx, + &cx, &codex)); + ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, domcodex, + modifier_flags, domkeyx, cx, + ui::EventTimeForNow()); ui::EventDispatchDetails details = host->event_processor()->OnEventFromSource(&press_event); CHECK(!details.dispatcher_destroyed); - ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags); + ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, domcodex, + modifier_flags, domkeyx, cx, + ui::EventTimeForNow()); details = host->event_processor()->OnEventFromSource(&release_event); CHECK(!details.dispatcher_destroyed); } // Then deal with the y movement. - if (codey != ui::VKEY_UNKNOWN) { - ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags); + if (domcodey != ui::DomCode::NONE) { + ui::KeyboardCode codey = ui::VKEY_UNKNOWN; + ui::DomKey domkeyy = ui::DomKey::NONE; + base::char16 cy; + ignore_result(DomCodeToUsLayoutMeaning(domcodey, ui::EF_NONE, &domkeyy, + &cy, &codey)); + ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, domcodey, + modifier_flags, domkeyy, cy, + ui::EventTimeForNow()); ui::EventDispatchDetails details = host->event_processor()->OnEventFromSource(&press_event); CHECK(!details.dispatcher_destroyed); - ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags); + ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, domcodey, + modifier_flags, domkeyy, cy, + ui::EventTimeForNow()); details = host->event_processor()->OnEventFromSource(&release_event); CHECK(!details.dispatcher_destroyed); } @@ -274,10 +298,16 @@ bool SendKeyEvent(const std::string type, } } + ui::DomCode dom_code = ui::DomCode::NONE; + if (!key_name.empty()) + dom_code = ui::KeycodeConverter::CodeStringToDomCode(key_name.c_str()); + if (dom_code == ui::DomCode::NONE) + dom_code = ui::UsLayoutKeyboardCodeToDomCode(code); + CHECK(dom_code != ui::DomCode::NONE); ui::KeyEvent event( event_type, code, - ui::KeycodeConverter::CodeStringToDomCode(key_name.c_str()), + dom_code, modifiers); ui::EventDispatchDetails details = host->event_processor()->OnEventFromSource(&event); |