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 "ui/aura/window_tree_host_win.h"
6
7#include <windows.h>
8
9#include <algorithm>
10
11#include "base/message_loop/message_loop.h"
12#include "ui/aura/client/cursor_client.h"
13#include "ui/aura/window_event_dispatcher.h"
14#include "ui/base/cursor/cursor_loader_win.h"
15#include "ui/base/view_prop.h"
16#include "ui/compositor/compositor.h"
17#include "ui/events/event.h"
18#include "ui/gfx/display.h"
19#include "ui/gfx/insets.h"
20#include "ui/gfx/native_widget_types.h"
21#include "ui/gfx/screen.h"
22#include "ui/platform_window/win/win_window.h"
23
24using std::max;
25using std::min;
26
27namespace aura {
28namespace {
29
30bool use_popup_as_root_window_for_test = false;
31
32}  // namespace
33
34// static
35WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
36  return new WindowTreeHostWin(bounds);
37}
38
39// static
40gfx::Size WindowTreeHost::GetNativeScreenSize() {
41  return gfx::Size(GetSystemMetrics(SM_CXSCREEN),
42                   GetSystemMetrics(SM_CYSCREEN));
43}
44
45WindowTreeHostWin::WindowTreeHostWin(const gfx::Rect& bounds)
46    : has_capture_(false),
47      widget_(gfx::kNullAcceleratedWidget),
48      window_(new ui::WinWindow(this, bounds)) {
49}
50
51WindowTreeHostWin::~WindowTreeHostWin() {
52  DestroyCompositor();
53  DestroyDispatcher();
54  window_.reset();
55}
56
57ui::EventSource* WindowTreeHostWin::GetEventSource() {
58  return this;
59}
60
61gfx::AcceleratedWidget WindowTreeHostWin::GetAcceleratedWidget() {
62  return widget_;
63}
64
65void WindowTreeHostWin::Show() {
66  window_->Show();
67}
68
69void WindowTreeHostWin::Hide() {
70  window_->Hide();
71}
72
73gfx::Rect WindowTreeHostWin::GetBounds() const {
74  return window_->GetBounds();
75}
76
77void WindowTreeHostWin::SetBounds(const gfx::Rect& bounds) {
78  window_->SetBounds(bounds);
79}
80
81gfx::Point WindowTreeHostWin::GetLocationOnNativeScreen() const {
82  return window_->GetBounds().origin();
83}
84
85void WindowTreeHostWin::SetCapture() {
86  if (!has_capture_) {
87    has_capture_ = true;
88    window_->SetCapture();
89  }
90}
91
92void WindowTreeHostWin::ReleaseCapture() {
93  if (has_capture_)
94    window_->ReleaseCapture();
95}
96
97void WindowTreeHostWin::SetCursorNative(gfx::NativeCursor native_cursor) {
98  // Custom web cursors are handled directly.
99  if (native_cursor == ui::kCursorCustom)
100    return;
101
102  ui::CursorLoaderWin cursor_loader;
103  cursor_loader.SetPlatformCursor(&native_cursor);
104  ::SetCursor(native_cursor.platform());
105}
106
107void WindowTreeHostWin::MoveCursorToNative(const gfx::Point& location) {
108  // Deliberately not implemented.
109}
110
111void WindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
112  NOTIMPLEMENTED();
113}
114
115void WindowTreeHostWin::PostNativeEvent(const base::NativeEvent& native_event) {
116  ::PostMessage(
117      widget_, native_event.message, native_event.wParam, native_event.lParam);
118}
119
120ui::EventProcessor* WindowTreeHostWin::GetEventProcessor() {
121  return dispatcher();
122}
123
124void WindowTreeHostWin::OnBoundsChanged(const gfx::Rect& new_bounds) {
125  gfx::Rect old_bounds = bounds_;
126  bounds_ = new_bounds;
127  if (bounds_.origin() != old_bounds.origin())
128    OnHostMoved(bounds_.origin());
129  if (bounds_.size() != old_bounds.size())
130    OnHostResized(bounds_.size());
131}
132
133void WindowTreeHostWin::OnDamageRect(const gfx::Rect& damage_rect) {
134  compositor()->ScheduleRedrawRect(damage_rect);
135}
136
137void WindowTreeHostWin::DispatchEvent(ui::Event* event) {
138  ui::EventDispatchDetails details = SendEventToProcessor(event);
139  if (details.dispatcher_destroyed)
140    event->SetHandled();
141}
142
143void WindowTreeHostWin::OnCloseRequest() {
144  // TODO: this obviously shouldn't be here.
145  base::MessageLoopForUI::current()->Quit();
146}
147
148void WindowTreeHostWin::OnClosed() {
149}
150
151void WindowTreeHostWin::OnWindowStateChanged(
152    ui::PlatformWindowState new_state) {
153}
154
155void WindowTreeHostWin::OnLostCapture() {
156  if (has_capture_) {
157    has_capture_ = false;
158    OnHostLostWindowCapture();
159  }
160}
161
162void WindowTreeHostWin::OnAcceleratedWidgetAvailable(
163    gfx::AcceleratedWidget widget) {
164  widget_ = widget;
165  CreateCompositor(widget);
166}
167
168void WindowTreeHostWin::OnActivationChanged(bool active) {
169  if (active)
170    OnHostActivated();
171}
172
173}  // namespace aura
174