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

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: 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
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"
17 16
18 namespace remoting { 17 namespace remoting {
19 18
20 namespace { 19 namespace {
21 20
22 using protocol::ClipboardEvent; 21 using protocol::ClipboardEvent;
23 using protocol::KeyEvent; 22 using protocol::KeyEvent;
24 using protocol::MouseEvent; 23 using protocol::MouseEvent;
25 24
26 // USB to Mac keycode mapping table. 25 // USB to Mac keycode mapping table.
27 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} 26 #define USB_KEYMAP(usb, xkb, win, mac) {usb, mac}
28 #include "remoting/host/usb_keycode_map.h" 27 #include "remoting/host/usb_keycode_map.h"
29 #undef USB_KEYMAP 28 #undef USB_KEYMAP
30 29
31 // A class to generate events on Mac. 30 // A class to generate events on Mac.
32 class EventExecutorMac : public EventExecutor { 31 class EventExecutorMac : public EventExecutor {
33 public: 32 public:
34 EventExecutorMac(MessageLoop* message_loop, Capturer* capturer); 33 EventExecutorMac(MessageLoop* message_loop);
35 virtual ~EventExecutorMac() {} 34 virtual ~EventExecutorMac() {}
36 35
37 // ClipboardStub interface. 36 // ClipboardStub interface.
38 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; 37 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE;
39 38
40 // InputStub interface. 39 // InputStub interface.
41 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; 40 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE;
42 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; 41 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE;
43 42
44 private: 43 private:
45 MessageLoop* message_loop_; 44 MessageLoop* message_loop_;
46 Capturer* capturer_; 45 SkIPoint mouse_pos_;
47 int last_x_, last_y_; 46 uint32 mouse_button_state_;
48 int mouse_buttons_;
49 47
50 DISALLOW_COPY_AND_ASSIGN(EventExecutorMac); 48 DISALLOW_COPY_AND_ASSIGN(EventExecutorMac);
51 }; 49 };
52 50
53 EventExecutorMac::EventExecutorMac( 51 EventExecutorMac::EventExecutorMac(
54 MessageLoop* message_loop, Capturer* capturer) 52 MessageLoop* message_loop)
55 : message_loop_(message_loop), 53 : message_loop_(message_loop), mouse_button_state_(0) {
56 capturer_(capturer), last_x_(0), last_y_(0), mouse_buttons_(0) {
57 } 54 }
58 55
59 // Hard-coded mapping from Virtual Key codes to Mac KeySyms. 56 // Hard-coded mapping from Virtual Key codes to Mac KeySyms.
60 // This mapping is only valid if both client and host are using a 57 // This mapping is only valid if both client and host are using a
61 // US English keyboard layout. 58 // US English keyboard layout.
62 // Because we're passing VK codes on the wire, with no Scancode, 59 // Because we're passing VK codes on the wire, with no Scancode,
63 // "extended" flag, etc, things like distinguishing left & right 60 // "extended" flag, etc, things like distinguishing left & right
64 // Shift keys doesn't work. 61 // Shift keys doesn't work.
65 // 62 //
66 // TODO(wez): Replace this with something more closely tied to what 63 // 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 264 // We use the deprecated event injection API because the new one doesn't
268 // work with switched-out sessions (curtain mode). 265 // work with switched-out sessions (curtain mode).
269 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); 266 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed());
270 if (error != kCGErrorSuccess) { 267 if (error != kCGErrorSuccess) {
271 LOG(WARNING) << "CGPostKeyboardEvent error " << error; 268 LOG(WARNING) << "CGPostKeyboardEvent error " << error;
272 } 269 }
273 } 270 }
274 271
275 void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { 272 void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) {
276 if (event.has_x() && event.has_y()) { 273 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) 274 // 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 275 // corresponds to local (0,0) (top-left of primary monitor). That won't in
281 // general be true on multi-monitor systems, though. 276 // general be true on multi-monitor systems, though.
282 SkISize size = capturer_->size_most_recent(); 277 VLOG(3) << "Moving mouse to " << event.x() << "," << event.y();
283 if (event.x() >= 0 || event.y() >= 0 || 278 mouse_pos_ = SkIPoint::MakeXY(event.x(), event.y());
284 event.x() < size.width() || event.y() < size.height()) {
Wez 2012/04/27 17:39:51 Ditto re CHECK()ing here, and in the Windows imple
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 } 279 }
292 if (event.has_button() && event.has_button_down()) { 280 if (event.has_button() && event.has_button_down()) {
293 if (event.button() >= 1 && event.button() <= 3) { 281 if (event.button() >= 1 && event.button() <= 3) {
294 VLOG(2) << "Button " << event.button() 282 VLOG(2) << "Button " << event.button()
295 << (event.button_down() ? " down" : " up"); 283 << (event.button_down() ? " down" : " up");
296 int button_change = 1 << (event.button() - 1); 284 int button_change = 1 << (event.button() - 1);
297 if (event.button_down()) 285 if (event.button_down())
298 mouse_buttons_ |= button_change; 286 mouse_button_state_ |= button_change;
299 else 287 else
300 mouse_buttons_ &= ~button_change; 288 mouse_button_state_ &= ~button_change;
301 } else { 289 } else {
302 VLOG(1) << "Unknown mouse button: " << event.button(); 290 VLOG(1) << "Unknown mouse button: " << event.button();
303 } 291 }
304 } 292 }
305 // We use the deprecated CGPostMouseEvent API because we receive low-level 293 // We use the deprecated CGPostMouseEvent API because we receive low-level
306 // mouse events, whereas CGEventCreateMouseEvent is for injecting higher-level 294 // mouse events, whereas CGEventCreateMouseEvent is for injecting higher-level
307 // events. For example, the deprecated APIs will detect double-clicks or drags 295 // 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 296 // 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 297 // mouse, whereas the new APIs expect us to inject these higher-level events
310 // directly. 298 // directly.
311 CGPoint position = CGPointMake(last_x_, last_y_); 299 CGPoint position = CGPointMake(mouse_pos_.x(), mouse_pos_.y());
312 enum { 300 enum {
313 LeftBit = 1 << (MouseEvent::BUTTON_LEFT - 1), 301 LeftBit = 1 << (MouseEvent::BUTTON_LEFT - 1),
314 MiddleBit = 1 << (MouseEvent::BUTTON_MIDDLE - 1), 302 MiddleBit = 1 << (MouseEvent::BUTTON_MIDDLE - 1),
315 RightBit = 1 << (MouseEvent::BUTTON_RIGHT - 1) 303 RightBit = 1 << (MouseEvent::BUTTON_RIGHT - 1)
316 }; 304 };
317 CGError error = CGPostMouseEvent(position, true, 3, 305 CGError error = CGPostMouseEvent(position, true, 3,
318 (mouse_buttons_ & LeftBit) != 0, 306 (mouse_button_state_ & LeftBit) != 0,
319 (mouse_buttons_ & RightBit) != 0, 307 (mouse_button_state_ & RightBit) != 0,
320 (mouse_buttons_ & MiddleBit) != 0); 308 (mouse_button_state_ & MiddleBit) != 0);
321 if (error != kCGErrorSuccess) { 309 if (error != kCGErrorSuccess) {
322 LOG(WARNING) << "CGPostMouseEvent error " << error; 310 LOG(WARNING) << "CGPostMouseEvent error " << error;
323 } 311 }
324 312
325 if (event.has_wheel_offset_x() && event.has_wheel_offset_y()) { 313 if (event.has_wheel_offset_x() && event.has_wheel_offset_y()) {
326 int dx = event.wheel_offset_x(); 314 int dx = event.wheel_offset_x();
327 int dy = event.wheel_offset_y(); 315 int dy = event.wheel_offset_y();
328 // Note that |dy| (the vertical wheel) is the primary wheel. 316 // Note that |dy| (the vertical wheel) is the primary wheel.
329 error = CGPostScrollWheelEvent(2, dy, dx); 317 error = CGPostScrollWheelEvent(2, dy, dx);
330 if (error != kCGErrorSuccess) { 318 if (error != kCGErrorSuccess) {
331 LOG(WARNING) << "CGPostScrollWheelEvent error " << error; 319 LOG(WARNING) << "CGPostScrollWheelEvent error " << error;
332 } 320 }
333 } 321 }
334 } 322 }
335 323
336 } // namespace 324 } // namespace
337 325
338 scoped_ptr<protocol::HostEventStub> EventExecutor::Create( 326 scoped_ptr<protocol::HostEventStub> EventExecutor::Create(
339 MessageLoop* message_loop, Capturer* capturer) { 327 MessageLoop* message_loop, Capturer* capturer) {
340 return scoped_ptr<protocol::HostEventStub>( 328 return scoped_ptr<protocol::HostEventStub>(
341 new EventExecutorMac(message_loop, capturer)); 329 new EventExecutorMac(message_loop));
342 } 330 }
343 331
344 } // namespace remoting 332 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698