Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(453)

Side by Side Diff: ash/display/mirror_window_controller.cc

Issue 15367003: Create a mirror window. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: win fix Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/display_info.h"
15 #include "ash/display/display_manager.h"
16 #include "ash/host/root_window_host_factory.h"
17 #include "ash/shell.h"
18 #include "base/stringprintf.h"
19 #include "ui/aura/client/capture_client.h"
20 #include "ui/aura/env.h"
21 #include "ui/aura/root_window.h"
22 #include "ui/aura/window_delegate.h"
23 #include "ui/base/cursor/cursors_aura.h"
24 #include "ui/base/hit_test.h"
25 #include "ui/base/layout.h"
26 #include "ui/base/resource/resource_bundle.h"
27 #include "ui/compositor/compositor.h"
28 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/image/image_skia.h"
30 #include "ui/gfx/native_widget_types.h"
31
32 namespace ash {
33 namespace internal {
34 namespace {
35
36 #if defined(USE_X11)
37 void DisableInput(XID window) {
38 long event_mask = ExposureMask | VisibilityChangeMask |
39 StructureNotifyMask | PropertyChangeMask;
40 XSelectInput(base::MessagePumpAuraX11::GetDefaultXDisplay(),
James Cook 2013/05/21 08:07:41 Comment this? Is it disabling input by selecting o
oshima 2013/05/21 14:41:50 I think it's pretty clear from the method name, an
41 window, event_mask);
42 }
43 #endif
44
45 class NoneCaptureClient : public aura::client::CaptureClient {
46 public:
47 NoneCaptureClient() {}
48 virtual ~NoneCaptureClient() {}
49
50 private:
51 // Does a capture on the |window|.
52 virtual void SetCapture(aura::Window* window) OVERRIDE {}
53
54 // Releases a capture from the |window|.
55 virtual void ReleaseCapture(aura::Window* window) OVERRIDE {}
56
57 // Returns the current capture window.
58 virtual aura::Window* GetCaptureWindow() OVERRIDE {
59 return NULL;
60 }
61
62 DISALLOW_COPY_AND_ASSIGN(NoneCaptureClient);
63 };
64
65 } // namespace
66
67 class CursorWindowDelegate : public aura::WindowDelegate {
68 public:
69 CursorWindowDelegate() {}
70 virtual ~CursorWindowDelegate() {}
71
72 // aura::WindowDelegate overrides:
73 virtual gfx::Size GetMinimumSize() const OVERRIDE {
74 return cursor_image_.size();
75 }
76 virtual gfx::Size GetMaximumSize() const OVERRIDE {
77 return cursor_image_.size();
78 }
79 virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
80 const gfx::Rect& new_bounds) OVERRIDE {
81 }
82 virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
83 return gfx::kNullCursor;
84 }
85 virtual int GetNonClientComponent(
86 const gfx::Point& point) const OVERRIDE {
87 return HTNOWHERE;
88 }
89 virtual bool ShouldDescendIntoChildForEventHandling(
90 aura::Window* child,
91 const gfx::Point& location) OVERRIDE {
92 return false;
93 }
94 virtual bool CanFocus() OVERRIDE {
95 return false;
96 }
97 virtual void OnCaptureLost() OVERRIDE {
98 }
99 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
100 canvas->DrawImageInt(cursor_image_, 0, 0);
101 }
102 virtual void OnDeviceScaleFactorChanged(
103 float device_scale_factor) OVERRIDE {
104 }
105 virtual void OnWindowDestroying() OVERRIDE {}
106 virtual void OnWindowDestroyed() OVERRIDE {}
107 virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
108 }
109 virtual bool HasHitTestMask() const OVERRIDE {
110 return false;
111 }
112 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
113 virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE {
114 NOTREACHED();
115 return scoped_refptr<ui::Texture>();
116 }
117
118 void SetCursorImage(const gfx::ImageSkia& image) {
119 cursor_image_ = image;
120 }
121
122 private:
123 gfx::ImageSkia cursor_image_;
124
125 DISALLOW_COPY_AND_ASSIGN(CursorWindowDelegate);
126 };
127
128 MirrorWindowController::MirrorWindowController()
129 : current_cursor_type_(ui::kCursorNone),
130 cursor_window_(NULL),
131 cursor_window_delegate_(new CursorWindowDelegate) {
132 }
133
134 MirrorWindowController::~MirrorWindowController() {
135 // Make sure the root window gets deleted before cursor_window_delegate.
136 root_window_.reset();
137 }
138
139 void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) {
140 static int mirror_root_window_count = 0;
141 if (root_window_.get()) {
142 root_window_->SetHostBounds(display_info.bounds_in_pixel());
143 return;
144 }
145 Shell* shell = Shell::GetInstance();
146 const gfx::Rect& bounds_in_pixel = display_info.bounds_in_pixel();
147 aura::RootWindow::CreateParams params(bounds_in_pixel);
148 params.host = shell->root_window_host_factory()->
149 CreateRootWindowHost(bounds_in_pixel);
150 root_window_.reset(new aura::RootWindow(params));
151 root_window_->SetName(
152 base::StringPrintf("MirrorRootWindow-%d", mirror_root_window_count++));
153 root_window_->compositor()->SetBackgroundColor(SK_ColorBLACK);
154 // No need to remove RootWindowObserver because
155 // the DisplayManager object outlives RootWindow objects.
156 root_window_->AddRootWindowObserver(shell->display_manager());
157 // TODO(oshima): TouchHUD is using idkey.
158 root_window_->SetProperty(internal::kDisplayIdKey, display_info.id());
159 root_window_->Init();
160 #if defined(USE_X11)
161 DisableInput(root_window_->GetAcceleratedWidget());
162 #endif
163 aura::client::SetCaptureClient(root_window_.get(), new NoneCaptureClient());
164 root_window_->ShowRootWindow();
165
166 cursor_window_ = new aura::Window(cursor_window_delegate_.get());
167 cursor_window_->Init(ui::LAYER_TEXTURED);
168 root_window_->AddChild(cursor_window_);
169 cursor_window_->Show();
170 }
171
172 void MirrorWindowController::Close() {
173 if (root_window_.get()) {
174 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>(
175 aura::client::GetCaptureClient(root_window_.get()));
James Cook 2013/05/21 08:07:41 Do you also need to SetCaptureClient() to NONE, or
oshima 2013/05/21 14:41:50 No, it's not owned by RootWindow.
176 delete capture_client;
177 root_window_.reset();
178 cursor_window_ = NULL;
179 }
180 }
181
182 void MirrorWindowController::UpdateCursorLocation() {
183 if (cursor_window_) {
184 gfx::Point point = aura::Env::GetInstance()->last_mouse_location();
185 point.Offset(-hot_point_.x(), -hot_point_.y());
186 gfx::Rect bounds = cursor_window_->bounds();
187 bounds.set_origin(point); // use hot point.
James Cook 2013/05/21 08:07:41 Two spaces before "// Use hot point."
oshima 2013/05/21 14:41:50 This was reminder for myself, which I forgot to re
188 cursor_window_->SetBounds(bounds);
189 }
190 }
191
192 void MirrorWindowController::SetMirroredCursor(gfx::NativeCursor cursor) {
193 if (current_cursor_type_ == cursor.native_type())
194 return;
195 current_cursor_type_ = cursor.native_type();
196 int resource_id;
197 bool success = ui::GetCursorDataFor(
198 current_cursor_type_, 1.0, &resource_id, &hot_point_);
199 if (!success)
200 return;
201 const gfx::ImageSkia* image =
202 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
203 cursor_window_delegate_->SetCursorImage(*image);
204 if (cursor_window_) {
205 cursor_window_->SchedulePaintInRect(
206 gfx::Rect(cursor_window_->bounds().size()));
207 UpdateCursorLocation();
208 }
209 }
210
211 void MirrorWindowController::SetMirroredCursorVisibility(bool visible) {
212 if (cursor_window_)
213 visible ? cursor_window_->Show() : cursor_window_->Hide();
214 }
215
216 } // namespace internal
217 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698