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 case DisplayManager::UNIFIED: { |
| 173 gfx::Display display; |
| 174 display.SetScaleAndBounds( |
| 175 1.0f, gfx::Rect(mirroring_origin, |
| 176 display_info.bounds_in_native().size())); |
| 177 mirroring_origin.SetPoint(display.bounds().right(), 0); |
| 178 scoped_ptr<RootWindowTransformer> transformer( |
| 179 CreateRootWindowTransformerForUnifiedDesktop(primary.bounds(), |
| 180 display)); |
| 181 mirroring_ash_host->SetRootWindowTransformer(transformer.Pass()); |
| 182 } break; |
| 183 case DisplayManager::EXTENDED: |
| 184 NOTREACHED(); |
| 185 } |
123 } | 186 } |
124 | 187 |
125 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 188 // Deleting WTHs for disconnected displays. |
126 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 189 if (mirroring_host_info_map_.size() > display_info_list.size()) { |
127 Shell::GetScreen()->GetPrimaryDisplay().id()); | 190 for (MirroringHostInfoMap::iterator iter = mirroring_host_info_map_.begin(); |
128 DCHECK(display_manager->IsInMirrorMode()); | 191 iter != mirroring_host_info_map_.end();) { |
129 scoped_ptr<RootWindowTransformer> transformer( | 192 if (std::find_if(display_info_list.begin(), display_info_list.end(), |
130 CreateRootWindowTransformerForMirroredDisplay(source_display_info, | 193 [iter](const DisplayInfo& info) { |
131 display_info)); | 194 return info.id() == iter->first; |
132 ash_host_->SetRootWindowTransformer(transformer.Pass()); | 195 }) == display_info_list.end()) { |
| 196 CloseHost(iter->second); |
| 197 iter = mirroring_host_info_map_.erase(iter); |
| 198 } else { |
| 199 ++iter; |
| 200 } |
| 201 } |
| 202 } |
133 } | 203 } |
134 | 204 |
135 void MirrorWindowController::UpdateWindow() { | 205 void MirrorWindowController::UpdateWindow() { |
136 if (ash_host_.get()) { | 206 if (!mirroring_host_info_map_.size()) |
137 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 207 return; |
138 const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( | 208 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
139 display_manager->mirroring_display_id()); | 209 std::vector<DisplayInfo> display_info_list; |
140 UpdateWindow(mirror_display_info); | 210 for (auto& pair : mirroring_host_info_map_) |
141 } | 211 display_info_list.push_back(display_manager->GetDisplayInfo(pair.first)); |
| 212 UpdateWindow(display_info_list); |
142 } | 213 } |
143 | 214 |
144 void MirrorWindowController::Close() { | 215 void MirrorWindowController::Close() { |
145 if (ash_host_.get()) { | 216 for (auto& info : mirroring_host_info_map_) { |
146 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); | 217 CloseHost(info.second); |
| 218 } |
| 219 mirroring_host_info_map_.clear(); |
| 220 if (reflector_) { |
147 aura::Env::GetInstance()->context_factory()->RemoveReflector( | 221 aura::Env::GetInstance()->context_factory()->RemoveReflector( |
148 reflector_.get()); | 222 reflector_.get()); |
149 reflector_ = nullptr; | 223 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 } | 224 } |
159 } | 225 } |
160 | 226 |
161 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { | 227 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { |
162 if (mirror_window_host_size_ == host->GetBounds().size()) | 228 for (auto& pair : mirroring_host_info_map_) { |
163 return; | 229 MirroringHostInfo* info = pair.second; |
164 mirror_window_host_size_ = host->GetBounds().size(); | 230 if (info->ash_host->AsWindowTreeHost() == host) { |
165 reflector_->OnMirroringCompositorResized(); | 231 if (info->mirror_window_host_size == host->GetBounds().size()) |
166 ash_host_->SetRootWindowTransformer(CreateRootWindowTransformer().Pass()); | 232 return; |
167 Shell::GetInstance()->display_controller()->cursor_window_controller()-> | 233 info->mirror_window_host_size = host->GetBounds().size(); |
168 UpdateLocation(); | 234 reflector_->OnMirroringCompositorResized(); |
| 235 info->ash_host->SetRootWindowTransformer( |
| 236 CreateRootWindowTransformer().Pass()); |
| 237 Shell::GetInstance() |
| 238 ->display_controller() |
| 239 ->cursor_window_controller() |
| 240 ->UpdateLocation(); |
| 241 return; |
| 242 } |
| 243 } |
169 } | 244 } |
170 | 245 |
171 aura::Window* MirrorWindowController::GetWindow() { | 246 aura::Window* MirrorWindowController::GetWindow() { |
172 return ash_host_.get() ? ash_host_->AsWindowTreeHost()->window() : NULL; | 247 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| 248 if (display_manager->multi_display_mode() != DisplayManager::MIRRORING || |
| 249 mirroring_host_info_map_.size() == 0) |
| 250 return nullptr; |
| 251 return mirroring_host_info_map_.begin() |
| 252 ->second->ash_host->AsWindowTreeHost() |
| 253 ->window(); |
| 254 } |
| 255 |
| 256 void MirrorWindowController::CloseHost(MirroringHostInfo* host_info) { |
| 257 aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); |
| 258 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
| 259 aura::client::GetCaptureClient(host->window())); |
| 260 aura::client::SetCaptureClient(host->window(), NULL); |
| 261 delete capture_client; |
| 262 |
| 263 host->RemoveObserver(Shell::GetInstance()->display_controller()); |
| 264 host->RemoveObserver(this); |
| 265 // reflector_->RemoveMirroringLayer(host_info->mirror_window->layer()); |
| 266 delete host_info; |
173 } | 267 } |
174 | 268 |
175 scoped_ptr<RootWindowTransformer> | 269 scoped_ptr<RootWindowTransformer> |
176 MirrorWindowController::CreateRootWindowTransformer() const { | 270 MirrorWindowController::CreateRootWindowTransformer() const { |
177 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 271 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
178 const DisplayInfo& mirror_display_info = | 272 const DisplayInfo& mirror_display_info = |
179 display_manager->GetDisplayInfo(display_manager->mirroring_display_id()); | 273 display_manager->GetDisplayInfo(display_manager->mirroring_display_id()); |
180 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 274 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
181 Shell::GetScreen()->GetPrimaryDisplay().id()); | 275 Shell::GetScreen()->GetPrimaryDisplay().id()); |
182 DCHECK(display_manager->IsInMirrorMode()); | 276 DCHECK(display_manager->IsInMirrorMode()); |
183 return scoped_ptr<RootWindowTransformer>( | 277 return scoped_ptr<RootWindowTransformer>( |
184 CreateRootWindowTransformerForMirroredDisplay(source_display_info, | 278 CreateRootWindowTransformerForMirroredDisplay(source_display_info, |
185 mirror_display_info)); | 279 mirror_display_info)); |
186 } | 280 } |
187 | 281 |
188 } // namespace ash | 282 } // namespace ash |
OLD | NEW |