summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-12 08:54:56 +0000
committerjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-12 08:54:56 +0000
commitb691a100e6ff4aec4880a6957d6a79921ac53eda (patch)
tree01dc0d75c38b0bc038397b635cd9f49a02ec063f /remoting
parent5eb431e2dfe9d55eaff2acc7a3ea64f403dec669 (diff)
downloadchromium_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.cc6
-rwxr-xr-xremoting/host/local_input_monitor_thread_win.cc114
-rwxr-xr-xremoting/host/local_input_monitor_thread_win.h46
-rw-r--r--remoting/host/local_input_monitor_win.cc25
-rw-r--r--remoting/remoting.gyp4
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',