OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/keycodes/keyboard_code_conversion.h" | 5 #include "ui/events/keycodes/keyboard_code_conversion.h" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
7 #include "ui/events/event_constants.h" | 9 #include "ui/events/event_constants.h" |
8 #include "ui/events/keycodes/dom3/dom_code.h" | 10 #include "ui/events/keycodes/dom3/dom_code.h" |
9 #include "ui/events/keycodes/dom3/dom_key.h" | 11 #include "ui/events/keycodes/dom3/dom_key.h" |
| 12 #include "ui/events/keycodes/dom_us_layout_data.h" |
10 | 13 |
11 namespace ui { | 14 namespace ui { |
12 | 15 |
13 namespace { | 16 namespace { |
14 | 17 |
15 // This table maps a subset of |KeyboardCode| (VKEYs) to DomKey and character. | 18 // This table maps a subset of |KeyboardCode| (VKEYs) to DomKey and character. |
16 // Only values not otherwise handled by GetMeaningFromKeyCode() are here. | 19 // Only values not otherwise handled by GetMeaningFromKeyCode() are here. |
17 const struct KeyboardCodeToMeaning { | 20 const struct KeyboardCodeToMeaning { |
18 KeyboardCode key_code; | 21 KeyboardCode key_code; |
19 DomKey key; | 22 DomKey key; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 {VKEY_OEM_103, DomKey::MEDIA_REWIND, 0, 0}, | 126 {VKEY_OEM_103, DomKey::MEDIA_REWIND, 0, 0}, |
124 {VKEY_OEM_104, DomKey::MEDIA_FAST_FORWARD, 0, 0}, | 127 {VKEY_OEM_104, DomKey::MEDIA_FAST_FORWARD, 0, 0}, |
125 #endif | 128 #endif |
126 }; | 129 }; |
127 | 130 |
128 bool IsRightSideDomCode(DomCode code) { | 131 bool IsRightSideDomCode(DomCode code) { |
129 return (code == DomCode::SHIFT_RIGHT) || (code == DomCode::CONTROL_RIGHT) || | 132 return (code == DomCode::SHIFT_RIGHT) || (code == DomCode::CONTROL_RIGHT) || |
130 (code == DomCode::ALT_RIGHT) || (code == DomCode::OS_RIGHT); | 133 (code == DomCode::ALT_RIGHT) || (code == DomCode::OS_RIGHT); |
131 } | 134 } |
132 | 135 |
| 136 bool IsModifierDomCode(DomCode code) { |
| 137 return (code == DomCode::CONTROL_LEFT) || (code == DomCode::CONTROL_RIGHT) || |
| 138 (code == DomCode::SHIFT_LEFT) || (code == DomCode::SHIFT_RIGHT) || |
| 139 (code == DomCode::ALT_LEFT) || (code == DomCode::ALT_RIGHT) || |
| 140 (code == DomCode::OS_LEFT) || (code == DomCode::OS_RIGHT); |
| 141 } |
| 142 |
| 143 // Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|, |
| 144 // assuming a base US English layout. The returned VKEY is located |
| 145 // (e.g. VKEY_LSHIFT). |
| 146 KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code) { |
| 147 const DomCodeToKeyboardCodeEntry* end = |
| 148 kDomCodeToKeyboardCodeMap + arraysize(kDomCodeToKeyboardCodeMap); |
| 149 const DomCodeToKeyboardCodeEntry* found = |
| 150 std::lower_bound(kDomCodeToKeyboardCodeMap, end, dom_code, |
| 151 [](const DomCodeToKeyboardCodeEntry& a, DomCode b) { |
| 152 return static_cast<int>(a.dom_code) < static_cast<int>(b); |
| 153 }); |
| 154 if ((found != end) && (found->dom_code == dom_code)) |
| 155 return found->key_code; |
| 156 return VKEY_UNKNOWN; |
| 157 } |
| 158 |
133 } // anonymous namespace | 159 } // anonymous namespace |
134 | 160 |
135 base::char16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags) { | 161 base::char16 GetCharacterFromKeyCode(KeyboardCode key_code, int flags) { |
136 ui::DomKey dom_key; | 162 ui::DomKey dom_key; |
137 base::char16 character; | 163 base::char16 character; |
138 if (GetMeaningFromKeyCode(key_code, flags, &dom_key, &character)) | 164 if (GetMeaningFromKeyCode(key_code, flags, &dom_key, &character)) |
139 return character; | 165 return character; |
140 return 0; | 166 return 0; |
141 } | 167 } |
142 | 168 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 *character = (shift && p->shift_character) ? p->shift_character | 286 *character = (shift && p->shift_character) ? p->shift_character |
261 : p->plain_character; | 287 : p->plain_character; |
262 return true; | 288 return true; |
263 } | 289 } |
264 } | 290 } |
265 *dom_key = DomKey::UNIDENTIFIED; | 291 *dom_key = DomKey::UNIDENTIFIED; |
266 *character = 0; | 292 *character = 0; |
267 return false; | 293 return false; |
268 } | 294 } |
269 | 295 |
| 296 bool DomCodeToUsLayoutMeaning(DomCode dom_code, |
| 297 int flags, |
| 298 DomKey* out_dom_key, |
| 299 base::char16* out_character, |
| 300 KeyboardCode* out_key_code) { |
| 301 if ((flags & EF_CONTROL_DOWN) == EF_CONTROL_DOWN) { |
| 302 if (DomCodeToControlCharacter(dom_code, flags, out_dom_key, out_character, |
| 303 out_key_code)) { |
| 304 return true; |
| 305 } |
| 306 if (!IsModifierDomCode(dom_code)) { |
| 307 *out_dom_key = DomKey::UNIDENTIFIED; |
| 308 *out_character = 0; |
| 309 *out_key_code = LocatedToNonLocatedKeyboardCode( |
| 310 DomCodeToUsLayoutKeyboardCode(dom_code)); |
| 311 return true; |
| 312 } |
| 313 } else { |
| 314 for (const auto& it : kPrintableCodeMap) { |
| 315 if (it.dom_code == dom_code) { |
| 316 int state = ((flags & EF_SHIFT_DOWN) == EF_SHIFT_DOWN); |
| 317 base::char16 ch = it.character[state]; |
| 318 *out_dom_key = DomKey::CHARACTER; |
| 319 *out_character = ch; |
| 320 if ((flags & EF_CAPS_LOCK_DOWN) == EF_CAPS_LOCK_DOWN) { |
| 321 ch |= 0x20; |
| 322 if ((ch >= 'a') && (ch <= 'z')) |
| 323 *out_character = it.character[state ^ 1]; |
| 324 } |
| 325 *out_key_code = LocatedToNonLocatedKeyboardCode( |
| 326 DomCodeToUsLayoutKeyboardCode(dom_code)); |
| 327 return true; |
| 328 } |
| 329 } |
| 330 } |
| 331 for (const auto& it : kNonPrintableCodeMap) { |
| 332 if (it.dom_code == dom_code) { |
| 333 *out_dom_key = it.dom_key; |
| 334 *out_character = it.character; |
| 335 *out_key_code = NonPrintableDomKeyToKeyboardCode(it.dom_key); |
| 336 return true; |
| 337 } |
| 338 } |
| 339 return false; |
| 340 } |
| 341 |
| 342 bool DomCodeToControlCharacter(DomCode dom_code, |
| 343 int flags, |
| 344 DomKey* dom_key, |
| 345 base::char16* character, |
| 346 KeyboardCode* key_code) { |
| 347 if ((flags & EF_CONTROL_DOWN) == 0) |
| 348 return false; |
| 349 |
| 350 int code = static_cast<int>(dom_code); |
| 351 const int kKeyA = static_cast<int>(DomCode::KEY_A); |
| 352 // Control-A - Control-Z map to 0x01 - 0x1A. |
| 353 if (code >= kKeyA && code <= static_cast<int>(DomCode::KEY_Z)) { |
| 354 *character = static_cast<base::char16>(code - kKeyA + 1); |
| 355 switch (dom_code) { |
| 356 case DomCode::KEY_H: |
| 357 *dom_key = DomKey::BACKSPACE; |
| 358 *key_code = VKEY_BACK; |
| 359 break; |
| 360 case DomCode::KEY_I: |
| 361 *dom_key = DomKey::TAB; |
| 362 *key_code = VKEY_TAB; |
| 363 break; |
| 364 case DomCode::KEY_M: |
| 365 *dom_key = DomKey::ENTER; |
| 366 *key_code = VKEY_RETURN; |
| 367 break; |
| 368 default: |
| 369 *dom_key = DomKey::CHARACTER; |
| 370 *key_code = static_cast<KeyboardCode>(code - kKeyA + VKEY_A); |
| 371 break; |
| 372 } |
| 373 return true; |
| 374 } |
| 375 |
| 376 if (flags & EF_SHIFT_DOWN) { |
| 377 switch (dom_code) { |
| 378 case DomCode::DIGIT2: |
| 379 // NUL |
| 380 *character = 0; |
| 381 *dom_key = DomKey::CHARACTER; |
| 382 *key_code = VKEY_2; |
| 383 return true; |
| 384 case DomCode::DIGIT6: |
| 385 // RS |
| 386 *character = 0x1E; |
| 387 *dom_key = DomKey::CHARACTER; |
| 388 *key_code = VKEY_6; |
| 389 return true; |
| 390 case DomCode::MINUS: |
| 391 // US |
| 392 *character = 0x1F; |
| 393 *dom_key = DomKey::CHARACTER; |
| 394 *key_code = VKEY_OEM_MINUS; |
| 395 return true; |
| 396 default: |
| 397 return false; |
| 398 } |
| 399 } |
| 400 |
| 401 switch (dom_code) { |
| 402 case DomCode::ENTER: |
| 403 // NL |
| 404 *character = 0x0A; |
| 405 *dom_key = DomKey::CHARACTER; |
| 406 *key_code = VKEY_RETURN; |
| 407 return true; |
| 408 case DomCode::BRACKET_LEFT: |
| 409 // ESC |
| 410 *character = 0x1B; |
| 411 *dom_key = DomKey::ESCAPE; |
| 412 *key_code = VKEY_OEM_4; |
| 413 return true; |
| 414 case DomCode::BACKSLASH: |
| 415 // FS |
| 416 *character = 0x1C; |
| 417 *dom_key = DomKey::CHARACTER; |
| 418 *key_code = VKEY_OEM_5; |
| 419 return true; |
| 420 case DomCode::BRACKET_RIGHT: |
| 421 // GS |
| 422 *character = 0x1D; |
| 423 *dom_key = DomKey::CHARACTER; |
| 424 *key_code = VKEY_OEM_6; |
| 425 return true; |
| 426 default: |
| 427 return false; |
| 428 } |
| 429 } |
| 430 |
| 431 // Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. |
| 432 // The returned VKEY is non-positional (e.g. VKEY_SHIFT). |
| 433 KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) { |
| 434 for (const auto& it : kDomKeyToKeyboardCodeMap) { |
| 435 if (it.dom_key == dom_key) |
| 436 return it.key_code; |
| 437 } |
| 438 return VKEY_UNKNOWN; |
| 439 } |
| 440 |
270 // Determine the non-located VKEY corresponding to a located VKEY. | 441 // Determine the non-located VKEY corresponding to a located VKEY. |
271 KeyboardCode LocatedToNonLocatedKeyboardCode(KeyboardCode key_code) { | 442 KeyboardCode LocatedToNonLocatedKeyboardCode(KeyboardCode key_code) { |
272 switch (key_code) { | 443 switch (key_code) { |
273 case VKEY_RWIN: | 444 case VKEY_RWIN: |
274 return VKEY_LWIN; | 445 return VKEY_LWIN; |
275 case VKEY_LSHIFT: | 446 case VKEY_LSHIFT: |
276 case VKEY_RSHIFT: | 447 case VKEY_RSHIFT: |
277 return VKEY_SHIFT; | 448 return VKEY_SHIFT; |
278 case VKEY_LCONTROL: | 449 case VKEY_LCONTROL: |
279 case VKEY_RCONTROL: | 450 case VKEY_RCONTROL: |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 return (dom_code == DomCode::NUMPAD7) ? VKEY_NUMPAD7 : VKEY_7; | 507 return (dom_code == DomCode::NUMPAD7) ? VKEY_NUMPAD7 : VKEY_7; |
337 case VKEY_8: | 508 case VKEY_8: |
338 return (dom_code == DomCode::NUMPAD8) ? VKEY_NUMPAD8 : VKEY_8; | 509 return (dom_code == DomCode::NUMPAD8) ? VKEY_NUMPAD8 : VKEY_8; |
339 case VKEY_9: | 510 case VKEY_9: |
340 return (dom_code == DomCode::NUMPAD9) ? VKEY_NUMPAD9 : VKEY_9; | 511 return (dom_code == DomCode::NUMPAD9) ? VKEY_NUMPAD9 : VKEY_9; |
341 default: | 512 default: |
342 return key_code; | 513 return key_code; |
343 } | 514 } |
344 } | 515 } |
345 | 516 |
| 517 DomCode UsLayoutKeyboardCodeToDomCode(KeyboardCode key_code) { |
| 518 key_code = NonLocatedToLocatedKeyboardCode(key_code, DomCode::NONE); |
| 519 for (const auto& it : kDomCodeToKeyboardCodeMap) { |
| 520 if (it.key_code == key_code) |
| 521 return it.dom_code; |
| 522 } |
| 523 for (const auto& it : kFallbackKeyboardCodeToDomCodeMap) { |
| 524 if (it.key_code == key_code) |
| 525 return it.dom_code; |
| 526 } |
| 527 return DomCode::NONE; |
| 528 } |
| 529 |
346 } // namespace ui | 530 } // namespace ui |
OLD | NEW |