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 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
10 | 10 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 // Returns the current capture window. | 70 // Returns the current capture window. |
71 aura::Window* GetCaptureWindow() override { return NULL; } | 71 aura::Window* GetCaptureWindow() override { return NULL; } |
72 aura::Window* GetGlobalCaptureWindow() override { return NULL; } | 72 aura::Window* GetGlobalCaptureWindow() override { return NULL; } |
73 | 73 |
74 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); | 74 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient); |
75 }; | 75 }; |
76 | 76 |
77 } // namespace | 77 } // namespace |
78 | 78 |
| 79 MirrorWindowController::MirroringHostInfo::MirroringHostInfo() { |
| 80 } |
| 81 MirrorWindowController::MirroringHostInfo::~MirroringHostInfo() { |
| 82 } |
| 83 |
79 MirrorWindowController::MirrorWindowController() {} | 84 MirrorWindowController::MirrorWindowController() {} |
80 | 85 |
81 MirrorWindowController::~MirrorWindowController() { | 86 MirrorWindowController::~MirrorWindowController() { |
82 // Make sure the root window gets deleted before cursor_window_delegate. | 87 // Make sure the root window gets deleted before cursor_window_delegate. |
83 Close(); | 88 Close(); |
84 } | 89 } |
85 | 90 |
86 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { | 91 void MirrorWindowController::UpdateWindow( |
| 92 const std::vector<DisplayInfo>& display_info_list) { |
87 static int mirror_host_count = 0; | 93 static int mirror_host_count = 0; |
88 if (!ash_host_.get()) { | 94 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
89 AshWindowTreeHostInitParams init_params; | 95 const gfx::Display& primary = Shell::GetScreen()->GetPrimaryDisplay(); |
90 init_params.initial_bounds = display_info.bounds_in_native(); | 96 const DisplayInfo& source_display_info = |
91 ash_host_.reset(AshWindowTreeHost::Create(init_params)); | 97 display_manager->GetDisplayInfo(primary.id()); |
92 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); | 98 |
93 host->window()->SetName( | 99 gfx::Point mirroring_origin; |
94 base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++)); | 100 for (const DisplayInfo& display_info : display_info_list) { |
95 host->compositor()->SetBackgroundColor(SK_ColorBLACK); | 101 if (mirroring_host_info_map_.find(display_info.id()) == |
96 // No need to remove the observer because the DisplayController outlives the | 102 mirroring_host_info_map_.end()) { |
97 // host. | 103 AshWindowTreeHostInitParams init_params; |
98 host->AddObserver(Shell::GetInstance()->display_controller()); | 104 init_params.initial_bounds = display_info.bounds_in_native(); |
99 host->AddObserver(this); | 105 MirroringHostInfo* host_info = new MirroringHostInfo; |
100 // TODO(oshima): TouchHUD is using idkey. | 106 host_info->ash_host.reset(AshWindowTreeHost::Create(init_params)); |
101 InitRootWindowSettings(host->window())->display_id = display_info.id(); | 107 mirroring_host_info_map_[display_info.id()] = host_info; |
102 host->InitHost(); | 108 |
| 109 aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); |
| 110 host->window()->SetName( |
| 111 base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++)); |
| 112 host->compositor()->SetBackgroundColor(SK_ColorBLACK); |
| 113 // No need to remove the observer because the DisplayController outlives |
| 114 // the |
| 115 // host. |
| 116 host->AddObserver(Shell::GetInstance()->display_controller()); |
| 117 host->AddObserver(this); |
| 118 // TODO(oshima): TouchHUD is using idkey. |
| 119 InitRootWindowSettings(host->window())->display_id = display_info.id(); |
| 120 host->InitHost(); |
103 #if defined(USE_X11) | 121 #if defined(USE_X11) |
104 DisableInput(host->GetAcceleratedWidget()); | 122 if (display_manager->multi_display_mode() != DisplayManager::UNIFIED) |
| 123 DisableInput(host->GetAcceleratedWidget()); |
105 #endif | 124 #endif |
106 | 125 |
107 aura::client::SetCaptureClient(host->window(), new NoneCaptureClient()); | 126 #if defined(OS_CHROMEOS) |
108 host->Show(); | 127 if (display_manager->multi_display_mode() == DisplayManager::UNIFIED) { |
| 128 host_info->ash_host->ConfineCursorToRootWindow(); |
| 129 AshWindowTreeHost* unified_ash_host = |
| 130 Shell::GetInstance() |
| 131 ->display_controller() |
| 132 ->GetAshWindowTreeHostForDisplayId( |
| 133 Shell::GetScreen()->GetPrimaryDisplay().id()); |
| 134 unified_ash_host->RegisterMirroringHost(host_info->ash_host.get()); |
| 135 } |
| 136 #endif |
109 | 137 |
110 // TODO(oshima): Start mirroring. | 138 aura::client::SetCaptureClient(host->window(), new NoneCaptureClient()); |
111 aura::Window* mirror_window = new aura::Window(NULL); | 139 host->Show(); |
112 mirror_window->Init(ui::LAYER_SOLID_COLOR); | 140 |
113 host->window()->AddChild(mirror_window); | 141 aura::Window* mirror_window = host_info->mirror_window = |
114 mirror_window->SetBounds(host->window()->bounds()); | 142 new aura::Window(nullptr); |
115 mirror_window->Show(); | 143 mirror_window->Init(ui::LAYER_SOLID_COLOR); |
116 reflector_ = aura::Env::GetInstance()->context_factory()->CreateReflector( | 144 host->window()->AddChild(mirror_window); |
117 Shell::GetPrimaryRootWindow()->GetHost()->compositor(), | 145 mirror_window->SetBounds(host->window()->bounds()); |
118 mirror_window->layer()); | 146 mirror_window->Show(); |
119 } else { | 147 if (reflector_) { |
120 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); | 148 // TODO(oshima): Enable this once reflect change is landed. |
121 GetRootWindowSettings(host->window())->display_id = display_info.id(); | 149 // reflector_->AddMirroringLayer(mirror_window->layer()); |
122 host->SetBounds(display_info.bounds_in_native()); | 150 } else { |
| 151 reflector_ = |
| 152 aura::Env::GetInstance()->context_factory()->CreateReflector( |
| 153 Shell::GetPrimaryRootWindow()->GetHost()->compositor(), |
| 154 mirror_window->layer()); |
| 155 } |
| 156 } else { |
| 157 aura::WindowTreeHost* host = mirroring_host_info_map_[display_info.id()] |
| 158 ->ash_host->AsWindowTreeHost(); |
| 159 GetRootWindowSettings(host->window())->display_id = display_info.id(); |
| 160 host->SetBounds(display_info.bounds_in_native()); |
| 161 } |
| 162 |
| 163 AshWindowTreeHost* mirroring_ash_host = |
| 164 mirroring_host_info_map_[display_info.id()]->ash_host.get(); |
| 165 switch (display_manager->multi_display_mode()) { |
| 166 case DisplayManager::MIRRORING: { |
| 167 scoped_ptr<RootWindowTransformer> transformer( |
| 168 CreateRootWindowTransformerForMirroredDisplay(source_display_info, |
| 169 display_info)); |
| 170 mirroring_ash_host->SetRootWindowTransformer(transformer.Pass()); |
| 171 break; |
| 172 } |
| 173 case DisplayManager::UNIFIED: { |
| 174 gfx::Display display; |
| 175 display.SetScaleAndBounds( |
| 176 1.0f, gfx::Rect(mirroring_origin, |
| 177 display_info.bounds_in_native().size())); |
| 178 mirroring_origin.SetPoint(display.bounds().right(), 0); |
| 179 scoped_ptr<RootWindowTransformer> transformer( |
| 180 CreateRootWindowTransformerForUnifiedDesktop(primary.bounds(), |
| 181 display)); |
| 182 mirroring_ash_host->SetRootWindowTransformer(transformer.Pass()); |
| 183 break; |
| 184 } |
| 185 case DisplayManager::EXTENDED: |
| 186 NOTREACHED(); |
| 187 } |
123 } | 188 } |
124 | 189 |
125 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 190 // Deleting WTHs for disconnected displays. |
126 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 191 if (mirroring_host_info_map_.size() > display_info_list.size()) { |
127 Shell::GetScreen()->GetPrimaryDisplay().id()); | 192 for (MirroringHostInfoMap::iterator iter = mirroring_host_info_map_.begin(); |
128 DCHECK(display_manager->IsInMirrorMode()); | 193 iter != mirroring_host_info_map_.end();) { |
129 scoped_ptr<RootWindowTransformer> transformer( | 194 if (std::find_if(display_info_list.begin(), display_info_list.end(), |
130 CreateRootWindowTransformerForMirroredDisplay(source_display_info, | 195 [iter](const DisplayInfo& info) { |
131 display_info)); | 196 return info.id() == iter->first; |
132 ash_host_->SetRootWindowTransformer(transformer.Pass()); | 197 }) == display_info_list.end()) { |
| 198 CloseAndDeleteHost(iter->second); |
| 199 iter = mirroring_host_info_map_.erase(iter); |
| 200 } else { |
| 201 ++iter; |
| 202 } |
| 203 } |
| 204 } |
133 } | 205 } |
134 | 206 |
135 void MirrorWindowController::UpdateWindow() { | 207 void MirrorWindowController::UpdateWindow() { |
136 if (ash_host_.get()) { | 208 if (!mirroring_host_info_map_.size()) |
137 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 209 return; |
138 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( | 210 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
139 display_manager->mirroring_display_id()); | 211 std::vector<DisplayInfo> display_info_list; |
140 UpdateWindow(mirror_display_info); | 212 for (auto& pair : mirroring_host_info_map_) |
141 } | 213 display_info_list.push_back(display_manager->GetDisplayInfo(pair.first)); |
| 214 UpdateWindow(display_info_list); |
142 } | 215 } |
143 | 216 |
144 void MirrorWindowController::Close() { | 217 void MirrorWindowController::Close() { |
145 if (ash_host_.get()) { | 218 for (auto& info : mirroring_host_info_map_) { |
146 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); | 219 CloseAndDeleteHost(info.second); |
| 220 } |
| 221 mirroring_host_info_map_.clear(); |
| 222 if (reflector_) { |
147 aura::Env::GetInstance()->context_factory()->RemoveReflector( | 223 aura::Env::GetInstance()->context_factory()->RemoveReflector( |
148 reflector_.get()); | 224 reflector_.get()); |
149 reflector_ = nullptr; | 225 reflector_.reset(); |
150 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( | |
151 aura::client::GetCaptureClient(host->window())); | |
152 aura::client::SetCaptureClient(host->window(), NULL); | |
153 delete capture_client; | |
154 | |
155 host->RemoveObserver(Shell::GetInstance()->display_controller()); | |
156 host->RemoveObserver(this); | |
157 ash_host_.reset(); | |
158 } | 226 } |
159 } | 227 } |
160 | 228 |
161 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { | 229 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { |
162 if (mirror_window_host_size_ == host->GetBounds().size()) | 230 for (auto& pair : mirroring_host_info_map_) { |
163 return; | 231 MirroringHostInfo* info = pair.second; |
164 mirror_window_host_size_ = host->GetBounds().size(); | 232 if (info->ash_host->AsWindowTreeHost() == host) { |
165 reflector_->OnMirroringCompositorResized(); | 233 if (info->mirror_window_host_size == host->GetBounds().size()) |
166 ash_host_->SetRootWindowTransformer(CreateRootWindowTransformer().Pass()); | 234 return; |
167 Shell::GetInstance()->display_controller()->cursor_window_controller()-> | 235 info->mirror_window_host_size = host->GetBounds().size(); |
168 UpdateLocation(); | 236 reflector_->OnMirroringCompositorResized(); |
| 237 info->ash_host->SetRootWindowTransformer( |
| 238 CreateRootWindowTransformer().Pass()); |
| 239 Shell::GetInstance() |
| 240 ->display_controller() |
| 241 ->cursor_window_controller() |
| 242 ->UpdateLocation(); |
| 243 return; |
| 244 } |
| 245 } |
169 } | 246 } |
170 | 247 |
171 aura::Window* MirrorWindowController::GetWindow() { | 248 aura::Window* MirrorWindowController::GetWindow() { |
172 return ash_host_.get() ? ash_host_->AsWindowTreeHost()->window() : NULL; | 249 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| 250 if (display_manager->multi_display_mode() != DisplayManager::MIRRORING || |
| 251 mirroring_host_info_map_.empty()) { |
| 252 return nullptr; |
| 253 } |
| 254 |
| 255 DCHECK_EQ(1U, mirroring_host_info_map_.size()); |
| 256 return mirroring_host_info_map_.begin() |
| 257 ->second->ash_host->AsWindowTreeHost() |
| 258 ->window(); |
| 259 } |
| 260 |
| 261 void MirrorWindowController::CloseAndDeleteHost(MirroringHostInfo* host_info) { |
| 262 aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); |
| 263 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
| 264 aura::client::GetCaptureClient(host->window())); |
| 265 aura::client::SetCaptureClient(host->window(), NULL); |
| 266 delete capture_client; |
| 267 |
| 268 host->RemoveObserver(Shell::GetInstance()->display_controller()); |
| 269 host->RemoveObserver(this); |
| 270 // reflector_->RemoveMirroringLayer(host_info->mirror_window->layer()); |
| 271 delete host_info; |
173 } | 272 } |
174 | 273 |
175 scoped_ptr<RootWindowTransformer> | 274 scoped_ptr<RootWindowTransformer> |
176 MirrorWindowController::CreateRootWindowTransformer() const { | 275 MirrorWindowController::CreateRootWindowTransformer() const { |
177 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 276 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
178 const DisplayInfo& mirror_display_info = | 277 const DisplayInfo& mirror_display_info = |
179 display_manager->GetDisplayInfo(display_manager->mirroring_display_id()); | 278 display_manager->GetDisplayInfo(display_manager->mirroring_display_id()); |
180 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 279 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
181 Shell::GetScreen()->GetPrimaryDisplay().id()); | 280 Shell::GetScreen()->GetPrimaryDisplay().id()); |
182 DCHECK(display_manager->IsInMirrorMode()); | 281 DCHECK(display_manager->IsInMirrorMode()); |
183 return scoped_ptr<RootWindowTransformer>( | 282 return scoped_ptr<RootWindowTransformer>( |
184 CreateRootWindowTransformerForMirroredDisplay(source_display_info, | 283 CreateRootWindowTransformerForMirroredDisplay(source_display_info, |
185 mirror_display_info)); | 284 mirror_display_info)); |
186 } | 285 } |
187 | 286 |
188 } // namespace ash | 287 } // namespace ash |
OLD | NEW |