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