Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: remoting/host/event_executor_mac.cc

Issue 10255007: Clamp events before they are sent to EventExecutors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typo. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/event_executor_linux.cc ('k') | remoting/protocol/mouse_input_filter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/mac/scoped_cftyperef.h" 12 #include "base/mac/scoped_cftyperef.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "remoting/host/capturer.h"
15 #include "remoting/proto/internal.pb.h" 14 #include "remoting/proto/internal.pb.h"
16 #include "remoting/protocol/message_decoder.h" 15 #include "remoting/protocol/message_decoder.h"
16 #include "third_party/skia/include/core/SkPoint.h"
17 17
18 namespace remoting { 18 namespace remoting {
19 19
20 namespace { 20 namespace {
21 21
22 using protocol::ClipboardEvent; 22 using protocol::ClipboardEvent;
23 using protocol::KeyEvent; 23 using protocol::KeyEvent;
24 using protocol::MouseEvent; 24 using protocol::MouseEvent;
25 25
26 // USB to Mac keycode mapping table. 26 // USB to Mac keycode mapping table.
27 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} 27 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac}
28 #include "remoting/host/usb_keycode_map.h" 28 #include "remoting/host/usb_keycode_map.h"
29 #undef USB_KEYMAP 29 #undef USB_KEYMAP
30 30
31 // A class to generate events on Mac. 31 // A class to generate events on Mac.
32 class EventExecutorMac : public EventExecutor { 32 class EventExecutorMac : public EventExecutor {
33 public: 33 public:
34 EventExecutorMac(MessageLoop* message_loop, Capturer* capturer); 34 EventExecutorMac(MessageLoop* message_loop);
35 virtual ~EventExecutorMac() {} 35 virtual ~EventExecutorMac() {}
36 36
37 // ClipboardStub interface. 37 // ClipboardStub interface.
38 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; 38 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE;
39 39
40 // InputStub interface. 40 // InputStub interface.
41 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; 41 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE;
42 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; 42 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE;
43 43
44 private: 44 private:
45 MessageLoop* message_loop_; 45 MessageLoop* message_loop_;
46 Capturer* capturer_; 46 SkIPoint mouse_pos_;
47 int last_x_, last_y_; 47 uint32 mouse_button_state_;
48 int mouse_buttons_;
49 48
50 DISALLOW_COPY_AND_ASSIGN(EventExecutorMac); 49 DISALLOW_COPY_AND_ASSIGN(EventExecutorMac);
51 }; 50 };
52 51
53 EventExecutorMac::EventExecutorMac( 52 EventExecutorMac::EventExecutorMac(
54 MessageLoop* message_loop, Capturer* capturer) 53 MessageLoop* message_loop)
55 : message_loop_(message_loop), 54 : message_loop_(message_loop), mouse_button_state_(0) {
56 capturer_(capturer), last_x_(0), last_y_(0), mouse_buttons_(0) {
57 } 55 }
58 56
59 // Hard-coded mapping from Virtual Key codes to Mac KeySyms. 57 // Hard-coded mapping from Virtual Key codes to Mac KeySyms.
60 // This mapping is only valid if both client and host are using a 58 // This mapping is only valid if both client and host are using a
61 // US English keyboard layout. 59 // US English keyboard layout.
62 // Because we're passing VK codes on the wire, with no Scancode, 60 // Because we're passing VK codes on the wire, with no Scancode,
63 // "extended" flag, etc, things like distinguishing left & right 61 // "extended" flag, etc, things like distinguishing left & right
64 // Shift keys doesn't work. 62 // Shift keys doesn't work.
65 // 63 //
66 // TODO(wez): Replace this with something more closely tied to what 64 // TODO(wez): Replace this with something more closely tied to what
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 // We use the deprecated event injection API because the new one doesn't 265 // We use the deprecated event injection API because the new one doesn't
268 // work with switched-out sessions (curtain mode). 266 // work with switched-out sessions (curtain mode).
269 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); 267 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed());
270 if (error != kCGErrorSuccess) { 268 if (error != kCGErrorSuccess) {
271 LOG(WARNING) << "CGPostKeyboardEvent error " << error; 269 LOG(WARNING) << "CGPostKeyboardEvent error " << error;
272 } 270 }
273 } 271 }
274 272
275 void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { 273 void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) {
276 if (event.has_x() && event.has_y()) { 274 if (event.has_x() && event.has_y()) {
277 // TODO(wez): Checking the validity of the MouseEvent should be done in core
278 // cross-platform code, not here!
279 // TODO(wez): This code assumes that MouseEvent(0,0) (top-left of client vie w) 275 // TODO(wez): This code assumes that MouseEvent(0,0) (top-left of client vie w)
280 // corresponds to local (0,0) (top-left of primary monitor). That won't in 276 // corresponds to local (0,0) (top-left of primary monitor). That won't in
281 // general be true on multi-monitor systems, though. 277 // general be true on multi-monitor systems, though.
282 SkISize size = capturer_->size_most_recent(); 278 VLOG(3) << "Moving mouse to " << event.x() << "," << event.y();
283 if (event.x() >= 0 || event.y() >= 0 || 279 mouse_pos_ = SkIPoint::Make(event.x(), event.y());
284 event.x() < size.width() || event.y() < size.height()) {
285 VLOG(3) << "Moving mouse to " << event.x() << "," << event.y();
286 last_x_ = event.x();
287 last_y_ = event.y();
288 } else {
289 VLOG(1) << "Invalid mouse position " << event.x() << "," << event.y();
290 }
291 } 280 }
292 if (event.has_button() && event.has_button_down()) { 281 if (event.has_button() && event.has_button_down()) {
293 if (event.button() >= 1 && event.button() <= 3) { 282 if (event.button() >= 1 && event.button() <= 3) {
294 VLOG(2) << "Button " << event.button() 283 VLOG(2) << "Button " << event.button()
295 << (event.button_down() ? " down" : " up"); 284 << (event.button_down() ? " down" : " up");
296 int button_change = 1 << (event.button() - 1); 285 int button_change = 1 << (event.button() - 1);
297 if (event.button_down()) 286 if (event.button_down())
298 mouse_buttons_ |= button_change; 287 mouse_button_state_ |= button_change;
299 else 288 else
300 mouse_buttons_ &= ~button_change; 289 mouse_button_state_ &= ~button_change;
301 } else { 290 } else {
302 VLOG(1) << "Unknown mouse button: " << event.button(); 291 VLOG(1) << "Unknown mouse button: " << event.button();
303 } 292 }
304 } 293 }
305 // We use the deprecated CGPostMouseEvent API because we receive low-level 294 // We use the deprecated CGPostMouseEvent API because we receive low-level
306 // mouse events, whereas CGEventCreateMouseEvent is for injecting higher-level 295 // mouse events, whereas CGEventCreateMouseEvent is for injecting higher-level
307 // events. For example, the deprecated APIs will detect double-clicks or drags 296 // events. For example, the deprecated APIs will detect double-clicks or drags
308 // in a way that is consistent with how they would be generated using a local 297 // in a way that is consistent with how they would be generated using a local
309 // mouse, whereas the new APIs expect us to inject these higher-level events 298 // mouse, whereas the new APIs expect us to inject these higher-level events
310 // directly. 299 // directly.
311 CGPoint position = CGPointMake(last_x_, last_y_); 300 CGPoint position = CGPointMake(mouse_pos_.x(), mouse_pos_.y());
312 enum { 301 enum {
313 LeftBit = 1 << (MouseEvent::BUTTON_LEFT - 1), 302 LeftBit = 1 << (MouseEvent::BUTTON_LEFT - 1),
314 MiddleBit = 1 << (MouseEvent::BUTTON_MIDDLE - 1), 303 MiddleBit = 1 << (MouseEvent::BUTTON_MIDDLE - 1),
315 RightBit = 1 << (MouseEvent::BUTTON_RIGHT - 1) 304 RightBit = 1 << (MouseEvent::BUTTON_RIGHT - 1)
316 }; 305 };
317 CGError error = CGPostMouseEvent(position, true, 3, 306 CGError error = CGPostMouseEvent(position, true, 3,
318 (mouse_buttons_ & LeftBit) != 0, 307 (mouse_button_state_ & LeftBit) != 0,
319 (mouse_buttons_ & RightBit) != 0, 308 (mouse_button_state_ & RightBit) != 0,
320 (mouse_buttons_ & MiddleBit) != 0); 309 (mouse_button_state_ & MiddleBit) != 0);
321 if (error != kCGErrorSuccess) { 310 if (error != kCGErrorSuccess) {
322 LOG(WARNING) << "CGPostMouseEvent error " << error; 311 LOG(WARNING) << "CGPostMouseEvent error " << error;
323 } 312 }
324 313
325 if (event.has_wheel_offset_x() && event.has_wheel_offset_y()) { 314 if (event.has_wheel_offset_x() && event.has_wheel_offset_y()) {
326 int dx = event.wheel_offset_x(); 315 int dx = event.wheel_offset_x();
327 int dy = event.wheel_offset_y(); 316 int dy = event.wheel_offset_y();
328 // Note that |dy| (the vertical wheel) is the primary wheel. 317 // Note that |dy| (the vertical wheel) is the primary wheel.
329 error = CGPostScrollWheelEvent(2, dy, dx); 318 error = CGPostScrollWheelEvent(2, dy, dx);
330 if (error != kCGErrorSuccess) { 319 if (error != kCGErrorSuccess) {
331 LOG(WARNING) << "CGPostScrollWheelEvent error " << error; 320 LOG(WARNING) << "CGPostScrollWheelEvent error " << error;
332 } 321 }
333 } 322 }
334 } 323 }
335 324
336 } // namespace 325 } // namespace
337 326
338 scoped_ptr<protocol::HostEventStub> EventExecutor::Create( 327 scoped_ptr<protocol::HostEventStub> EventExecutor::Create(
339 MessageLoop* message_loop, Capturer* capturer) { 328 MessageLoop* message_loop, Capturer* capturer) {
340 return scoped_ptr<protocol::HostEventStub>( 329 return scoped_ptr<protocol::HostEventStub>(
341 new EventExecutorMac(message_loop, capturer)); 330 new EventExecutorMac(message_loop));
342 } 331 }
343 332
344 } // namespace remoting 333 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/event_executor_linux.cc ('k') | remoting/protocol/mouse_input_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698