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/event_executor.h" | 5 #include "remoting/host/event_executor.h" |
6 | 6 |
7 #include <ApplicationServices/ApplicationServices.h> | 7 #include <ApplicationServices/ApplicationServices.h> |
8 #include <Carbon/Carbon.h> | 8 #include <Carbon/Carbon.h> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/mac/scoped_cftyperef.h" | 14 #include "base/mac/scoped_cftyperef.h" |
15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
16 #include "remoting/host/clipboard.h" | 16 #include "remoting/host/clipboard.h" |
17 #include "remoting/proto/internal.pb.h" | 17 #include "remoting/proto/internal.pb.h" |
18 #include "remoting/protocol/message_decoder.h" | 18 #include "remoting/protocol/message_decoder.h" |
19 #include "third_party/skia/include/core/SkPoint.h" | 19 #include "third_party/skia/include/core/SkPoint.h" |
| 20 #include "third_party/skia/include/core/SkRect.h" |
20 | 21 |
21 namespace remoting { | 22 namespace remoting { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 using protocol::ClipboardEvent; | 26 using protocol::ClipboardEvent; |
26 using protocol::KeyEvent; | 27 using protocol::KeyEvent; |
27 using protocol::MouseEvent; | 28 using protocol::MouseEvent; |
28 | 29 |
29 // USB to Mac keycode mapping table. | 30 // USB to Mac keycode mapping table. |
30 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} | 31 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} |
31 #include "ui/base/keycodes/usb_keycode_map.h" | 32 #include "ui/base/keycodes/usb_keycode_map.h" |
32 #undef USB_KEYMAP | 33 #undef USB_KEYMAP |
33 | 34 |
| 35 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). |
| 36 SkIRect CGRectToSkIRect(const CGRect& rect) { |
| 37 SkIRect sk_rect = { |
| 38 SkScalarRound(rect.origin.x), |
| 39 SkScalarRound(rect.origin.y), |
| 40 SkScalarRound(rect.origin.x + rect.size.width), |
| 41 SkScalarRound(rect.origin.y + rect.size.height) |
| 42 }; |
| 43 return sk_rect; |
| 44 } |
| 45 |
34 // A class to generate events on Mac. | 46 // A class to generate events on Mac. |
35 class EventExecutorMac : public EventExecutor { | 47 class EventExecutorMac : public EventExecutor { |
36 public: | 48 public: |
37 EventExecutorMac(scoped_refptr<base::SingleThreadTaskRunner> task_runner); | 49 EventExecutorMac(scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
38 virtual ~EventExecutorMac() {} | 50 virtual ~EventExecutorMac() {} |
39 | 51 |
40 // ClipboardStub interface. | 52 // ClipboardStub interface. |
41 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; | 53 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; |
42 | 54 |
43 // InputStub interface. | 55 // InputStub interface. |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 312 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
301 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); | 313 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); |
302 #pragma clang diagnostic pop | 314 #pragma clang diagnostic pop |
303 if (error != kCGErrorSuccess) { | 315 if (error != kCGErrorSuccess) { |
304 LOG(WARNING) << "CGPostKeyboardEvent error " << error; | 316 LOG(WARNING) << "CGPostKeyboardEvent error " << error; |
305 } | 317 } |
306 } | 318 } |
307 | 319 |
308 void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { | 320 void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { |
309 if (event.has_x() && event.has_y()) { | 321 if (event.has_x() && event.has_y()) { |
310 // TODO(wez): This code assumes that MouseEvent(0,0) (top-left of client vie
w) | 322 // On multi-monitor systems (0,0) refers to the top-left of the "main" |
311 // corresponds to local (0,0) (top-left of primary monitor). That won't in | 323 // display, whereas our coordinate scheme places (0,0) at the top-left of |
312 // general be true on multi-monitor systems, though. | 324 // the bounding rectangle around all the displays, so we need to translate |
| 325 // accordingly. |
| 326 // TODO(wez): Move display config tracking into a separate class used both |
| 327 // here and in the Capturer. |
| 328 |
| 329 // Set the mouse position assuming single-monitor. |
| 330 mouse_pos_ = SkIPoint::Make(event.x(), event.y()); |
| 331 |
| 332 // Determine how many active displays there are. |
| 333 CGDisplayCount display_count; |
| 334 CGError error = CGGetActiveDisplayList(0, NULL, &display_count); |
| 335 CHECK_EQ(error, CGDisplayNoErr); |
| 336 |
| 337 if (display_count > 1) { |
| 338 // Determine the bounding box of the displays, to get the top-left origin. |
| 339 std::vector<CGDirectDisplayID> display_ids(display_count); |
| 340 error = CGGetActiveDisplayList(display_count, &display_ids[0], |
| 341 &display_count); |
| 342 CHECK_EQ(error, CGDisplayNoErr); |
| 343 CHECK_EQ(display_count, display_ids.size()); |
| 344 |
| 345 SkIRect desktop_bounds = SkIRect::MakeEmpty(); |
| 346 for (unsigned int d = 0; d < display_count; ++d) { |
| 347 CGRect display_bounds = CGDisplayBounds(display_ids[d]); |
| 348 desktop_bounds.join(CGRectToSkIRect(display_bounds)); |
| 349 } |
| 350 |
| 351 // Adjust the injected mouse event position. |
| 352 mouse_pos_ += SkIPoint::Make(desktop_bounds.left(), desktop_bounds.top()); |
| 353 } |
| 354 |
313 VLOG(3) << "Moving mouse to " << event.x() << "," << event.y(); | 355 VLOG(3) << "Moving mouse to " << event.x() << "," << event.y(); |
314 mouse_pos_ = SkIPoint::Make(event.x(), event.y()); | |
315 } | 356 } |
316 if (event.has_button() && event.has_button_down()) { | 357 if (event.has_button() && event.has_button_down()) { |
317 if (event.button() >= 1 && event.button() <= 3) { | 358 if (event.button() >= 1 && event.button() <= 3) { |
318 VLOG(2) << "Button " << event.button() | 359 VLOG(2) << "Button " << event.button() |
319 << (event.button_down() ? " down" : " up"); | 360 << (event.button_down() ? " down" : " up"); |
320 int button_change = 1 << (event.button() - 1); | 361 int button_change = 1 << (event.button() - 1); |
321 if (event.button_down()) | 362 if (event.button_down()) |
322 mouse_button_state_ |= button_change; | 363 mouse_button_state_ |= button_change; |
323 else | 364 else |
324 mouse_button_state_ &= ~button_change; | 365 mouse_button_state_ &= ~button_change; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 | 432 |
392 } // namespace | 433 } // namespace |
393 | 434 |
394 scoped_ptr<EventExecutor> EventExecutor::Create( | 435 scoped_ptr<EventExecutor> EventExecutor::Create( |
395 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 436 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
396 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 437 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
397 return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); | 438 return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); |
398 } | 439 } |
399 | 440 |
400 } // namespace remoting | 441 } // namespace remoting |
OLD | NEW |