Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
|
Lambros
2014/08/05 22:47:24
Does this need to be a .mm file? It doesn't seem t
ronakvora do not use
2014/08/06 20:56:16
Guess not! I just saw that every mac file was .mm
| |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "remoting/host/single_window_input_injector.h" | |
| 6 | |
| 7 #include <ApplicationServices/ApplicationServices.h> | |
| 8 #include <Carbon/Carbon.h> | |
| 9 | |
| 10 #include "base/mac/scoped_cftyperef.h" | |
| 11 #include "remoting/proto/internal.pb.h" | |
| 12 #include "third_party/webrtc/modules/desktop_capture/mac/desktop_configuration.h " | |
| 13 | |
| 14 namespace remoting { | |
| 15 | |
| 16 using protocol::ClipboardEvent; | |
| 17 using protocol::KeyEvent; | |
| 18 using protocol::TextEvent; | |
| 19 using protocol::MouseEvent; | |
| 20 | |
| 21 // A class to generate events to a window on Mac. | |
| 22 class SingleWindowInputInjectorMac : public SingleWindowInputInjector { | |
| 23 public: | |
| 24 SingleWindowInputInjectorMac( | |
| 25 webrtc::WindowId window_id, | |
| 26 scoped_ptr<InputInjector> input_injector); | |
| 27 | |
| 28 virtual ~SingleWindowInputInjectorMac(); | |
| 29 | |
| 30 // InputInjector interface. | |
| 31 virtual void Start( | |
| 32 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; | |
| 33 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; | |
| 34 virtual void InjectTextEvent(const TextEvent& event) OVERRIDE; | |
| 35 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; | |
| 36 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; | |
| 37 | |
| 38 private: | |
| 39 CGRect FindCGRectOfWindow(); | |
| 40 | |
| 41 CGWindowID window_id_; | |
| 42 scoped_ptr<InputInjector> input_injector_; | |
| 43 | |
| 44 DISALLOW_COPY_AND_ASSIGN(SingleWindowInputInjectorMac); | |
| 45 }; | |
| 46 | |
| 47 SingleWindowInputInjectorMac::SingleWindowInputInjectorMac( | |
| 48 webrtc::WindowId window_id, | |
| 49 scoped_ptr<InputInjector> input_injector): | |
|
Lambros
2014/08/05 22:47:24
nit: Move ':' to next line, and format like this:
ronakvora do not use
2014/08/06 20:56:16
Done.
| |
| 50 window_id_((CGWindowID)window_id), | |
|
Lambros
2014/08/05 22:47:24
nit: static_cast<CGWindowID>(window_id)
(see forma
ronakvora do not use
2014/08/06 20:56:16
Done.
| |
| 51 input_injector_(input_injector.Pass()) { | |
| 52 } | |
| 53 | |
| 54 SingleWindowInputInjectorMac::~SingleWindowInputInjectorMac() { | |
| 55 } | |
| 56 | |
| 57 void SingleWindowInputInjectorMac::Start( | |
| 58 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | |
| 59 input_injector_->Start(client_clipboard.Pass()); | |
| 60 } | |
| 61 | |
| 62 void SingleWindowInputInjectorMac::InjectKeyEvent(const KeyEvent& event) { | |
| 63 input_injector_->InjectKeyEvent(event); | |
| 64 } | |
| 65 | |
| 66 void SingleWindowInputInjectorMac::InjectTextEvent(const TextEvent& event) { | |
| 67 input_injector_->InjectTextEvent(event); | |
| 68 } | |
| 69 | |
| 70 void SingleWindowInputInjectorMac::InjectMouseEvent(const MouseEvent& event) { | |
| 71 if (event.has_x() && event.has_y()) { | |
| 72 CGRect windowRect = FindCGRectOfWindow(); | |
| 73 if (CGRectIsNull(windowRect)) { | |
| 74 LOG(ERROR) << "Failing silently and just forwarding event"; | |
| 75 input_injector_->InjectMouseEvent(event); | |
| 76 return; | |
| 77 } | |
| 78 webrtc::MacDesktopConfiguration desktop_config = | |
| 79 webrtc::MacDesktopConfiguration::GetCurrent( | |
| 80 webrtc::MacDesktopConfiguration::TopLeftOrigin); | |
| 81 | |
| 82 // Create a vector that has the origin of the window. | |
| 83 webrtc::DesktopVector mouse_pos(CGRectGetMinX(windowRect), | |
| 84 CGRectGetMinY(windowRect)); | |
| 85 | |
| 86 // Subtract coordinates that are already added in for multiple | |
| 87 // desktops. They get added in already in InputInjector. | |
| 88 mouse_pos.subtract( | |
| 89 webrtc::DesktopVector(desktop_config.pixel_bounds.left(), | |
| 90 desktop_config.pixel_bounds.top())); | |
| 91 | |
| 92 // Create a new event with coordinates that are in respect to the window. | |
| 93 MouseEvent modified_event(event); | |
| 94 modified_event.set_x( | |
| 95 event.x() + mouse_pos.x() * desktop_config.dip_to_pixel_scale); | |
| 96 modified_event.set_y( | |
| 97 event.y() + mouse_pos.y() * desktop_config.dip_to_pixel_scale); | |
| 98 input_injector_->InjectMouseEvent(modified_event); | |
| 99 } else { | |
| 100 input_injector_->InjectMouseEvent(event); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 void SingleWindowInputInjectorMac::InjectClipboardEvent( | |
| 105 const ClipboardEvent& event) { | |
| 106 input_injector_->InjectClipboardEvent(event); | |
| 107 } | |
| 108 | |
| 109 // This method is used if we are capturing a window instead of a screen. | |
| 110 // It finds the rectangle of the window we are streaming using | |
| 111 // |window_id_|. The InputInjector can then use this rectangle | |
| 112 // to translate the input event to coordinates of the window rather | |
| 113 // than the screen. | |
| 114 CGRect SingleWindowInputInjectorMac::FindCGRectOfWindow() { | |
| 115 CGRect rect; | |
| 116 CGWindowID ids[1] = {window_id_}; | |
| 117 base::ScopedCFTypeRef<CFArrayRef> window_id_array( | |
| 118 CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL)); | |
| 119 | |
| 120 base::ScopedCFTypeRef<CFArrayRef> window_array( | |
| 121 CGWindowListCreateDescriptionFromArray(window_id_array)); | |
| 122 | |
| 123 if (window_array == NULL || CFArrayGetCount(window_array) == 0) { | |
|
Lambros
2014/08/05 22:47:23
I think you can do 'window_array.is_null()' ?
ronakvora do not use
2014/08/06 20:56:16
I don't think ScopedCFTypeRef has this method impl
| |
| 124 // Could not find the window. It might have been closed. | |
| 125 LOG(ERROR) << "Specified window to stream not found for id: " | |
| 126 << window_id_; | |
| 127 return CGRectNull; | |
| 128 } | |
| 129 | |
| 130 CFDictionaryRef window = | |
|
Lambros
2014/08/05 22:47:23
To answer your question, the raw CFDictonaryRef is
ronakvora do not use
2014/08/06 20:56:16
Acknowledged.
| |
| 131 reinterpret_cast<CFDictionaryRef>( | |
|
Lambros
2014/08/05 22:47:23
nit: Use CFCast<> from base/mac/foundation_util.h
ronakvora do not use
2014/08/06 20:56:16
Done.
| |
| 132 CFArrayGetValueAtIndex(window_array, 0)); | |
| 133 | |
| 134 if (CFDictionaryContainsKey(window, kCGWindowBounds)) { | |
|
Lambros
2014/08/05 22:47:24
nit: Use GetValueFromDictionary() from base/mac/fo
ronakvora do not use
2014/08/06 20:56:16
Done.
| |
| 135 CFDictionaryRef bounds = | |
|
Lambros
2014/08/05 22:47:23
Same here. This ref is owned by the |window| dicti
ronakvora do not use
2014/08/06 20:56:16
Acknowledged.
| |
| 136 reinterpret_cast<CFDictionaryRef>( | |
| 137 CFDictionaryGetValue(window, kCGWindowBounds)); | |
| 138 if (bounds) { | |
| 139 CGRectMakeWithDictionaryRepresentation(bounds, &rect); | |
|
Lambros
2014/08/05 22:47:24
Check that CGRectMakeWithDictionaryRepresentation
ronakvora do not use
2014/08/06 20:56:16
Done.
| |
| 140 } else { | |
| 141 return CGRectNull; | |
| 142 } | |
| 143 } else { | |
| 144 return CGRectNull; | |
| 145 } | |
| 146 | |
| 147 return rect; | |
| 148 } | |
| 149 | |
| 150 scoped_ptr<InputInjector> SingleWindowInputInjector::Create( | |
| 151 webrtc::WindowId window_id, | |
| 152 scoped_ptr<InputInjector> input_injector) { | |
| 153 scoped_ptr<SingleWindowInputInjectorMac>injector( | |
|
Lambros
2014/08/05 22:47:24
nit: space between '>' and injector
ronakvora do not use
2014/08/06 20:56:16
Done.
| |
| 154 new SingleWindowInputInjectorMac(window_id, input_injector.Pass())); | |
| 155 return injector.PassAs<InputInjector>(); | |
| 156 } | |
| 157 | |
| 158 | |
| 159 | |
| 160 } // namespace remoting | |
| OLD | NEW |