diff options
-rw-r--r-- | remoting/host/local_input_monitor_mac.mm | 63 |
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() { |