summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--remoting/host/local_input_monitor_mac.mm63
1 files changed, 50 insertions, 13 deletions
diff --git a/remoting/host/local_input_monitor_mac.mm b/remoting/host/local_input_monitor_mac.mm
index fb105d3..5c4cd9d 100644
--- a/remoting/host/local_input_monitor_mac.mm
+++ b/remoting/host/local_input_monitor_mac.mm
@@ -5,9 +5,12 @@
#include "remoting/host/local_input_monitor.h"
#import <AppKit/AppKit.h>
+#include <set>
#include "base/compiler_specific.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/synchronization/lock.h"
#include "remoting/host/chromoting_host.h"
#import "third_party/GTM/AppKit/GTMCarbonEvent.h"
@@ -15,10 +18,15 @@
// http://boredzo.org/blog/wp-content/uploads/2007/05/IMTx-virtual-keycodes.pdf
static const NSUInteger kEscKeyCode = 53;
+namespace {
+typedef std::set<remoting::ChromotingHost*> Hosts;
+}
+
@interface HotKeyMonitor : NSObject {
@private
GTMCarbonHotKey* hot_key_;
- remoting::ChromotingHost* host_;
+ base::Lock hosts_lock_;
+ Hosts hosts_;
}
// Called when the hotKey is hit.
@@ -28,13 +36,20 @@ static const NSUInteger kEscKeyCode = 53;
// Similar to NSTimer in that more than a simple release is required.
- (void)invalidate;
+// Called to add a host to the list of those to be Shutdown() when the hotkey
+// is pressed.
+- (void)addHost:(remoting::ChromotingHost*)host;
+
+// Called to remove a host. Returns true if it was the last host being
+// monitored, in which case the object should be destroyed.
+- (bool)removeHost:(remoting::ChromotingHost*)host;
+
@end
@implementation HotKeyMonitor
-- (id)initWithHost:(remoting::ChromotingHost*)host {
+- (id)init {
if ((self = [super init])) {
- host_ = host;
GTMCarbonEventDispatcherHandler* handler =
[GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
hot_key_ = [handler registerHotKey:kEscKeyCode
@@ -52,7 +67,10 @@ static const NSUInteger kEscKeyCode = 53;
}
- (void)hotKeyHit:(GTMCarbonHotKey*)hotKey {
- host_->Shutdown(NULL);
+ base::AutoLock lock(hosts_lock_);
+ for (Hosts::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i) {
+ (*i)->Shutdown(NULL);
+ }
}
- (void)invalidate {
@@ -61,23 +79,36 @@ static const NSUInteger kEscKeyCode = 53;
[handler unregisterHotKey:hot_key_];
}
+- (void)addHost:(remoting::ChromotingHost*)host {
+ base::AutoLock lock(hosts_lock_);
+ hosts_.insert(host);
+}
+
+- (bool)removeHost:(remoting::ChromotingHost*)host {
+ base::AutoLock lock(hosts_lock_);
+ hosts_.erase(host);
+ return hosts_.empty();
+}
+
@end
namespace {
class LocalInputMonitorMac : public remoting::LocalInputMonitor {
public:
- LocalInputMonitorMac() : hot_key_monitor_(NULL) {}
+ LocalInputMonitorMac() : host_(NULL) {}
virtual ~LocalInputMonitorMac();
virtual void Start(remoting::ChromotingHost* host) OVERRIDE;
virtual void Stop() OVERRIDE;
private:
- HotKeyMonitor* hot_key_monitor_;
-
+ remoting::ChromotingHost* host_;
DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorMac);
};
+base::LazyInstance<base::Lock> monitor_lock(base::LINKER_INITIALIZED);
+HotKeyMonitor* hot_key_monitor = NULL;
+
} // namespace
LocalInputMonitorMac::~LocalInputMonitorMac() {
@@ -85,15 +116,21 @@ LocalInputMonitorMac::~LocalInputMonitorMac() {
}
void LocalInputMonitorMac::Start(remoting::ChromotingHost* host) {
- CHECK(!hot_key_monitor_);
- hot_key_monitor_ = [[HotKeyMonitor alloc] initWithHost:host];
- CHECK(hot_key_monitor_);
+ base::AutoLock lock(monitor_lock.Get());
+ if (!hot_key_monitor)
+ hot_key_monitor = [[HotKeyMonitor alloc] init];
+ CHECK(hot_key_monitor);
+ [hot_key_monitor addHost:host];
+ host_ = host;
}
void LocalInputMonitorMac::Stop() {
- [hot_key_monitor_ invalidate];
- [hot_key_monitor_ release];
- hot_key_monitor_ = nil;
+ base::AutoLock lock(monitor_lock.Get());
+ if ([hot_key_monitor removeHost:host_]) {
+ [hot_key_monitor invalidate];
+ [hot_key_monitor release];
+ hot_key_monitor = nil;
+ }
}
remoting::LocalInputMonitor* remoting::LocalInputMonitor::Create() {