OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "ash/display/mirror_window_controller.h" | 5 #include "ash/display/mirror_window_controller.h" |
6 | 6 |
7 #if defined(USE_X11) | 7 #if defined(USE_X11) |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 // Xlib.h defines RootWindow. | 10 // Xlib.h defines RootWindow. |
11 #undef RootWindow | 11 #undef RootWindow |
12 #endif | 12 #endif |
13 | 13 |
| 14 #include "ash/display/cursor_window_controller.h" |
14 #include "ash/display/display_controller.h" | 15 #include "ash/display/display_controller.h" |
15 #include "ash/display/display_info.h" | 16 #include "ash/display/display_info.h" |
16 #include "ash/display/display_manager.h" | 17 #include "ash/display/display_manager.h" |
17 #include "ash/display/root_window_transformers.h" | 18 #include "ash/display/root_window_transformers.h" |
18 #include "ash/host/root_window_host_factory.h" | 19 #include "ash/host/root_window_host_factory.h" |
19 #include "ash/root_window_settings.h" | 20 #include "ash/root_window_settings.h" |
20 #include "ash/shell.h" | 21 #include "ash/shell.h" |
21 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
22 #include "ui/aura/client/capture_client.h" | 23 #include "ui/aura/client/capture_client.h" |
23 #include "ui/aura/env.h" | |
24 #include "ui/aura/root_window.h" | 24 #include "ui/aura/root_window.h" |
25 #include "ui/aura/root_window_transformer.h" | 25 #include "ui/aura/root_window_transformer.h" |
26 #include "ui/aura/window_delegate.h" | 26 #include "ui/aura/window_delegate.h" |
27 #include "ui/base/cursor/cursors_aura.h" | |
28 #include "ui/base/hit_test.h" | |
29 #include "ui/base/layout.h" | 27 #include "ui/base/layout.h" |
30 #include "ui/base/resource/resource_bundle.h" | |
31 #include "ui/compositor/reflector.h" | 28 #include "ui/compositor/reflector.h" |
32 #include "ui/gfx/canvas.h" | 29 #include "ui/gfx/canvas.h" |
33 #include "ui/gfx/image/image_skia.h" | |
34 #include "ui/gfx/image/image_skia_operations.h" | |
35 #include "ui/gfx/native_widget_types.h" | 30 #include "ui/gfx/native_widget_types.h" |
36 | 31 |
37 #if defined(USE_X11) | 32 #if defined(USE_X11) |
38 #include "ui/gfx/x/x11_types.h" | 33 #include "ui/gfx/x/x11_types.h" |
39 #endif | 34 #endif |
40 | 35 |
41 namespace ash { | 36 namespace ash { |
42 namespace internal { | 37 namespace internal { |
43 namespace { | 38 namespace { |
44 | 39 |
(...skipping 24 matching lines...) Expand all Loading... |
69 } | 64 } |
70 virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE { | 65 virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE { |
71 return NULL; | 66 return NULL; |
72 } | 67 } |
73 | 68 |
74 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); | 69 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); |
75 }; | 70 }; |
76 | 71 |
77 } // namespace | 72 } // namespace |
78 | 73 |
79 class CursorWindowDelegate : public aura::WindowDelegate { | 74 MirrorWindowController::MirrorWindowController() {} |
80 public: | |
81 CursorWindowDelegate() {} | |
82 virtual ~CursorWindowDelegate() {} | |
83 | |
84 // aura::WindowDelegate overrides: | |
85 virtual gfx::Size GetMinimumSize() const OVERRIDE { | |
86 return size_; | |
87 } | |
88 virtual gfx::Size GetMaximumSize() const OVERRIDE { | |
89 return size_; | |
90 } | |
91 virtual void OnBoundsChanged(const gfx::Rect& old_bounds, | |
92 const gfx::Rect& new_bounds) OVERRIDE { | |
93 } | |
94 virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE { | |
95 return gfx::kNullCursor; | |
96 } | |
97 virtual int GetNonClientComponent( | |
98 const gfx::Point& point) const OVERRIDE { | |
99 return HTNOWHERE; | |
100 } | |
101 virtual bool ShouldDescendIntoChildForEventHandling( | |
102 aura::Window* child, | |
103 const gfx::Point& location) OVERRIDE { | |
104 return false; | |
105 } | |
106 virtual bool CanFocus() OVERRIDE { | |
107 return false; | |
108 } | |
109 virtual void OnCaptureLost() OVERRIDE { | |
110 } | |
111 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { | |
112 canvas->DrawImageInt(cursor_image_, 0, 0); | |
113 } | |
114 virtual void OnDeviceScaleFactorChanged( | |
115 float device_scale_factor) OVERRIDE { | |
116 } | |
117 virtual void OnWindowDestroying() OVERRIDE {} | |
118 virtual void OnWindowDestroyed() OVERRIDE {} | |
119 virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE { | |
120 } | |
121 virtual bool HasHitTestMask() const OVERRIDE { | |
122 return false; | |
123 } | |
124 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {} | |
125 virtual void DidRecreateLayer(ui::Layer* old_layer, | |
126 ui::Layer* new_layer) OVERRIDE {} | |
127 | |
128 // Set the cursor image for the |display|'s scale factor. Note that | |
129 // mirror window's scale factor is always 1.0f, therefore we need to | |
130 // take 2x's image and paint as if it's 1x image. | |
131 void SetCursorImage(const gfx::ImageSkia& image, | |
132 const gfx::Display& display) { | |
133 const gfx::ImageSkiaRep& image_rep = | |
134 image.GetRepresentation(display.device_scale_factor()); | |
135 size_ = image_rep.pixel_size(); | |
136 cursor_image_ = gfx::ImageSkia::CreateFrom1xBitmap(image_rep.sk_bitmap()); | |
137 } | |
138 | |
139 const gfx::Size size() const { return size_; } | |
140 | |
141 private: | |
142 gfx::ImageSkia cursor_image_; | |
143 gfx::Size size_; | |
144 | |
145 DISALLOW_COPY_AND_ASSIGN(CursorWindowDelegate); | |
146 }; | |
147 | |
148 MirrorWindowController::MirrorWindowController() | |
149 : current_cursor_type_(ui::kCursorNone), | |
150 current_cursor_rotation_(gfx::Display::ROTATE_0), | |
151 cursor_window_(NULL), | |
152 cursor_window_delegate_(new CursorWindowDelegate) { | |
153 } | |
154 | 75 |
155 MirrorWindowController::~MirrorWindowController() { | 76 MirrorWindowController::~MirrorWindowController() { |
156 // Make sure the root window gets deleted before cursor_window_delegate. | 77 // Make sure the root window gets deleted before cursor_window_delegate. |
157 Close(); | 78 Close(); |
158 } | 79 } |
159 | 80 |
160 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { | 81 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { |
161 static int mirror_root_window_count = 0; | 82 static int mirror_root_window_count = 0; |
162 | 83 |
163 if (!root_window_.get()) { | 84 if (!root_window_.get()) { |
(...skipping 24 matching lines...) Expand all Loading... |
188 | 109 |
189 // TODO(oshima): Start mirroring. | 110 // TODO(oshima): Start mirroring. |
190 aura::Window* mirror_window = new aura::Window(NULL); | 111 aura::Window* mirror_window = new aura::Window(NULL); |
191 mirror_window->Init(aura::WINDOW_LAYER_TEXTURED); | 112 mirror_window->Init(aura::WINDOW_LAYER_TEXTURED); |
192 root_window_->window()->AddChild(mirror_window); | 113 root_window_->window()->AddChild(mirror_window); |
193 mirror_window->SetBounds(root_window_->window()->bounds()); | 114 mirror_window->SetBounds(root_window_->window()->bounds()); |
194 mirror_window->Show(); | 115 mirror_window->Show(); |
195 reflector_ = ui::ContextFactory::GetInstance()->CreateReflector( | 116 reflector_ = ui::ContextFactory::GetInstance()->CreateReflector( |
196 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->compositor(), | 117 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->compositor(), |
197 mirror_window->layer()); | 118 mirror_window->layer()); |
198 | |
199 cursor_window_ = new aura::Window(cursor_window_delegate_.get()); | |
200 cursor_window_->SetTransparent(true); | |
201 cursor_window_->Init(aura::WINDOW_LAYER_TEXTURED); | |
202 root_window_->window()->AddChild(cursor_window_); | |
203 cursor_window_->Show(); | |
204 } else { | 119 } else { |
205 GetRootWindowSettings(root_window_->window())->display_id = | 120 GetRootWindowSettings(root_window_->window())->display_id = |
206 display_info.id(); | 121 display_info.id(); |
207 root_window_->host()->SetBounds(display_info.bounds_in_native()); | 122 root_window_->host()->SetBounds(display_info.bounds_in_native()); |
208 } | 123 } |
209 | 124 |
210 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 125 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
211 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 126 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
212 Shell::GetScreen()->GetPrimaryDisplay().id()); | 127 Shell::GetScreen()->GetPrimaryDisplay().id()); |
213 DCHECK(display_manager->IsMirrored()); | 128 DCHECK(display_manager->IsMirrored()); |
214 scoped_ptr<aura::RootWindowTransformer> transformer( | 129 scoped_ptr<aura::RootWindowTransformer> transformer( |
215 internal::CreateRootWindowTransformerForMirroredDisplay( | 130 internal::CreateRootWindowTransformerForMirroredDisplay( |
216 source_display_info, | 131 source_display_info, |
217 display_info)); | 132 display_info)); |
218 root_window_->host()->SetRootWindowTransformer(transformer.Pass()); | 133 root_window_->host()->SetRootWindowTransformer(transformer.Pass()); |
219 | |
220 UpdateCursorLocation(); | |
221 } | 134 } |
222 | 135 |
223 void MirrorWindowController::UpdateWindow() { | 136 void MirrorWindowController::UpdateWindow() { |
224 if (root_window_.get()) { | 137 if (root_window_.get()) { |
225 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 138 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
226 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( | 139 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( |
227 display_manager->mirrored_display_id()); | 140 display_manager->mirrored_display_id()); |
228 UpdateWindow(mirror_display_info); | 141 UpdateWindow(mirror_display_info); |
229 } | 142 } |
230 } | 143 } |
231 | 144 |
232 void MirrorWindowController::Close() { | 145 void MirrorWindowController::Close() { |
233 if (root_window_.get()) { | 146 if (root_window_.get()) { |
234 ui::ContextFactory::GetInstance()->RemoveReflector(reflector_); | 147 ui::ContextFactory::GetInstance()->RemoveReflector(reflector_); |
235 reflector_ = NULL; | 148 reflector_ = NULL; |
236 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( | 149 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
237 aura::client::GetCaptureClient(root_window_->window())); | 150 aura::client::GetCaptureClient(root_window_->window())); |
238 aura::client::SetCaptureClient(root_window_->window(), NULL); | 151 aura::client::SetCaptureClient(root_window_->window(), NULL); |
239 delete capture_client; | 152 delete capture_client; |
240 | 153 |
241 root_window_->RemoveRootWindowObserver( | 154 root_window_->RemoveRootWindowObserver( |
242 Shell::GetInstance()->display_controller()); | 155 Shell::GetInstance()->display_controller()); |
243 root_window_->RemoveRootWindowObserver(this); | 156 root_window_->RemoveRootWindowObserver(this); |
244 root_window_.reset(); | 157 root_window_.reset(); |
245 cursor_window_ = NULL; | |
246 } | 158 } |
247 } | 159 } |
248 | 160 |
249 void MirrorWindowController::UpdateCursorLocation() { | |
250 if (cursor_window_) { | |
251 // TODO(oshima): Rotate cursor image (including hotpoint). | |
252 gfx::Point point = aura::Env::GetInstance()->last_mouse_location(); | |
253 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->ConvertPointToHost( | |
254 &point); | |
255 point.Offset(-hot_point_.x(), -hot_point_.y()); | |
256 gfx::Rect bounds = cursor_window_->bounds(); | |
257 bounds.set_origin(point); | |
258 cursor_window_->SetBounds(bounds); | |
259 } | |
260 } | |
261 | |
262 void MirrorWindowController::SetMirroredCursor(gfx::NativeCursor cursor) { | |
263 const gfx::Display& display = Shell::GetScreen()->GetPrimaryDisplay(); | |
264 if (current_cursor_type_ == cursor.native_type() && | |
265 current_cursor_rotation_ == display.rotation()) | |
266 return; | |
267 current_cursor_type_ = cursor.native_type(); | |
268 current_cursor_rotation_ = display.rotation(); | |
269 int resource_id; | |
270 bool success = ui::GetCursorDataFor( | |
271 ui::CURSOR_SET_NORMAL, // Not support custom cursor set. | |
272 current_cursor_type_, | |
273 display.device_scale_factor(), | |
274 &resource_id, | |
275 &hot_point_); | |
276 if (!success) | |
277 return; | |
278 const gfx::ImageSkia* image = | |
279 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); | |
280 gfx::ImageSkia rotated = *image; | |
281 switch (current_cursor_rotation_) { | |
282 case gfx::Display::ROTATE_0: | |
283 break; | |
284 case gfx::Display::ROTATE_90: | |
285 rotated = gfx::ImageSkiaOperations::CreateRotatedImage( | |
286 *image, SkBitmapOperations::ROTATION_90_CW); | |
287 hot_point_.SetPoint( | |
288 rotated.width() - hot_point_.y(), | |
289 hot_point_.x()); | |
290 break; | |
291 case gfx::Display::ROTATE_180: | |
292 rotated = gfx::ImageSkiaOperations::CreateRotatedImage( | |
293 *image, SkBitmapOperations::ROTATION_180_CW); | |
294 hot_point_.SetPoint( | |
295 rotated.height() - hot_point_.x(), | |
296 rotated.width() - hot_point_.y()); | |
297 break; | |
298 case gfx::Display::ROTATE_270: | |
299 rotated = gfx::ImageSkiaOperations::CreateRotatedImage( | |
300 *image, SkBitmapOperations::ROTATION_270_CW); | |
301 hot_point_.SetPoint( | |
302 hot_point_.y(), | |
303 rotated.height() - hot_point_.x()); | |
304 break; | |
305 } | |
306 cursor_window_delegate_->SetCursorImage(rotated, display); | |
307 | |
308 if (cursor_window_) { | |
309 cursor_window_->SetBounds(gfx::Rect(cursor_window_delegate_->size())); | |
310 cursor_window_->SchedulePaintInRect( | |
311 gfx::Rect(cursor_window_->bounds().size())); | |
312 UpdateCursorLocation(); | |
313 } | |
314 } | |
315 | |
316 void MirrorWindowController::SetMirroredCursorVisibility(bool visible) { | |
317 if (cursor_window_) | |
318 visible ? cursor_window_->Show() : cursor_window_->Hide(); | |
319 } | |
320 | |
321 void MirrorWindowController::OnWindowTreeHostResized( | 161 void MirrorWindowController::OnWindowTreeHostResized( |
322 const aura::RootWindow* root) { | 162 const aura::RootWindow* root) { |
323 // Do not use |old_size| as it contains RootWindow's (but not host's) size, | 163 // Do not use |old_size| as it contains RootWindow's (but not host's) size, |
324 // and this parameter wil be removed soon. | 164 // and this parameter wil be removed soon. |
325 if (mirror_window_host_size_ == root->host()->GetBounds().size()) | 165 if (mirror_window_host_size_ == root->host()->GetBounds().size()) |
326 return; | 166 return; |
327 mirror_window_host_size_ = root->host()->GetBounds().size(); | 167 mirror_window_host_size_ = root->host()->GetBounds().size(); |
328 reflector_->OnMirroringCompositorResized(); | 168 reflector_->OnMirroringCompositorResized(); |
329 root_window_->host()->SetRootWindowTransformer( | 169 root_window_->host()->SetRootWindowTransformer( |
330 CreateRootWindowTransformer().Pass()); | 170 CreateRootWindowTransformer().Pass()); |
331 UpdateCursorLocation(); | 171 Shell::GetInstance()->display_controller()->cursor_window_controller()-> |
| 172 UpdateLocation(); |
332 } | 173 } |
333 | 174 |
334 | 175 |
335 scoped_ptr<aura::RootWindowTransformer> | 176 scoped_ptr<aura::RootWindowTransformer> |
336 MirrorWindowController::CreateRootWindowTransformer() const { | 177 MirrorWindowController::CreateRootWindowTransformer() const { |
337 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 178 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
338 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( | 179 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( |
339 display_manager->mirrored_display_id()); | 180 display_manager->mirrored_display_id()); |
340 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 181 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
341 Shell::GetScreen()->GetPrimaryDisplay().id()); | 182 Shell::GetScreen()->GetPrimaryDisplay().id()); |
342 DCHECK(display_manager->IsMirrored()); | 183 DCHECK(display_manager->IsMirrored()); |
343 return scoped_ptr<aura::RootWindowTransformer>( | 184 return scoped_ptr<aura::RootWindowTransformer>( |
344 internal::CreateRootWindowTransformerForMirroredDisplay( | 185 internal::CreateRootWindowTransformerForMirroredDisplay( |
345 source_display_info, | 186 source_display_info, |
346 mirror_display_info)); | 187 mirror_display_info)); |
347 } | 188 } |
348 | 189 |
349 } // namespace internal | 190 } // namespace internal |
350 } // namespace ash | 191 } // namespace ash |
OLD | NEW |