1 // Copyright 2019 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.
4 
5 #include "ui/views/win/scoped_enable_unadjusted_mouse_events_win.h"
6 
7 #include "ui/views/win/hwnd_message_handler.h"
8 
9 namespace views {
10 namespace {
11 
12 // From the HID Usage Tables specification.
13 constexpr USHORT kGenericDesktopPage = 1;
14 constexpr USHORT kMouseUsage = 2;
15 
GetRawInputDevices(HWND hwnd,DWORD flags)16 std::unique_ptr<RAWINPUTDEVICE> GetRawInputDevices(HWND hwnd, DWORD flags) {
17   std::unique_ptr<RAWINPUTDEVICE> device = std::make_unique<RAWINPUTDEVICE>();
18   device->dwFlags = flags;
19   device->usUsagePage = kGenericDesktopPage;
20   device->usUsage = kMouseUsage;
21   device->hwndTarget = hwnd;
22   return device;
23 }
24 
25 }  // namespace
26 
ScopedEnableUnadjustedMouseEventsWin(HWNDMessageHandler * owner)27 ScopedEnableUnadjustedMouseEventsWin::ScopedEnableUnadjustedMouseEventsWin(
28     HWNDMessageHandler* owner)
29     : owner_(owner) {}
30 
~ScopedEnableUnadjustedMouseEventsWin()31 ScopedEnableUnadjustedMouseEventsWin::~ScopedEnableUnadjustedMouseEventsWin() {
32   // Stop receiving raw input.
33   std::unique_ptr<RAWINPUTDEVICE> device(
34       GetRawInputDevices(nullptr, RIDEV_REMOVE));
35   if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device)))
36     PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_REMOVE ";
37 
38   DCHECK(owner_->using_wm_input());
39   owner_->set_using_wm_input(false);
40 }
41 
42 // static
43 std::unique_ptr<ScopedEnableUnadjustedMouseEventsWin>
StartMonitor(HWNDMessageHandler * owner)44 ScopedEnableUnadjustedMouseEventsWin::StartMonitor(HWNDMessageHandler* owner) {
45   std::unique_ptr<RAWINPUTDEVICE> device(
46       GetRawInputDevices(owner->hwnd(), RIDEV_INPUTSINK));
47   if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) {
48     PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK ";
49     return nullptr;
50   }
51   DCHECK(!owner->using_wm_input());
52   owner->set_using_wm_input(true);
53   return std::make_unique<ScopedEnableUnadjustedMouseEventsWin>(owner);
54 }
55 
56 }  // namespace views
57