Commit 6d42bdce authored by wez@chromium.org's avatar wez@chromium.org

Let Windows SendInput() calculate the VK for USB events.

Windows SendInput() API provides a flag callers can use to have the API do the conversion, which is more reliable than doing it manually with MapVirtualKeyEx().

BUG=124499
TEST=Manual. Verify that NumLock behaves as expected when connecting between two Windows hosts using Chromoting.

Review URL: https://chromiumcodereview.appspot.com/10162021

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133784 0039d316-1c4b-4281-b951-d872f2087c98
parent 6a9951be
...@@ -118,20 +118,25 @@ void EventExecutorWin::HandleKey(const KeyEvent& event) { ...@@ -118,20 +118,25 @@ void EventExecutorWin::HandleKey(const KeyEvent& event) {
// window's current keyboard layout. // window's current keyboard layout.
HKL layout = GetForegroundKeyboardLayout(); HKL layout = GetForegroundKeyboardLayout();
int key = event.keycode(); // Populate the a Windows INPUT structure for the event.
bool down = event.pressed(); INPUT input;
memset(&input, 0, sizeof(input));
input.type = INPUT_KEYBOARD;
input.ki.time = 0;
input.ki.dwFlags = event.pressed() ? 0 : KEYEVENTF_KEYUP;
int scancode = kInvalidKeycode; int scancode = kInvalidKeycode;
if (event.has_usb_keycode()) { if (event.has_usb_keycode()) {
// If the event contains a USB-style code, map to a Windows scancode, and // If the event contains a USB-style code, map to a Windows scancode, and
// look up the corresponding VKEY under the foreground layout. // set a flag to have Windows look up the corresponding VK code.
input.ki.dwFlags |= KEYEVENTF_SCANCODE;
scancode = UsbKeycodeToNativeKeycode(event.usb_keycode()); scancode = UsbKeycodeToNativeKeycode(event.usb_keycode());
key = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK_EX, layout);
VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode()
<< " to scancode: " << scancode << " to scancode: " << scancode << std::dec;
<< " and VKEY: " << key << std::dec;
} else { } else {
// If the event provides only a VKEY, determine the corresponding scancode. // If the event provides only a VKEY then use it, and map to the scancode.
scancode = MapVirtualKeyEx(key, MAPVK_VK_TO_VSC_EX, layout); input.ki.wVk = event.keycode();
scancode = MapVirtualKeyEx(event.keycode(), MAPVK_VK_TO_VSC_EX, layout);
VLOG(3) << "Converting VKEY: " << std::hex << event.keycode() VLOG(3) << "Converting VKEY: " << std::hex << event.keycode()
<< " to scancode: " << scancode << std::dec; << " to scancode: " << scancode << std::dec;
} }
...@@ -140,25 +145,15 @@ void EventExecutorWin::HandleKey(const KeyEvent& event) { ...@@ -140,25 +145,15 @@ void EventExecutorWin::HandleKey(const KeyEvent& event) {
if (scancode == kInvalidKeycode) if (scancode == kInvalidKeycode)
return; return;
INPUT input; // Windows scancodes are only 8-bit, so store the low-order byte into the
memset(&input, 0, sizeof(input)); // event and set the extended flag if any high-order bits are set. The only
// high-order values we should see are 0xE0 or 0xE1. The extended bit usually
input.type = INPUT_KEYBOARD; // distinguishes keys with the same meaning, e.g. left & right shift.
input.ki.time = 0; input.ki.wScan = scancode & 0xFF;
input.ki.wVk = key; if ((scancode & 0xFF00) != 0x0000) {
input.ki.wScan = scancode;
// Flag to mark extended 'e0' key scancodes. Without this, the left and
// right windows keys will not be handled properly (on US keyboard).
if ((scancode & 0xFF00) == 0xE000) {
input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
} }
// Flag to mark keyup events. Default is keydown.
if (!down) {
input.ki.dwFlags |= KEYEVENTF_KEYUP;
}
if (SendInput(1, &input, sizeof(INPUT)) == 0) { if (SendInput(1, &input, sizeof(INPUT)) == 0) {
LOG_GETLASTERROR(ERROR) << "Failed to inject a key event"; LOG_GETLASTERROR(ERROR) << "Failed to inject a key event";
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment