| 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/local_input_monitor.h" | 5 #include "remoting/host/local_input_monitor.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/threading/non_thread_safe.h" | 13 #include "base/threading/non_thread_safe.h" |
| 14 #include "base/win/wrapped_window_proc.h" | 14 #include "base/win/wrapped_window_proc.h" |
| 15 #include "remoting/host/mouse_move_observer.h" | 15 #include "remoting/host/client_session_control.h" |
| 16 #include "third_party/skia/include/core/SkPoint.h" | 16 #include "third_party/skia/include/core/SkPoint.h" |
| 17 | 17 |
| 18 namespace remoting { | 18 namespace remoting { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 const wchar_t kWindowClassFormat[] = L"Chromoting_LocalInputMonitorWin_%p"; | 22 const wchar_t kWindowClassFormat[] = L"Chromoting_LocalInputMonitorWin_%p"; |
| 23 | 23 |
| 24 // From the HID Usage Tables specification. | 24 // From the HID Usage Tables specification. |
| 25 const USHORT kGenericDesktopPage = 1; | 25 const USHORT kGenericDesktopPage = 1; |
| 26 const USHORT kMouseUsage = 2; | 26 const USHORT kMouseUsage = 2; |
| 27 | 27 |
| 28 class LocalInputMonitorWin : public base::NonThreadSafe, | 28 class LocalInputMonitorWin : public base::NonThreadSafe, |
| 29 public LocalInputMonitor { | 29 public LocalInputMonitor { |
| 30 public: | 30 public: |
| 31 LocalInputMonitorWin( | 31 LocalInputMonitorWin( |
| 32 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 32 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 33 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); | 33 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 34 base::WeakPtr<ClientSessionControl> client_session_control); |
| 34 ~LocalInputMonitorWin(); | 35 ~LocalInputMonitorWin(); |
| 35 | 36 |
| 36 virtual void Start(MouseMoveObserver* mouse_move_observer, | |
| 37 const base::Closure& disconnect_callback) OVERRIDE; | |
| 38 virtual void Stop() OVERRIDE; | |
| 39 | |
| 40 private: | 37 private: |
| 41 // The actual implementation resides in LocalInputMonitorWin::Core class. | 38 // The actual implementation resides in LocalInputMonitorWin::Core class. |
| 42 class Core : public base::RefCountedThreadSafe<Core> { | 39 class Core : public base::RefCountedThreadSafe<Core> { |
| 43 public: | 40 public: |
| 44 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 41 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 45 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); | 42 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 43 base::WeakPtr<ClientSessionControl> client_session_control); |
| 46 | 44 |
| 47 void Start(MouseMoveObserver* mouse_move_observer); | 45 void Start(); |
| 48 void Stop(); | 46 void Stop(); |
| 49 | 47 |
| 50 private: | 48 private: |
| 51 friend class base::RefCountedThreadSafe<Core>; | 49 friend class base::RefCountedThreadSafe<Core>; |
| 52 virtual ~Core(); | 50 virtual ~Core(); |
| 53 | 51 |
| 54 void StartOnUiThread(); | 52 void StartOnUiThread(); |
| 55 void StopOnUiThread(); | 53 void StopOnUiThread(); |
| 56 | 54 |
| 57 // Posts OnLocalMouseMoved() notification to |mouse_move_observer_| on | |
| 58 // the |caller_task_runner_| thread. | |
| 59 void OnLocalMouseMoved(const SkIPoint& position); | |
| 60 | |
| 61 // Handles WM_CREATE messages. | 55 // Handles WM_CREATE messages. |
| 62 LRESULT OnCreate(HWND hwnd); | 56 LRESULT OnCreate(HWND hwnd); |
| 63 | 57 |
| 64 // Handles WM_INPUT messages. | 58 // Handles WM_INPUT messages. |
| 65 LRESULT OnInput(HRAWINPUT input_handle); | 59 LRESULT OnInput(HRAWINPUT input_handle); |
| 66 | 60 |
| 67 // Window procedure invoked by the OS to process window messages. | 61 // Window procedure invoked by the OS to process window messages. |
| 68 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, | 62 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, |
| 69 WPARAM wparam, LPARAM lparam); | 63 WPARAM wparam, LPARAM lparam); |
| 70 | 64 |
| 71 // Task runner on which public methods of this class must be called. | 65 // Task runner on which public methods of this class must be called. |
| 72 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; | 66 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
| 73 | 67 |
| 74 // Task runner on which |window_| is created. | 68 // Task runner on which |window_| is created. |
| 75 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 69 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
| 76 | 70 |
| 77 // Atom representing the input window class. | 71 // Atom representing the input window class. |
| 78 ATOM atom_; | 72 ATOM atom_; |
| 79 | 73 |
| 80 // Instance of the module containing the window procedure. | 74 // Instance of the module containing the window procedure. |
| 81 HINSTANCE instance_; | 75 HINSTANCE instance_; |
| 82 | 76 |
| 83 // Handle of the input window. | 77 // Handle of the input window. |
| 84 HWND window_; | 78 HWND window_; |
| 85 | 79 |
| 86 // Observer to dispatch mouse event notifications to. | 80 // Points to the object receiving mouse event notifications. |
| 87 MouseMoveObserver* mouse_move_observer_; | 81 base::WeakPtr<ClientSessionControl> client_session_control_; |
| 88 | 82 |
| 89 DISALLOW_COPY_AND_ASSIGN(Core); | 83 DISALLOW_COPY_AND_ASSIGN(Core); |
| 90 }; | 84 }; |
| 91 | 85 |
| 92 scoped_refptr<Core> core_; | 86 scoped_refptr<Core> core_; |
| 93 | 87 |
| 94 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorWin); | 88 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorWin); |
| 95 }; | 89 }; |
| 96 | 90 |
| 97 LocalInputMonitorWin::LocalInputMonitorWin( | 91 LocalInputMonitorWin::LocalInputMonitorWin( |
| 98 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 92 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 99 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 93 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 100 : core_(new Core(caller_task_runner, ui_task_runner)) { | 94 base::WeakPtr<ClientSessionControl> client_session_control) |
| 95 : core_(new Core(caller_task_runner, |
| 96 ui_task_runner, |
| 97 client_session_control)) { |
| 98 core_->Start(); |
| 101 } | 99 } |
| 102 | 100 |
| 103 LocalInputMonitorWin::~LocalInputMonitorWin() { | 101 LocalInputMonitorWin::~LocalInputMonitorWin() { |
| 104 } | |
| 105 | |
| 106 void LocalInputMonitorWin::Start(MouseMoveObserver* mouse_move_observer, | |
| 107 const base::Closure& disconnect_callback) { | |
| 108 core_->Start(mouse_move_observer); | |
| 109 } | |
| 110 | |
| 111 void LocalInputMonitorWin::Stop() { | |
| 112 core_->Stop(); | 102 core_->Stop(); |
| 113 } | 103 } |
| 114 | 104 |
| 115 LocalInputMonitorWin::Core::Core( | 105 LocalInputMonitorWin::Core::Core( |
| 116 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 106 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 117 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 107 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 108 base::WeakPtr<ClientSessionControl> client_session_control) |
| 118 : caller_task_runner_(caller_task_runner), | 109 : caller_task_runner_(caller_task_runner), |
| 119 ui_task_runner_(ui_task_runner), | 110 ui_task_runner_(ui_task_runner), |
| 120 atom_(0), | 111 atom_(0), |
| 121 instance_(NULL), | 112 instance_(NULL), |
| 122 window_(NULL), | 113 window_(NULL), |
| 123 mouse_move_observer_(NULL) { | 114 client_session_control_(client_session_control) { |
| 115 DCHECK(client_session_control_); |
| 124 } | 116 } |
| 125 | 117 |
| 126 void LocalInputMonitorWin::Core::Start(MouseMoveObserver* mouse_move_observer) { | 118 void LocalInputMonitorWin::Core::Start() { |
| 127 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 119 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 128 DCHECK(!mouse_move_observer_); | |
| 129 DCHECK(mouse_move_observer); | |
| 130 | 120 |
| 131 mouse_move_observer_ = mouse_move_observer; | |
| 132 ui_task_runner_->PostTask(FROM_HERE, | 121 ui_task_runner_->PostTask(FROM_HERE, |
| 133 base::Bind(&Core::StartOnUiThread, this)); | 122 base::Bind(&Core::StartOnUiThread, this)); |
| 134 } | 123 } |
| 135 | 124 |
| 136 void LocalInputMonitorWin::Core::Stop() { | 125 void LocalInputMonitorWin::Core::Stop() { |
| 137 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 126 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 138 | 127 |
| 139 mouse_move_observer_ = NULL; | |
| 140 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this)); | 128 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this)); |
| 141 } | 129 } |
| 142 | 130 |
| 143 LocalInputMonitorWin::Core::~Core() { | 131 LocalInputMonitorWin::Core::~Core() { |
| 144 DCHECK(!atom_); | 132 DCHECK(!atom_); |
| 145 DCHECK(!instance_); | 133 DCHECK(!instance_); |
| 146 DCHECK(!window_); | 134 DCHECK(!window_); |
| 147 DCHECK(!mouse_move_observer_); | |
| 148 } | 135 } |
| 149 | 136 |
| 150 void LocalInputMonitorWin::Core::StartOnUiThread() { | 137 void LocalInputMonitorWin::Core::StartOnUiThread() { |
| 151 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 138 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 152 | 139 |
| 153 // Create a window for receiving raw input. | 140 // Create a window for receiving raw input. |
| 154 string16 window_class_name = base::StringPrintf(kWindowClassFormat, this); | 141 string16 window_class_name = base::StringPrintf(kWindowClassFormat, this); |
| 155 WNDCLASSEX window_class; | 142 WNDCLASSEX window_class; |
| 156 base::win::InitializeWindowClass( | 143 base::win::InitializeWindowClass( |
| 157 window_class_name.c_str(), | 144 window_class_name.c_str(), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 182 window_ = NULL; | 169 window_ = NULL; |
| 183 } | 170 } |
| 184 | 171 |
| 185 if (atom_ != 0) { | 172 if (atom_ != 0) { |
| 186 UnregisterClass(MAKEINTATOM(atom_), instance_); | 173 UnregisterClass(MAKEINTATOM(atom_), instance_); |
| 187 atom_ = 0; | 174 atom_ = 0; |
| 188 instance_ = NULL; | 175 instance_ = NULL; |
| 189 } | 176 } |
| 190 } | 177 } |
| 191 | 178 |
| 192 void LocalInputMonitorWin::Core::OnLocalMouseMoved(const SkIPoint& position) { | |
| 193 if (!caller_task_runner_->BelongsToCurrentThread()) { | |
| 194 caller_task_runner_->PostTask( | |
| 195 FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position)); | |
| 196 return; | |
| 197 } | |
| 198 | |
| 199 if (mouse_move_observer_) | |
| 200 mouse_move_observer_->OnLocalMouseMoved(position); | |
| 201 } | |
| 202 | |
| 203 LRESULT LocalInputMonitorWin::Core::OnCreate(HWND hwnd) { | 179 LRESULT LocalInputMonitorWin::Core::OnCreate(HWND hwnd) { |
| 204 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 180 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 205 | 181 |
| 206 // Register to receive raw mouse input. | 182 // Register to receive raw mouse input. |
| 207 RAWINPUTDEVICE device = {0}; | 183 RAWINPUTDEVICE device = {0}; |
| 208 device.dwFlags = RIDEV_INPUTSINK; | 184 device.dwFlags = RIDEV_INPUTSINK; |
| 209 device.usUsagePage = kGenericDesktopPage; | 185 device.usUsagePage = kGenericDesktopPage; |
| 210 device.usUsage = kMouseUsage; | 186 device.usUsage = kMouseUsage; |
| 211 device.hwndTarget = hwnd; | 187 device.hwndTarget = hwnd; |
| 212 if (!RegisterRawInputDevices(&device, 1, sizeof(device))) { | 188 if (!RegisterRawInputDevices(&device, 1, sizeof(device))) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 // Notify the observer about mouse events generated locally. Remote (injected) | 224 // Notify the observer about mouse events generated locally. Remote (injected) |
| 249 // mouse events do not specify a device handle (based on observed behavior). | 225 // mouse events do not specify a device handle (based on observed behavior). |
| 250 if (input->header.dwType == RIM_TYPEMOUSE && | 226 if (input->header.dwType == RIM_TYPEMOUSE && |
| 251 input->header.hDevice != NULL) { | 227 input->header.hDevice != NULL) { |
| 252 POINT position; | 228 POINT position; |
| 253 if (!GetCursorPos(&position)) { | 229 if (!GetCursorPos(&position)) { |
| 254 position.x = 0; | 230 position.x = 0; |
| 255 position.y = 0; | 231 position.y = 0; |
| 256 } | 232 } |
| 257 | 233 |
| 258 OnLocalMouseMoved(SkIPoint::Make(position.x, position.y)); | 234 caller_task_runner_->PostTask( |
| 235 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved, |
| 236 client_session_control_, |
| 237 SkIPoint::Make(position.x, position.y))); |
| 259 } | 238 } |
| 260 | 239 |
| 261 return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER)); | 240 return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER)); |
| 262 } | 241 } |
| 263 | 242 |
| 264 // static | 243 // static |
| 265 LRESULT CALLBACK LocalInputMonitorWin::Core::WindowProc( | 244 LRESULT CALLBACK LocalInputMonitorWin::Core::WindowProc( |
| 266 HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { | 245 HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { |
| 267 // Store |this| to the window's user data. | 246 // Store |this| to the window's user data. |
| 268 if (message == WM_CREATE) { | 247 if (message == WM_CREATE) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 284 default: | 263 default: |
| 285 return DefWindowProc(hwnd, message, wparam, lparam); | 264 return DefWindowProc(hwnd, message, wparam, lparam); |
| 286 } | 265 } |
| 287 } | 266 } |
| 288 | 267 |
| 289 } // namespace | 268 } // namespace |
| 290 | 269 |
| 291 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( | 270 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( |
| 292 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 271 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 293 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 272 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
| 294 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 273 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 274 base::WeakPtr<ClientSessionControl> client_session_control) { |
| 295 return scoped_ptr<LocalInputMonitor>( | 275 return scoped_ptr<LocalInputMonitor>( |
| 296 new LocalInputMonitorWin(caller_task_runner, ui_task_runner)); | 276 new LocalInputMonitorWin(caller_task_runner, |
| 277 ui_task_runner, |
| 278 client_session_control)); |
| 297 } | 279 } |
| 298 | 280 |
| 299 } // namespace remoting | 281 } // namespace remoting |
| OLD | NEW |