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/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "remoting/capturer/mac/desktop_configuration.h" |
17 #include "remoting/host/clipboard.h" | 18 #include "remoting/host/clipboard.h" |
18 #include "remoting/proto/internal.pb.h" | 19 #include "remoting/proto/internal.pb.h" |
19 #include "remoting/protocol/message_decoder.h" | 20 #include "remoting/protocol/message_decoder.h" |
| 21 #include "skia/ext/skia_utils_mac.h" |
20 #include "third_party/skia/include/core/SkPoint.h" | 22 #include "third_party/skia/include/core/SkPoint.h" |
21 #include "third_party/skia/include/core/SkRect.h" | 23 #include "third_party/skia/include/core/SkRect.h" |
22 | 24 |
23 namespace remoting { | 25 namespace remoting { |
24 | 26 |
25 namespace { | 27 namespace { |
26 | 28 |
27 using protocol::ClipboardEvent; | 29 using protocol::ClipboardEvent; |
28 using protocol::KeyEvent; | 30 using protocol::KeyEvent; |
29 using protocol::MouseEvent; | 31 using protocol::MouseEvent; |
30 | 32 |
31 // USB to Mac keycode mapping table. | 33 // USB to Mac keycode mapping table. |
32 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} | 34 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} |
33 #include "ui/base/keycodes/usb_keycode_map.h" | 35 #include "ui/base/keycodes/usb_keycode_map.h" |
34 #undef USB_KEYMAP | 36 #undef USB_KEYMAP |
35 | 37 |
36 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). | 38 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). |
37 SkIRect CGRectToSkIRect(const CGRect& rect) { | 39 SkIRect CGRectToSkIRect(const CGRect& rect) { |
38 SkIRect sk_rect = { | 40 SkIRect result; |
39 SkScalarRound(rect.origin.x), | 41 gfx::CGRectToSkRect(rect).round(&result); |
40 SkScalarRound(rect.origin.y), | 42 return result; |
41 SkScalarRound(rect.origin.x + rect.size.width), | |
42 SkScalarRound(rect.origin.y + rect.size.height) | |
43 }; | |
44 return sk_rect; | |
45 } | 43 } |
46 | 44 |
47 // A class to generate events on Mac. | 45 // A class to generate events on Mac. |
48 class EventExecutorMac : public EventExecutor { | 46 class EventExecutorMac : public EventExecutor { |
49 public: | 47 public: |
50 explicit EventExecutorMac( | 48 explicit EventExecutorMac( |
51 scoped_refptr<base::SingleThreadTaskRunner> task_runner); | 49 scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
52 virtual ~EventExecutorMac(); | 50 virtual ~EventExecutorMac(); |
53 | 51 |
54 // ClipboardStub interface. | 52 // ClipboardStub interface. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 // On multi-monitor systems (0,0) refers to the top-left of the "main" | 181 // On multi-monitor systems (0,0) refers to the top-left of the "main" |
184 // display, whereas our coordinate scheme places (0,0) at the top-left of | 182 // display, whereas our coordinate scheme places (0,0) at the top-left of |
185 // the bounding rectangle around all the displays, so we need to translate | 183 // the bounding rectangle around all the displays, so we need to translate |
186 // accordingly. | 184 // accordingly. |
187 // TODO(wez): Move display config tracking into a separate class used both | 185 // TODO(wez): Move display config tracking into a separate class used both |
188 // here and in the Capturer. | 186 // here and in the Capturer. |
189 | 187 |
190 // Set the mouse position assuming single-monitor. | 188 // Set the mouse position assuming single-monitor. |
191 mouse_pos_ = SkIPoint::Make(event.x(), event.y()); | 189 mouse_pos_ = SkIPoint::Make(event.x(), event.y()); |
192 | 190 |
193 // Determine how many active displays there are. | 191 // Fetch the desktop configuration. |
194 CGDisplayCount display_count; | 192 // TODO(wez): Optimize this out, or at least only enumerate displays in |
195 CGError error = CGGetActiveDisplayList(0, NULL, &display_count); | 193 // response to display-changed events. VideoFrameCapturer's VideoFrames |
196 CHECK_EQ(error, CGDisplayNoErr); | 194 // could be augmented to include native cursor coordinates for use by |
| 195 // MouseClampingFilter, removing the need for translation here. |
| 196 MacDesktopConfiguration desktop_config |
| 197 = MacDesktopConfiguration::GetCurrent(); |
197 | 198 |
198 if (display_count > 1) { | 199 // Translate the mouse position into desktop coordinates. |
199 // Determine the bounding box of the displays, to get the top-left origin. | 200 mouse_pos_ += SkIPoint::Make(desktop_config.pixel_bounds.left(), |
200 std::vector<CGDirectDisplayID> display_ids(display_count); | 201 desktop_config.pixel_bounds.top()); |
201 error = CGGetActiveDisplayList(display_count, &display_ids[0], | |
202 &display_count); | |
203 CHECK_EQ(error, CGDisplayNoErr); | |
204 CHECK_EQ(display_count, display_ids.size()); | |
205 | 202 |
206 SkIRect desktop_bounds = SkIRect::MakeEmpty(); | 203 // Convert from pixel to Density Independent Pixel coordinates. |
207 for (unsigned int d = 0; d < display_count; ++d) { | 204 mouse_pos_ = SkIPoint::Make( |
208 CGRect display_bounds = CGDisplayBounds(display_ids[d]); | 205 SkScalarRound(mouse_pos_.x() / desktop_config.dip_to_pixel_scale), |
209 desktop_bounds.join(CGRectToSkIRect(display_bounds)); | 206 SkScalarRound(mouse_pos_.y() / desktop_config.dip_to_pixel_scale)); |
210 } | |
211 | 207 |
212 // Adjust the injected mouse event position. | 208 VLOG(3) << "Moving mouse to " << mouse_pos_.x() << "," << mouse_pos_.y(); |
213 mouse_pos_ += SkIPoint::Make(desktop_bounds.left(), desktop_bounds.top()); | |
214 } | |
215 | |
216 VLOG(3) << "Moving mouse to " << event.x() << "," << event.y(); | |
217 } | 209 } |
218 if (event.has_button() && event.has_button_down()) { | 210 if (event.has_button() && event.has_button_down()) { |
219 if (event.button() >= 1 && event.button() <= 3) { | 211 if (event.button() >= 1 && event.button() <= 3) { |
220 VLOG(2) << "Button " << event.button() | 212 VLOG(2) << "Button " << event.button() |
221 << (event.button_down() ? " down" : " up"); | 213 << (event.button_down() ? " down" : " up"); |
222 int button_change = 1 << (event.button() - 1); | 214 int button_change = 1 << (event.button() - 1); |
223 if (event.button_down()) | 215 if (event.button_down()) |
224 mouse_button_state_ |= button_change; | 216 mouse_button_state_ |= button_change; |
225 else | 217 else |
226 mouse_button_state_ &= ~button_change; | 218 mouse_button_state_ &= ~button_change; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 | 280 |
289 } // namespace | 281 } // namespace |
290 | 282 |
291 scoped_ptr<EventExecutor> EventExecutor::Create( | 283 scoped_ptr<EventExecutor> EventExecutor::Create( |
292 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 284 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
293 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 285 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
294 return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); | 286 return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); |
295 } | 287 } |
296 | 288 |
297 } // namespace remoting | 289 } // namespace remoting |
OLD | NEW |