mirror_window_controller.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/display/mirror_window_controller.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(USE_X11)
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <X11/Xlib.h>
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Xlib.h defines RootWindow.
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#undef RootWindow
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ash/display/display_controller.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/display/display_info.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/display/display_manager.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/display/root_window_transformers.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/host/root_window_host_factory.h"
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ash/root_window_settings.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/shell.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/client/capture_client.h"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/env.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/root_window.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/aura/root_window_transformer.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/window_delegate.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/cursor/cursors_aura.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/hit_test.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/layout.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/reflector.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/canvas.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/image/image_skia.h"
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h"
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/native_widget_types.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(USE_X11)
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_types.h"
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace ash {
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace internal {
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(USE_X11)
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Mirror window shouldn't handle input events.
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisableInput(XID window) {
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  long event_mask = ExposureMask | VisibilityChangeMask |
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      StructureNotifyMask | PropertyChangeMask;
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  XSelectInput(gfx::GetXDisplay(), window, event_mask);
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NoneCaptureClient : public aura::client::CaptureClient {
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NoneCaptureClient() {}
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~NoneCaptureClient() {}
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Does a capture on the |window|.
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void SetCapture(aura::Window* window) OVERRIDE {}
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Releases a capture from the |window|.
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void ReleaseCapture(aura::Window* window) OVERRIDE {}
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Returns the current capture window.
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual aura::Window* GetCaptureWindow() OVERRIDE {
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient);
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class CursorWindowDelegate : public aura::WindowDelegate {
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CursorWindowDelegate() {}
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~CursorWindowDelegate() {}
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // aura::WindowDelegate overrides:
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual gfx::Size GetMinimumSize() const OVERRIDE {
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return size_;
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual gfx::Size GetMaximumSize() const OVERRIDE {
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return size_;
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               const gfx::Rect& new_bounds) OVERRIDE {
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return gfx::kNullCursor;
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual int GetNonClientComponent(
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const gfx::Point& point) const OVERRIDE {
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return HTNOWHERE;
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool ShouldDescendIntoChildForEventHandling(
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      aura::Window* child,
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const gfx::Point& location) OVERRIDE {
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool CanFocus() OVERRIDE {
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnCaptureLost() OVERRIDE {
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    canvas->DrawImageInt(cursor_image_, 0, 0);
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnDeviceScaleFactorChanged(
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      float device_scale_factor) OVERRIDE {
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnWindowDestroying() OVERRIDE {}
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnWindowDestroyed() OVERRIDE {}
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool HasHitTestMask() const OVERRIDE {
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DidRecreateLayer(ui::Layer* old_layer,
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                ui::Layer* new_layer) OVERRIDE {}
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Set the cursor image for the |display|'s scale factor.  Note that
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // mirror window's scale factor is always 1.0f, therefore we need to
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // take 2x's image and paint as if it's 1x image.
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void SetCursorImage(const gfx::ImageSkia& image,
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      const gfx::Display& display) {
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const gfx::ImageSkiaRep& image_rep =
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        image.GetRepresentation(display.device_scale_factor());
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_ = image_rep.pixel_size();
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cursor_image_ = gfx::ImageSkia::CreateFrom1xBitmap(image_rep.sk_bitmap());
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::Size size() const { return size_; }
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::ImageSkia cursor_image_;
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  gfx::Size size_;
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CursorWindowDelegate);
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MirrorWindowController::MirrorWindowController()
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : current_cursor_type_(ui::kCursorNone),
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      current_cursor_rotation_(gfx::Display::ROTATE_0),
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      cursor_window_(NULL),
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      cursor_window_delegate_(new CursorWindowDelegate) {
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MirrorWindowController::~MirrorWindowController() {
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure the root window gets deleted before cursor_window_delegate.
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Close();
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) {
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static int mirror_root_window_count = 0;
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!root_window_.get()) {
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    aura::RootWindow::CreateParams params(bounds_in_native);
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    params.host = Shell::GetInstance()->root_window_host_factory()->
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        CreateRootWindowHost(bounds_in_native);
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_.reset(new aura::RootWindow(params));
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->SetName(
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::StringPrintf("MirrorRootWindow-%d", mirror_root_window_count++));
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->compositor()->SetBackgroundColor(SK_ColorBLACK);
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // No need to remove RootWindowObserver because
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // the DisplayController object outlives RootWindow objects.
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    root_window_->AddRootWindowObserver(
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        Shell::GetInstance()->display_controller());
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->AddRootWindowObserver(this);
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(oshima): TouchHUD is using idkey.
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    InitRootWindowSettings(root_window_.get())->display_id = display_info.id();
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->Init();
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(USE_X11)
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DisableInput(root_window_->GetAcceleratedWidget());
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    aura::client::SetCaptureClient(root_window_.get(), new NoneCaptureClient());
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->ShowRootWindow();
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(oshima): Start mirroring.
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    aura::Window* mirror_window = new aura::Window(NULL);
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mirror_window->Init(ui::LAYER_TEXTURED);
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->AddChild(mirror_window);
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mirror_window->SetBounds(root_window_->bounds());
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mirror_window->Show();
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    reflector_ = ui::ContextFactory::GetInstance()->CreateReflector(
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Shell::GetPrimaryRootWindow()->GetDispatcher()->compositor(),
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        mirror_window->layer());
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cursor_window_ = new aura::Window(cursor_window_delegate_.get());
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cursor_window_->SetTransparent(true);
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cursor_window_->Init(ui::LAYER_TEXTURED);
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->AddChild(cursor_window_);
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cursor_window_->Show();
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GetRootWindowSettings(root_window_.get())->display_id = display_info.id();
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    root_window_->SetHostBounds(display_info.bounds_in_native());
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Shell::GetScreen()->GetPrimaryDisplay().id());
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(display_manager->IsMirrored());
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<aura::RootWindowTransformer> transformer(
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      internal::CreateRootWindowTransformerForMirroredDisplay(
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          source_display_info,
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          display_info));
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  root_window_->SetRootWindowTransformer(transformer.Pass());
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateCursorLocation();
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MirrorWindowController::UpdateWindow() {
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (root_window_.get()) {
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DisplayManager* display_manager = Shell::GetInstance()->display_manager();
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        display_manager->mirrored_display_id());
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UpdateWindow(mirror_display_info);
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MirrorWindowController::Close() {
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (root_window_.get()) {
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ui::ContextFactory::GetInstance()->RemoveReflector(reflector_);
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    reflector_ = NULL;
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>(
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        aura::client::GetCaptureClient(root_window_.get()));
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    aura::client::SetCaptureClient(root_window_.get(), NULL);
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    delete capture_client;
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->RemoveRootWindowObserver(
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        Shell::GetInstance()->display_controller());
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    root_window_->RemoveRootWindowObserver(this);
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    root_window_.reset();
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    cursor_window_ = NULL;
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MirrorWindowController::UpdateCursorLocation() {
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (cursor_window_) {
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(oshima): Rotate cursor image (including hotpoint).
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gfx::Point point = aura::Env::GetInstance()->last_mouse_location();
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    Shell::GetPrimaryRootWindow()->GetDispatcher()->ConvertPointToHost(&point);
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    point.Offset(-hot_point_.x(), -hot_point_.y());
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gfx::Rect bounds = cursor_window_->bounds();
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bounds.set_origin(point);
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    cursor_window_->SetBounds(bounds);
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MirrorWindowController::SetMirroredCursor(gfx::NativeCursor cursor) {
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const gfx::Display& display = Shell::GetScreen()->GetPrimaryDisplay();
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (current_cursor_type_ == cursor.native_type() &&
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      current_cursor_rotation_ == display.rotation())
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  current_cursor_type_ = cursor.native_type();
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  current_cursor_rotation_ = display.rotation();
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int resource_id;
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool success = ui::GetCursorDataFor(
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      ui::CURSOR_SET_NORMAL,  // Not support custom cursor set.
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      current_cursor_type_,
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      display.device_scale_factor(),
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      &resource_id,
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      &hot_point_);
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!success)
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gfx::ImageSkia* image =
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::ImageSkia rotated = *image;
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (current_cursor_rotation_) {
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case gfx::Display::ROTATE_0:
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case gfx::Display::ROTATE_90:
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          *image, SkBitmapOperations::ROTATION_90_CW);
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      hot_point_.SetPoint(
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          rotated.width() - hot_point_.y(),
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          hot_point_.x());
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case gfx::Display::ROTATE_180:
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          *image, SkBitmapOperations::ROTATION_180_CW);
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      hot_point_.SetPoint(
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          rotated.height() - hot_point_.x(),
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          rotated.width() - hot_point_.y());
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case gfx::Display::ROTATE_270:
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          *image, SkBitmapOperations::ROTATION_270_CW);
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      hot_point_.SetPoint(
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          hot_point_.y(),
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          rotated.height() - hot_point_.x());
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  cursor_window_delegate_->SetCursorImage(rotated, display);
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (cursor_window_) {
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    cursor_window_->SetBounds(gfx::Rect(cursor_window_delegate_->size()));
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    cursor_window_->SchedulePaintInRect(
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        gfx::Rect(cursor_window_->bounds().size()));
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UpdateCursorLocation();
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MirrorWindowController::SetMirroredCursorVisibility(bool visible) {
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (cursor_window_)
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    visible ? cursor_window_->Show() : cursor_window_->Hide();
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MirrorWindowController::OnRootWindowHostResized(
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const aura::RootWindow* root) {
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Do not use |old_size| as it contains RootWindow's (but not host's) size,
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and this parameter wil be removed soon.
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (mirror_window_host_size_ == root->GetHostSize())
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mirror_window_host_size_ = root->GetHostSize();
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  reflector_->OnMirroringCompositorResized();
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  root_window_->SetRootWindowTransformer(
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      CreateRootWindowTransformer().Pass());
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UpdateCursorLocation();
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_ptr<aura::RootWindowTransformer>
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)MirrorWindowController::CreateRootWindowTransformer() const {
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      display_manager->mirrored_display_id());
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Shell::GetScreen()->GetPrimaryDisplay().id());
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(display_manager->IsMirrored());
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return scoped_ptr<aura::RootWindowTransformer>(
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      internal::CreateRootWindowTransformerForMirroredDisplay(
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          source_display_info,
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          mirror_display_info));
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace internal
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace ash
344