Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(868)

Side by Side Diff: remoting/host/local_input_monitor_win.cc

Issue 13142002: Moved code implementing message-only windows to a dedicated class (Windows only). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/clipboard_win.cc ('k') | remoting/host/win/host_service.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
15 #include "remoting/host/client_session_control.h" 14 #include "remoting/host/client_session_control.h"
15 #include "remoting/host/win/message_window.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 base::WeakPtr<ClientSessionControl> client_session_control);
35 ~LocalInputMonitorWin(); 35 ~LocalInputMonitorWin();
36 36
37 private: 37 private:
38 // The actual implementation resides in LocalInputMonitorWin::Core class. 38 // The actual implementation resides in LocalInputMonitorWin::Core class.
39 class Core : public base::RefCountedThreadSafe<Core> { 39 class Core : public base::RefCountedThreadSafe<Core>,
40 public win::MessageWindow::Delegate {
40 public: 41 public:
41 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 42 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
42 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 43 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
43 base::WeakPtr<ClientSessionControl> client_session_control); 44 base::WeakPtr<ClientSessionControl> client_session_control);
44 45
45 void Start(); 46 void Start();
46 void Stop(); 47 void Stop();
47 48
48 private: 49 private:
49 friend class base::RefCountedThreadSafe<Core>; 50 friend class base::RefCountedThreadSafe<Core>;
50 virtual ~Core(); 51 virtual ~Core();
51 52
52 void StartOnUiThread(); 53 void StartOnUiThread();
53 void StopOnUiThread(); 54 void StopOnUiThread();
54 55
55 // Handles WM_CREATE messages.
56 LRESULT OnCreate(HWND hwnd);
57
58 // Handles WM_INPUT messages. 56 // Handles WM_INPUT messages.
59 LRESULT OnInput(HRAWINPUT input_handle); 57 LRESULT OnInput(HRAWINPUT input_handle);
60 58
61 // Window procedure invoked by the OS to process window messages. 59 // win::MessageWindow::Delegate interface.
62 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, 60 virtual bool HandleMessage(HWND hwnd,
63 WPARAM wparam, LPARAM lparam); 61 UINT message,
62 WPARAM wparam,
63 LPARAM lparam,
64 LRESULT* result) OVERRIDE;
64 65
65 // Task runner on which public methods of this class must be called. 66 // Task runner on which public methods of this class must be called.
66 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 67 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
67 68
68 // Task runner on which |window_| is created. 69 // Task runner on which |window_| is created.
69 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 70 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
70 71
71 // Atom representing the input window class. 72 // Used to receive raw input.
72 ATOM atom_; 73 scoped_ptr<win::MessageWindow> window_;
73
74 // Instance of the module containing the window procedure.
75 HINSTANCE instance_;
76
77 // Handle of the input window.
78 HWND window_;
79 74
80 // Points to the object receiving mouse event notifications. 75 // Points to the object receiving mouse event notifications.
81 base::WeakPtr<ClientSessionControl> client_session_control_; 76 base::WeakPtr<ClientSessionControl> client_session_control_;
82 77
83 DISALLOW_COPY_AND_ASSIGN(Core); 78 DISALLOW_COPY_AND_ASSIGN(Core);
84 }; 79 };
85 80
86 scoped_refptr<Core> core_; 81 scoped_refptr<Core> core_;
87 82
88 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorWin); 83 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorWin);
(...skipping 12 matching lines...) Expand all
101 LocalInputMonitorWin::~LocalInputMonitorWin() { 96 LocalInputMonitorWin::~LocalInputMonitorWin() {
102 core_->Stop(); 97 core_->Stop();
103 } 98 }
104 99
105 LocalInputMonitorWin::Core::Core( 100 LocalInputMonitorWin::Core::Core(
106 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 101 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
107 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 102 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
108 base::WeakPtr<ClientSessionControl> client_session_control) 103 base::WeakPtr<ClientSessionControl> client_session_control)
109 : caller_task_runner_(caller_task_runner), 104 : caller_task_runner_(caller_task_runner),
110 ui_task_runner_(ui_task_runner), 105 ui_task_runner_(ui_task_runner),
111 atom_(0),
112 instance_(NULL),
113 window_(NULL),
114 client_session_control_(client_session_control) { 106 client_session_control_(client_session_control) {
115 DCHECK(client_session_control_); 107 DCHECK(client_session_control_);
116 } 108 }
117 109
118 void LocalInputMonitorWin::Core::Start() { 110 void LocalInputMonitorWin::Core::Start() {
119 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 111 DCHECK(caller_task_runner_->BelongsToCurrentThread());
120 112
121 ui_task_runner_->PostTask(FROM_HERE, 113 ui_task_runner_->PostTask(FROM_HERE,
122 base::Bind(&Core::StartOnUiThread, this)); 114 base::Bind(&Core::StartOnUiThread, this));
123 } 115 }
124 116
125 void LocalInputMonitorWin::Core::Stop() { 117 void LocalInputMonitorWin::Core::Stop() {
126 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 118 DCHECK(caller_task_runner_->BelongsToCurrentThread());
127 119
128 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this)); 120 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
129 } 121 }
130 122
131 LocalInputMonitorWin::Core::~Core() { 123 LocalInputMonitorWin::Core::~Core() {
132 DCHECK(!atom_);
133 DCHECK(!instance_);
134 DCHECK(!window_); 124 DCHECK(!window_);
135 } 125 }
136 126
137 void LocalInputMonitorWin::Core::StartOnUiThread() { 127 void LocalInputMonitorWin::Core::StartOnUiThread() {
138 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 128 DCHECK(ui_task_runner_->BelongsToCurrentThread());
139 129
140 // Create a window for receiving raw input. 130 window_.reset(new win::MessageWindow());
141 string16 window_class_name = base::StringPrintf(kWindowClassFormat, this); 131 if (!window_->Create(this)) {
142 WNDCLASSEX window_class; 132 LOG_GETLASTERROR(ERROR) << "Failed to create the raw input window";
143 base::win::InitializeWindowClass( 133 window_.reset();
144 window_class_name.c_str(),
145 &base::win::WrappedWindowProc<WindowProc>,
146 0, 0, 0, NULL, NULL, NULL, NULL, NULL,
147 &window_class);
148 instance_ = window_class.hInstance;
149 atom_ = RegisterClassEx(&window_class);
150 if (atom_ == 0) {
151 LOG_GETLASTERROR(ERROR)
152 << "Failed to register the window class '" << window_class_name << "'";
153 return;
154 }
155 134
156 window_ = CreateWindow(MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 135 // If the local input cannot be monitored, the remote user can take over
157 instance_, this); 136 // the session. Disconnect the session now to prevent this.
158 if (window_ == NULL) { 137 caller_task_runner_->PostTask(
159 LOG_GETLASTERROR(ERROR) << "Failed to create the raw input window"; 138 FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession,
160 return; 139 client_session_control_));
161 } 140 }
162 } 141 }
163 142
164 void LocalInputMonitorWin::Core::StopOnUiThread() { 143 void LocalInputMonitorWin::Core::StopOnUiThread() {
165 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 144 DCHECK(ui_task_runner_->BelongsToCurrentThread());
166 145
167 if (window_ != NULL) { 146 // Stop receiving raw mouse input.
168 DestroyWindow(window_); 147 if (window_) {
169 window_ = NULL; 148 RAWINPUTDEVICE device = {0};
149 device.dwFlags = RIDEV_REMOVE;
150 device.usUsagePage = kGenericDesktopPage;
151 device.usUsage = kMouseUsage;
152 device.hwndTarget = window_->hwnd();
153
154 // The error is harmless, ignore it.
155 RegisterRawInputDevices(&device, 1, sizeof(device));
170 } 156 }
171 157
172 if (atom_ != 0) { 158 window_.reset();
173 UnregisterClass(MAKEINTATOM(atom_), instance_);
174 atom_ = 0;
175 instance_ = NULL;
176 }
177 }
178
179 LRESULT LocalInputMonitorWin::Core::OnCreate(HWND hwnd) {
180 DCHECK(ui_task_runner_->BelongsToCurrentThread());
181
182 // Register to receive raw mouse input.
183 RAWINPUTDEVICE device = {0};
184 device.dwFlags = RIDEV_INPUTSINK;
185 device.usUsagePage = kGenericDesktopPage;
186 device.usUsage = kMouseUsage;
187 device.hwndTarget = hwnd;
188 if (!RegisterRawInputDevices(&device, 1, sizeof(device))) {
189 LOG_GETLASTERROR(ERROR) << "RegisterRawInputDevices() failed";
190 return -1;
191 }
192
193 return 0;
194 } 159 }
195 160
196 LRESULT LocalInputMonitorWin::Core::OnInput(HRAWINPUT input_handle) { 161 LRESULT LocalInputMonitorWin::Core::OnInput(HRAWINPUT input_handle) {
197 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 162 DCHECK(ui_task_runner_->BelongsToCurrentThread());
198 163
199 // Get the size of the input record. 164 // Get the size of the input record.
200 UINT size = 0; 165 UINT size = 0;
201 UINT result = GetRawInputData(input_handle, 166 UINT result = GetRawInputData(input_handle,
202 RID_INPUT, 167 RID_INPUT,
203 NULL, 168 NULL,
(...skipping 29 matching lines...) Expand all
233 198
234 caller_task_runner_->PostTask( 199 caller_task_runner_->PostTask(
235 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved, 200 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved,
236 client_session_control_, 201 client_session_control_,
237 SkIPoint::Make(position.x, position.y))); 202 SkIPoint::Make(position.x, position.y)));
238 } 203 }
239 204
240 return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER)); 205 return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER));
241 } 206 }
242 207
243 // static 208 bool LocalInputMonitorWin::Core::HandleMessage(
244 LRESULT CALLBACK LocalInputMonitorWin::Core::WindowProc( 209 HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) {
245 HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
246 // Store |this| to the window's user data.
247 if (message == WM_CREATE) {
248 CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lparam);
249 SetLastError(ERROR_SUCCESS);
250 LONG_PTR result = SetWindowLongPtr(
251 hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(cs->lpCreateParams));
252 CHECK(result != 0 || GetLastError() == ERROR_SUCCESS);
253 }
254
255 Core* self = reinterpret_cast<Core*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
256 switch (message) { 210 switch (message) {
257 case WM_CREATE: 211 case WM_CREATE: {
258 return self->OnCreate(hwnd); 212 // Register to receive raw mouse input.
213 RAWINPUTDEVICE device = {0};
214 device.dwFlags = RIDEV_INPUTSINK;
215 device.usUsagePage = kGenericDesktopPage;
216 device.usUsage = kMouseUsage;
217 device.hwndTarget = hwnd;
218 if (RegisterRawInputDevices(&device, 1, sizeof(device))) {
219 *result = 0;
220 } else {
221 LOG_GETLASTERROR(ERROR) << "RegisterRawInputDevices() failed";
222 *result = -1;
223 }
224 return true;
225 }
259 226
260 case WM_INPUT: 227 case WM_INPUT:
261 return self->OnInput(reinterpret_cast<HRAWINPUT>(lparam)); 228 *result = OnInput(reinterpret_cast<HRAWINPUT>(lparam));
229 return true;
262 230
263 default: 231 default:
264 return DefWindowProc(hwnd, message, wparam, lparam); 232 return false;
265 } 233 }
266 } 234 }
267 235
268 } // namespace 236 } // namespace
269 237
270 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( 238 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create(
271 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 239 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
272 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, 240 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
273 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 241 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
274 base::WeakPtr<ClientSessionControl> client_session_control) { 242 base::WeakPtr<ClientSessionControl> client_session_control) {
275 return scoped_ptr<LocalInputMonitor>( 243 return scoped_ptr<LocalInputMonitor>(
276 new LocalInputMonitorWin(caller_task_runner, 244 new LocalInputMonitorWin(caller_task_runner,
277 ui_task_runner, 245 ui_task_runner,
278 client_session_control)); 246 client_session_control));
279 } 247 }
280 248
281 } // namespace remoting 249 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/clipboard_win.cc ('k') | remoting/host/win/host_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698