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 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/mac/scoped_cftyperef.h" | 14 #include "base/mac/scoped_cftyperef.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
17 #include "remoting/host/chromoting_host.h" | 17 #include "remoting/host/mouse_move_observer.h" |
18 #include "third_party/skia/include/core/SkPoint.h" | |
18 #import "third_party/GTM/AppKit/GTMCarbonEvent.h" | 19 #import "third_party/GTM/AppKit/GTMCarbonEvent.h" |
19 | 20 |
20 // Esc Key Code is 53. | 21 // Esc Key Code is 53. |
21 // http://boredzo.org/blog/wp-content/uploads/2007/05/IMTx-virtual-keycodes.pdf | 22 // http://boredzo.org/blog/wp-content/uploads/2007/05/IMTx-virtual-keycodes.pdf |
22 static const NSUInteger kEscKeyCode = 53; | 23 static const NSUInteger kEscKeyCode = 53; |
23 | 24 |
25 namespace remoting { | |
26 | |
24 namespace { | 27 namespace { |
25 typedef std::set<scoped_refptr<remoting::ChromotingHost> > Hosts; | 28 |
26 } | 29 class LocalInputMonitorMac : public LocalInputMonitor { |
Jamie
2012/05/25 21:19:24
I realize that you inherited this from the older c
Sergey Ulanov
2012/05/25 21:59:30
Yes, I agree that the current terminology is confu
| |
30 public: | |
31 LocalInputMonitorMac() : mouse_move_observer_(NULL) {} | |
32 virtual ~LocalInputMonitorMac(); | |
33 virtual void Start(MouseMoveObserver* mouse_move_observer, | |
34 const base::Closure& disconnect_callback) OVERRIDE; | |
35 virtual void Stop() OVERRIDE; | |
36 | |
37 void OnMouseMoved(const SkIPoint& new_pos); | |
38 void OnDisconnectShortcut(); | |
39 | |
40 private: | |
41 MouseMoveObserver* mouse_move_observer_; | |
42 base::Closure disconnect_callback_; | |
43 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorMac); | |
44 }; | |
45 | |
46 typedef std::set<remoting::LocalInputMonitorMac*> LocalInputMonitors; | |
47 | |
48 } // namespace | |
49 | |
50 } // namespace remoting | |
27 | 51 |
28 @interface LocalInputMonitorImpl : NSObject { | 52 @interface LocalInputMonitorImpl : NSObject { |
29 @private | 53 @private |
30 GTMCarbonHotKey* hotKey_; | 54 GTMCarbonHotKey* hotKey_; |
31 CFRunLoopSourceRef mouseRunLoopSource_; | 55 CFRunLoopSourceRef mouseRunLoopSource_; |
32 base::mac::ScopedCFTypeRef<CFMachPortRef> mouseMachPort_; | 56 base::mac::ScopedCFTypeRef<CFMachPortRef> mouseMachPort_; |
33 base::Lock hostsLock_; | 57 base::Lock lock_; |
34 Hosts hosts_; | 58 remoting::LocalInputMonitors monitors_; |
35 } | 59 } |
36 | 60 |
37 // Called when the hotKey is hit. | 61 // Called when the hotKey is hit. |
38 - (void)hotKeyHit:(GTMCarbonHotKey*)hotKey; | 62 - (void)hotKeyHit:(GTMCarbonHotKey*)hotKey; |
39 | 63 |
40 // Called when the local mouse moves | 64 // Called when the local mouse moves |
41 - (void)localMouseMoved:(const SkIPoint&)mousePos; | 65 - (void)localMouseMoved:(const SkIPoint&)mousePos; |
42 | 66 |
43 // Must be called when the LocalInputMonitorImpl is no longer to be used. | 67 // Must be called when the LocalInputMonitorImpl is no longer to be used. |
44 // Similar to NSTimer in that more than a simple release is required. | 68 // Similar to NSTimer in that more than a simple release is required. |
45 - (void)invalidate; | 69 - (void)invalidate; |
46 | 70 |
47 // Called to add a host to the list of those to be Shutdown() when the hotkey | 71 // Called to add a monitor. |
48 // is pressed. | 72 - (void)addMonitor:(remoting::LocalInputMonitorMac*)monitor; |
49 - (void)addHost:(remoting::ChromotingHost*)host; | |
50 | 73 |
51 // Called to remove a host. Returns true if it was the last host being | 74 // Called to remove a mouse move observers. Returns true if it was the |
Jamie
2012/05/25 21:19:24
s/observers/observer/
Sergey Ulanov
2012/05/25 21:59:30
It actually removes monitor.
| |
52 // monitored, in which case the object should be destroyed. | 75 // last observer, in which case the object should be destroyed. |
53 - (bool)removeHost:(remoting::ChromotingHost*)host; | 76 - (bool)removeMonitor:(remoting::LocalInputMonitorMac*)monitor; |
54 | |
55 // Disabled disconnection keyboard shortcut. | |
56 - (void)disableShortcut; | |
57 | 77 |
58 @end | 78 @end |
59 | 79 |
60 static CGEventRef LocalMouseMoved(CGEventTapProxy proxy, CGEventType type, | 80 static CGEventRef LocalMouseMoved(CGEventTapProxy proxy, CGEventType type, |
61 CGEventRef event, void* context) { | 81 CGEventRef event, void* context) { |
62 int64_t pid = CGEventGetIntegerValueField(event, kCGEventSourceUnixProcessID); | 82 int64_t pid = CGEventGetIntegerValueField(event, kCGEventSourceUnixProcessID); |
63 if (pid == 0) { | 83 if (pid == 0) { |
64 CGPoint cgMousePos = CGEventGetLocation(event); | 84 CGPoint cgMousePos = CGEventGetLocation(event); |
65 SkIPoint mousePos = SkIPoint::Make(cgMousePos.x, cgMousePos.y); | 85 SkIPoint mousePos = SkIPoint::Make(cgMousePos.x, cgMousePos.y); |
66 [static_cast<LocalInputMonitorImpl*>(context) localMouseMoved:mousePos]; | 86 [static_cast<LocalInputMonitorImpl*>(context) localMouseMoved:mousePos]; |
(...skipping 29 matching lines...) Expand all Loading... | |
96 } | 116 } |
97 if (!hotKey_ && !mouseMachPort_) { | 117 if (!hotKey_ && !mouseMachPort_) { |
98 [self release]; | 118 [self release]; |
99 return nil; | 119 return nil; |
100 } | 120 } |
101 } | 121 } |
102 return self; | 122 return self; |
103 } | 123 } |
104 | 124 |
105 - (void)hotKeyHit:(GTMCarbonHotKey*)hotKey { | 125 - (void)hotKeyHit:(GTMCarbonHotKey*)hotKey { |
106 base::AutoLock lock(hostsLock_); | 126 base::AutoLock lock(lock_); |
107 for (Hosts::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i) { | 127 for (remoting::LocalInputMonitors::const_iterator i = monitors_.begin(); |
108 (*i)->Shutdown(base::Closure()); | 128 i != monitors_.end(); ++i) { |
129 (*i)->OnDisconnectShortcut(); | |
109 } | 130 } |
110 } | 131 } |
111 | 132 |
112 - (void)localMouseMoved:(const SkIPoint&)mousePos { | 133 - (void)localMouseMoved:(const SkIPoint&)mousePos { |
113 base::AutoLock lock(hostsLock_); | 134 base::AutoLock lock(lock_); |
114 for (Hosts::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i) { | 135 for (remoting::LocalInputMonitors::const_iterator i = monitors_.begin(); |
115 (*i)->LocalMouseMoved(mousePos); | 136 i != monitors_.end(); ++i) { |
137 (*i)->OnMouseMoved(mousePos); | |
116 } | 138 } |
117 } | 139 } |
118 | 140 |
119 - (void)invalidate { | 141 - (void)invalidate { |
120 if (hotKey_) { | 142 if (hotKey_) { |
121 GTMCarbonEventDispatcherHandler* handler = | 143 GTMCarbonEventDispatcherHandler* handler = |
122 [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]; | 144 [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]; |
123 [handler unregisterHotKey:hotKey_]; | 145 [handler unregisterHotKey:hotKey_]; |
124 hotKey_ = NULL; | 146 hotKey_ = NULL; |
125 } | 147 } |
126 if (mouseRunLoopSource_) { | 148 if (mouseRunLoopSource_) { |
127 CFMachPortInvalidate(mouseMachPort_); | 149 CFMachPortInvalidate(mouseMachPort_); |
128 CFRunLoopRemoveSource( | 150 CFRunLoopRemoveSource( |
129 CFRunLoopGetMain(), mouseRunLoopSource_, kCFRunLoopCommonModes); | 151 CFRunLoopGetMain(), mouseRunLoopSource_, kCFRunLoopCommonModes); |
130 CFRelease(mouseRunLoopSource_); | 152 CFRelease(mouseRunLoopSource_); |
131 mouseMachPort_.reset(0); | 153 mouseMachPort_.reset(0); |
132 mouseRunLoopSource_ = NULL; | 154 mouseRunLoopSource_ = NULL; |
133 } | 155 } |
134 } | 156 } |
135 | 157 |
136 - (void)addHost:(remoting::ChromotingHost*)host { | 158 - (void)addMonitor:(remoting::LocalInputMonitorMac*)monitor { |
137 base::AutoLock lock(hostsLock_); | 159 base::AutoLock lock(lock_); |
138 hosts_.insert(host); | 160 monitors_.insert(monitor); |
139 } | 161 } |
140 | 162 |
141 - (bool)removeHost:(remoting::ChromotingHost*)host { | 163 - (bool)removeMonitor:(remoting::LocalInputMonitorMac*)monitor { |
142 base::AutoLock lock(hostsLock_); | 164 base::AutoLock lock(lock_); |
143 hosts_.erase(host); | 165 monitors_.erase(monitor); |
144 return hosts_.empty(); | 166 return monitors_.empty(); |
145 } | |
146 | |
147 - (void)disableShortcut { | |
148 if (hotKey_) { | |
149 GTMCarbonEventDispatcherHandler* handler = | |
150 [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]; | |
151 [handler unregisterHotKey:hotKey_]; | |
152 hotKey_ = NULL; | |
153 } | |
154 } | 167 } |
155 | 168 |
156 @end | 169 @end |
157 | 170 |
158 namespace remoting { | 171 namespace remoting { |
159 | 172 |
160 namespace { | 173 namespace { |
161 | 174 |
162 class LocalInputMonitorMac : public LocalInputMonitor { | 175 base::LazyInstance<base::Lock>::Leaky g_monitor_lock = |
163 public: | 176 LAZY_INSTANCE_INITIALIZER; |
164 LocalInputMonitorMac() : host_(NULL) {} | 177 LocalInputMonitorImpl* g_local_input_monitor = NULL; |
165 virtual ~LocalInputMonitorMac(); | |
166 virtual void Start(ChromotingHost* host) OVERRIDE; | |
167 virtual void Stop() OVERRIDE; | |
168 virtual void DisableShortcutOnMac() OVERRIDE; | |
169 | |
170 private: | |
171 ChromotingHost* host_; | |
172 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorMac); | |
173 }; | |
174 | |
175 base::LazyInstance<base::Lock>::Leaky monitor_lock = LAZY_INSTANCE_INITIALIZER; | |
176 LocalInputMonitorImpl* local_input_monitor = NULL; | |
177 | 178 |
178 } // namespace | 179 } // namespace |
179 | 180 |
180 LocalInputMonitorMac::~LocalInputMonitorMac() { | 181 LocalInputMonitorMac::~LocalInputMonitorMac() { |
181 Stop(); | 182 Stop(); |
182 } | 183 } |
183 | 184 |
184 void LocalInputMonitorMac::Start(ChromotingHost* host) { | 185 void LocalInputMonitorMac::Start(MouseMoveObserver* mouse_move_observer, |
185 base::AutoLock lock(monitor_lock.Get()); | 186 const base::Closure& disconnect_callback) { |
186 if (!local_input_monitor) | 187 base::AutoLock lock(g_monitor_lock.Get()); |
187 local_input_monitor = [[LocalInputMonitorImpl alloc] init]; | 188 if (!g_local_input_monitor) |
188 CHECK(local_input_monitor); | 189 g_local_input_monitor = [[LocalInputMonitorImpl alloc] init]; |
189 [local_input_monitor addHost:host]; | 190 CHECK(g_local_input_monitor); |
190 host_ = host; | 191 mouse_move_observer_ = mouse_move_observer; |
192 disconnect_callback_ = disconnect_callback; | |
193 [g_local_input_monitor addMonitor:this]; | |
191 } | 194 } |
192 | 195 |
193 void LocalInputMonitorMac::Stop() { | 196 void LocalInputMonitorMac::Stop() { |
194 base::AutoLock lock(monitor_lock.Get()); | 197 base::AutoLock lock(g_monitor_lock.Get()); |
195 if ([local_input_monitor removeHost:host_]) { | 198 if ([g_local_input_monitor removeMonitor:this]) { |
196 [local_input_monitor invalidate]; | 199 [g_local_input_monitor invalidate]; |
197 [local_input_monitor release]; | 200 [g_local_input_monitor release]; |
198 local_input_monitor = nil; | 201 g_local_input_monitor = nil; |
199 } | 202 } |
200 } | 203 } |
201 | 204 |
202 void LocalInputMonitorMac::DisableShortcutOnMac() { | 205 void LocalInputMonitorMac::OnMouseMoved(const SkIPoint& new_pos) { |
203 [local_input_monitor disableShortcut]; | 206 mouse_move_observer_->OnMouseMoved(new_pos); |
207 } | |
208 | |
209 void LocalInputMonitorMac::OnDisconnectShortcut() { | |
210 disconnect_callback_.Run(); | |
204 } | 211 } |
205 | 212 |
206 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create() { | 213 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create() { |
207 return scoped_ptr<LocalInputMonitor>(new LocalInputMonitorMac()); | 214 return scoped_ptr<LocalInputMonitor>(new LocalInputMonitorMac()); |
208 } | 215 } |
209 | 216 |
210 } // namespace remoting | 217 } // namespace remoting |
OLD | NEW |