diff options
-rw-r--r-- | content/content_renderer.gypi | 1 | ||||
-rw-r--r-- | content/content_tests.gypi | 1 | ||||
-rw-r--r-- | content/public/test/browser_test_utils.cc | 33 | ||||
-rw-r--r-- | content/renderer/pepper/usb_key_code_conversion_linux.cc | 15 | ||||
-rw-r--r-- | content/renderer/pepper/usb_key_code_conversion_mac.cc | 15 | ||||
-rw-r--r-- | content/renderer/pepper/usb_key_code_conversion_win.cc | 15 | ||||
-rw-r--r-- | remoting/host/input_injector_linux.cc | 11 | ||||
-rw-r--r-- | remoting/host/input_injector_mac.cc | 11 | ||||
-rw-r--r-- | remoting/host/input_injector_win.cc | 12 | ||||
-rw-r--r-- | remoting/remoting.gyp | 1 | ||||
-rw-r--r-- | ui/base/keycodes/OWNERS | 4 | ||||
-rw-r--r-- | ui/base/keycodes/keycode_converter.cc | 115 | ||||
-rw-r--r-- | ui/base/keycodes/keycode_converter.h | 87 | ||||
-rw-r--r-- | ui/base/keycodes/keycode_converter_data.h (renamed from ui/base/keycodes/usb_keycode_map.h) | 322 | ||||
-rw-r--r-- | ui/base/keycodes/keycode_converter_unittest.cc | 110 | ||||
-rw-r--r-- | ui/base/keycodes/usb_keycode_map_unittest.cc | 106 | ||||
-rw-r--r-- | ui/ui.gyp | 13 | ||||
-rw-r--r-- | ui/ui_unittests.gypi | 3 |
18 files changed, 492 insertions, 383 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 6276ab8..0d2039d 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -16,6 +16,7 @@ '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h', '../ui/native_theme/native_theme.gyp:native_theme', '../ui/surface/surface.gyp:surface', + '../ui/ui.gyp:keycode_converter', '../v8/tools/gyp/v8.gyp:v8', '../webkit/common/gpu/webkit_gpu.gyp:webkit_gpu', '../webkit/common/webkit_common.gyp:webkit_common', diff --git a/content/content_tests.gypi b/content/content_tests.gypi index b209101..164eb57 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -13,6 +13,7 @@ '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', + '../ui/ui.gyp:keycode_converter', '../ui/ui.gyp:ui', '../ui/ui.gyp:ui_resources', '../ui/ui.gyp:ui_test_support', diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 6267eed2..3158619 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc @@ -31,19 +31,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_WIN) -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code} -#elif defined(OS_LINUX) -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code} -#elif defined(OS_MACOSX) -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code} -#else -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, 0, code} -#endif -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - +#include "ui/base/keycodes/keycode_converter.h" #include "ui/base/resource/resource_bundle.h" static const int kDefaultWsPort = 8880; @@ -290,7 +278,8 @@ void SimulateKeyPressWithCode(WebContents* web_contents, bool shift, bool alt, bool command) { - int native_key_code = CodeToNativeKeycode(code); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + int native_key_code = key_converter->CodeToNativeKeycode(code); int modifiers = 0; @@ -302,7 +291,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::RawKeyDown, ui::VKEY_CONTROL, - CodeToNativeKeycode("ControlLeft"), + key_converter->CodeToNativeKeycode("ControlLeft"), modifiers); } @@ -312,7 +301,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::RawKeyDown, ui::VKEY_SHIFT, - CodeToNativeKeycode("ShiftLeft"), + key_converter->CodeToNativeKeycode("ShiftLeft"), modifiers); } @@ -322,7 +311,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::RawKeyDown, ui::VKEY_MENU, - CodeToNativeKeycode("AltLeft"), + key_converter->CodeToNativeKeycode("AltLeft"), modifiers); } @@ -332,7 +321,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::RawKeyDown, ui::VKEY_COMMAND, - CodeToNativeKeycode("OSLeft"), + key_converter->CodeToNativeKeycode("OSLeft"), modifiers); } @@ -364,7 +353,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::KeyUp, ui::VKEY_CONTROL, - CodeToNativeKeycode("ControlLeft"), + key_converter->CodeToNativeKeycode("ControlLeft"), modifiers); } @@ -374,7 +363,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::KeyUp, ui::VKEY_SHIFT, - CodeToNativeKeycode("ShiftLeft"), + key_converter->CodeToNativeKeycode("ShiftLeft"), modifiers); } @@ -384,7 +373,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::KeyUp, ui::VKEY_MENU, - CodeToNativeKeycode("AltLeft"), + key_converter->CodeToNativeKeycode("AltLeft"), modifiers); } @@ -394,7 +383,7 @@ void SimulateKeyPressWithCode(WebContents* web_contents, web_contents, WebKit::WebInputEvent::KeyUp, ui::VKEY_COMMAND, - CodeToNativeKeycode("OSLeft"), + key_converter->CodeToNativeKeycode("OSLeft"), modifiers); } diff --git a/content/renderer/pepper/usb_key_code_conversion_linux.cc b/content/renderer/pepper/usb_key_code_conversion_linux.cc index 849793c..c50fe4e 100644 --- a/content/renderer/pepper/usb_key_code_conversion_linux.cc +++ b/content/renderer/pepper/usb_key_code_conversion_linux.cc @@ -6,29 +6,24 @@ #include "base/basictypes.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/base/keycodes/keycode_converter.h" using WebKit::WebKeyboardEvent; namespace content { -namespace { - -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code} -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - -} // anonymous namespace - uint32_t UsbKeyCodeForKeyboardEvent(const WebKeyboardEvent& key_event) { // TODO(garykac): This code assumes that on Linux we're receiving events via // the XKB driver. We should detect between "XKB", "kbd" and "evdev" at // run-time and re-map accordingly, but that's not possible here, inside the // sandbox. - return NativeKeycodeToUsbKeycode(key_event.nativeKeyCode); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + return key_converter->NativeKeycodeToUsbKeycode(key_event.nativeKeyCode); } const char* CodeForKeyboardEvent(const WebKeyboardEvent& key_event) { - return NativeKeycodeToCode(key_event.nativeKeyCode); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + return key_converter->NativeKeycodeToCode(key_event.nativeKeyCode); } } // namespace content diff --git a/content/renderer/pepper/usb_key_code_conversion_mac.cc b/content/renderer/pepper/usb_key_code_conversion_mac.cc index 4e1350a..bcead0e 100644 --- a/content/renderer/pepper/usb_key_code_conversion_mac.cc +++ b/content/renderer/pepper/usb_key_code_conversion_mac.cc @@ -6,25 +6,20 @@ #include "base/basictypes.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/base/keycodes/keycode_converter.h" using WebKit::WebKeyboardEvent; namespace content { -namespace { - -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code} -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - -} // anonymous namespace - uint32_t UsbKeyCodeForKeyboardEvent(const WebKeyboardEvent& key_event) { - return NativeKeycodeToUsbKeycode(key_event.nativeKeyCode); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + return key_converter->NativeKeycodeToUsbKeycode(key_event.nativeKeyCode); } const char* CodeForKeyboardEvent(const WebKeyboardEvent& key_event) { - return NativeKeycodeToCode(key_event.nativeKeyCode); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + return key_converter->NativeKeycodeToCode(key_event.nativeKeyCode); } } // namespace content diff --git a/content/renderer/pepper/usb_key_code_conversion_win.cc b/content/renderer/pepper/usb_key_code_conversion_win.cc index 7245e9f..b04cd73 100644 --- a/content/renderer/pepper/usb_key_code_conversion_win.cc +++ b/content/renderer/pepper/usb_key_code_conversion_win.cc @@ -6,30 +6,25 @@ #include "base/basictypes.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/base/keycodes/keycode_converter.h" using WebKit::WebKeyboardEvent; namespace content { -namespace { - -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code} -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - -} // anonymous namespace - uint32_t UsbKeyCodeForKeyboardEvent(const WebKeyboardEvent& key_event) { // Extract the scancode and extended bit from the native key event's lParam. int scancode = (key_event.nativeKeyCode >> 16) & 0x000000FF; if ((key_event.nativeKeyCode & (1 << 24)) != 0) scancode |= 0xe000; - return NativeKeycodeToUsbKeycode(scancode); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + return key_converter->NativeKeycodeToUsbKeycode(scancode); } const char* CodeForKeyboardEvent(const WebKeyboardEvent& key_event) { - return NativeKeycodeToCode(key_event.nativeKeyCode); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + return key_converter->NativeKeycodeToCode(key_event.nativeKeyCode); } } // namespace content diff --git a/remoting/host/input_injector_linux.cc b/remoting/host/input_injector_linux.cc index d61d8f2..b109b77 100644 --- a/remoting/host/input_injector_linux.cc +++ b/remoting/host/input_injector_linux.cc @@ -19,6 +19,7 @@ #include "remoting/host/clipboard.h" #include "remoting/proto/internal.pb.h" #include "third_party/skia/include/core/SkPoint.h" +#include "ui/base/keycodes/keycode_converter.h" namespace remoting { @@ -28,11 +29,6 @@ using protocol::ClipboardEvent; using protocol::KeyEvent; using protocol::MouseEvent; -// USB to XKB keycode map table. -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code} -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - // Pixel-to-wheel-ticks conversion ratio used by GTK. // From third_party/WebKit/Source/web/gtk/WebInputEventFactory.cpp . const float kWheelTicksPerPixel = 3.0f / 160.0f; @@ -219,13 +215,14 @@ void InputInjectorLinux::Core::InjectKeyEvent(const KeyEvent& event) { return; } - int keycode = UsbKeycodeToNativeKeycode(event.usb_keycode()); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + int keycode = key_converter->UsbKeycodeToNativeKeycode(event.usb_keycode()); VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() << " to keycode: " << keycode << std::dec; // Ignore events which can't be mapped. - if (keycode == InvalidNativeKeycode()) + if (keycode == key_converter->InvalidNativeKeycode()) return; if (event.pressed()) { diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc index 145db22..ac68761 100644 --- a/remoting/host/input_injector_mac.cc +++ b/remoting/host/input_injector_mac.cc @@ -22,6 +22,7 @@ #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/webrtc/modules/desktop_capture/mac/desktop_configuration.h" +#include "ui/base/keycodes/keycode_converter.h" namespace remoting { @@ -31,11 +32,6 @@ using protocol::ClipboardEvent; using protocol::KeyEvent; using protocol::MouseEvent; -// USB to Mac keycode mapping table. -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code} -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). SkIRect CGRectToSkIRect(const CGRect& rect) { SkIRect result; @@ -157,13 +153,14 @@ void InputInjectorMac::Core::InjectKeyEvent(const KeyEvent& event) { if (!event.has_pressed() || !event.has_usb_keycode()) return; - int keycode = UsbKeycodeToNativeKeycode(event.usb_keycode()); + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + int keycode = key_converter->UsbKeycodeToNativeKeycode(event.usb_keycode()); VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() << " to keycode: " << keycode << std::dec; // If we couldn't determine the Mac virtual key code then ignore the event. - if (keycode == InvalidNativeKeycode()) + if (keycode == key_converter->InvalidNativeKeycode()) return; base::ScopedCFTypeRef<CGEventRef> eventRef( diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc index 352f82b..121e229 100644 --- a/remoting/host/input_injector_win.cc +++ b/remoting/host/input_injector_win.cc @@ -17,6 +17,7 @@ // SkSize.h assumes that stdint.h-style types are already defined. #include "third_party/skia/include/core/SkTypes.h" #include "third_party/skia/include/core/SkSize.h" +#include "ui/base/keycodes/keycode_converter.h" namespace remoting { @@ -26,11 +27,6 @@ using protocol::ClipboardEvent; using protocol::KeyEvent; using protocol::MouseEvent; -// USB to XKB keycode map table. -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code} -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - // A class to generate events on Windows. class InputInjectorWin : public InputInjector { public: @@ -185,13 +181,13 @@ void InputInjectorWin::Core::HandleKey(const KeyEvent& event) { // Reset the system idle suspend timeout. SetThreadExecutionState(ES_SYSTEM_REQUIRED); - int scancode = UsbKeycodeToNativeKeycode(event.usb_keycode()); - + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + int scancode = key_converter->UsbKeycodeToNativeKeycode(event.usb_keycode()); VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() << " to scancode: " << scancode << std::dec; // Ignore events which can't be mapped. - if (scancode == InvalidNativeKeycode()) + if (scancode == key_converter->InvalidNativeKeycode()) return; // Populate the a Windows INPUT structure for the event. diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index a464532..a8bda51 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -277,6 +277,7 @@ '../google_apis/google_apis.gyp:google_apis', '../ipc/ipc.gyp:ipc', '../third_party/webrtc/modules/modules.gyp:desktop_capture', + '../ui/ui.gyp:keycode_converter', ], 'defines': [ 'VERSION=<(version_full)', diff --git a/ui/base/keycodes/OWNERS b/ui/base/keycodes/OWNERS index 7dc2fa7..a49314c 100644 --- a/ui/base/keycodes/OWNERS +++ b/ui/base/keycodes/OWNERS @@ -1,2 +1,2 @@ -per-file usb_keycode_map*=garykac@chromium.org -per-file usb_keycode_map*=wez@chromium.org +garykac@chromium.org +wez@chromium.org diff --git a/ui/base/keycodes/keycode_converter.cc b/ui/base/keycodes/keycode_converter.cc new file mode 100644 index 0000000..a7010aa --- /dev/null +++ b/ui/base/keycodes/keycode_converter.cc @@ -0,0 +1,115 @@ +// Copyright (c) 2013 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/base/keycodes/keycode_converter.h" + +namespace ui { + +namespace { + +#if defined(OS_WIN) +#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code} +#elif defined(OS_LINUX) +#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code} +#elif defined(OS_MACOSX) +#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code} +#else +#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, 0, code} +#endif +#include "ui/base/keycodes/keycode_converter_data.h" + +const size_t kKeycodeMapEntries = arraysize(usb_keycode_map); + +} // namespace + +KeycodeConverter::KeycodeConverter() { +} + +KeycodeConverter* KeycodeConverter::GetInstance() { + return Singleton<KeycodeConverter>::get(); +} + +size_t KeycodeConverter::NumKeycodeMapEntriesForTest() { + return kKeycodeMapEntries; +} + +const KeycodeMapEntry* KeycodeConverter::GetKeycodeMapForTest() { + return &usb_keycode_map[0]; +} + +uint16_t KeycodeConverter::InvalidNativeKeycode() { + return usb_keycode_map[0].native_keycode; +} + +const char* KeycodeConverter::InvalidKeyboardEventCode() { + return "Unidentified"; +} + +const char* KeycodeConverter::NativeKeycodeToCode(uint16_t native_keycode) { + for (size_t i = 0; i < kKeycodeMapEntries; ++i) { + if (usb_keycode_map[i].native_keycode == native_keycode) { + if (usb_keycode_map[i].code != NULL) + return usb_keycode_map[i].code; + break; + } + } + return InvalidKeyboardEventCode(); +} + +uint16_t KeycodeConverter::CodeToNativeKeycode(const char* code) { + if (!code || + strcmp(code, InvalidKeyboardEventCode()) == 0) { + return InvalidNativeKeycode(); + } + + for (size_t i = 0; i < kKeycodeMapEntries; ++i) { + if (usb_keycode_map[i].code && + strcmp(usb_keycode_map[i].code, code) == 0) { + return usb_keycode_map[i].native_keycode; + } + } + return InvalidNativeKeycode(); +} + +// USB keycodes +// Note that USB keycodes are not part of any web standard. +// Please don't use USB keycodes in new code. + +uint16_t KeycodeConverter::InvalidUsbKeycode() { + return usb_keycode_map[0].usb_keycode; +} + +uint16_t KeycodeConverter::UsbKeycodeToNativeKeycode(uint32_t usb_keycode) { + // Deal with some special-cases that don't fit the 1:1 mapping. + if (usb_keycode == 0x070032) // non-US hash. + usb_keycode = 0x070031; // US backslash. +#if defined(OS_MACOSX) + if (usb_keycode == 0x070046) // PrintScreen. + usb_keycode = 0x070068; // F13. +#endif + + for (size_t i = 0; i < kKeycodeMapEntries; ++i) { + if (usb_keycode_map[i].usb_keycode == usb_keycode) + return usb_keycode_map[i].native_keycode; + } + return InvalidNativeKeycode(); +} + +uint32_t KeycodeConverter::NativeKeycodeToUsbKeycode(uint16_t native_keycode) { + for (size_t i = 0; i < kKeycodeMapEntries; ++i) { + if (usb_keycode_map[i].native_keycode == native_keycode) + return usb_keycode_map[i].usb_keycode; + } + return InvalidUsbKeycode(); +} + +const char* KeycodeConverter::UsbKeycodeToCode(uint32_t usb_keycode) { + for (size_t i = 0; i < kKeycodeMapEntries; ++i) { + if (usb_keycode_map[i].usb_keycode == usb_keycode) + return usb_keycode_map[i].code; + } + return InvalidKeyboardEventCode(); +} + +} // namespace ui diff --git a/ui/base/keycodes/keycode_converter.h b/ui/base/keycodes/keycode_converter.h new file mode 100644 index 0000000..cd9ac43 --- /dev/null +++ b/ui/base/keycodes/keycode_converter.h @@ -0,0 +1,87 @@ +// Copyright (c) 2013 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_BASE_KEYCODES_KEYCODE_CONVERTER_H_ +#define UI_BASE_KEYCODES_KEYCODE_CONVERTER_H_ + +#include <stdint.h> +#include "base/basictypes.h" +#include "base/memory/singleton.h" + +// For reference, the W3C UI Event spec is located at: +// http://www.w3.org/TR/uievents/ + +namespace ui { + +// This structure is used to define the keycode mapping table. +// It is defined here because the unittests need access to it. +typedef struct { + // USB keycode: + // Upper 16-bits: USB Usage Page. + // Lower 16-bits: USB Usage Id: Assigned ID within this usage page. + uint32_t usb_keycode; + + // Contains one of the following: + // On Linux: XKB scancode + // On Windows: Windows OEM scancode + // On Mac: Mac keycode + uint16_t native_keycode; + + // The UIEvents (aka: DOM4Events) |code| value as defined in: + // https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm + const char* code; +} KeycodeMapEntry; + +// A class to convert between the current platform's native keycode (scancode) +// and platform-neutral |code| values (as defined in the W3C UI Events +// spec (http://www.w3.org/TR/uievents/). +class KeycodeConverter { + public: + static KeycodeConverter* GetInstance(); + + // Return the value that identifies an invalid native keycode. + uint16_t InvalidNativeKeycode(); + + // Return the string that indentifies an invalid UI Event |code|. + // The returned pointer references a static global string. + const char* InvalidKeyboardEventCode(); + + // Convert a native (Mac/Win/Linux) keycode into the |code| string. + // The returned pointer references a static global string. + const char* NativeKeycodeToCode(uint16_t native_keycode); + + // Convert a UI Events |code| string value into a native keycode. + uint16_t CodeToNativeKeycode(const char* code); + + // The following methods relate to USB keycodes. + // Note that USB keycodes are not part of any web standard. + // Please don't use USB keycodes in new code. + + // Return the value that identifies an invalid USB keycode. + uint16_t InvalidUsbKeycode(); + + // Convert a USB keycode into an equivalent platform native keycode. + uint16_t UsbKeycodeToNativeKeycode(uint32_t usb_keycode); + + // Convert a platform native keycode into an equivalent USB keycode. + uint32_t NativeKeycodeToUsbKeycode(uint16_t native_keycode); + + // Convert a USB keycode into the string with the UI Event |code| value. + // The returned pointer references a static global string. + const char* UsbKeycodeToCode(uint32_t usb_keycode); + + // Static methods to support testing. + size_t NumKeycodeMapEntriesForTest(); + const KeycodeMapEntry* GetKeycodeMapForTest(); + + private: + KeycodeConverter(); + friend struct DefaultSingletonTraits<KeycodeConverter>; + + DISALLOW_COPY_AND_ASSIGN(KeycodeConverter); +}; + +} // namespace ui + +#endif // UI_BASE_KEYCODE_CONVERTER_H_ diff --git a/ui/base/keycodes/usb_keycode_map.h b/ui/base/keycodes/keycode_converter_data.h index 5fb6495..d7788e5 100644 --- a/ui/base/keycodes/usb_keycode_map.h +++ b/ui/base/keycodes/keycode_converter_data.h @@ -2,32 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef UI_BASE_KEYCODES_KEYCODE_CONVERTER_DATA_H_ +#define UI_BASE_KEYCODES_KEYCODE_CONVERTER_DATA_H_ + // Data in this file was created by referencing: // USB HID Usage Tables (v1.11) 27 June 2001 // HIToolbox/Events.h (Mac) -#include <stdint.h> - -typedef struct { - // USB keycode: - // Upper 16-bits: USB Usage Page. - // Lower 16-bits: USB Usage Id: Assigned ID within this usage page. - uint32_t usb_keycode; - - // Contains one of the following: - // On Linux: XKB scancode - // On Windows: Windows OEM scancode - // On Mac: Mac keycode - uint16_t native_keycode; - - // The UIEvents (aka: DOM4Events) |code| value as defined in: - // https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm - const char* code; -} usb_keymap; - -const usb_keymap usb_keycode_map[] = { +const KeycodeMapEntry usb_keycode_map[] = { - // USB XKB Win Mac + // USB XKB Win Mac Code USB_KEYMAP(0x000000, 0x0000, 0x0000, 0xffff, NULL), // Invalid // ========================================= @@ -46,7 +30,7 @@ const usb_keymap usb_keycode_map[] = { // ========================================= // TODO(garykac): - // XKB#005c ISO Level3 Shift + // XKB#005c ISO Level3 Shift (AltGr) // XKB#005e <>|| // XKB#006d Linefeed // XKB#008a SunProps cf. USB#0700a3 CrSel/Props @@ -56,16 +40,16 @@ const usb_keymap usb_keycode_map[] = { // Mac#0066 kVK_JIS_Eisu (USB#07008a Henkan?) // USB XKB Win Mac - USB_KEYMAP(0x070000, 0x0000, 0x0000, 0xffff, NULL), // Reserved - USB_KEYMAP(0x070001, 0x0000, 0x0000, 0xffff, NULL), // ErrorRollOver - USB_KEYMAP(0x070002, 0x0000, 0x0000, 0xffff, NULL), // POSTFail - USB_KEYMAP(0x070003, 0x0000, 0x0000, 0xffff, NULL), // ErrorUndefined + USB_KEYMAP(0x070000, 0x0000, 0x0000, 0xffff, NULL), // Reserved + USB_KEYMAP(0x070001, 0x0000, 0x0000, 0xffff, NULL), // ErrorRollOver + USB_KEYMAP(0x070002, 0x0000, 0x0000, 0xffff, NULL), // POSTFail + USB_KEYMAP(0x070003, 0x0000, 0x0000, 0xffff, NULL), // ErrorUndefined USB_KEYMAP(0x070004, 0x0026, 0x001e, 0x0000, "KeyA"), // aA USB_KEYMAP(0x070005, 0x0038, 0x0030, 0x000b, "KeyB"), // bB USB_KEYMAP(0x070006, 0x0036, 0x002e, 0x0008, "KeyC"), // cC USB_KEYMAP(0x070007, 0x0028, 0x0020, 0x0002, "KeyD"), // dD - USB_KEYMAP(0x070008, 0x001a, 0x0012, 0x000e, "KeyE"), // eE + USB_KEYMAP(0x070008, 0x001a, 0x0012, 0x000e, "KeyE"), // eEo USB_KEYMAP(0x070009, 0x0029, 0x0021, 0x0003, "KeyF"), // fF USB_KEYMAP(0x07000a, 0x002a, 0x0022, 0x0005, "KeyG"), // gG USB_KEYMAP(0x07000b, 0x002b, 0x0023, 0x0004, "KeyH"), // hH @@ -101,17 +85,17 @@ const usb_keymap usb_keycode_map[] = { USB_KEYMAP(0x070026, 0x0012, 0x000a, 0x0019, "Digit9"), // 9( USB_KEYMAP(0x070027, 0x0013, 0x000b, 0x001d, "Digit0"), // 0) - USB_KEYMAP(0x070028, 0x0024, 0x001c, 0x0024, "Enter"), // Return - USB_KEYMAP(0x070029, 0x0009, 0x0001, 0x0035, "Escape"), // Escape - USB_KEYMAP(0x07002a, 0x0016, 0x000e, 0x0033, "Backspace"), // Backspace - USB_KEYMAP(0x07002b, 0x0017, 0x000f, 0x0030, "Tab"), // Tab - USB_KEYMAP(0x07002c, 0x0041, 0x0039, 0x0031, "Space"), // Spacebar - USB_KEYMAP(0x07002d, 0x0014, 0x000c, 0x001b, "Minus"), // -_ - USB_KEYMAP(0x07002e, 0x0015, 0x000d, 0x0018, "Equal"), // =+ - USB_KEYMAP(0x07002f, 0x0022, 0x001a, 0x0021, "BracketLeft"), // [{ + USB_KEYMAP(0x070028, 0x0024, 0x001c, 0x0024, "Enter"), + USB_KEYMAP(0x070029, 0x0009, 0x0001, 0x0035, "Escape"), + USB_KEYMAP(0x07002a, 0x0016, 0x000e, 0x0033, "Backspace"), + USB_KEYMAP(0x07002b, 0x0017, 0x000f, 0x0030, "Tab"), + USB_KEYMAP(0x07002c, 0x0041, 0x0039, 0x0031, "Space"), // Spacebar + USB_KEYMAP(0x07002d, 0x0014, 0x000c, 0x001b, "Minus"), // -_ + USB_KEYMAP(0x07002e, 0x0015, 0x000d, 0x0018, "Equal"), // =+ + USB_KEYMAP(0x07002f, 0x0022, 0x001a, 0x0021, "BracketLeft"),// [{ USB_KEYMAP(0x070030, 0x0023, 0x001b, 0x001e, "BracketRight"), // ]} - USB_KEYMAP(0x070031, 0x0033, 0x002b, 0x002a, "Backslash"), // \| (US keyboard only) + USB_KEYMAP(0x070031, 0x0033, 0x002b, 0x002a, "Backslash"), // \| (US keyboard only) // USB#070032 never appears on keyboards that have USB#070031. // Platforms use the same scancode as for the two keys. // The keycap varies on international keyboards: @@ -119,51 +103,52 @@ const usb_keymap usb_keycode_map[] = { // TODO(garykac): Verify Mac intl keyboard. //USB_KEYMAP(0x070032, 0x0033, 0x002b, 0x002a, "IntlHash"), // #~ (Non-US) USB_KEYMAP(0x070033, 0x002f, 0x0027, 0x0029, "Semicolon"), // ;: - USB_KEYMAP(0x070034, 0x0030, 0x0028, 0x0027, "Quote"), // '" + USB_KEYMAP(0x070034, 0x0030, 0x0028, 0x0027, "Quote"), // '" USB_KEYMAP(0x070035, 0x0031, 0x0029, 0x0032, "Backquote"), // `~ - USB_KEYMAP(0x070036, 0x003b, 0x0033, 0x002b, "Comma"), // ,< - USB_KEYMAP(0x070037, 0x003c, 0x0034, 0x002f, "Period"), // .> + USB_KEYMAP(0x070036, 0x003b, 0x0033, 0x002b, "Comma"), // ,< + USB_KEYMAP(0x070037, 0x003c, 0x0034, 0x002f, "Period"), // .> - USB_KEYMAP(0x070038, 0x003d, 0x0035, 0x002c, "Slash"), // /? + USB_KEYMAP(0x070038, 0x003d, 0x0035, 0x002c, "Slash"), // /? // TODO(garykac): CapsLock requires special handling for each platform. - USB_KEYMAP(0x070039, 0x0042, 0x003a, 0x0039, "CapsLock"), // CapsLock - USB_KEYMAP(0x07003a, 0x0043, 0x003b, 0x007a, "F1"), // F1 - USB_KEYMAP(0x07003b, 0x0044, 0x003c, 0x0078, "F2"), // F2 - USB_KEYMAP(0x07003c, 0x0045, 0x003d, 0x0063, "F3"), // F3 - USB_KEYMAP(0x07003d, 0x0046, 0x003e, 0x0076, "F4"), // F4 - USB_KEYMAP(0x07003e, 0x0047, 0x003f, 0x0060, "F5"), // F5 - USB_KEYMAP(0x07003f, 0x0048, 0x0040, 0x0061, "F6"), // F6 - - USB_KEYMAP(0x070040, 0x0049, 0x0041, 0x0062, "F7"), // F7 - USB_KEYMAP(0x070041, 0x004a, 0x0042, 0x0064, "F8"), // F8 - USB_KEYMAP(0x070042, 0x004b, 0x0043, 0x0065, "F9"), // F9 - USB_KEYMAP(0x070043, 0x004c, 0x0044, 0x006d, "F10"), // F10 - USB_KEYMAP(0x070044, 0x005f, 0x0057, 0x0067, "F11"), // F11 - USB_KEYMAP(0x070045, 0x0060, 0x0058, 0x006f, "F12"), // F12 + USB_KEYMAP(0x070039, 0x0042, 0x003a, 0x0039, "CapsLock"), + USB_KEYMAP(0x07003a, 0x0043, 0x003b, 0x007a, "F1"), + USB_KEYMAP(0x07003b, 0x0044, 0x003c, 0x0078, "F2"), + USB_KEYMAP(0x07003c, 0x0045, 0x003d, 0x0063, "F3"), + USB_KEYMAP(0x07003d, 0x0046, 0x003e, 0x0076, "F4"), + USB_KEYMAP(0x07003e, 0x0047, 0x003f, 0x0060, "F5"), + USB_KEYMAP(0x07003f, 0x0048, 0x0040, 0x0061, "F6"), + + USB_KEYMAP(0x070040, 0x0049, 0x0041, 0x0062, "F7"), + USB_KEYMAP(0x070041, 0x004a, 0x0042, 0x0064, "F8"), + USB_KEYMAP(0x070042, 0x004b, 0x0043, 0x0065, "F9"), + USB_KEYMAP(0x070043, 0x004c, 0x0044, 0x006d, "F10"), + USB_KEYMAP(0x070044, 0x005f, 0x0057, 0x0067, "F11"), + USB_KEYMAP(0x070045, 0x0060, 0x0058, 0x006f, "F12"), // PrintScreen is effectively F13 on Mac OS X. - USB_KEYMAP(0x070046, 0x006b, 0xe037, 0xffff, "PrintScreen"), // PrintScreen - USB_KEYMAP(0x070047, 0x004e, 0x0046, 0xffff, "ScrollLock"), // ScrollLock + USB_KEYMAP(0x070046, 0x006b, 0xe037, 0xffff, "PrintScreen"), + USB_KEYMAP(0x070047, 0x004e, 0x0046, 0xffff, "ScrollLock"), - USB_KEYMAP(0x070048, 0x007f, 0x0000, 0xffff, "Pause"), // Pause + USB_KEYMAP(0x070048, 0x007f, 0x0000, 0xffff, "Pause"), // Labeled "Help/Insert" on Mac. - USB_KEYMAP(0x070049, 0x0076, 0xe052, 0x0072, "Insert"), // Insert - USB_KEYMAP(0x07004a, 0x006e, 0xe047, 0x0073, "Home"), // Home - USB_KEYMAP(0x07004b, 0x0070, 0xe049, 0x0074, "PageUp"), // PageUp - USB_KEYMAP(0x07004c, 0x0077, 0xe053, 0x0075, "Delete"), // Delete (Forward Delete) - USB_KEYMAP(0x07004d, 0x0073, 0xe04f, 0x0077, "End"), // End - USB_KEYMAP(0x07004e, 0x0075, 0xe051, 0x0079, "PageDown"), // PageDown - USB_KEYMAP(0x07004f, 0x0072, 0xe04d, 0x007c, "ArrowRight"), // RightArrow - - USB_KEYMAP(0x070050, 0x0071, 0xe04b, 0x007b, "ArrowLeft"), // LeftArrow - USB_KEYMAP(0x070051, 0x0074, 0xe050, 0x007d, "ArrowDown"), // DownArrow - USB_KEYMAP(0x070052, 0x006f, 0xe048, 0x007e, "ArrowUp"), // UpArrow - USB_KEYMAP(0x070053, 0x004d, 0x0045, 0x0047, "NumLock"), // Keypad_NumLock Clear + USB_KEYMAP(0x070049, 0x0076, 0xe052, 0x0072, "Insert"), + USB_KEYMAP(0x07004a, 0x006e, 0xe047, 0x0073, "Home"), + USB_KEYMAP(0x07004b, 0x0070, 0xe049, 0x0074, "PageUp"), + // Delete (Forward Delete) + USB_KEYMAP(0x07004c, 0x0077, 0xe053, 0x0075, "Delete"), + USB_KEYMAP(0x07004d, 0x0073, 0xe04f, 0x0077, "End"), + USB_KEYMAP(0x07004e, 0x0075, 0xe051, 0x0079, "PageDown"), + USB_KEYMAP(0x07004f, 0x0072, 0xe04d, 0x007c, "ArrowRight"), + + USB_KEYMAP(0x070050, 0x0071, 0xe04b, 0x007b, "ArrowLeft"), + USB_KEYMAP(0x070051, 0x0074, 0xe050, 0x007d, "ArrowDown"), + USB_KEYMAP(0x070052, 0x006f, 0xe048, 0x007e, "ArrowUp"), + USB_KEYMAP(0x070053, 0x004d, 0x0045, 0x0047, "NumLock"), // Keypad_NumLock Clear USB_KEYMAP(0x070054, 0x006a, 0xe035, 0x004b, "NumpadDivide"), // Keypad_/ - USB_KEYMAP(0x070055, 0x003f, 0x0037, 0x0043, "NumpadMultiply"), // Keypad_* - USB_KEYMAP(0x070056, 0x0052, 0x004a, 0x004e, "NumpadSubtract"), // Keypad_- - USB_KEYMAP(0x070057, 0x0056, 0x004e, 0x0045, "NumpadAdd"), // Keypad_+ + USB_KEYMAP(0x070055, 0x003f, 0x0037, 0x0043, "NumpadMultiply"),// Keypad_* + USB_KEYMAP(0x070056, 0x0052, 0x004a, 0x004e, "NumpadSubtract"),// Keypad_- + USB_KEYMAP(0x070057, 0x0056, 0x004e, 0x0045, "NumpadAdd"), // Keypad_+ - USB_KEYMAP(0x070058, 0x0068, 0xe01c, 0x004c, "NumpadEnter"), // Keypad_Enter + USB_KEYMAP(0x070058, 0x0068, 0xe01c, 0x004c, "NumpadEnter"), // Keypad_Enter USB_KEYMAP(0x070059, 0x0057, 0x004f, 0x0053, "Numpad1"), // Keypad_1 End USB_KEYMAP(0x07005a, 0x0058, 0x0050, 0x0054, "Numpad2"), // Keypad_2 DownArrow USB_KEYMAP(0x07005b, 0x0059, 0x0051, 0x0055, "Numpad3"), // Keypad_3 PageDown @@ -181,80 +166,91 @@ const usb_keymap usb_keycode_map[] = { // The keycap varies on international keyboards: // Dan: <> Dutch: ][ Ger: <> UK: \| USB_KEYMAP(0x070064, 0x005e, 0x0056, 0x000a, "IntlBackslash"), // Non-US \| - USB_KEYMAP(0x070065, 0x0087, 0xe05d, 0x006e, "ContextMenu"), // AppMenu (next to RWin key) - USB_KEYMAP(0x070066, 0x007c, 0x0000, 0xffff, "Power"), // Power + // AppMenu (next to RWin key) + USB_KEYMAP(0x070065, 0x0087, 0xe05d, 0x006e, "ContextMenu"), + USB_KEYMAP(0x070066, 0x007c, 0x0000, 0xffff, "Power"), USB_KEYMAP(0x070067, 0x007d, 0x0000, 0x0051, "NumpadEqual"), // Keypad_= - USB_KEYMAP(0x070068, 0x0000, 0x005b, 0x0069, "F13"), // F13 - USB_KEYMAP(0x070069, 0x0000, 0x005c, 0x006b, "F14"), // F14 - USB_KEYMAP(0x07006a, 0x0000, 0x005d, 0x0071, "F15"), // F15 - USB_KEYMAP(0x07006b, 0x0000, 0x0063, 0x006a, "F16"), // F16 - USB_KEYMAP(0x07006c, 0x0000, 0x0064, 0x0040, "F17"), // F17 - USB_KEYMAP(0x07006d, 0x0000, 0x0065, 0x004f, "F18"), // F18 - USB_KEYMAP(0x07006e, 0x0000, 0x0066, 0x0050, "F19"), // F19 - USB_KEYMAP(0x07006f, 0x0000, 0x0067, 0x005a, "F20"), // F20 - - USB_KEYMAP(0x070070, 0x0000, 0x0068, 0xffff, "F21"), // F21 - USB_KEYMAP(0x070071, 0x0000, 0x0069, 0xffff, "F22"), // F22 - USB_KEYMAP(0x070072, 0x0000, 0x006a, 0xffff, "F23"), // F23 - USB_KEYMAP(0x070073, 0x0000, 0x006b, 0xffff, "F24"), // F24 + USB_KEYMAP(0x070068, 0x0000, 0x005b, 0x0069, "F13"), + USB_KEYMAP(0x070069, 0x0000, 0x005c, 0x006b, "F14"), + USB_KEYMAP(0x07006a, 0x0000, 0x005d, 0x0071, "F15"), + USB_KEYMAP(0x07006b, 0x0000, 0x0063, 0x006a, "F16"), + USB_KEYMAP(0x07006c, 0x0000, 0x0064, 0x0040, "F17"), + USB_KEYMAP(0x07006d, 0x0000, 0x0065, 0x004f, "F18"), + USB_KEYMAP(0x07006e, 0x0000, 0x0066, 0x0050, "F19"), + USB_KEYMAP(0x07006f, 0x0000, 0x0067, 0x005a, "F20"), + + USB_KEYMAP(0x070070, 0x0000, 0x0068, 0xffff, "F21"), + USB_KEYMAP(0x070071, 0x0000, 0x0069, 0xffff, "F22"), + USB_KEYMAP(0x070072, 0x0000, 0x006a, 0xffff, "F23"), + USB_KEYMAP(0x070073, 0x0000, 0x006b, 0xffff, "F24"), USB_KEYMAP(0x070074, 0x0000, 0x0000, 0xffff, NULL), // Execute - USB_KEYMAP(0x070075, 0x0092, 0xe03b, 0xffff, "Help"), // Help + USB_KEYMAP(0x070075, 0x0092, 0xe03b, 0xffff, "Help"), USB_KEYMAP(0x070076, 0x0093, 0x0000, 0xffff, NULL), // Menu //USB_KEYMAP(0x070077, 0x0000, 0x0000, 0xffff, NULL), // Select //USB_KEYMAP(0x070078, 0x0000, 0x0000, 0xffff, NULL), // Stop USB_KEYMAP(0x070079, 0x0089, 0x0000, 0xffff, NULL), // Again (Redo) - USB_KEYMAP(0x07007a, 0x008b, 0xe008, 0xffff, "Undo"), // Undo - USB_KEYMAP(0x07007b, 0x0091, 0xe017, 0xffff, "Cut"), // Cut - USB_KEYMAP(0x07007c, 0x008d, 0xe018, 0xffff, "Copy"), // Copy - USB_KEYMAP(0x07007d, 0x008f, 0xe00a, 0xffff, "Paste"), // Paste + USB_KEYMAP(0x07007a, 0x008b, 0xe008, 0xffff, "Undo"), + USB_KEYMAP(0x07007b, 0x0091, 0xe017, 0xffff, "Cut"), + USB_KEYMAP(0x07007c, 0x008d, 0xe018, 0xffff, "Copy"), + USB_KEYMAP(0x07007d, 0x008f, 0xe00a, 0xffff, "Paste"), USB_KEYMAP(0x07007e, 0x0090, 0x0000, 0xffff, NULL), // Find - USB_KEYMAP(0x07007f, 0x0079, 0xe020, 0x004a, "VolumeMute"), // Mute + USB_KEYMAP(0x07007f, 0x0079, 0xe020, 0x004a, "VolumeMute"), - USB_KEYMAP(0x070080, 0x007b, 0xe030, 0x0048, "VolumeUp"), // VolumeUp - USB_KEYMAP(0x070081, 0x007a, 0xe02e, 0x0049, "VolumeDown"), // VolumeDown + USB_KEYMAP(0x070080, 0x007b, 0xe030, 0x0048, "VolumeUp"), + USB_KEYMAP(0x070081, 0x007a, 0xe02e, 0x0049, "VolumeDown"), //USB_KEYMAP(0x070082, 0x0000, 0x0000, 0xffff, NULL), // LockingCapsLock //USB_KEYMAP(0x070083, 0x0000, 0x0000, 0xffff, NULL), // LockingNumLock //USB_KEYMAP(0x070084, 0x0000, 0x0000, 0xffff, NULL), // LockingScrollLock // USB#070085 is used as Brazilian Keypad_. USB_KEYMAP(0x070085, 0x0000, 0x0000, 0x005f, "NumpadComma"), // Keypad_Comma + + // International1 // USB#070086 is used on AS/400 keyboards. Standard Keypad_= is USB#070067. //USB_KEYMAP(0x070086, 0x0000, 0x0000, 0xffff, NULL), // Keypad_= // USB#070087 is used for Brazilian /? and Japanese _ 'ro'. - USB_KEYMAP(0x070087, 0x0061, 0x0000, 0x005e, "IntlRo"), // International1 - + USB_KEYMAP(0x070087, 0x0061, 0x0000, 0x005e, "IntlRo"), + // International2 // USB#070088 is used as Japanese Hiragana/Katakana key. - USB_KEYMAP(0x070088, 0x0065, 0x0000, 0x0068, "KanaMode"), // International2 + USB_KEYMAP(0x070088, 0x0065, 0x0000, 0x0068, "KanaMode"), + // International3 // USB#070089 is used as Japanese Yen key. - USB_KEYMAP(0x070089, 0x0084, 0x007d, 0x005d, "IntlYen"), // International3 + USB_KEYMAP(0x070089, 0x0084, 0x007d, 0x005d, "IntlYen"), + // International4 // USB#07008a is used as Japanese Henkan (Convert) key. - USB_KEYMAP(0x07008a, 0x0064, 0x0000, 0xffff, "Convert"), // International4 + USB_KEYMAP(0x07008a, 0x0064, 0x0000, 0xffff, "Convert"), + // International5 // USB#07008b is used as Japanese Muhenkan (No-convert) key. - USB_KEYMAP(0x07008b, 0x0066, 0x0000, 0xffff, "NoConvert"), // International5 + USB_KEYMAP(0x07008b, 0x0066, 0x0000, 0xffff, "NoConvert"), //USB_KEYMAP(0x07008c, 0x0000, 0x0000, 0xffff, NULL), // International6 //USB_KEYMAP(0x07008d, 0x0000, 0x0000, 0xffff, NULL), // International7 //USB_KEYMAP(0x07008e, 0x0000, 0x0000, 0xffff, NULL), // International8 //USB_KEYMAP(0x07008f, 0x0000, 0x0000, 0xffff, NULL), // International9 + // LANG1 // USB#070090 is used as Korean Hangul/English toggle key. - USB_KEYMAP(0x070090, 0x0082, 0x0000, 0xffff, "HangulMode"), // LANG1 + USB_KEYMAP(0x070090, 0x0082, 0x0000, 0xffff, "HangulMode"), + // LANG2 // USB#070091 is used as Korean Hanja conversion key. - USB_KEYMAP(0x070091, 0x0083, 0x0000, 0xffff, "Hanja"), // LANG2 + USB_KEYMAP(0x070091, 0x0083, 0x0000, 0xffff, "Hanja"), + // LANG3 // USB#070092 is used as Japanese Katakana key. - USB_KEYMAP(0x070092, 0x0062, 0x0000, 0xffff, NULL), // LANG3 + USB_KEYMAP(0x070092, 0x0062, 0x0000, 0xffff, NULL), + // LANG4 // USB#070093 is used as Japanese Hiragana key. - USB_KEYMAP(0x070093, 0x0063, 0x0000, 0xffff, NULL), // LANG4 + USB_KEYMAP(0x070093, 0x0063, 0x0000, 0xffff, NULL), + // LANG5 // USB#070094 is used as Japanese Zenkaku/Hankaku (Fullwidth/halfwidth) key. - //USB_KEYMAP(0x070094, 0x0000, 0x0000, 0xffff, NULL), // LANG5 + //USB_KEYMAP(0x070094, 0x0000, 0x0000, 0xffff, NULL), //USB_KEYMAP(0x070095, 0x0000, 0x0000, 0xffff, NULL), // LANG6 //USB_KEYMAP(0x070096, 0x0000, 0x0000, 0xffff, NULL), // LANG7 //USB_KEYMAP(0x070097, 0x0000, 0x0000, 0xffff, NULL), // LANG8 - //USB_KEYMAP(0x070098, 0x0000, 0x0000, 0xffff, NULL), // LANG9 + //USB_KEYMAP(0x070099, 0x0000, 0x0000, 0xffff, NULL), // AlternateErase //USB_KEYMAP(0x07009a, 0x0000, 0x0000, 0xffff, NULL), // SysReq/Attention - USB_KEYMAP(0x07009b, 0x0088, 0x0000, 0xffff, "Cancel"), // Cancel + USB_KEYMAP(0x07009b, 0x0088, 0x0000, 0xffff, "Cancel"), //USB_KEYMAP(0x07009c, 0x0000, 0x0000, 0xffff, NULL), // Clear //USB_KEYMAP(0x07009d, 0x0000, 0x0000, 0xffff, NULL), // Prior //USB_KEYMAP(0x07009e, 0x0000, 0x0000, 0xffff, NULL), // Return @@ -272,7 +268,7 @@ const usb_keymap usb_keycode_map[] = { //USB_KEYMAP(0x0700b3, 0x0000, 0x0000, 0xffff, NULL), // DecimalSeparator //USB_KEYMAP(0x0700b4, 0x0000, 0x0000, 0xffff, NULL), // CurrencyUnit //USB_KEYMAP(0x0700b5, 0x0000, 0x0000, 0xffff, NULL), // CurrencySubunit - USB_KEYMAP(0x0700b6, 0x00bb, 0x0000, 0xffff, "NumpadParenLeft"), // Keypad_( + USB_KEYMAP(0x0700b6, 0x00bb, 0x0000, 0xffff, "NumpadParenLeft"), // Keypad_( USB_KEYMAP(0x0700b7, 0x00bc, 0x0000, 0xffff, "NumpadParenRight"), // Keypad_) //USB_KEYMAP(0x0700b8, 0x0000, 0x0000, 0xffff, NULL), // Keypad_{ @@ -319,14 +315,14 @@ const usb_keymap usb_keycode_map[] = { //USB_KEYMAP(0x0700dd, 0x0000, 0x0000, 0xffff, NULL), // Keypad_Hexadecimal // USB#0700de - #0700df are reserved. - USB_KEYMAP(0x0700e0, 0x0025, 0x001d, 0x003b, "ControlLeft"), // LeftControl - USB_KEYMAP(0x0700e1, 0x0032, 0x002a, 0x0038, "ShiftLeft"), // LeftShift - USB_KEYMAP(0x0700e2, 0x0040, 0x0038, 0x003a, "AltLeft"), // LeftAlt/Option - USB_KEYMAP(0x0700e3, 0x0085, 0xe05b, 0x0037, "OSLeft"), // LeftGUI/Super/Win/Cmd - USB_KEYMAP(0x0700e4, 0x0069, 0xe01d, 0x003e, "ControlRight"), // RightControl - USB_KEYMAP(0x0700e5, 0x003e, 0x0036, 0x003c, "ShiftRight"), // RightShift + USB_KEYMAP(0x0700e0, 0x0025, 0x001d, 0x003b, "ControlLeft"), + USB_KEYMAP(0x0700e1, 0x0032, 0x002a, 0x0038, "ShiftLeft"), + USB_KEYMAP(0x0700e2, 0x0040, 0x0038, 0x003a, "AltLeft"), // LeftAlt/Option + USB_KEYMAP(0x0700e3, 0x0085, 0xe05b, 0x0037, "OSLeft"), // LeftGUI/Super/Win/Cmd + USB_KEYMAP(0x0700e4, 0x0069, 0xe01d, 0x003e, "ControlRight"), + USB_KEYMAP(0x0700e5, 0x003e, 0x0036, 0x003c, "ShiftRight"), USB_KEYMAP(0x0700e6, 0x006c, 0xe038, 0x003d, "AltRight"), // RightAlt/Option - USB_KEYMAP(0x0700e7, 0x0086, 0xe05c, 0x0036, "OSRight"), // RightGUI/Super/Win/Cmd + USB_KEYMAP(0x0700e7, 0x0086, 0xe05c, 0x0036, "OSRight"), // RightGUI/Super/Win/Cmd // USB#0700e8 - #07ffff are reserved @@ -356,11 +352,11 @@ const usb_keymap usb_keycode_map[] = { // XKB... remaining XF86 keys // USB XKB Win Mac - USB_KEYMAP(0x0c00b5, 0x0000, 0xe019, 0xffff, "MediaTrackNext"), // ScanNextTrack - USB_KEYMAP(0x0c00b6, 0x0000, 0xe010, 0xffff, "MediaTrackPrevious"), // ScanPreviousTrack - USB_KEYMAP(0x0c00b7, 0x0000, 0xe024, 0xffff, "MediaStop"), // Stop - USB_KEYMAP(0x0c00b8, 0x0000, 0xe02c, 0xffff, "Eject"), // Eject - USB_KEYMAP(0x0c00cd, 0x0000, 0xe022, 0xffff, "MediaPlayPause"), // Play/Pause + USB_KEYMAP(0x0c00b5, 0x0000, 0xe019, 0xffff, "MediaTrackNext"), + USB_KEYMAP(0x0c00b6, 0x0000, 0xe010, 0xffff, "MediaTrackPrevious"), + USB_KEYMAP(0x0c00b7, 0x0000, 0xe024, 0xffff, "MediaStop"), + USB_KEYMAP(0x0c00b8, 0x0000, 0xe02c, 0xffff, "Eject"), + USB_KEYMAP(0x0c00cd, 0x0000, 0xe022, 0xffff, "MediaPlayPause"), USB_KEYMAP(0x0c018a, 0x0000, 0xe01e, 0xffff, "LaunchMail"), // AL_EmailReader USB_KEYMAP(0x0c0192, 0x0094, 0x0000, 0xffff, NULL), // AL_Calculator // USB#0c0194: My Computer @@ -368,11 +364,11 @@ const usb_keymap usb_keycode_map[] = { USB_KEYMAP(0x0c01a7, 0x00f3, 0x0000, 0xffff, NULL), // AL_Documents // USB#0c01b4: Home Directory USB_KEYMAP(0x0c01b4, 0x0098, 0x0000, 0xffff, NULL), // AL_FileBrowser (Explorer) - USB_KEYMAP(0x0c0221, 0x0000, 0xe065, 0xffff, "BrowserSearch"), // AC_Search - USB_KEYMAP(0x0c0223, 0x0000, 0xe032, 0xffff, "BrowserHome"), // AC_Home - USB_KEYMAP(0x0c0224, 0x00a6, 0xe06a, 0xffff, "BrowserBack"), // AC_Back + USB_KEYMAP(0x0c0221, 0x0000, 0xe065, 0xffff, "BrowserSearch"), // AC_Search + USB_KEYMAP(0x0c0223, 0x0000, 0xe032, 0xffff, "BrowserHome"), // AC_Home + USB_KEYMAP(0x0c0224, 0x00a6, 0xe06a, 0xffff, "BrowserBack"), // AC_Back USB_KEYMAP(0x0c0225, 0x00a7, 0xe069, 0xffff, "BrowserForward"), // AC_Forward - USB_KEYMAP(0x0c0226, 0x0000, 0xe068, 0xffff, "BrowserStop"), // AC_Stop + USB_KEYMAP(0x0c0226, 0x0000, 0xe068, 0xffff, "BrowserStop"), // AC_Stop USB_KEYMAP(0x0c0227, 0x00b5, 0xe067, 0xffff, "BrowserRefresh"), // AC_Refresh (Reload) USB_KEYMAP(0x0c022a, 0x00a4, 0xe066, 0xffff, NULL), // AC_Bookmarks (Favorites) USB_KEYMAP(0x0c0289, 0x00f0, 0x0000, 0xffff, NULL), // AC_Reply @@ -380,76 +376,4 @@ const usb_keymap usb_keycode_map[] = { USB_KEYMAP(0x0c028c, 0x00ef, 0x0000, 0xffff, NULL), // AC_Send }; -inline uint16_t InvalidNativeKeycode() { - return usb_keycode_map[0].native_keycode; -} - -inline const char* InvalidKeyboardEventCode() { - return "Unidentified"; -} - -inline const char* NativeKeycodeToCode(uint16_t native_keycode) { - for (size_t i = 0; i < arraysize(usb_keycode_map); ++i) { - if (usb_keycode_map[i].native_keycode == native_keycode) { - if (usb_keycode_map[i].code != NULL) - return usb_keycode_map[i].code; - break; - } - } - return InvalidKeyboardEventCode(); -} - -inline uint16_t CodeToNativeKeycode(const char* code) { - if (!code || - strcmp(code, InvalidKeyboardEventCode()) == 0) { - return InvalidNativeKeycode(); - } - - for (size_t i = 0; i < arraysize(usb_keycode_map); ++i) { - if (usb_keycode_map[i].code && - strcmp(usb_keycode_map[i].code, code) == 0) { - return usb_keycode_map[i].native_keycode; - } - } - return InvalidNativeKeycode(); -} - -// USB keycodes -// Note that USB keycodes are not part of any web standard. -// Please don't use USB keycodes in new code. - -inline uint16_t InvalidUsbKeycode() { - return usb_keycode_map[0].usb_keycode; -} - -inline uint16_t UsbKeycodeToNativeKeycode(uint32_t usb_keycode) { - // Deal with some special-cases that don't fit the 1:1 mapping. - if (usb_keycode == 0x070032) // non-US hash. - usb_keycode = 0x070031; // US backslash. -#if defined(OS_MACOSX) - if (usb_keycode == 0x070046) // PrintScreen. - usb_keycode = 0x070068; // F13. -#endif - - for (size_t i = 0; i < arraysize(usb_keycode_map); ++i) { - if (usb_keycode_map[i].usb_keycode == usb_keycode) - return usb_keycode_map[i].native_keycode; - } - return InvalidNativeKeycode(); -} - -inline uint32_t NativeKeycodeToUsbKeycode(uint16_t native_keycode) { - for (size_t i = 0; i < arraysize(usb_keycode_map); ++i) { - if (usb_keycode_map[i].native_keycode == native_keycode) - return usb_keycode_map[i].usb_keycode; - } - return InvalidUsbKeycode(); -} - -inline const char* UsbKeycodeToCode(uint32_t usb_keycode) { - for (size_t i = 0; i < arraysize(usb_keycode_map); ++i) { - if (usb_keycode_map[i].usb_keycode == usb_keycode) - return usb_keycode_map[i].code; - } - return InvalidKeyboardEventCode(); -} +#endif // UI_BASE_KEYCODES_KEYCODE_CONVERTER_DATA_H_ diff --git a/ui/base/keycodes/keycode_converter_unittest.cc b/ui/base/keycodes/keycode_converter_unittest.cc new file mode 100644 index 0000000..3362d53 --- /dev/null +++ b/ui/base/keycodes/keycode_converter_unittest.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2012 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/base/keycodes/keycode_converter.h" + +#include <map> + +#include "base/basictypes.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ui::KeycodeConverter; + +namespace { + +#if defined(OS_WIN) +const size_t kExpectedMappedKeyCount = 138; +#elif defined(OS_LINUX) +const size_t kExpectedMappedKeyCount = 145; +#elif defined(OS_MACOSX) +const size_t kExpectedMappedKeyCount = 118; +#else +const size_t kExpectedMappedKeyCount = 0; +#endif + +const uint32_t kUsbNonExistentKeycode = 0xffffff; +const uint32_t kUsbUsBackslash = 0x070031; +const uint32_t kUsbNonUsHash = 0x070032; + +TEST(UsbKeycodeMap, Basic) { + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + // Verify that the first element in the table is the "invalid" code. + const ui::KeycodeMapEntry* keycode_map = + key_converter->GetKeycodeMapForTest(); + EXPECT_EQ(key_converter->InvalidUsbKeycode(), keycode_map[0].usb_keycode); + EXPECT_EQ(key_converter->InvalidNativeKeycode(), + keycode_map[0].native_keycode); + EXPECT_STREQ(key_converter->InvalidKeyboardEventCode(), "Unidentified"); + EXPECT_EQ(key_converter->InvalidNativeKeycode(), + key_converter->CodeToNativeKeycode("Unidentified")); + + // Verify that there are no duplicate entries in the mapping. + std::map<uint32_t, uint16_t> usb_to_native; + std::map<uint16_t, uint32_t> native_to_usb; + size_t numEntries = key_converter->NumKeycodeMapEntriesForTest(); + for (size_t i = 0; i < numEntries; ++i) { + const ui::KeycodeMapEntry* entry = &keycode_map[i]; + // Don't test keys with no native keycode mapping on this platform. + if (entry->native_keycode == key_converter->InvalidNativeKeycode()) + continue; + + // Verify UsbKeycodeToNativeKeycode works for this key. + EXPECT_EQ(entry->native_keycode, + key_converter->UsbKeycodeToNativeKeycode(entry->usb_keycode)); + + // Verify CodeToNativeKeycode and NativeKeycodeToCode work correctly. + if (entry->code) { + EXPECT_EQ(entry->native_keycode, + key_converter->CodeToNativeKeycode(entry->code)); + EXPECT_STREQ(entry->code, + key_converter->NativeKeycodeToCode(entry->native_keycode)); + } + else { + EXPECT_EQ(key_converter->InvalidNativeKeycode(), + key_converter->CodeToNativeKeycode(entry->code)); + } + + // Verify that the USB or native codes aren't duplicated. + EXPECT_EQ(0U, usb_to_native.count(entry->usb_keycode)) + << " duplicate of USB code 0x" << std::hex << std::setfill('0') + << std::setw(6) << entry->usb_keycode + << " to native 0x" + << std::setw(4) << entry->native_keycode + << " (previous was 0x" + << std::setw(4) << usb_to_native[entry->usb_keycode] + << ")"; + usb_to_native[entry->usb_keycode] = entry->native_keycode; + EXPECT_EQ(0U, native_to_usb.count(entry->native_keycode)) + << " duplicate of native code 0x" << std::hex << std::setfill('0') + << std::setw(4) << entry->native_keycode + << " to USB 0x" + << std::setw(6) << entry->usb_keycode + << " (previous was 0x" + << std::setw(6) << native_to_usb[entry->native_keycode] + << ")"; + native_to_usb[entry->native_keycode] = entry->usb_keycode; + } + ASSERT_EQ(usb_to_native.size(), native_to_usb.size()); + + // Verify that the number of mapped keys is what we expect, i.e. we haven't + // lost any, and if we've added some then the expectation has been updated. + EXPECT_EQ(kExpectedMappedKeyCount, usb_to_native.size()); +} + +TEST(UsbKeycodeMap, NonExistent) { + // Verify that UsbKeycodeToNativeKeycode works for a non-existent USB keycode. + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + EXPECT_EQ(key_converter->InvalidNativeKeycode(), + key_converter->UsbKeycodeToNativeKeycode(kUsbNonExistentKeycode)); +} + +TEST(UsbKeycodeMap, UsBackslashIsNonUsHash) { + // Verify that UsbKeycodeToNativeKeycode treats the non-US "hash" key + // as equivalent to the US "backslash" key. + ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); + EXPECT_EQ(key_converter->UsbKeycodeToNativeKeycode(kUsbUsBackslash), + key_converter->UsbKeycodeToNativeKeycode(kUsbNonUsHash)); +} + +} // namespace diff --git a/ui/base/keycodes/usb_keycode_map_unittest.cc b/ui/base/keycodes/usb_keycode_map_unittest.cc deleted file mode 100644 index 1646a00..0000000 --- a/ui/base/keycodes/usb_keycode_map_unittest.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2012 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 <map> - -#include "base/basictypes.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -#if defined(OS_WIN) -const size_t kExpectedMappedKeyCount = 138; -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, win, code} -#elif defined(OS_LINUX) -const size_t kExpectedMappedKeyCount = 145; -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, xkb, code} -#elif defined(OS_MACOSX) -const size_t kExpectedMappedKeyCount = 118; -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, mac, code} -#else -const size_t kExpectedMappedKeyCount = 0; -#define USB_KEYMAP(usb, xkb, win, mac, code) {usb, 0, code} -#endif -#include "ui/base/keycodes/usb_keycode_map.h" -#undef USB_KEYMAP - -const uint32_t kUsbNonExistentKeycode = 0xffffff; -const uint32_t kUsbUsBackslash = 0x070031; -const uint32_t kUsbNonUsHash = 0x070032; - -TEST(UsbKeycodeMap, Basic) { - // Verify that the first element in the table is the "invalid" code. - EXPECT_EQ(InvalidUsbKeycode(), usb_keycode_map[0].usb_keycode); - EXPECT_EQ(InvalidNativeKeycode(), usb_keycode_map[0].native_keycode); - EXPECT_STREQ(InvalidKeyboardEventCode(), "Unidentified"); - EXPECT_EQ(InvalidNativeKeycode(), CodeToNativeKeycode("Unidentified")); - - // Verify that there are no duplicate entries in the mapping. - std::map<uint32_t, uint16_t> usb_to_native; - std::map<uint16_t, uint32_t> native_to_usb; - for (size_t i = 0; i < arraysize(usb_keycode_map); ++i) { - // Don't test keys with no native keycode mapping on this platform. - if (usb_keycode_map[i].native_keycode == InvalidNativeKeycode()) - continue; - - // Verify UsbKeycodeToNativeKeycode works for this key. - EXPECT_EQ(usb_keycode_map[i].native_keycode, - UsbKeycodeToNativeKeycode(usb_keycode_map[i].usb_keycode)); - - // Verify CodeToNativeKeycode and NativeKeycodeToCode work correctly. - if (usb_keycode_map[i].code) { - EXPECT_EQ(usb_keycode_map[i].native_keycode, - CodeToNativeKeycode(usb_keycode_map[i].code)); - EXPECT_STREQ(usb_keycode_map[i].code, - NativeKeycodeToCode(usb_keycode_map[i].native_keycode)); - } - else { - EXPECT_EQ(InvalidNativeKeycode(), - CodeToNativeKeycode(usb_keycode_map[i].code)); - } - - // Verify that the USB or native codes aren't duplicated. - EXPECT_EQ(0U, usb_to_native.count(usb_keycode_map[i].usb_keycode)) - << " duplicate of USB code 0x" << std::hex << std::setfill('0') - << std::setw(6) << usb_keycode_map[i].usb_keycode - << " to native 0x" - << std::setw(4) << usb_keycode_map[i].native_keycode - << " (previous was 0x" - << std::setw(4) << usb_to_native[usb_keycode_map[i].usb_keycode] - << ")"; - usb_to_native[usb_keycode_map[i].usb_keycode] = - usb_keycode_map[i].native_keycode; - EXPECT_EQ(0U, native_to_usb.count(usb_keycode_map[i].native_keycode)) - << " duplicate of native code 0x" << std::hex << std::setfill('0') - << std::setw(4) << usb_keycode_map[i].native_keycode - << " to USB 0x" - << std::setw(6) << usb_keycode_map[i].usb_keycode - << " (previous was 0x" - << std::setw(6) << native_to_usb[usb_keycode_map[i].native_keycode] - << ")"; - native_to_usb[usb_keycode_map[i].native_keycode] = - usb_keycode_map[i].usb_keycode; - } - ASSERT_EQ(usb_to_native.size(), native_to_usb.size()); - - // Verify that the number of mapped keys is what we expect, i.e. we haven't - // lost any, and if we've added some then the expectation has been updated. - EXPECT_EQ(kExpectedMappedKeyCount, usb_to_native.size()); -} - -TEST(UsbKeycodeMap, NonExistent) { - // Verify that UsbKeycodeToNativeKeycode works for a non-existent USB keycode. - EXPECT_EQ(InvalidNativeKeycode(), - UsbKeycodeToNativeKeycode(kUsbNonExistentKeycode)); -} - -TEST(UsbKeycodeMap, UsBackslashIsNonUsHash) { - // Verify that UsbKeycodeToNativeKeycode treats the non-US "hash" key - // as equivalent to the US "backslash" key. - EXPECT_EQ(UsbKeycodeToNativeKeycode(kUsbUsBackslash), - UsbKeycodeToNativeKeycode(kUsbNonUsHash)); - -} - -} // namespace @@ -203,7 +203,6 @@ 'base/gtk/scoped_region.cc', 'base/gtk/scoped_region.h', 'base/hit_test.h', - 'base/keycodes/usb_keycode_map.h', 'base/latency_info.cc', 'base/latency_info.h', 'base/l10n/l10n_font_util.cc', @@ -961,6 +960,18 @@ '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources', ] } + }, + { + 'target_name': 'keycode_converter', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + ], + 'sources': [ + 'base/keycodes/keycode_converter.cc', + 'base/keycodes/keycode_converter.h', + 'base/keycodes/keycode_converter_data.h', + ], } ], 'conditions': [ diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi index 3064c3a..629fbd9 100644 --- a/ui/ui_unittests.gypi +++ b/ui/ui_unittests.gypi @@ -82,6 +82,7 @@ '../third_party/libpng/libpng.gyp:libpng', '../url/url.gyp:url_lib', 'base/strings/ui_strings.gyp:ui_strings', + 'keycode_converter', 'run_ui_unittests', 'shell_dialogs', 'ui', @@ -155,7 +156,7 @@ 'base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc', 'base/gtk/gtk_expanded_container_unittest.cc', 'base/gtk/gtk_im_context_util_unittest.cc', - 'base/keycodes/usb_keycode_map_unittest.cc', + 'base/keycodes/keycode_converter_unittest.cc', 'base/latency_info_unittest.cc', 'base/models/list_model_unittest.cc', 'base/models/list_selection_model_unittest.cc', |