Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / test / chromedriver / keycode_text_conversion_win.cc
blob52a075024108938ced3f1c2f88ca1d65d573caf1
1 // Copyright (c) 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.
5 #include "chrome/test/chromedriver/keycode_text_conversion.h"
7 #include <VersionHelpers.h>
8 #include <stdlib.h>
9 #include <windows.h>
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/test/chromedriver/chrome/ui_events.h"
15 bool ConvertKeyCodeToText(
16 ui::KeyboardCode key_code, int modifiers, std::string* text,
17 std::string* error_msg) {
18 UINT scan_code = ::MapVirtualKeyW(key_code, MAPVK_VK_TO_VSC);
19 BYTE keyboard_state[256];
20 memset(keyboard_state, 0, 256);
21 *error_msg = std::string();
22 if (modifiers & kShiftKeyModifierMask)
23 keyboard_state[VK_SHIFT] |= 0x80;
24 if (modifiers & kControlKeyModifierMask)
25 keyboard_state[VK_CONTROL] |= 0x80;
26 if (modifiers & kAltKeyModifierMask)
27 keyboard_state[VK_MENU] |= 0x80;
28 wchar_t chars[5];
29 int code = ::ToUnicode(key_code, scan_code, keyboard_state, chars, 4, 0);
30 // |ToUnicode| converts some non-text key codes like F1 to various
31 // control chars. Filter those out.
32 if (code <= 0 || (code == 1 && iswcntrl(chars[0])))
33 *text = std::string();
34 else
35 base::WideToUTF8(chars, code, text);
36 return true;
39 bool ConvertCharToKeyCode(
40 base::char16 key, ui::KeyboardCode* key_code, int *necessary_modifiers,
41 std::string* error_msg) {
42 short vkey_and_modifiers = ::VkKeyScanW(key);
43 bool translated = vkey_and_modifiers != -1 &&
44 LOBYTE(vkey_and_modifiers) != 0xFF &&
45 HIBYTE(vkey_and_modifiers) != 0xFF;
46 *error_msg = std::string();
47 if (translated) {
48 *key_code = static_cast<ui::KeyboardCode>(LOBYTE(vkey_and_modifiers));
49 int win_modifiers = HIBYTE(vkey_and_modifiers);
50 int modifiers = 0;
51 if (win_modifiers & 0x01)
52 modifiers |= kShiftKeyModifierMask;
53 if (win_modifiers & 0x02)
54 modifiers |= kControlKeyModifierMask;
55 if (win_modifiers & 0x04)
56 modifiers |= kAltKeyModifierMask;
57 // Ignore bit 0x08: It is for Hankaku key.
58 *necessary_modifiers = modifiers;
60 return translated;
63 bool SwitchToUSKeyboardLayout() {
64 // For LoadKeyboardLayout - Prior to Windows 8: If the specified input
65 // locale identifier is not already loaded, the function loads and
66 // activates the input locale identifier for the current thread.
67 // Beginning in Windows 8: If the specified input locale identifier is not
68 // already loaded, the function loads and activates the input
69 // locale identifier for the system.
70 // For Windows 8 - Use ActivateKeyboardLayout instead of LoadKeyboardLayout
71 LPCTSTR kUsKeyboardLayout = TEXT("00000409");
73 if (IsWindows8OrGreater()) {
74 int size;
75 TCHAR active_keyboard[KL_NAMELENGTH];
77 if ((size = ::GetKeyboardLayoutList(0, NULL)) <= 0)
78 return false;
80 scoped_ptr<HKL[]> keyboard_handles_list(new HKL[size]);
81 ::GetKeyboardLayoutList(size, keyboard_handles_list.get());
83 for (int keyboard_index = 0; keyboard_index < size; keyboard_index++) {
84 ::ActivateKeyboardLayout(keyboard_handles_list[keyboard_index],
85 KLF_SETFORPROCESS);
86 ::GetKeyboardLayoutName(active_keyboard);
87 if (wcscmp(active_keyboard, kUsKeyboardLayout) == 0)
88 return true;
90 return false;
91 } else {
92 return ::LoadKeyboardLayout(kUsKeyboardLayout, KLF_ACTIVATE) != NULL;