Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ash / display / mirror_window_controller.cc
blobad8db4b6137943a5ace00a4c24468a737b51f36e
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
3 // found in the LICENSE file.
5 #include "ash/display/mirror_window_controller.h"
7 #if defined(USE_X11)
8 #include <X11/Xlib.h>
10 // Xlib.h defines RootWindow.
11 #undef RootWindow
12 #endif
14 #include "ash/display/cursor_window_controller.h"
15 #include "ash/display/display_controller.h"
16 #include "ash/display/display_info.h"
17 #include "ash/display/display_manager.h"
18 #include "ash/display/root_window_transformers.h"
19 #include "ash/host/ash_window_tree_host.h"
20 #include "ash/host/ash_window_tree_host_init_params.h"
21 #include "ash/host/root_window_transformer.h"
22 #include "ash/root_window_settings.h"
23 #include "ash/shell.h"
24 #include "base/strings/stringprintf.h"
25 #include "ui/aura/client/capture_client.h"
26 #include "ui/aura/env.h"
27 #include "ui/aura/window_delegate.h"
28 #include "ui/aura/window_event_dispatcher.h"
29 #include "ui/aura/window_tree_host.h"
30 #include "ui/base/layout.h"
31 #include "ui/compositor/reflector.h"
32 #include "ui/gfx/canvas.h"
33 #include "ui/gfx/native_widget_types.h"
35 #if defined(USE_X11)
36 #include "ui/gfx/x/x11_types.h"
37 #endif
39 namespace ash {
40 namespace {
42 #if defined(USE_X11)
43 // Mirror window shouldn't handle input events.
44 void DisableInput(XID window) {
45 long event_mask = ExposureMask | VisibilityChangeMask |
46 StructureNotifyMask | PropertyChangeMask;
47 XSelectInput(gfx::GetXDisplay(), window, event_mask);
49 #endif
51 class NoneCaptureClient : public aura::client::CaptureClient {
52 public:
53 NoneCaptureClient() {}
54 virtual ~NoneCaptureClient() {}
56 private:
57 // Does a capture on the |window|.
58 virtual void SetCapture(aura::Window* window) OVERRIDE {}
60 // Releases a capture from the |window|.
61 virtual void ReleaseCapture(aura::Window* window) OVERRIDE {}
63 // Returns the current capture window.
64 virtual aura::Window* GetCaptureWindow() OVERRIDE {
65 return NULL;
67 virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE {
68 return NULL;
71 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient);
74 } // namespace
76 MirrorWindowController::MirrorWindowController() {}
78 MirrorWindowController::~MirrorWindowController() {
79 // Make sure the root window gets deleted before cursor_window_delegate.
80 Close();
83 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) {
84 static int mirror_host_count = 0;
85 if (!ash_host_.get()) {
86 AshWindowTreeHostInitParams init_params;
87 init_params.initial_bounds = display_info.bounds_in_native();
88 ash_host_.reset(AshWindowTreeHost::Create(init_params));
89 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost();
90 host->window()->SetName(
91 base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++));
92 host->compositor()->SetBackgroundColor(SK_ColorBLACK);
93 // No need to remove the observer because the DisplayController outlives the
94 // host.
95 host->AddObserver(Shell::GetInstance()->display_controller());
96 host->AddObserver(this);
97 // TODO(oshima): TouchHUD is using idkey.
98 InitRootWindowSettings(host->window())->display_id = display_info.id();
99 host->InitHost();
100 #if defined(USE_X11)
101 DisableInput(host->GetAcceleratedWidget());
102 #endif
104 aura::client::SetCaptureClient(host->window(), new NoneCaptureClient());
105 host->Show();
107 // TODO(oshima): Start mirroring.
108 aura::Window* mirror_window = new aura::Window(NULL);
109 mirror_window->Init(aura::WINDOW_LAYER_TEXTURED);
110 host->window()->AddChild(mirror_window);
111 mirror_window->SetBounds(host->window()->bounds());
112 mirror_window->Show();
113 reflector_ = aura::Env::GetInstance()->context_factory()->CreateReflector(
114 Shell::GetPrimaryRootWindow()->GetHost()->compositor(),
115 mirror_window->layer());
116 } else {
117 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost();
118 GetRootWindowSettings(host->window())->display_id = display_info.id();
119 host->SetBounds(display_info.bounds_in_native());
122 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
123 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
124 Shell::GetScreen()->GetPrimaryDisplay().id());
125 DCHECK(display_manager->IsMirrored());
126 scoped_ptr<RootWindowTransformer> transformer(
127 CreateRootWindowTransformerForMirroredDisplay(source_display_info,
128 display_info));
129 ash_host_->SetRootWindowTransformer(transformer.Pass());
132 void MirrorWindowController::UpdateWindow() {
133 if (ash_host_.get()) {
134 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
135 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
136 display_manager->mirrored_display_id());
137 UpdateWindow(mirror_display_info);
141 void MirrorWindowController::Close() {
142 if (ash_host_.get()) {
143 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost();
144 aura::Env::GetInstance()->context_factory()->RemoveReflector(reflector_);
145 reflector_ = NULL;
146 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>(
147 aura::client::GetCaptureClient(host->window()));
148 aura::client::SetCaptureClient(host->window(), NULL);
149 delete capture_client;
151 host->RemoveObserver(Shell::GetInstance()->display_controller());
152 host->RemoveObserver(this);
153 ash_host_.reset();
157 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) {
158 if (mirror_window_host_size_ == host->GetBounds().size())
159 return;
160 mirror_window_host_size_ = host->GetBounds().size();
161 reflector_->OnMirroringCompositorResized();
162 ash_host_->SetRootWindowTransformer(CreateRootWindowTransformer().Pass());
163 Shell::GetInstance()->display_controller()->cursor_window_controller()->
164 UpdateLocation();
167 aura::Window* MirrorWindowController::GetWindow() {
168 return ash_host_.get() ? ash_host_->AsWindowTreeHost()->window() : NULL;
171 scoped_ptr<RootWindowTransformer>
172 MirrorWindowController::CreateRootWindowTransformer() const {
173 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
174 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
175 display_manager->mirrored_display_id());
176 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
177 Shell::GetScreen()->GetPrimaryDisplay().id());
178 DCHECK(display_manager->IsMirrored());
179 return scoped_ptr<RootWindowTransformer>(
180 CreateRootWindowTransformerForMirroredDisplay(source_display_info,
181 mirror_display_info));
184 } // namespace ash