OLD | NEW |
---|---|
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/input_injector.h" | 5 #include "remoting/host/input_injector.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <windows.h> | 8 #include <windows.h> |
9 | 9 |
10 #include <utility> | 10 #include <utility> |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 | 192 |
193 private: | 193 private: |
194 friend class base::RefCountedThreadSafe<Core>; | 194 friend class base::RefCountedThreadSafe<Core>; |
195 virtual ~Core(); | 195 virtual ~Core(); |
196 | 196 |
197 void HandleKey(const KeyEvent& event); | 197 void HandleKey(const KeyEvent& event); |
198 void HandleText(const TextEvent& event); | 198 void HandleText(const TextEvent& event); |
199 void HandleMouse(const MouseEvent& event); | 199 void HandleMouse(const MouseEvent& event); |
200 void HandleTouch(const TouchEvent& event); | 200 void HandleTouch(const TouchEvent& event); |
201 | 201 |
202 // Check if the given scan code is caps lock or num lock. | |
203 bool IsLockKey(int scancode); | |
204 | |
205 // Sets the keyboard lock states to those provided. | |
206 void SetLockStates(uint32_t states); | |
207 | |
202 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 208 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
203 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 209 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
204 std::unique_ptr<Clipboard> clipboard_; | 210 std::unique_ptr<Clipboard> clipboard_; |
205 std::unique_ptr<TouchInjectorWin> touch_injector_; | 211 std::unique_ptr<TouchInjectorWin> touch_injector_; |
206 | 212 |
207 DISALLOW_COPY_AND_ASSIGN(Core); | 213 DISALLOW_COPY_AND_ASSIGN(Core); |
208 }; | 214 }; |
209 | 215 |
210 scoped_refptr<Core> core_; | 216 scoped_refptr<Core> core_; |
211 | 217 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 | 347 |
342 int scancode = | 348 int scancode = |
343 ui::KeycodeConverter::UsbKeycodeToNativeKeycode(event.usb_keycode()); | 349 ui::KeycodeConverter::UsbKeycodeToNativeKeycode(event.usb_keycode()); |
344 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() | 350 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() |
345 << " to scancode: " << scancode << std::dec; | 351 << " to scancode: " << scancode << std::dec; |
346 | 352 |
347 // Ignore events which can't be mapped. | 353 // Ignore events which can't be mapped. |
348 if (scancode == ui::KeycodeConverter::InvalidNativeKeycode()) | 354 if (scancode == ui::KeycodeConverter::InvalidNativeKeycode()) |
349 return; | 355 return; |
350 | 356 |
357 if (event.has_lock_states() && !IsLockKey(scancode)) { | |
358 SetLockStates(event.lock_states()); | |
359 } | |
360 | |
351 uint32_t flags = KEYEVENTF_SCANCODE | (event.pressed() ? 0 : KEYEVENTF_KEYUP); | 361 uint32_t flags = KEYEVENTF_SCANCODE | (event.pressed() ? 0 : KEYEVENTF_KEYUP); |
352 SendKeyboardInput(flags, scancode); | 362 SendKeyboardInput(flags, scancode); |
353 } | 363 } |
354 | 364 |
355 void InputInjectorWin::Core::HandleText(const TextEvent& event) { | 365 void InputInjectorWin::Core::HandleText(const TextEvent& event) { |
356 // HostEventDispatcher should filter events missing the pressed field. | 366 // HostEventDispatcher should filter events missing the pressed field. |
357 DCHECK(event.has_text()); | 367 DCHECK(event.has_text()); |
358 | 368 |
359 base::string16 text = base::UTF8ToUTF16(event.text()); | 369 base::string16 text = base::UTF8ToUTF16(event.text()); |
360 for (base::string16::const_iterator it = text.begin(); | 370 for (base::string16::const_iterator it = text.begin(); |
(...skipping 16 matching lines...) Expand all Loading... | |
377 if (SendInput(inputs.size(), inputs.data(), sizeof(INPUT)) != inputs.size()) | 387 if (SendInput(inputs.size(), inputs.data(), sizeof(INPUT)) != inputs.size()) |
378 PLOG(ERROR) << "Failed to inject a mouse event"; | 388 PLOG(ERROR) << "Failed to inject a mouse event"; |
379 } | 389 } |
380 } | 390 } |
381 | 391 |
382 void InputInjectorWin::Core::HandleTouch(const TouchEvent& event) { | 392 void InputInjectorWin::Core::HandleTouch(const TouchEvent& event) { |
383 DCHECK(touch_injector_); | 393 DCHECK(touch_injector_); |
384 touch_injector_->InjectTouchEvent(event); | 394 touch_injector_->InjectTouchEvent(event); |
385 } | 395 } |
386 | 396 |
397 bool InputInjectorWin::Core::IsLockKey(int scancode) { | |
398 UINT virtual_key = MapVirtualKey(scancode, MAPVK_VSC_TO_VK); | |
399 return virtual_key == VK_CAPITAL || virtual_key == VK_NUMLOCK; | |
400 } | |
401 | |
402 void InputInjectorWin::Core::SetLockStates(uint32_t states) { | |
403 // Can't use SendKeyboardInput because we need to send virtual key codes, not | |
404 // scan codes. | |
405 INPUT input[2] = {}; | |
406 input[0].type = INPUT_KEYBOARD; | |
407 input[1].type = INPUT_KEYBOARD; | |
408 input[1].ki.dwFlags = KEYEVENTF_KEYUP; | |
409 | |
410 bool client_capslock_state = | |
411 states & protocol::KeyEvent::LOCK_STATES_CAPSLOCK; | |
joedow
2017/05/01 15:14:28
I get a build error, this works though:
bool clien
rkjnsn
2017/05/01 17:46:27
I ran the code through Clang before uploading, but
| |
412 bool host_capslock_state = GetKeyState(VK_CAPITAL) & 1; | |
413 if (client_capslock_state != host_capslock_state) { | |
414 input[0].ki.wVk = VK_CAPITAL; | |
415 input[1].ki.wVk = VK_CAPITAL; | |
416 SendInput(arraysize(input), input, sizeof(INPUT)); | |
417 } | |
418 | |
419 bool client_numlock_state = states & protocol::KeyEvent::LOCK_STATES_NUMLOCK; | |
joedow
2017/05/01 15:14:28
Another build error:
bool client_numlock_state =
rkjnsn
2017/05/01 17:46:27
Changed along with following line.
| |
420 bool host_numlock_state = GetKeyState(VK_NUMLOCK) & 1; | |
421 if (client_numlock_state != host_numlock_state) { | |
422 input[0].ki.wVk = VK_NUMLOCK; | |
423 input[1].ki.wVk = VK_NUMLOCK; | |
424 SendInput(arraysize(input), input, sizeof(INPUT)); | |
425 } | |
426 } | |
427 | |
387 } // namespace | 428 } // namespace |
388 | 429 |
389 // static | 430 // static |
390 std::unique_ptr<InputInjector> InputInjector::Create( | 431 std::unique_ptr<InputInjector> InputInjector::Create( |
391 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 432 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
392 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 433 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
393 return base::WrapUnique( | 434 return base::WrapUnique( |
394 new InputInjectorWin(main_task_runner, ui_task_runner)); | 435 new InputInjectorWin(main_task_runner, ui_task_runner)); |
395 } | 436 } |
396 | 437 |
397 // static | 438 // static |
398 bool InputInjector::SupportsTouchEvents() { | 439 bool InputInjector::SupportsTouchEvents() { |
399 return base::win::GetVersion() >= base::win::VERSION_WIN8; | 440 return base::win::GetVersion() >= base::win::VERSION_WIN8; |
400 } | 441 } |
401 | 442 |
402 } // namespace remoting | 443 } // namespace remoting |
OLD | NEW |