Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / ash / display / mirror_window_controller.cc
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.
4
5 #include "ash/display/mirror_window_controller.h"
6
7 #if defined(USE_X11)
8 #include <X11/Xlib.h>
9
10 // Xlib.h defines RootWindow.
11 #undef RootWindow
12 #endif
13
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/window_tree_host_factory.h"
20 #include "ash/root_window_settings.h"
21 #include "ash/shell.h"
22 #include "base/strings/stringprintf.h"
23 #include "ui/aura/client/capture_client.h"
24 #include "ui/aura/root_window_transformer.h"
25 #include "ui/aura/window_delegate.h"
26 #include "ui/aura/window_event_dispatcher.h"
27 #include "ui/base/layout.h"
28 #include "ui/compositor/reflector.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/native_widget_types.h"
31
32 #if defined(USE_X11)
33 #include "ui/gfx/x/x11_types.h"
34 #endif
35
36 namespace ash {
37 namespace internal {
38 namespace {
39
40 #if defined(USE_X11)
41 // Mirror window shouldn't handle input events.
42 void DisableInput(XID window) {
43   long event_mask = ExposureMask | VisibilityChangeMask |
44       StructureNotifyMask | PropertyChangeMask;
45   XSelectInput(gfx::GetXDisplay(), window, event_mask);
46 }
47 #endif
48
49 class NoneCaptureClient : public aura::client::CaptureClient {
50  public:
51   NoneCaptureClient() {}
52   virtual ~NoneCaptureClient() {}
53
54  private:
55   // Does a capture on the |window|.
56   virtual void SetCapture(aura::Window* window) OVERRIDE {}
57
58   // Releases a capture from the |window|.
59   virtual void ReleaseCapture(aura::Window* window) OVERRIDE {}
60
61   // Returns the current capture window.
62   virtual aura::Window* GetCaptureWindow() OVERRIDE {
63     return NULL;
64   }
65   virtual aura::Window* GetGlobalCaptureWindow() OVERRIDE {
66     return NULL;
67   }
68
69   DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient);
70 };
71
72 }  // namespace
73
74 MirrorWindowController::MirrorWindowController() {}
75
76 MirrorWindowController::~MirrorWindowController() {
77   // Make sure the root window gets deleted before cursor_window_delegate.
78   Close();
79 }
80
81 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) {
82   static int mirror_host_count = 0;
83
84   if (!host_.get()) {
85     const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
86     host_.reset(Shell::GetInstance()->window_tree_host_factory()->
87         CreateWindowTreeHost(bounds_in_native));
88     host_->window()->SetName(
89         base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++));
90     host_->compositor()->SetBackgroundColor(SK_ColorBLACK);
91     // No need to remove the observer because the DisplayController outlives the
92     // host.
93     host_->AddObserver(Shell::GetInstance()->display_controller());
94     host_->AddObserver(this);
95     // TODO(oshima): TouchHUD is using idkey.
96     InitRootWindowSettings(host_->window())->display_id = display_info.id();
97     host_->InitHost();
98 #if defined(USE_X11)
99     DisableInput(host_->GetAcceleratedWidget());
100 #endif
101
102     aura::client::SetCaptureClient(host_->window(), new NoneCaptureClient());
103     host_->Show();
104
105     // TODO(oshima): Start mirroring.
106     aura::Window* mirror_window = new aura::Window(NULL);
107     mirror_window->Init(aura::WINDOW_LAYER_TEXTURED);
108     host_->window()->AddChild(mirror_window);
109     mirror_window->SetBounds(host_->window()->bounds());
110     mirror_window->Show();
111     reflector_ = ui::ContextFactory::GetInstance()->CreateReflector(
112         Shell::GetPrimaryRootWindow()->GetHost()->compositor(),
113         mirror_window->layer());
114   } else {
115     GetRootWindowSettings(host_->window())->display_id = display_info.id();
116     host_->SetBounds(display_info.bounds_in_native());
117   }
118
119   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
120   const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
121       Shell::GetScreen()->GetPrimaryDisplay().id());
122   DCHECK(display_manager->IsMirrored());
123   scoped_ptr<aura::RootWindowTransformer> transformer(
124       internal::CreateRootWindowTransformerForMirroredDisplay(
125           source_display_info,
126           display_info));
127   host_->SetRootWindowTransformer(transformer.Pass());
128 }
129
130 void MirrorWindowController::UpdateWindow() {
131   if (host_.get()) {
132     DisplayManager* display_manager = Shell::GetInstance()->display_manager();
133     const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
134         display_manager->mirrored_display_id());
135     UpdateWindow(mirror_display_info);
136   }
137 }
138
139 void MirrorWindowController::Close() {
140   if (host_.get()) {
141     ui::ContextFactory::GetInstance()->RemoveReflector(reflector_);
142     reflector_ = NULL;
143     NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>(
144         aura::client::GetCaptureClient(host_->window()));
145     aura::client::SetCaptureClient(host_->window(), NULL);
146     delete capture_client;
147
148     host_->RemoveObserver(Shell::GetInstance()->display_controller());
149     host_->RemoveObserver(this);
150     host_.reset();
151   }
152 }
153
154 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) {
155   if (mirror_window_host_size_ == host->GetBounds().size())
156     return;
157   mirror_window_host_size_ = host->GetBounds().size();
158   reflector_->OnMirroringCompositorResized();
159   host_->SetRootWindowTransformer(CreateRootWindowTransformer().Pass());
160   Shell::GetInstance()->display_controller()->cursor_window_controller()->
161       UpdateLocation();
162 }
163
164
165 scoped_ptr<aura::RootWindowTransformer>
166 MirrorWindowController::CreateRootWindowTransformer() const {
167   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
168   const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo(
169       display_manager->mirrored_display_id());
170   const DisplayInfo& source_display_info = display_manager->GetDisplayInfo(
171       Shell::GetScreen()->GetPrimaryDisplay().id());
172   DCHECK(display_manager->IsMirrored());
173   return scoped_ptr<aura::RootWindowTransformer>(
174       internal::CreateRootWindowTransformerForMirroredDisplay(
175           source_display_info,
176           mirror_display_info));
177 }
178
179 }  // namespace internal
180 }  // namespace ash