15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/local_input_monitor.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/single_thread_task_runner.h"
125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/non_thread_safe.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/win/message_window.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "remoting/host/client_session_control.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const wchar_t kWindowClassFormat[] = L"Chromoting_LocalInputMonitorWin_%p";
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// From the HID Usage Tables specification.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const USHORT kGenericDesktopPage = 1;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const USHORT kMouseUsage = 2;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LocalInputMonitorWin : public base::NonThreadSafe,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             public LocalInputMonitor {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LocalInputMonitorWin(
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::WeakPtr<ClientSessionControl> client_session_control);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LocalInputMonitorWin();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The actual implementation resides in LocalInputMonitorWin::Core class.
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  class Core : public base::RefCountedThreadSafe<Core> {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         base::WeakPtr<ClientSessionControl> client_session_control);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void Start();
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void Stop();
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    friend class base::RefCountedThreadSafe<Core>;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~Core();
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void StartOnUiThread();
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void StopOnUiThread();
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Handles WM_INPUT messages.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LRESULT OnInput(HRAWINPUT input_handle);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Handles messages received by |window_|.
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool HandleMessage(UINT message,
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       WPARAM wparam,
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       LPARAM lparam,
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       LRESULT* result);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Task runner on which public methods of this class must be called.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Task runner on which |window_| is created.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Used to receive raw input.
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<base::win::MessageWindow> window_;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Points to the object receiving mouse event notifications.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WeakPtr<ClientSessionControl> client_session_control_;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(Core);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Core> core_;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorWin);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LocalInputMonitorWin::LocalInputMonitorWin(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WeakPtr<ClientSessionControl> client_session_control)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : core_(new Core(caller_task_runner,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     ui_task_runner,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     client_session_control)) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  core_->Start();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LocalInputMonitorWin::~LocalInputMonitorWin() {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  core_->Stop();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LocalInputMonitorWin::Core::Core(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WeakPtr<ClientSessionControl> client_session_control)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : caller_task_runner_(caller_task_runner),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_task_runner_(ui_task_runner),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client_session_control_(client_session_control) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(client_session_control_);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalInputMonitorWin::Core::Start() {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(caller_task_runner_->BelongsToCurrentThread());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            base::Bind(&Core::StartOnUiThread, this));
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalInputMonitorWin::Core::Stop() {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(caller_task_runner_->BelongsToCurrentThread());
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LocalInputMonitorWin::Core::~Core() {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!window_);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalInputMonitorWin::Core::StartOnUiThread() {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(ui_task_runner_->BelongsToCurrentThread());
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  window_.reset(new base::win::MessageWindow());
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!window_->Create(base::Bind(&Core::HandleMessage,
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                  base::Unretained(this)))) {
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to create the raw input window";
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window_.reset();
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the local input cannot be monitored, the remote user can take over
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the session. Disconnect the session now to prevent this.
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    caller_task_runner_->PostTask(
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession,
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              client_session_control_));
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalInputMonitorWin::Core::StopOnUiThread() {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(ui_task_runner_->BelongsToCurrentThread());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stop receiving  raw mouse input.
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (window_) {
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RAWINPUTDEVICE device = {0};
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device.dwFlags = RIDEV_REMOVE;
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device.usUsagePage = kGenericDesktopPage;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device.usUsage = kMouseUsage;
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    device.hwndTarget = NULL;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The error is harmless, ignore it.
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RegisterRawInputDevices(&device, 1, sizeof(device));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_.reset();
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LRESULT LocalInputMonitorWin::Core::OnInput(HRAWINPUT input_handle) {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(ui_task_runner_->BelongsToCurrentThread());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the size of the input record.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UINT size = 0;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UINT result = GetRawInputData(input_handle,
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                RID_INPUT,
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                NULL,
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                &size,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                sizeof(RAWINPUTHEADER));
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result == -1) {
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "GetRawInputData() failed";
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Retrieve the input record itself.
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> buffer(new uint8[size]);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get());
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result = GetRawInputData(input_handle,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           RID_INPUT,
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           buffer.get(),
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           &size,
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           sizeof(RAWINPUTHEADER));
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result == -1) {
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "GetRawInputData() failed";
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the observer about mouse events generated locally. Remote (injected)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mouse events do not specify a device handle (based on observed behavior).
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input->header.dwType == RIM_TYPEMOUSE &&
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      input->header.hDevice != NULL) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    POINT position;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!GetCursorPos(&position)) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      position.x = 0;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      position.y = 0;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    caller_task_runner_->PostTask(
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved,
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              client_session_control_,
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              webrtc::DesktopVector(position.x, position.y)));
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool LocalInputMonitorWin::Core::HandleMessage(
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (message) {
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WM_CREATE: {
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Register to receive raw mouse input.
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      RAWINPUTDEVICE device = {0};
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      device.dwFlags = RIDEV_INPUTSINK;
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      device.usUsagePage = kGenericDesktopPage;
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      device.usUsage = kMouseUsage;
216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      device.hwndTarget = window_->hwnd();
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (RegisterRawInputDevices(&device, 1, sizeof(device))) {
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *result = 0;
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PLOG(ERROR) << "RegisterRawInputDevices() failed";
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *result = -1;
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return true;
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WM_INPUT:
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *result = OnInput(reinterpret_cast<HRAWINPUT>(lparam));
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return true;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create(
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WeakPtr<ClientSessionControl> client_session_control) {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<LocalInputMonitor>(
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new LocalInputMonitorWin(caller_task_runner,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               ui_task_runner,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               client_session_control));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
249