diff options
author | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-12 08:54:56 +0000 |
---|---|---|
committer | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-12 08:54:56 +0000 |
commit | b691a100e6ff4aec4880a6957d6a79921ac53eda (patch) | |
tree | 01dc0d75c38b0bc038397b635cd9f49a02ec063f /remoting | |
parent | 5eb431e2dfe9d55eaff2acc7a3ea64f403dec669 (diff) | |
download | chromium_src-b691a100e6ff4aec4880a6957d6a79921ac53eda.zip chromium_src-b691a100e6ff4aec4880a6957d6a79921ac53eda.tar.gz chromium_src-b691a100e6ff4aec4880a6957d6a79921ac53eda.tar.bz2 |
Implemented floor control for Windows. This also fixes a bug in the event executor that was causing pointer events to be off by 1px.
BUG=96649
TEST=Manual
Review URL: http://codereview.chromium.org/8114023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105043 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/event_executor_win.cc | 6 | ||||
-rwxr-xr-x | remoting/host/local_input_monitor_thread_win.cc | 114 | ||||
-rwxr-xr-x | remoting/host/local_input_monitor_thread_win.h | 46 | ||||
-rw-r--r-- | remoting/host/local_input_monitor_win.cc | 25 | ||||
-rw-r--r-- | remoting/remoting.gyp | 4 |
5 files changed, 188 insertions, 7 deletions
diff --git a/remoting/host/event_executor_win.cc b/remoting/host/event_executor_win.cc index ebedf25..7e3d801 100644 --- a/remoting/host/event_executor_win.cc +++ b/remoting/host/event_executor_win.cc @@ -110,9 +110,9 @@ void EventExecutorWin::HandleMouse(const MouseEvent& event) { input.type = INPUT_MOUSE; input.mi.time = 0; SkISize screen_size = capturer_->size_most_recent(); - if ((screen_size.width() > 0) && (screen_size.height() > 0)) { - input.mi.dx = static_cast<int>((x * 65535) / screen_size.width()); - input.mi.dy = static_cast<int>((y * 65535) / screen_size.height()); + if ((screen_size.width() > 1) && (screen_size.height() > 1)) { + input.mi.dx = static_cast<int>((x * 65535) / (screen_size.width() - 1)); + input.mi.dy = static_cast<int>((y * 65535) / (screen_size.height() - 1)); input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; SendInput(1, &input, sizeof(INPUT)); } diff --git a/remoting/host/local_input_monitor_thread_win.cc b/remoting/host/local_input_monitor_thread_win.cc new file mode 100755 index 0000000..abd0ae6 --- /dev/null +++ b/remoting/host/local_input_monitor_thread_win.cc @@ -0,0 +1,114 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/local_input_monitor_thread_win.h" + +#include "base/lazy_instance.h" +#include "base/logging.h" + +#include "base/synchronization/waitable_event.h" + +using namespace remoting; + +namespace { +LocalInputMonitorThread* g_local_input_monitor_thread = NULL; +base::LazyInstance<base::Lock> g_thread_lock(base::LINKER_INITIALIZED); +} // namespace + + +LocalInputMonitorThread::LocalInputMonitorThread() + : base::SimpleThread("LocalInputMonitor") { +} + +LocalInputMonitorThread::~LocalInputMonitorThread() { + DCHECK(hosts_.empty()); +} + +void LocalInputMonitorThread::AddHost(ChromotingHost* host) { + base::AutoLock lock(hosts_lock_); + hosts_.insert(host); +} + +bool LocalInputMonitorThread::RemoveHost(ChromotingHost* host) { + base::AutoLock lock(hosts_lock_); + hosts_.erase(host); + return hosts_.empty(); +} + +void LocalInputMonitorThread::Stop() { + CHECK(PostThreadMessage(tid(), WM_QUIT, 0, 0)); + Join(); +} + +void LocalInputMonitorThread::Run() { + extern HMODULE g_hModule; + HHOOK win_event_hook = SetWindowsHookEx(WH_MOUSE_LL, HandleLowLevelMouseEvent, + g_hModule, 0); + if (!win_event_hook) { + DWORD err = GetLastError(); + LOG(ERROR) << "SetWindowHookEx failed: " << err; + return; + } + + MSG msg; + BOOL result; + while ((result = GetMessage(&msg, NULL, 0, 0)) != 0) { + if (result == -1) { + DWORD err = GetLastError(); + LOG(ERROR) << "GetMessage failed: " << err; + break; + } else { + DispatchMessage(&msg); + } + } + + if (win_event_hook) { + CHECK(UnhookWindowsHookEx(win_event_hook)); + } +} + +void LocalInputMonitorThread::LocalMouseMoved(const SkIPoint& mouse_position) { + base::AutoLock lock(hosts_lock_); + for (ChromotingHosts::const_iterator i = hosts_.begin(); + i != hosts_.end(); ++i) { + (*i)->LocalMouseMoved(mouse_position); + } +} + +LRESULT WINAPI LocalInputMonitorThread::HandleLowLevelMouseEvent( + int code, WPARAM event_type, LPARAM event_data) { + if (code == HC_ACTION) { + if (event_type == WM_MOUSEMOVE) { + PMSLLHOOKSTRUCT data = reinterpret_cast<PMSLLHOOKSTRUCT>(event_data); + if ((data->flags & LLMHF_INJECTED) == 0) { + SkIPoint mouse_position = SkIPoint::Make(data->pt.x, data->pt.y); + // |g_local_input_monitor_thread| cannot be NULL because this function + // is called from within the GetMessage call running on that thread. + DCHECK(g_local_input_monitor_thread); + g_local_input_monitor_thread->LocalMouseMoved(mouse_position); + } + } + } + return CallNextHookEx(NULL, code, event_type, event_data); +} + + +void LocalInputMonitorThread::AddHostToInputMonitor(ChromotingHost* host) { + base::AutoLock lock(g_thread_lock.Get()); + if (!g_local_input_monitor_thread) { + g_local_input_monitor_thread = new LocalInputMonitorThread; + g_local_input_monitor_thread->Start(); + } + g_local_input_monitor_thread->AddHost(host); +} + +void LocalInputMonitorThread::RemoveHostFromInputMonitor(ChromotingHost* host) { + DCHECK(g_local_input_monitor_thread); + base::AutoLock lock(g_thread_lock.Get()); + if (g_local_input_monitor_thread->RemoveHost(host)) { + g_local_input_monitor_thread->Stop(); + delete g_local_input_monitor_thread; + g_local_input_monitor_thread = NULL; + } +} diff --git a/remoting/host/local_input_monitor_thread_win.h b/remoting/host/local_input_monitor_thread_win.h new file mode 100755 index 0000000..0080628 --- /dev/null +++ b/remoting/host/local_input_monitor_thread_win.h @@ -0,0 +1,46 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef LOCAL_INPUT_MONITOR_THREAD_WIN_H_ +#define LOCAL_INPUT_MONITOR_THREAD_WIN_H_ + +#include <set> + +#include "base/compiler_specific.h" +#include "base/synchronization/lock.h" +#include "base/threading/simple_thread.h" +#include "remoting/host/chromoting_host.h" + +namespace remoting { + +class LocalInputMonitorThread : public base::SimpleThread { + public: + static void AddHostToInputMonitor(ChromotingHost* host); + static void RemoveHostFromInputMonitor(ChromotingHost* host); + + private: + LocalInputMonitorThread(); + virtual ~LocalInputMonitorThread(); + + void AddHost(ChromotingHost* host); + bool RemoveHost(ChromotingHost* host); + + void Stop(); + virtual void Run() OVERRIDE; // Overridden from SimpleThread. + + void LocalMouseMoved(const SkIPoint& mouse_position); + static LRESULT WINAPI HandleLowLevelMouseEvent(int code, + WPARAM event_type, + LPARAM event_data); + + base::Lock hosts_lock_; + typedef std::set<ChromotingHost*> ChromotingHosts; + ChromotingHosts hosts_; + + DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorThread); +}; + +} // namespace remoting + +#endif diff --git a/remoting/host/local_input_monitor_win.cc b/remoting/host/local_input_monitor_win.cc index 6d06bc09..d728a50 100644 --- a/remoting/host/local_input_monitor_win.cc +++ b/remoting/host/local_input_monitor_win.cc @@ -6,27 +6,46 @@ #include "base/compiler_specific.h" #include "base/logging.h" +#include "remoting/host/chromoting_host.h" +#include "remoting/host/local_input_monitor_thread_win.h" namespace { class LocalInputMonitorWin : public remoting::LocalInputMonitor { public: - LocalInputMonitorWin() {} + LocalInputMonitorWin(); + ~LocalInputMonitorWin(); + virtual void Start(remoting::ChromotingHost* host) OVERRIDE; virtual void Stop() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorWin); + + remoting::ChromotingHost* chromoting_host_; }; } // namespace + +LocalInputMonitorWin::LocalInputMonitorWin() : chromoting_host_(NULL) { +} + +LocalInputMonitorWin::~LocalInputMonitorWin() { + DCHECK(chromoting_host_ == NULL); +} + void LocalInputMonitorWin::Start(remoting::ChromotingHost* host) { - NOTIMPLEMENTED(); + DCHECK(chromoting_host_ == NULL); + chromoting_host_ = host; + remoting::LocalInputMonitorThread::AddHostToInputMonitor(chromoting_host_); } void LocalInputMonitorWin::Stop() { - NOTIMPLEMENTED(); + DCHECK(chromoting_host_ != NULL); + remoting::LocalInputMonitorThread::RemoveHostFromInputMonitor( + chromoting_host_); + chromoting_host_ = NULL; } remoting::LocalInputMonitor* remoting::LocalInputMonitor::Create() { diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index a71932c..3f14491 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -459,8 +459,10 @@ 'host/local_input_monitor.h', 'host/local_input_monitor_linux.cc', 'host/local_input_monitor_mac.mm', - 'host/local_input_monitor_thread_linux.h', 'host/local_input_monitor_thread_linux.cc', + 'host/local_input_monitor_thread_linux.h', + 'host/local_input_monitor_thread_win.cc', + 'host/local_input_monitor_thread_win.h', 'host/local_input_monitor_win.cc', 'host/register_support_host_request.cc', 'host/register_support_host_request.h', |