Chromium Code Reviews| Index: remoting/host/local_input_monitor_win.cc |
| diff --git a/remoting/host/local_input_monitor_win.cc b/remoting/host/local_input_monitor_win.cc |
| index 28deebc030ed561d2daebdb963c2a9e2782ec399..454dd759ad642bc14294da22147877409c92b576 100644 |
| --- a/remoting/host/local_input_monitor_win.cc |
| +++ b/remoting/host/local_input_monitor_win.cc |
| @@ -11,8 +11,8 @@ |
| #include "base/single_thread_task_runner.h" |
| #include "base/stringprintf.h" |
| #include "base/threading/non_thread_safe.h" |
| -#include "base/win/wrapped_window_proc.h" |
| #include "remoting/host/client_session_control.h" |
| +#include "remoting/host/win/message_window.h" |
| #include "third_party/skia/include/core/SkPoint.h" |
| namespace remoting { |
| @@ -36,7 +36,8 @@ class LocalInputMonitorWin : public base::NonThreadSafe, |
| private: |
| // The actual implementation resides in LocalInputMonitorWin::Core class. |
| - class Core : public base::RefCountedThreadSafe<Core> { |
| + class Core : public base::RefCountedThreadSafe<Core>, |
| + public win::MessageWindow::Delegate { |
| public: |
| Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| @@ -52,15 +53,15 @@ class LocalInputMonitorWin : public base::NonThreadSafe, |
| void StartOnUiThread(); |
| void StopOnUiThread(); |
| - // Handles WM_CREATE messages. |
| - LRESULT OnCreate(HWND hwnd); |
| + // Enables |window_| to receive the raw input. |
| + void EnableRawInput(); |
| // Handles WM_INPUT messages. |
| LRESULT OnInput(HRAWINPUT input_handle); |
| - // Window procedure invoked by the OS to process window messages. |
| - static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, |
| - WPARAM wparam, LPARAM lparam); |
| + // win::MessageWindow::Delegate interface. |
| + virtual bool HandleMessage(UINT message, WPARAM wparam, LPARAM lparam, |
| + LRESULT* result) OVERRIDE; |
| // Task runner on which public methods of this class must be called. |
| scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
| @@ -68,14 +69,8 @@ class LocalInputMonitorWin : public base::NonThreadSafe, |
| // Task runner on which |window_| is created. |
| scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
| - // Atom representing the input window class. |
| - ATOM atom_; |
| - |
| - // Instance of the module containing the window procedure. |
| - HINSTANCE instance_; |
| - |
| - // Handle of the input window. |
| - HWND window_; |
| + // Used to receive raw input. |
| + scoped_ptr<win::MessageWindow> window_; |
| // Points to the object receiving mouse event notifications. |
| base::WeakPtr<ClientSessionControl> client_session_control_; |
| @@ -108,9 +103,6 @@ LocalInputMonitorWin::Core::Core( |
| base::WeakPtr<ClientSessionControl> client_session_control) |
| : caller_task_runner_(caller_task_runner), |
| ui_task_runner_(ui_task_runner), |
| - atom_(0), |
| - instance_(NULL), |
| - window_(NULL), |
| client_session_control_(client_session_control) { |
| DCHECK(client_session_control_); |
| } |
| @@ -129,68 +121,63 @@ void LocalInputMonitorWin::Core::Stop() { |
| } |
| LocalInputMonitorWin::Core::~Core() { |
| - DCHECK(!atom_); |
| - DCHECK(!instance_); |
| DCHECK(!window_); |
| } |
| void LocalInputMonitorWin::Core::StartOnUiThread() { |
| DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| - // Create a window for receiving raw input. |
| - string16 window_class_name = base::StringPrintf(kWindowClassFormat, this); |
| - WNDCLASSEX window_class; |
| - base::win::InitializeWindowClass( |
| - window_class_name.c_str(), |
| - &base::win::WrappedWindowProc<WindowProc>, |
| - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, |
| - &window_class); |
| - instance_ = window_class.hInstance; |
| - atom_ = RegisterClassEx(&window_class); |
| - if (atom_ == 0) { |
| - LOG_GETLASTERROR(ERROR) |
| - << "Failed to register the window class '" << window_class_name << "'"; |
| - return; |
| - } |
| - |
| - window_ = CreateWindow(MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, |
| - instance_, this); |
| - if (window_ == NULL) { |
| + window_.reset(new win::MessageWindow()); |
| + if (!window_->Create(this)) { |
| LOG_GETLASTERROR(ERROR) << "Failed to create the raw input window"; |
| - return; |
| + |
| + // If the local input cannot be monitored, the remote user can take over |
| + // the session. Disconnect the session now to prevent this. |
| + caller_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession, |
| + client_session_control_)); |
| } |
| } |
| void LocalInputMonitorWin::Core::StopOnUiThread() { |
| DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| - if (window_ != NULL) { |
| - DestroyWindow(window_); |
| - window_ = NULL; |
| - } |
| + // Stop receiving raw mouse input. |
| + if (window_ && window_->hwnd()) { |
| + RAWINPUTDEVICE device = {0}; |
| + device.dwFlags = RIDEV_REMOVE; |
| + device.usUsagePage = kGenericDesktopPage; |
| + device.usUsage = kMouseUsage; |
| + device.hwndTarget = window_->hwnd(); |
| - if (atom_ != 0) { |
| - UnregisterClass(MAKEINTATOM(atom_), instance_); |
| - atom_ = 0; |
| - instance_ = NULL; |
| + // The error is harmless, ignore it. |
| + RegisterRawInputDevices(&device, 1, sizeof(device)); |
| } |
| + |
| + window_.reset(); |
| } |
| -LRESULT LocalInputMonitorWin::Core::OnCreate(HWND hwnd) { |
| +void LocalInputMonitorWin::Core::EnableRawInput() { |
| DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| - // Register to receive raw mouse input. |
| - RAWINPUTDEVICE device = {0}; |
| - device.dwFlags = RIDEV_INPUTSINK; |
| - device.usUsagePage = kGenericDesktopPage; |
| - device.usUsage = kMouseUsage; |
| - device.hwndTarget = hwnd; |
| - if (!RegisterRawInputDevices(&device, 1, sizeof(device))) { |
| + if (window_ && window_->hwnd()) { |
| + // Register to receive raw mouse input. |
| + RAWINPUTDEVICE device = {0}; |
| + device.dwFlags = RIDEV_INPUTSINK; |
| + device.usUsagePage = kGenericDesktopPage; |
| + device.usUsage = kMouseUsage; |
| + device.hwndTarget = window_->hwnd(); |
| + if (RegisterRawInputDevices(&device, 1, sizeof(device))) |
| + return; |
| + |
| LOG_GETLASTERROR(ERROR) << "RegisterRawInputDevices() failed"; |
| - return -1; |
| } |
| - return 0; |
| + // If the local input cannot be monitored, the remote user can take over |
| + // the session. Disconnect the session now to prevent this. |
| + caller_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession, |
| + client_session_control_)); |
| } |
| LRESULT LocalInputMonitorWin::Core::OnInput(HRAWINPUT input_handle) { |
| @@ -240,28 +227,23 @@ LRESULT LocalInputMonitorWin::Core::OnInput(HRAWINPUT input_handle) { |
| return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER)); |
| } |
| -// static |
| -LRESULT CALLBACK LocalInputMonitorWin::Core::WindowProc( |
| - HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { |
| - // Store |this| to the window's user data. |
| - if (message == WM_CREATE) { |
| - CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lparam); |
| - SetLastError(ERROR_SUCCESS); |
| - LONG_PTR result = SetWindowLongPtr( |
| - hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(cs->lpCreateParams)); |
| - CHECK(result != 0 || GetLastError() == ERROR_SUCCESS); |
| - } |
| - |
| - Core* self = reinterpret_cast<Core*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); |
| +bool LocalInputMonitorWin::Core::HandleMessage( |
| + UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) { |
| switch (message) { |
| case WM_CREATE: |
| - return self->OnCreate(hwnd); |
| + // |window_->hwnd()| is not available yet. Enable raw mouse input once |
|
dcaiafa
2013/03/28 23:25:35
Refer to my comment on MessageWindow. I think hwnd
alexeypa (please no reviews)
2013/03/29 16:57:01
Done.
|
| + // the window is fully created. |
| + ui_task_runner_->PostTask(FROM_HERE, |
| + base::Bind(&Core::EnableRawInput, this)); |
| + *result = 0; |
| + return true; |
| case WM_INPUT: |
| - return self->OnInput(reinterpret_cast<HRAWINPUT>(lparam)); |
| + *result = OnInput(reinterpret_cast<HRAWINPUT>(lparam)); |
| + return true; |
| default: |
| - return DefWindowProc(hwnd, message, wparam, lparam); |
| + return false; |
| } |
| } |