Index: remoting/host/event_executor_mac.cc |
diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc |
deleted file mode 100644 |
index 8a5286b00ee850c896b6007604355bea96421212..0000000000000000000000000000000000000000 |
--- a/remoting/host/event_executor_mac.cc |
+++ /dev/null |
@@ -1,294 +0,0 @@ |
-// Copyright (c) 2012 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/event_executor.h" |
- |
-#include <algorithm> |
-#include <ApplicationServices/ApplicationServices.h> |
-#include <Carbon/Carbon.h> |
- |
-#include "base/basictypes.h" |
-#include "base/bind.h" |
-#include "base/compiler_specific.h" |
-#include "base/location.h" |
-#include "base/mac/scoped_cftyperef.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/single_thread_task_runner.h" |
-#include "media/video/capture/screen/mac/desktop_configuration.h" |
-#include "remoting/host/clipboard.h" |
-#include "remoting/proto/internal.pb.h" |
-#include "remoting/protocol/message_decoder.h" |
-#include "skia/ext/skia_utils_mac.h" |
-#include "third_party/skia/include/core/SkPoint.h" |
-#include "third_party/skia/include/core/SkRect.h" |
- |
-namespace remoting { |
- |
-namespace { |
- |
-using protocol::ClipboardEvent; |
-using protocol::KeyEvent; |
-using protocol::MouseEvent; |
- |
-// USB to Mac keycode mapping table. |
-#define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} |
-#include "ui/base/keycodes/usb_keycode_map.h" |
-#undef USB_KEYMAP |
- |
-// skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). |
-SkIRect CGRectToSkIRect(const CGRect& rect) { |
- SkIRect result; |
- gfx::CGRectToSkRect(rect).round(&result); |
- return result; |
-} |
- |
-// A class to generate events on Mac. |
-class EventExecutorMac : public EventExecutor { |
- public: |
- explicit EventExecutorMac( |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
- virtual ~EventExecutorMac(); |
- |
- // ClipboardStub interface. |
- virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; |
- |
- // InputStub interface. |
- virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; |
- virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; |
- |
- // EventExecutor interface. |
- virtual void Start( |
- scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; |
- |
- private: |
- // The actual implementation resides in EventExecutorMac::Core class. |
- class Core : public base::RefCountedThreadSafe<Core> { |
- public: |
- explicit Core(scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
- |
- // Mirrors the ClipboardStub interface. |
- void InjectClipboardEvent(const ClipboardEvent& event); |
- |
- // Mirrors the InputStub interface. |
- void InjectKeyEvent(const KeyEvent& event); |
- void InjectMouseEvent(const MouseEvent& event); |
- |
- // Mirrors the EventExecutor interface. |
- void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard); |
- |
- void Stop(); |
- |
- private: |
- friend class base::RefCountedThreadSafe<Core>; |
- virtual ~Core(); |
- |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
- SkIPoint mouse_pos_; |
- uint32 mouse_button_state_; |
- scoped_ptr<Clipboard> clipboard_; |
- |
- DISALLOW_COPY_AND_ASSIGN(Core); |
- }; |
- |
- scoped_refptr<Core> core_; |
- |
- DISALLOW_COPY_AND_ASSIGN(EventExecutorMac); |
-}; |
- |
-EventExecutorMac::EventExecutorMac( |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
- core_ = new Core(task_runner); |
-} |
- |
-EventExecutorMac::~EventExecutorMac() { |
- core_->Stop(); |
-} |
- |
-void EventExecutorMac::InjectClipboardEvent(const ClipboardEvent& event) { |
- core_->InjectClipboardEvent(event); |
-} |
- |
-void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { |
- core_->InjectKeyEvent(event); |
-} |
- |
-void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { |
- core_->InjectMouseEvent(event); |
-} |
- |
-void EventExecutorMac::Start( |
- scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
- core_->Start(client_clipboard.Pass()); |
-} |
- |
-EventExecutorMac::Core::Core( |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
- : task_runner_(task_runner), |
- mouse_button_state_(0), |
- clipboard_(Clipboard::Create()) { |
- // Ensure that local hardware events are not suppressed after injecting |
- // input events. This allows LocalInputMonitor to detect if the local mouse |
- // is being moved whilst a remote user is connected. |
- // This API is deprecated, but it is needed when using the deprecated |
- // injection APIs. |
- // If the non-deprecated injection APIs were used instead, the equivalent of |
- // this line would not be needed, as OS X defaults to _not_ suppressing local |
- // inputs in that case. |
-#pragma clang diagnostic push |
-#pragma clang diagnostic ignored "-Wdeprecated-declarations" |
- CGSetLocalEventsSuppressionInterval(0.0); |
-#pragma clang diagnostic pop |
-} |
- |
-void EventExecutorMac::Core::InjectClipboardEvent(const ClipboardEvent& event) { |
- if (!task_runner_->BelongsToCurrentThread()) { |
- task_runner_->PostTask( |
- FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); |
- return; |
- } |
- |
- // |clipboard_| will ignore unknown MIME-types, and verify the data's format. |
- clipboard_->InjectClipboardEvent(event); |
-} |
- |
-void EventExecutorMac::Core::InjectKeyEvent(const KeyEvent& event) { |
- // HostEventDispatcher should filter events missing the pressed field. |
- if (!event.has_pressed() || !event.has_usb_keycode()) |
- return; |
- |
- int keycode = UsbKeycodeToNativeKeycode(event.usb_keycode()); |
- |
- VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() |
- << " to keycode: " << keycode << std::dec; |
- |
- // If we couldn't determine the Mac virtual key code then ignore the event. |
- if (keycode == InvalidNativeKeycode()) |
- return; |
- |
- // We use the deprecated event injection API because the new one doesn't |
- // work with switched-out sessions (curtain mode). |
-#pragma clang diagnostic push |
-#pragma clang diagnostic ignored "-Wdeprecated-declarations" |
- CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); |
-#pragma clang diagnostic pop |
- if (error != kCGErrorSuccess) |
- LOG(WARNING) << "CGPostKeyboardEvent error " << error; |
-} |
- |
-void EventExecutorMac::Core::InjectMouseEvent(const MouseEvent& event) { |
- if (event.has_x() && event.has_y()) { |
- // On multi-monitor systems (0,0) refers to the top-left of the "main" |
- // display, whereas our coordinate scheme places (0,0) at the top-left of |
- // the bounding rectangle around all the displays, so we need to translate |
- // accordingly. |
- |
- // Set the mouse position assuming single-monitor. |
- mouse_pos_ = SkIPoint::Make(event.x(), event.y()); |
- |
- // Fetch the desktop configuration. |
- // TODO(wez): Optimize this out, or at least only enumerate displays in |
- // response to display-changed events. VideoFrameCapturer's VideoFrames |
- // could be augmented to include native cursor coordinates for use by |
- // MouseClampingFilter, removing the need for translation here. |
- media::MacDesktopConfiguration desktop_config = |
- media::MacDesktopConfiguration::GetCurrent( |
- media::MacDesktopConfiguration::TopLeftOrigin); |
- |
- // Translate the mouse position into desktop coordinates. |
- mouse_pos_ += SkIPoint::Make(desktop_config.pixel_bounds.left(), |
- desktop_config.pixel_bounds.top()); |
- |
- // Constrain the mouse position to the desktop coordinates. |
- mouse_pos_ = SkIPoint::Make( |
- std::max(desktop_config.pixel_bounds.left(), |
- std::min(desktop_config.pixel_bounds.right(), mouse_pos_.x())), |
- std::max(desktop_config.pixel_bounds.top(), |
- std::min(desktop_config.pixel_bounds.bottom(), mouse_pos_.y()))); |
- |
- // Convert from pixel to Density Independent Pixel coordinates. |
- mouse_pos_ = SkIPoint::Make( |
- SkScalarRound(mouse_pos_.x() / desktop_config.dip_to_pixel_scale), |
- SkScalarRound(mouse_pos_.y() / desktop_config.dip_to_pixel_scale)); |
- |
- VLOG(3) << "Moving mouse to " << mouse_pos_.x() << "," << mouse_pos_.y(); |
- } |
- if (event.has_button() && event.has_button_down()) { |
- if (event.button() >= 1 && event.button() <= 3) { |
- VLOG(2) << "Button " << event.button() |
- << (event.button_down() ? " down" : " up"); |
- int button_change = 1 << (event.button() - 1); |
- if (event.button_down()) |
- mouse_button_state_ |= button_change; |
- else |
- mouse_button_state_ &= ~button_change; |
- } else { |
- VLOG(1) << "Unknown mouse button: " << event.button(); |
- } |
- } |
- // We use the deprecated CGPostMouseEvent API because we receive low-level |
- // mouse events, whereas CGEventCreateMouseEvent is for injecting higher-level |
- // events. For example, the deprecated APIs will detect double-clicks or drags |
- // in a way that is consistent with how they would be generated using a local |
- // mouse, whereas the new APIs expect us to inject these higher-level events |
- // directly. |
- CGPoint position = CGPointMake(mouse_pos_.x(), mouse_pos_.y()); |
- enum { |
- LeftBit = 1 << (MouseEvent::BUTTON_LEFT - 1), |
- MiddleBit = 1 << (MouseEvent::BUTTON_MIDDLE - 1), |
- RightBit = 1 << (MouseEvent::BUTTON_RIGHT - 1) |
- }; |
-#pragma clang diagnostic push |
-#pragma clang diagnostic ignored "-Wdeprecated-declarations" |
- CGError error = CGPostMouseEvent(position, true, 3, |
- (mouse_button_state_ & LeftBit) != 0, |
- (mouse_button_state_ & RightBit) != 0, |
- (mouse_button_state_ & MiddleBit) != 0); |
-#pragma clang diagnostic pop |
- if (error != kCGErrorSuccess) |
- LOG(WARNING) << "CGPostMouseEvent error " << error; |
- |
- if (event.has_wheel_delta_x() && event.has_wheel_delta_y()) { |
- int delta_x = static_cast<int>(event.wheel_delta_x()); |
- int delta_y = static_cast<int>(event.wheel_delta_y()); |
- base::mac::ScopedCFTypeRef<CGEventRef> event( |
- CGEventCreateScrollWheelEvent( |
- NULL, kCGScrollEventUnitPixel, 2, delta_y, delta_x)); |
- if (event) |
- CGEventPost(kCGSessionEventTap, event); |
- } |
-} |
- |
-void EventExecutorMac::Core::Start( |
- scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
- if (!task_runner_->BelongsToCurrentThread()) { |
- task_runner_->PostTask( |
- FROM_HERE, |
- base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); |
- return; |
- } |
- |
- clipboard_->Start(client_clipboard.Pass()); |
-} |
- |
-void EventExecutorMac::Core::Stop() { |
- if (!task_runner_->BelongsToCurrentThread()) { |
- task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); |
- return; |
- } |
- |
- clipboard_->Stop(); |
-} |
- |
-EventExecutorMac::Core::~Core() { |
-} |
- |
-} // namespace |
- |
-scoped_ptr<EventExecutor> EventExecutor::Create( |
- scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
- return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); |
-} |
- |
-} // namespace remoting |