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>
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;
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();
35 base::WideToUTF8(chars
, code
, text
);
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();
48 *key_code
= static_cast<ui::KeyboardCode
>(LOBYTE(vkey_and_modifiers
));
49 int win_modifiers
= HIBYTE(vkey_and_modifiers
);
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
;
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()) {
75 TCHAR active_keyboard
[KL_NAMELENGTH
];
77 if ((size
= ::GetKeyboardLayoutList(0, NULL
)) <= 0)
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
],
86 ::GetKeyboardLayoutName(active_keyboard
);
87 if (wcscmp(active_keyboard
, kUsKeyboardLayout
) == 0)
92 return ::LoadKeyboardLayout(kUsKeyboardLayout
, KLF_ACTIVATE
) != NULL
;