1// Copyright (c) 2012 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 "base/at_exit.h"
6#include "base/command_line.h"
7#include "base/i18n/icu_util.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/message_loop/message_loop.h"
10#include "third_party/skia/include/core/SkXfermode.h"
11#include "ui/aura/client/default_capture_client.h"
12#include "ui/aura/client/window_tree_client.h"
13#include "ui/aura/env.h"
14#include "ui/aura/test/test_focus_client.h"
15#include "ui/aura/test/test_screen.h"
16#include "ui/aura/window.h"
17#include "ui/aura/window_delegate.h"
18#include "ui/aura/window_tree_host.h"
19#include "ui/base/hit_test.h"
20#include "ui/compositor/test/in_process_context_factory.h"
21#include "ui/events/event.h"
22#include "ui/gfx/canvas.h"
23#include "ui/gfx/rect.h"
24#include "ui/gl/gl_surface.h"
25
26#if defined(USE_X11)
27#include "ui/gfx/x/x11_connection.h"
28#endif
29
30#if defined(OS_WIN)
31#include "ui/gfx/win/dpi.h"
32#endif
33
34namespace {
35
36// Trivial WindowDelegate implementation that draws a colored background.
37class DemoWindowDelegate : public aura::WindowDelegate {
38 public:
39  explicit DemoWindowDelegate(SkColor color) : color_(color) {}
40
41  // Overridden from WindowDelegate:
42  virtual gfx::Size GetMinimumSize() const OVERRIDE {
43    return gfx::Size();
44  }
45
46  virtual gfx::Size GetMaximumSize() const OVERRIDE {
47    return gfx::Size();
48  }
49
50  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
51                               const gfx::Rect& new_bounds) OVERRIDE {}
52  virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
53    return gfx::kNullCursor;
54  }
55  virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
56    return HTCAPTION;
57  }
58  virtual bool ShouldDescendIntoChildForEventHandling(
59      aura::Window* child,
60      const gfx::Point& location) OVERRIDE {
61    return true;
62  }
63  virtual bool CanFocus() OVERRIDE { return true; }
64  virtual void OnCaptureLost() OVERRIDE {}
65  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
66    canvas->DrawColor(color_, SkXfermode::kSrc_Mode);
67  }
68  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {}
69  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {}
70  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {}
71  virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {}
72  virtual bool HasHitTestMask() const OVERRIDE { return false; }
73  virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
74
75 private:
76  SkColor color_;
77
78  DISALLOW_COPY_AND_ASSIGN(DemoWindowDelegate);
79};
80
81class DemoWindowTreeClient : public aura::client::WindowTreeClient {
82 public:
83  explicit DemoWindowTreeClient(aura::Window* window) : window_(window) {
84    aura::client::SetWindowTreeClient(window_, this);
85  }
86
87  virtual ~DemoWindowTreeClient() {
88    aura::client::SetWindowTreeClient(window_, NULL);
89  }
90
91  // Overridden from aura::client::WindowTreeClient:
92  virtual aura::Window* GetDefaultParent(aura::Window* context,
93                                         aura::Window* window,
94                                         const gfx::Rect& bounds) OVERRIDE {
95    if (!capture_client_) {
96      capture_client_.reset(
97          new aura::client::DefaultCaptureClient(window_->GetRootWindow()));
98    }
99    return window_;
100  }
101
102 private:
103  aura::Window* window_;
104
105  scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
106
107  DISALLOW_COPY_AND_ASSIGN(DemoWindowTreeClient);
108};
109
110int DemoMain() {
111#if defined(USE_X11)
112  // This demo uses InProcessContextFactory which uses X on a separate Gpu
113  // thread.
114  gfx::InitializeThreadedX11();
115#endif
116
117  gfx::GLSurface::InitializeOneOff();
118
119#if defined(OS_WIN)
120  gfx::InitDeviceScaleFactor(1.0f);
121#endif
122
123  // The ContextFactory must exist before any Compositors are created.
124  scoped_ptr<ui::InProcessContextFactory> context_factory(
125      new ui::InProcessContextFactory());
126
127  // Create the message-loop here before creating the root window.
128  base::MessageLoopForUI message_loop;
129
130  aura::Env::CreateInstance(true);
131  aura::Env::GetInstance()->set_context_factory(context_factory.get());
132  scoped_ptr<aura::TestScreen> test_screen(
133      aura::TestScreen::Create(gfx::Size()));
134  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get());
135  scoped_ptr<aura::WindowTreeHost> host(
136      test_screen->CreateHostForPrimaryDisplay());
137  scoped_ptr<DemoWindowTreeClient> window_tree_client(
138      new DemoWindowTreeClient(host->window()));
139  aura::test::TestFocusClient focus_client;
140  aura::client::SetFocusClient(host->window(), &focus_client);
141
142  // Create a hierarchy of test windows.
143  DemoWindowDelegate window_delegate1(SK_ColorBLUE);
144  aura::Window window1(&window_delegate1);
145  window1.set_id(1);
146  window1.Init(aura::WINDOW_LAYER_TEXTURED);
147  window1.SetBounds(gfx::Rect(100, 100, 400, 400));
148  window1.Show();
149  aura::client::ParentWindowWithContext(&window1, host->window(), gfx::Rect());
150
151  DemoWindowDelegate window_delegate2(SK_ColorRED);
152  aura::Window window2(&window_delegate2);
153  window2.set_id(2);
154  window2.Init(aura::WINDOW_LAYER_TEXTURED);
155  window2.SetBounds(gfx::Rect(200, 200, 350, 350));
156  window2.Show();
157  aura::client::ParentWindowWithContext(&window2, host->window(), gfx::Rect());
158
159  DemoWindowDelegate window_delegate3(SK_ColorGREEN);
160  aura::Window window3(&window_delegate3);
161  window3.set_id(3);
162  window3.Init(aura::WINDOW_LAYER_TEXTURED);
163  window3.SetBounds(gfx::Rect(10, 10, 50, 50));
164  window3.Show();
165  window2.AddChild(&window3);
166
167  host->Show();
168  base::MessageLoopForUI::current()->Run();
169
170  return 0;
171}
172
173}  // namespace
174
175int main(int argc, char** argv) {
176  CommandLine::Init(argc, argv);
177
178  // The exit manager is in charge of calling the dtors of singleton objects.
179  base::AtExitManager exit_manager;
180
181  base::i18n::InitializeICU();
182
183  return DemoMain();
184}
185