Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: remoting/host/event_executor_win.cc

Issue 10162021: Let Windows SendInput() calculate the VK for USB events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typo. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "remoting/host/event_executor.h" 5 #include "remoting/host/event_executor.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // HostEventDispatcher should filter events missing the pressed field. 111 // HostEventDispatcher should filter events missing the pressed field.
112 DCHECK(event.has_pressed()); 112 DCHECK(event.has_pressed());
113 113
114 // Reset the system idle suspend timeout. 114 // Reset the system idle suspend timeout.
115 SetThreadExecutionState(ES_SYSTEM_REQUIRED); 115 SetThreadExecutionState(ES_SYSTEM_REQUIRED);
116 116
117 // The mapping between scancodes and VKEY values depends on the foreground 117 // The mapping between scancodes and VKEY values depends on the foreground
118 // window's current keyboard layout. 118 // window's current keyboard layout.
119 HKL layout = GetForegroundKeyboardLayout(); 119 HKL layout = GetForegroundKeyboardLayout();
120 120
121 int key = event.keycode(); 121 // Populate the a Windows INPUT structure for the event.
122 bool down = event.pressed(); 122 INPUT input;
123 memset(&input, 0, sizeof(input));
124 input.type = INPUT_KEYBOARD;
125 input.ki.time = 0;
126 input.ki.dwFlags = event.pressed() ? 0 : KEYEVENTF_KEYUP;
127
123 int scancode = kInvalidKeycode; 128 int scancode = kInvalidKeycode;
124 if (event.has_usb_keycode()) { 129 if (event.has_usb_keycode()) {
125 // If the event contains a USB-style code, map to a Windows scancode, and 130 // If the event contains a USB-style code, map to a Windows scancode, and
126 // look up the corresponding VKEY under the foreground layout. 131 // set a flag to have Windows look up the corresponding VK code.
132 input.ki.dwFlags |= KEYEVENTF_SCANCODE;
127 scancode = UsbKeycodeToNativeKeycode(event.usb_keycode()); 133 scancode = UsbKeycodeToNativeKeycode(event.usb_keycode());
128 key = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK_EX, layout);
129 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() 134 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode()
130 << " to scancode: " << scancode 135 << " to scancode: " << scancode << std::dec;
131 << " and VKEY: " << key << std::dec;
132 } else { 136 } else {
133 // If the event provides only a VKEY, determine the corresponding scancode. 137 // If the event provides only a VKEY then use it, and map to the scancode.
134 scancode = MapVirtualKeyEx(key, MAPVK_VK_TO_VSC_EX, layout); 138 input.ki.wVk = event.keycode();
139 scancode = MapVirtualKeyEx(event.keycode(), MAPVK_VK_TO_VSC_EX, layout);
135 VLOG(3) << "Converting VKEY: " << std::hex << event.keycode() 140 VLOG(3) << "Converting VKEY: " << std::hex << event.keycode()
136 << " to scancode: " << scancode << std::dec; 141 << " to scancode: " << scancode << std::dec;
137 } 142 }
138 143
139 // Ignore events with no VK- or USB-keycode, or which can't be mapped. 144 // Ignore events with no VK- or USB-keycode, or which can't be mapped.
140 if (scancode == kInvalidKeycode) 145 if (scancode == kInvalidKeycode)
141 return; 146 return;
142 147
143 INPUT input; 148 // Windows scancodes are only 8-bit, so store the low-order byte into the
144 memset(&input, 0, sizeof(input)); 149 // event and set the extended flag if any high-order bits are set. The only
145 150 // high-order values we should see are 0xE0 or 0xE1. The extended bit usually
146 input.type = INPUT_KEYBOARD; 151 // distinguishes keys with the same meaning, e.g. left & right shift.
147 input.ki.time = 0; 152 input.ki.wScan = scancode & 0xFF;
148 input.ki.wVk = key; 153 if ((scancode & 0xFF00) != 0x0000) {
149 input.ki.wScan = scancode;
150
151 // Flag to mark extended 'e0' key scancodes. Without this, the left and
152 // right windows keys will not be handled properly (on US keyboard).
153 if ((scancode & 0xFF00) == 0xE000) {
154 input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; 154 input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
155 } 155 }
156 156
157 // Flag to mark keyup events. Default is keydown.
158 if (!down) {
159 input.ki.dwFlags |= KEYEVENTF_KEYUP;
160 }
161
162 if (SendInput(1, &input, sizeof(INPUT)) == 0) { 157 if (SendInput(1, &input, sizeof(INPUT)) == 0) {
163 LOG_GETLASTERROR(ERROR) << "Failed to inject a key event"; 158 LOG_GETLASTERROR(ERROR) << "Failed to inject a key event";
164 } 159 }
165 } 160 }
166 161
167 void EventExecutorWin::HandleMouse(const MouseEvent& event) { 162 void EventExecutorWin::HandleMouse(const MouseEvent& event) {
168 // Reset the system idle suspend timeout. 163 // Reset the system idle suspend timeout.
169 SetThreadExecutionState(ES_SYSTEM_REQUIRED); 164 SetThreadExecutionState(ES_SYSTEM_REQUIRED);
170 165
171 // TODO(garykac) Collapse mouse (x,y) and button events into a single 166 // TODO(garykac) Collapse mouse (x,y) and button events into a single
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 238
244 } // namespace 239 } // namespace
245 240
246 scoped_ptr<protocol::HostEventStub> EventExecutor::Create( 241 scoped_ptr<protocol::HostEventStub> EventExecutor::Create(
247 MessageLoop* message_loop, Capturer* capturer) { 242 MessageLoop* message_loop, Capturer* capturer) {
248 return scoped_ptr<protocol::HostEventStub>( 243 return scoped_ptr<protocol::HostEventStub>(
249 new EventExecutorWin(message_loop, capturer)); 244 new EventExecutorWin(message_loop, capturer));
250 } 245 }
251 246
252 } // namespace remoting 247 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698