| 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/display_controller.h" | 14 #include "ash/display/display_controller.h" |
| 15 #include "ash/display/display_info.h" | 15 #include "ash/display/display_info.h" |
| 16 #include "ash/display/display_manager.h" | 16 #include "ash/display/display_manager.h" |
| 17 #include "ash/display/root_window_transformers.h" | 17 #include "ash/display/root_window_transformers.h" |
| 18 #include "ash/host/root_window_host_factory.h" | 18 #include "ash/host/root_window_host_factory.h" |
| 19 #include "ash/root_window_settings.h" | 19 #include "ash/root_window_settings.h" |
| 20 #include "ash/shell.h" | 20 #include "ash/shell.h" |
| 21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "ui/aura/client/capture_client.h" | 22 #include "ui/aura/client/capture_client.h" |
| 23 #include "ui/aura/env.h" | |
| 24 #include "ui/aura/root_window.h" | 23 #include "ui/aura/root_window.h" |
| 25 #include "ui/aura/root_window_transformer.h" | 24 #include "ui/aura/root_window_transformer.h" |
| 26 #include "ui/aura/window_delegate.h" | 25 #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" | 26 #include "ui/base/layout.h" |
| 30 #include "ui/base/resource/resource_bundle.h" | |
| 31 #include "ui/compositor/reflector.h" | 27 #include "ui/compositor/reflector.h" |
| 32 #include "ui/gfx/canvas.h" | 28 #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" | 29 #include "ui/gfx/native_widget_types.h" |
| 36 | 30 |
| 37 #if defined(USE_X11) | 31 #if defined(USE_X11) |
| 38 #include "ui/gfx/x/x11_types.h" | 32 #include "ui/gfx/x/x11_types.h" |
| 39 #endif | 33 #endif |
| 40 | 34 |
| 41 namespace ash { | 35 namespace ash { |
| 42 namespace internal { | 36 namespace internal { |
| 43 namespace { | 37 namespace { |
| 44 | 38 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 69 } | 63 } |
| 70 virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE { | 64 virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE { |
| 71 return NULL; | 65 return NULL; |
| 72 } | 66 } |
| 73 | 67 |
| 74 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); | 68 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); |
| 75 }; | 69 }; |
| 76 | 70 |
| 77 } // namespace | 71 } // namespace |
| 78 | 72 |
| 79 class CursorWindowDelegate : public aura::WindowDelegate { | |
| 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() | 73 MirrorWindowController::MirrorWindowController() |
| 149 : current_cursor_type_(ui::kCursorNone), | 74 : CursorWindowController(true) { |
| 150 current_cursor_rotation_(gfx::Display::ROTATE_0), | |
| 151 cursor_window_(NULL), | |
| 152 cursor_window_delegate_(new CursorWindowDelegate) { | |
| 153 } | 75 } |
| 154 | 76 |
| 155 MirrorWindowController::~MirrorWindowController() { | 77 MirrorWindowController::~MirrorWindowController() { |
| 156 // Make sure the root window gets deleted before cursor_window_delegate. | 78 // Make sure the root window gets deleted before cursor_window_delegate. |
| 157 Close(); | 79 Close(); |
| 158 } | 80 } |
| 159 | 81 |
| 160 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { | 82 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { |
| 161 static int mirror_root_window_count = 0; | 83 static int mirror_root_window_count = 0; |
| 162 | 84 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 189 // TODO(oshima): Start mirroring. | 111 // TODO(oshima): Start mirroring. |
| 190 aura::Window* mirror_window = new aura::Window(NULL); | 112 aura::Window* mirror_window = new aura::Window(NULL); |
| 191 mirror_window->Init(aura::WINDOW_LAYER_TEXTURED); | 113 mirror_window->Init(aura::WINDOW_LAYER_TEXTURED); |
| 192 root_window_->window()->AddChild(mirror_window); | 114 root_window_->window()->AddChild(mirror_window); |
| 193 mirror_window->SetBounds(root_window_->window()->bounds()); | 115 mirror_window->SetBounds(root_window_->window()->bounds()); |
| 194 mirror_window->Show(); | 116 mirror_window->Show(); |
| 195 reflector_ = ui::ContextFactory::GetInstance()->CreateReflector( | 117 reflector_ = ui::ContextFactory::GetInstance()->CreateReflector( |
| 196 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->compositor(), | 118 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->compositor(), |
| 197 mirror_window->layer()); | 119 mirror_window->layer()); |
| 198 | 120 |
| 199 cursor_window_ = new aura::Window(cursor_window_delegate_.get()); | 121 InitCursorWindow(root_window_->window()); |
| 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 { | 122 } else { |
| 205 GetRootWindowSettings(root_window_->window())->display_id = | 123 GetRootWindowSettings(root_window_->window())->display_id = |
| 206 display_info.id(); | 124 display_info.id(); |
| 207 root_window_->host()->SetBounds(display_info.bounds_in_native()); | 125 root_window_->host()->SetBounds(display_info.bounds_in_native()); |
| 208 } | 126 } |
| 209 | 127 |
| 210 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 128 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| 211 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 129 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
| 212 Shell::GetScreen()->GetPrimaryDisplay().id()); | 130 Shell::GetScreen()->GetPrimaryDisplay().id()); |
| 213 DCHECK(display_manager->IsMirrored()); | 131 DCHECK(display_manager->IsMirrored()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 235 reflector_ = NULL; | 153 reflector_ = NULL; |
| 236 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( | 154 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
| 237 aura::client::GetCaptureClient(root_window_->window())); | 155 aura::client::GetCaptureClient(root_window_->window())); |
| 238 aura::client::SetCaptureClient(root_window_->window(), NULL); | 156 aura::client::SetCaptureClient(root_window_->window(), NULL); |
| 239 delete capture_client; | 157 delete capture_client; |
| 240 | 158 |
| 241 root_window_->RemoveRootWindowObserver( | 159 root_window_->RemoveRootWindowObserver( |
| 242 Shell::GetInstance()->display_controller()); | 160 Shell::GetInstance()->display_controller()); |
| 243 root_window_->RemoveRootWindowObserver(this); | 161 root_window_->RemoveRootWindowObserver(this); |
| 244 root_window_.reset(); | 162 root_window_.reset(); |
| 245 cursor_window_ = NULL; | 163 CloseCursorWindow(); |
| 246 } | 164 } |
| 247 } | 165 } |
| 248 | 166 |
| 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( | 167 void MirrorWindowController::OnWindowTreeHostResized( |
| 322 const aura::RootWindow* root) { | 168 const aura::RootWindow* root) { |
| 323 // Do not use |old_size| as it contains RootWindow's (but not host's) size, | 169 // Do not use |old_size| as it contains RootWindow's (but not host's) size, |
| 324 // and this parameter wil be removed soon. | 170 // and this parameter wil be removed soon. |
| 325 if (mirror_window_host_size_ == root->host()->GetBounds().size()) | 171 if (mirror_window_host_size_ == root->host()->GetBounds().size()) |
| 326 return; | 172 return; |
| 327 mirror_window_host_size_ = root->host()->GetBounds().size(); | 173 mirror_window_host_size_ = root->host()->GetBounds().size(); |
| 328 reflector_->OnMirroringCompositorResized(); | 174 reflector_->OnMirroringCompositorResized(); |
| 329 root_window_->host()->SetRootWindowTransformer( | 175 root_window_->host()->SetRootWindowTransformer( |
| 330 CreateRootWindowTransformer().Pass()); | 176 CreateRootWindowTransformer().Pass()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 341 Shell::GetScreen()->GetPrimaryDisplay().id()); | 187 Shell::GetScreen()->GetPrimaryDisplay().id()); |
| 342 DCHECK(display_manager->IsMirrored()); | 188 DCHECK(display_manager->IsMirrored()); |
| 343 return scoped_ptr<aura::RootWindowTransformer>( | 189 return scoped_ptr<aura::RootWindowTransformer>( |
| 344 internal::CreateRootWindowTransformerForMirroredDisplay( | 190 internal::CreateRootWindowTransformerForMirroredDisplay( |
| 345 source_display_info, | 191 source_display_info, |
| 346 mirror_display_info)); | 192 mirror_display_info)); |
| 347 } | 193 } |
| 348 | 194 |
| 349 } // namespace internal | 195 } // namespace internal |
| 350 } // namespace ash | 196 } // namespace ash |
| OLD | NEW |