OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/events/keycodes/dom/keycode_converter.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "ui/events/keycodes/dom/dom_code.h" |
| 9 #include "ui/events/keycodes/dom/dom_key.h" |
| 10 |
| 11 namespace ui { |
| 12 |
| 13 namespace { |
| 14 |
| 15 // Table of USB codes (equivalent to DomCode values), native scan codes, |
| 16 // and DOM Level 3 |code| strings. |
| 17 #if defined(OS_WIN) |
| 18 #define USB_KEYMAP(usb, xkb, win, mac, code, id) {usb, win, code} |
| 19 #elif defined(OS_LINUX) |
| 20 #define USB_KEYMAP(usb, xkb, win, mac, code, id) {usb, xkb, code} |
| 21 #elif defined(OS_MACOSX) |
| 22 #define USB_KEYMAP(usb, xkb, win, mac, code, id) {usb, mac, code} |
| 23 #else |
| 24 #define USB_KEYMAP(usb, xkb, win, mac, code, id) {usb, 0, code} |
| 25 #endif |
| 26 #define USB_KEYMAP_DECLARATION const KeycodeMapEntry usb_keycode_map[] = |
| 27 #include "ui/events/keycodes/dom/keycode_converter_data.inc" |
| 28 #undef USB_KEYMAP |
| 29 #undef USB_KEYMAP_DECLARATION |
| 30 |
| 31 const size_t kKeycodeMapEntries = arraysize(usb_keycode_map); |
| 32 |
| 33 // Table of DomKey enum values and DOM Level 3 |key| strings. |
| 34 struct DomKeyMapEntry { |
| 35 DomKey dom_key; |
| 36 const char* string; |
| 37 }; |
| 38 |
| 39 #define DOM_KEY_MAP(key, id) {DomKey::id, key} |
| 40 #define DOM_KEY_MAP_DECLARATION const DomKeyMapEntry dom_key_map[] = |
| 41 #include "ui/events/keycodes/dom/dom_key_data.inc" |
| 42 #undef DOM_KEY_MAP |
| 43 #undef DOM_KEY_MAP_DECLARATION |
| 44 |
| 45 const size_t kDomKeyMapEntries = arraysize(dom_key_map); |
| 46 |
| 47 } // namespace |
| 48 |
| 49 // static |
| 50 size_t KeycodeConverter::NumKeycodeMapEntriesForTest() { |
| 51 return kKeycodeMapEntries; |
| 52 } |
| 53 |
| 54 // static |
| 55 const KeycodeMapEntry* KeycodeConverter::GetKeycodeMapForTest() { |
| 56 return &usb_keycode_map[0]; |
| 57 } |
| 58 |
| 59 // static |
| 60 const char* KeycodeConverter::DomKeyStringForTest(size_t index) { |
| 61 if (index >= kDomKeyMapEntries) |
| 62 return nullptr; |
| 63 return dom_key_map[index].string; |
| 64 } |
| 65 |
| 66 // static |
| 67 int KeycodeConverter::InvalidNativeKeycode() { |
| 68 return usb_keycode_map[0].native_keycode; |
| 69 } |
| 70 |
| 71 // static |
| 72 DomCode KeycodeConverter::NativeKeycodeToDomCode(int native_keycode) { |
| 73 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 74 if (usb_keycode_map[i].native_keycode == native_keycode) { |
| 75 if (usb_keycode_map[i].code != NULL) |
| 76 return static_cast<DomCode>(usb_keycode_map[i].usb_keycode); |
| 77 break; |
| 78 } |
| 79 } |
| 80 return DomCode::NONE; |
| 81 } |
| 82 |
| 83 // static |
| 84 int KeycodeConverter::DomCodeToNativeKeycode(DomCode code) { |
| 85 return UsbKeycodeToNativeKeycode(static_cast<uint32_t>(code)); |
| 86 } |
| 87 |
| 88 // static |
| 89 DomCode KeycodeConverter::CodeStringToDomCode(const char* code) { |
| 90 if (!code || !*code) { |
| 91 LOG(WARNING) << "empty code string"; |
| 92 return DomCode::NONE; |
| 93 } |
| 94 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 95 if (usb_keycode_map[i].code && |
| 96 strcmp(usb_keycode_map[i].code, code) == 0) { |
| 97 return static_cast<DomCode>(usb_keycode_map[i].usb_keycode); |
| 98 } |
| 99 } |
| 100 LOG(WARNING) << "unrecognized code string '" << code << "'"; |
| 101 return DomCode::NONE; |
| 102 } |
| 103 |
| 104 // static |
| 105 const char* KeycodeConverter::DomCodeToCodeString(DomCode dom_code) { |
| 106 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 107 if (usb_keycode_map[i].usb_keycode == static_cast<uint32_t>(dom_code)) { |
| 108 if (usb_keycode_map[i].code) |
| 109 return usb_keycode_map[i].code; |
| 110 break; |
| 111 } |
| 112 } |
| 113 return ""; |
| 114 } |
| 115 |
| 116 // static |
| 117 DomKeyLocation KeycodeConverter::DomCodeToLocation(DomCode dom_code) { |
| 118 static const struct { |
| 119 DomCode code; |
| 120 DomKeyLocation location; |
| 121 } kLocations[] = {{DomCode::CONTROL_LEFT, DomKeyLocation::LEFT}, |
| 122 {DomCode::SHIFT_LEFT, DomKeyLocation::LEFT}, |
| 123 {DomCode::ALT_LEFT, DomKeyLocation::LEFT}, |
| 124 {DomCode::OS_LEFT, DomKeyLocation::LEFT}, |
| 125 {DomCode::CONTROL_RIGHT, DomKeyLocation::RIGHT}, |
| 126 {DomCode::SHIFT_RIGHT, DomKeyLocation::RIGHT}, |
| 127 {DomCode::ALT_RIGHT, DomKeyLocation::RIGHT}, |
| 128 {DomCode::OS_RIGHT, DomKeyLocation::RIGHT}, |
| 129 {DomCode::NUMPAD_DIVIDE, DomKeyLocation::NUMPAD}, |
| 130 {DomCode::NUMPAD_MULTIPLY, DomKeyLocation::NUMPAD}, |
| 131 {DomCode::NUMPAD_SUBTRACT, DomKeyLocation::NUMPAD}, |
| 132 {DomCode::NUMPAD_ADD, DomKeyLocation::NUMPAD}, |
| 133 {DomCode::NUMPAD_ENTER, DomKeyLocation::NUMPAD}, |
| 134 {DomCode::NUMPAD1, DomKeyLocation::NUMPAD}, |
| 135 {DomCode::NUMPAD2, DomKeyLocation::NUMPAD}, |
| 136 {DomCode::NUMPAD3, DomKeyLocation::NUMPAD}, |
| 137 {DomCode::NUMPAD4, DomKeyLocation::NUMPAD}, |
| 138 {DomCode::NUMPAD5, DomKeyLocation::NUMPAD}, |
| 139 {DomCode::NUMPAD6, DomKeyLocation::NUMPAD}, |
| 140 {DomCode::NUMPAD7, DomKeyLocation::NUMPAD}, |
| 141 {DomCode::NUMPAD8, DomKeyLocation::NUMPAD}, |
| 142 {DomCode::NUMPAD9, DomKeyLocation::NUMPAD}, |
| 143 {DomCode::NUMPAD0, DomKeyLocation::NUMPAD}, |
| 144 {DomCode::NUMPAD_DECIMAL, DomKeyLocation::NUMPAD}, |
| 145 {DomCode::NUMPAD_EQUAL, DomKeyLocation::NUMPAD}, |
| 146 {DomCode::NUMPAD_COMMA, DomKeyLocation::NUMPAD}, |
| 147 {DomCode::NUMPAD_PAREN_LEFT, DomKeyLocation::NUMPAD}, |
| 148 {DomCode::NUMPAD_PAREN_RIGHT, DomKeyLocation::NUMPAD}, |
| 149 {DomCode::NUMPAD_BACKSPACE, DomKeyLocation::NUMPAD}, |
| 150 {DomCode::NUMPAD_MEMORY_STORE, DomKeyLocation::NUMPAD}, |
| 151 {DomCode::NUMPAD_MEMORY_RECALL, DomKeyLocation::NUMPAD}, |
| 152 {DomCode::NUMPAD_MEMORY_CLEAR, DomKeyLocation::NUMPAD}, |
| 153 {DomCode::NUMPAD_MEMORY_ADD, DomKeyLocation::NUMPAD}, |
| 154 {DomCode::NUMPAD_MEMORY_SUBTRACT, DomKeyLocation::NUMPAD}, |
| 155 {DomCode::NUMPAD_SIGN_CHANGE, DomKeyLocation::NUMPAD}, |
| 156 {DomCode::NUMPAD_CLEAR, DomKeyLocation::NUMPAD}, |
| 157 {DomCode::NUMPAD_CLEAR_ENTRY, DomKeyLocation::NUMPAD}}; |
| 158 for (const auto& key : kLocations) { |
| 159 if (key.code == dom_code) |
| 160 return key.location; |
| 161 } |
| 162 return DomKeyLocation::STANDARD; |
| 163 } |
| 164 |
| 165 // static |
| 166 DomKey KeycodeConverter::KeyStringToDomKey(const char* key) { |
| 167 if (!key || !*key) |
| 168 return DomKey::NONE; |
| 169 for (size_t i = 0; i < kDomKeyMapEntries; ++i) { |
| 170 if (dom_key_map[i].string && |
| 171 strcmp(dom_key_map[i].string, key) == 0) { |
| 172 return dom_key_map[i].dom_key; |
| 173 } |
| 174 } |
| 175 return DomKey::NONE; |
| 176 } |
| 177 |
| 178 // static |
| 179 const char* KeycodeConverter::DomKeyToKeyString(DomKey dom_key) { |
| 180 for (size_t i = 0; i < kDomKeyMapEntries; ++i) { |
| 181 if (dom_key_map[i].dom_key == dom_key) |
| 182 return dom_key_map[i].string; |
| 183 } |
| 184 return ""; |
| 185 } |
| 186 |
| 187 // USB keycodes |
| 188 // Note that USB keycodes are not part of any web standard. |
| 189 // Please don't use USB keycodes in new code. |
| 190 |
| 191 // static |
| 192 uint32_t KeycodeConverter::InvalidUsbKeycode() { |
| 193 return usb_keycode_map[0].usb_keycode; |
| 194 } |
| 195 |
| 196 // static |
| 197 int KeycodeConverter::UsbKeycodeToNativeKeycode(uint32_t usb_keycode) { |
| 198 // Deal with some special-cases that don't fit the 1:1 mapping. |
| 199 if (usb_keycode == 0x070032) // non-US hash. |
| 200 usb_keycode = 0x070031; // US backslash. |
| 201 #if defined(OS_MACOSX) |
| 202 if (usb_keycode == 0x070046) // PrintScreen. |
| 203 usb_keycode = 0x070068; // F13. |
| 204 #endif |
| 205 |
| 206 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 207 if (usb_keycode_map[i].usb_keycode == usb_keycode) |
| 208 return usb_keycode_map[i].native_keycode; |
| 209 } |
| 210 return InvalidNativeKeycode(); |
| 211 } |
| 212 |
| 213 // static |
| 214 uint32_t KeycodeConverter::NativeKeycodeToUsbKeycode(int native_keycode) { |
| 215 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 216 if (usb_keycode_map[i].native_keycode == native_keycode) |
| 217 return usb_keycode_map[i].usb_keycode; |
| 218 } |
| 219 return InvalidUsbKeycode(); |
| 220 } |
| 221 |
| 222 // static |
| 223 DomCode KeycodeConverter::UsbKeycodeToDomCode(uint32_t usb_keycode) { |
| 224 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 225 if (usb_keycode_map[i].usb_keycode == usb_keycode) |
| 226 return static_cast<DomCode>(usb_keycode); |
| 227 } |
| 228 return DomCode::NONE; |
| 229 } |
| 230 |
| 231 // static |
| 232 uint32_t KeycodeConverter::DomCodeToUsbKeycode(DomCode dom_code) { |
| 233 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 234 if (usb_keycode_map[i].usb_keycode == static_cast<uint32_t>(dom_code)) |
| 235 return usb_keycode_map[i].usb_keycode; |
| 236 } |
| 237 return InvalidUsbKeycode(); |
| 238 } |
| 239 |
| 240 // static |
| 241 uint32_t KeycodeConverter::CodeToUsbKeycode(const char* code) { |
| 242 if (!code || !*code) |
| 243 return InvalidUsbKeycode(); |
| 244 |
| 245 for (size_t i = 0; i < kKeycodeMapEntries; ++i) { |
| 246 if (usb_keycode_map[i].code && |
| 247 strcmp(usb_keycode_map[i].code, code) == 0) { |
| 248 return usb_keycode_map[i].usb_keycode; |
| 249 } |
| 250 } |
| 251 return InvalidUsbKeycode(); |
| 252 } |
| 253 |
| 254 } // namespace ui |
OLD | NEW |