1// Copyright 2014 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 "athena/screen/public/screen_manager.h"
6
7#include "athena/common/fill_layout_manager.h"
8#include "athena/input/public/accelerator_manager.h"
9#include "athena/screen/background_controller.h"
10#include "athena/screen/screen_accelerator_handler.h"
11#include "base/logging.h"
12#include "base/memory/scoped_ptr.h"
13#include "ui/aura/client/screen_position_client.h"
14#include "ui/aura/client/window_tree_client.h"
15#include "ui/aura/layout_manager.h"
16#include "ui/aura/window.h"
17#include "ui/aura/window_tree_host.h"
18#include "ui/wm/core/capture_controller.h"
19
20namespace athena {
21namespace {
22
23ScreenManager* instance = NULL;
24
25class AthenaWindowTreeClient : public aura::client::WindowTreeClient {
26 public:
27  explicit AthenaWindowTreeClient(aura::Window* container)
28      : container_(container) {}
29
30 private:
31  virtual ~AthenaWindowTreeClient() {}
32
33  // aura::client::WindowTreeClient:
34  virtual aura::Window* GetDefaultParent(aura::Window* context,
35                                         aura::Window* window,
36                                         const gfx::Rect& bounds) OVERRIDE {
37    return container_;
38  }
39
40  aura::Window* container_;
41
42  DISALLOW_COPY_AND_ASSIGN(AthenaWindowTreeClient);
43};
44
45class AthenaScreenPositionClient : public aura::client::ScreenPositionClient {
46 public:
47  AthenaScreenPositionClient() {
48  }
49  virtual ~AthenaScreenPositionClient() {
50  }
51
52 private:
53  // aura::client::ScreenPositionClient:
54  virtual void ConvertPointToScreen(const aura::Window* window,
55                                    gfx::Point* point) OVERRIDE {
56    const aura::Window* root = window->GetRootWindow();
57    aura::Window::ConvertPointToTarget(window, root, point);
58  }
59
60  virtual void ConvertPointFromScreen(const aura::Window* window,
61                                      gfx::Point* point) OVERRIDE {
62    const aura::Window* root = window->GetRootWindow();
63    aura::Window::ConvertPointToTarget(root, window, point);
64  }
65
66  virtual void ConvertHostPointToScreen(aura::Window* window,
67                                        gfx::Point* point) OVERRIDE {
68    // TODO(oshima): Implement this when adding multiple display support.
69    NOTREACHED();
70  }
71
72  virtual void SetBounds(aura::Window* window,
73                         const gfx::Rect& bounds,
74                         const gfx::Display& display) OVERRIDE {
75    window->SetBounds(bounds);
76  }
77
78  DISALLOW_COPY_AND_ASSIGN(AthenaScreenPositionClient);
79};
80
81aura::Window* CreateContainerInternal(aura::Window* parent,
82                                      const std::string& name) {
83  aura::Window* container = new aura::Window(NULL);
84  container->Init(aura::WINDOW_LAYER_NOT_DRAWN);
85  container->SetName(name);
86  parent->AddChild(container);
87  container->Show();
88  return container;
89}
90
91class ScreenManagerImpl : public ScreenManager {
92 public:
93  explicit ScreenManagerImpl(aura::Window* root_window);
94  virtual ~ScreenManagerImpl();
95
96  void Init();
97
98 private:
99  // ScreenManager:
100  virtual aura::Window* CreateDefaultContainer(
101      const std::string& name) OVERRIDE;
102  virtual aura::Window* CreateContainer(const std::string& name) OVERRIDE;
103  virtual aura::Window* GetContext() OVERRIDE { return root_window_; }
104  virtual void SetBackgroundImage(const gfx::ImageSkia& image) OVERRIDE;
105
106  aura::Window* root_window_;
107  aura::Window* background_window_;
108
109  scoped_ptr<BackgroundController> background_controller_;
110  scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
111  scoped_ptr<AcceleratorHandler> accelerator_handler_;
112  scoped_ptr< ::wm::ScopedCaptureClient> capture_client_;
113  scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_;
114
115  DISALLOW_COPY_AND_ASSIGN(ScreenManagerImpl);
116};
117
118void ScreenManagerImpl::Init() {
119  root_window_->SetLayoutManager(new FillLayoutManager(root_window_));
120  background_window_ =
121      CreateContainerInternal(root_window_, "AthenaBackground");
122  background_window_->SetLayoutManager(
123      new FillLayoutManager(background_window_));
124  background_controller_.reset(new BackgroundController(background_window_));
125
126  capture_client_.reset(new ::wm::ScopedCaptureClient(root_window_));
127  accelerator_handler_.reset(new ScreenAcceleratorHandler(root_window_));
128}
129
130aura::Window* ScreenManagerImpl::CreateDefaultContainer(
131    const std::string& name) {
132  aura::Window* container = CreateContainerInternal(root_window_, name);
133  window_tree_client_.reset(new AthenaWindowTreeClient(container));
134  aura::client::SetWindowTreeClient(root_window_, window_tree_client_.get());
135
136  screen_position_client_.reset(new AthenaScreenPositionClient());
137  aura::client::SetScreenPositionClient(root_window_,
138                                        screen_position_client_.get());
139
140  return container;
141}
142
143aura::Window* ScreenManagerImpl::CreateContainer(const std::string& name) {
144  return CreateContainerInternal(root_window_, name);
145}
146
147void ScreenManagerImpl::SetBackgroundImage(const gfx::ImageSkia& image) {
148  background_controller_->SetImage(image);
149}
150
151ScreenManagerImpl::ScreenManagerImpl(aura::Window* root_window)
152    : root_window_(root_window) {
153  DCHECK(root_window_);
154  DCHECK(!instance);
155  instance = this;
156}
157
158ScreenManagerImpl::~ScreenManagerImpl() {
159  aura::client::SetScreenPositionClient(root_window_, NULL);
160  aura::client::SetWindowTreeClient(root_window_, NULL);
161  instance = NULL;
162}
163
164}  // namespace
165
166// static
167ScreenManager* ScreenManager::Create(aura::Window* root_window) {
168  (new ScreenManagerImpl(root_window))->Init();
169  DCHECK(instance);
170  return instance;
171}
172
173// static
174ScreenManager* ScreenManager::Get() {
175  DCHECK(instance);
176  return instance;
177}
178
179// static
180void ScreenManager::Shutdown() {
181  DCHECK(instance);
182  delete instance;
183  DCHECK(!instance);
184}
185
186}  // namespace athena
187