123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "remoting/host/input_monitor/local_pointer_input_monitor.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/location.h"
- #include "base/logging.h"
- #include "base/task/single_thread_task_runner.h"
- #include "remoting/host/input_monitor/local_input_monitor_win.h"
- #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
- #include "ui/events/event.h"
- namespace remoting {
- namespace {
- // From the HID Usage Tables specification.
- const USHORT kGenericDesktopPage = 1;
- const USHORT kMouseUsage = 2;
- class MouseRawInputHandlerWin : public LocalInputMonitorWin::RawInputHandler {
- public:
- MouseRawInputHandlerWin(
- scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- LocalInputMonitor::PointerMoveCallback on_mouse_move,
- base::OnceClosure disconnect_callback);
- MouseRawInputHandlerWin(const MouseRawInputHandlerWin&) = delete;
- MouseRawInputHandlerWin& operator=(const MouseRawInputHandlerWin&) = delete;
- ~MouseRawInputHandlerWin() override;
- // LocalInputMonitorWin::RawInputHandler implementation.
- bool Register(HWND hwnd) override;
- void Unregister() override;
- void OnInputEvent(const RAWINPUT* input) override;
- void OnError() override;
- scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
- LocalInputMonitor::PointerMoveCallback on_mouse_move_;
- base::OnceClosure disconnect_callback_;
- webrtc::DesktopVector mouse_position_;
- // Tracks whether the instance is registered to receive raw input events.
- bool registered_ = false;
- };
- MouseRawInputHandlerWin::MouseRawInputHandlerWin(
- scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- LocalInputMonitor::PointerMoveCallback on_mouse_move,
- base::OnceClosure disconnect_callback)
- : caller_task_runner_(caller_task_runner),
- ui_task_runner_(ui_task_runner),
- on_mouse_move_(std::move(on_mouse_move)),
- disconnect_callback_(std::move(disconnect_callback)) {}
- MouseRawInputHandlerWin::~MouseRawInputHandlerWin() {
- DCHECK(!registered_);
- }
- bool MouseRawInputHandlerWin::Register(HWND hwnd) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- // Register to receive raw keyboard input.
- RAWINPUTDEVICE device = {0};
- device.dwFlags = RIDEV_INPUTSINK;
- device.usUsagePage = kGenericDesktopPage;
- device.usUsage = kMouseUsage;
- device.hwndTarget = hwnd;
- if (!RegisterRawInputDevices(&device, 1, sizeof(device))) {
- PLOG(ERROR) << "RegisterRawInputDevices() failed";
- return false;
- }
- registered_ = true;
- return true;
- }
- void MouseRawInputHandlerWin::Unregister() {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- RAWINPUTDEVICE device = {0};
- device.dwFlags = RIDEV_REMOVE;
- device.usUsagePage = kGenericDesktopPage;
- device.usUsage = kMouseUsage;
- device.hwndTarget = nullptr;
- // The error is harmless, ignore it.
- RegisterRawInputDevices(&device, 1, sizeof(device));
- registered_ = false;
- }
- void MouseRawInputHandlerWin::OnInputEvent(const RAWINPUT* input) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- // Notify the observer about mouse events generated locally. Remote (injected)
- // mouse events do not specify a device handle (based on observed behavior).
- if (input->header.dwType != RIM_TYPEMOUSE ||
- input->header.hDevice == nullptr) {
- return;
- }
- POINT position;
- if (!GetCursorPos(&position)) {
- position.x = 0;
- position.y = 0;
- }
- webrtc::DesktopVector new_position(position.x, position.y);
- // Ignore the event if the cursor position or button states have not changed.
- // Note: If GetCursorPos fails above, we err on the safe side and treat it
- // like a movement.
- if (mouse_position_.equals(new_position) &&
- !input->data.mouse.usButtonFlags && !new_position.is_zero()) {
- return;
- }
- mouse_position_ = new_position;
- caller_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(on_mouse_move_, std::move(new_position),
- ui::ET_MOUSE_MOVED));
- }
- void MouseRawInputHandlerWin::OnError() {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- if (disconnect_callback_) {
- caller_task_runner_->PostTask(FROM_HERE, std::move(disconnect_callback_));
- }
- }
- // Note that this class does not detect touch input and so is named accordingly.
- class LocalMouseInputMonitorWin : public LocalPointerInputMonitor {
- public:
- explicit LocalMouseInputMonitorWin(
- std::unique_ptr<LocalInputMonitorWin> local_input_monitor);
- ~LocalMouseInputMonitorWin() override;
- private:
- std::unique_ptr<LocalInputMonitorWin> local_input_monitor_;
- };
- LocalMouseInputMonitorWin::LocalMouseInputMonitorWin(
- std::unique_ptr<LocalInputMonitorWin> local_input_monitor)
- : local_input_monitor_(std::move(local_input_monitor)) {}
- LocalMouseInputMonitorWin::~LocalMouseInputMonitorWin() = default;
- } // namespace
- std::unique_ptr<LocalPointerInputMonitor> LocalPointerInputMonitor::Create(
- scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- LocalInputMonitor::PointerMoveCallback on_mouse_move,
- base::OnceClosure disconnect_callback) {
- auto raw_input_handler = std::make_unique<MouseRawInputHandlerWin>(
- caller_task_runner, ui_task_runner, std::move(on_mouse_move),
- std::move(disconnect_callback));
- return std::make_unique<LocalMouseInputMonitorWin>(
- LocalInputMonitorWin::Create(caller_task_runner, ui_task_runner,
- std::move(raw_input_handler)));
- }
- } // namespace remoting
|