OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/ozone/platform/dri/dri_cursor.h" | 5 #include "ui/ozone/platform/dri/dri_cursor.h" |
6 | 6 |
7 #include "base/thread_task_runner_handle.h" | 7 #include "base/thread_task_runner_handle.h" |
8 #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" | 8 #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" |
9 #include "ui/gfx/geometry/point.h" | 9 #include "ui/gfx/geometry/point.h" |
10 #include "ui/gfx/geometry/point_conversions.h" | 10 #include "ui/gfx/geometry/point_conversions.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
56 #if DCHECK_IS_ON() | 56 #if DCHECK_IS_ON() |
57 if (!ui_task_runner_) | 57 if (!ui_task_runner_) |
58 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 58 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
59 #endif | 59 #endif |
60 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 60 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
61 base::AutoLock lock(state_.lock); | 61 base::AutoLock lock(state_.lock); |
62 | 62 |
63 if (state_.window == gfx::kNullAcceleratedWidget) { | 63 if (state_.window == gfx::kNullAcceleratedWidget) { |
64 // First window added & cursor is not placed. Place it. | 64 // First window added & cursor is not placed. Place it. |
65 state_.window = window; | 65 state_.window = window; |
66 state_.bounds = bounds; | 66 state_.display_bounds_in_screen = bounds; |
67 SetCursorLocationLocked(bounds.CenterPoint() - bounds.OffsetFromOrigin()); | 67 DriWindow* dri_window = window_manager_->GetWindow(window); |
spang
2015/01/23 18:18:40
Instead of looking the window up, just change the
| |
68 state_.confined_bounds = dri_window->GetCursorConfinedBounds(); | |
69 SetCursorLocationLocked(state_.confined_bounds.CenterPoint()); | |
68 } | 70 } |
69 } | 71 } |
70 | 72 |
71 void DriCursor::OnWindowRemoved(gfx::AcceleratedWidget window) { | 73 void DriCursor::OnWindowRemoved(gfx::AcceleratedWidget window) { |
72 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 74 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
73 base::AutoLock lock(state_.lock); | 75 base::AutoLock lock(state_.lock); |
74 | 76 |
75 if (state_.window == window) { | 77 if (state_.window == window) { |
76 // Try to find a new location for the cursor. | 78 // Try to find a new location for the cursor. |
77 gfx::PointF screen_location = | |
78 state_.location + state_.bounds.OffsetFromOrigin(); | |
79 DriWindow* dest_window = window_manager_->GetPrimaryWindow(); | 79 DriWindow* dest_window = window_manager_->GetPrimaryWindow(); |
80 | 80 |
81 if (dest_window) { | 81 if (dest_window) { |
82 state_.window = dest_window->GetAcceleratedWidget(); | 82 state_.window = dest_window->GetAcceleratedWidget(); |
83 state_.bounds = dest_window->GetBounds(); | 83 state_.display_bounds_in_screen = dest_window->GetBounds(); |
84 SetCursorLocationLocked(state_.bounds.CenterPoint() - | 84 state_.confined_bounds = dest_window->GetCursorConfinedBounds(); |
85 state_.bounds.OffsetFromOrigin()); | 85 SetCursorLocationLocked(state_.confined_bounds.CenterPoint()); |
86 SendCursorShowLocked(); | 86 SendCursorShowLocked(); |
87 } else { | 87 } else { |
88 state_.window = gfx::kNullAcceleratedWidget; | 88 state_.window = gfx::kNullAcceleratedWidget; |
89 state_.bounds = gfx::Rect(); | 89 state_.display_bounds_in_screen = gfx::Rect(); |
90 state_.confined_bounds = gfx::Rect(); | |
90 state_.location = gfx::Point(); | 91 state_.location = gfx::Point(); |
91 } | 92 } |
92 } | 93 } |
93 } | 94 } |
94 | 95 |
95 void DriCursor::PrepareForBoundsChange(gfx::AcceleratedWidget window) { | 96 void DriCursor::PrepareForBoundsChange(gfx::AcceleratedWidget window) { |
96 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 97 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
97 base::AutoLock lock(state_.lock); | 98 base::AutoLock lock(state_.lock); |
98 | 99 |
99 // Bounds changes can reparent the window to a different display, so | 100 // Bounds changes can reparent the window to a different display, so |
100 // we hide prior to the change so that we avoid leaving a cursor | 101 // we hide prior to the change so that we avoid leaving a cursor |
101 // behind on the old display. | 102 // behind on the old display. |
102 // TODO(spang): The GPU-side code should handle this. | 103 // TODO(spang): The GPU-side code should handle this. |
103 if (state_.window == window) | 104 if (state_.window == window) |
104 SendCursorHideLocked(); | 105 SendCursorHideLocked(); |
106 | |
pkotwicz
2015/01/23 03:40:27
Yes, this is ugly...
| |
107 // The cursor will be shown and moved once the confined bounds for |window| | |
108 // are updated. | |
105 } | 109 } |
106 | 110 |
107 void DriCursor::CommitBoundsChange(gfx::AcceleratedWidget window, | 111 void DriCursor::ConfineCursorToBounds(gfx::AcceleratedWidget window, |
108 const gfx::Rect& bounds) { | 112 const gfx::Rect& bounds) { |
109 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 113 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
110 base::AutoLock lock(state_.lock); | 114 base::AutoLock lock(state_.lock); |
111 if (state_.window == window) { | 115 if (state_.window == window) { |
112 state_.bounds = bounds; | 116 state_.confined_bounds = bounds; |
113 SetCursorLocationLocked(state_.location); | 117 SetCursorLocationLocked(state_.location); |
114 SendCursorShowLocked(); | 118 SendCursorShowLocked(); |
115 } | 119 } |
116 } | 120 } |
117 | 121 |
118 void DriCursor::MoveCursorTo(gfx::AcceleratedWidget window, | 122 void DriCursor::MoveCursorTo(gfx::AcceleratedWidget window, |
119 const gfx::PointF& location) { | 123 const gfx::PointF& location) { |
120 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 124 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
121 base::AutoLock lock(state_.lock); | 125 base::AutoLock lock(state_.lock); |
122 gfx::AcceleratedWidget old_window = state_.window; | 126 gfx::AcceleratedWidget old_window = state_.window; |
123 | 127 |
124 if (window != old_window) { | 128 if (window != old_window) { |
125 // When moving between displays, hide the cursor on the old display | 129 // When moving between displays, hide the cursor on the old display |
126 // prior to showing it on the new display. | 130 // prior to showing it on the new display. |
127 if (old_window != gfx::kNullAcceleratedWidget) | 131 if (old_window != gfx::kNullAcceleratedWidget) |
128 SendCursorHideLocked(); | 132 SendCursorHideLocked(); |
129 | 133 |
130 DriWindow* dri_window = window_manager_->GetWindow(window); | 134 DriWindow* dri_window = window_manager_->GetWindow(window); |
131 state_.bounds = dri_window->GetBounds(); | 135 state_.display_bounds_in_screen = dri_window->GetBounds(); |
136 state_.confined_bounds = dri_window->GetCursorConfinedBounds(); | |
132 state_.window = window; | 137 state_.window = window; |
133 } | 138 } |
134 | 139 |
135 SetCursorLocationLocked(location); | 140 SetCursorLocationLocked(location); |
136 | 141 |
137 if (window != old_window) | 142 if (window != old_window) |
138 SendCursorShowLocked(); | 143 SendCursorShowLocked(); |
139 else | 144 else |
140 SendCursorMoveLocked(); | 145 SendCursorMoveLocked(); |
141 } | 146 } |
142 | 147 |
143 void DriCursor::MoveCursorTo(const gfx::PointF& screen_location) { | 148 void DriCursor::MoveCursorTo(const gfx::PointF& screen_location) { |
144 base::AutoLock lock(state_.lock); | 149 base::AutoLock lock(state_.lock); |
145 | 150 |
146 // TODO(spang): Moving between windows doesn't work here, but | 151 // TODO(spang): Moving between windows doesn't work here, but |
147 // is not needed for current uses. | 152 // is not needed for current uses. |
148 | 153 |
149 SetCursorLocationLocked(screen_location - state_.bounds.OffsetFromOrigin()); | 154 SetCursorLocationLocked(screen_location - |
155 state_.display_bounds_in_screen.OffsetFromOrigin()); | |
150 } | 156 } |
151 | 157 |
152 void DriCursor::MoveCursor(const gfx::Vector2dF& delta) { | 158 void DriCursor::MoveCursor(const gfx::Vector2dF& delta) { |
153 base::AutoLock lock(state_.lock); | 159 base::AutoLock lock(state_.lock); |
154 if (state_.window == gfx::kNullAcceleratedWidget) | 160 if (state_.window == gfx::kNullAcceleratedWidget) |
155 return; | 161 return; |
156 | 162 |
157 gfx::Point location; | 163 gfx::Point location; |
158 #if defined(OS_CHROMEOS) | 164 #if defined(OS_CHROMEOS) |
159 gfx::Vector2dF transformed_delta = delta; | 165 gfx::Vector2dF transformed_delta = delta; |
160 ui::CursorController::GetInstance()->ApplyCursorConfigForWindow( | 166 ui::CursorController::GetInstance()->ApplyCursorConfigForWindow( |
161 state_.window, &transformed_delta); | 167 state_.window, &transformed_delta); |
162 SetCursorLocationLocked(state_.location + transformed_delta); | 168 SetCursorLocationLocked(state_.location + transformed_delta); |
163 #else | 169 #else |
164 SetCursorLocationLocked(state_.location + delta); | 170 SetCursorLocationLocked(state_.location + delta); |
165 #endif | 171 #endif |
166 | 172 |
167 SendCursorMoveLocked(); | 173 SendCursorMoveLocked(); |
168 } | 174 } |
169 | 175 |
170 bool DriCursor::IsCursorVisible() { | 176 bool DriCursor::IsCursorVisible() { |
171 base::AutoLock lock(state_.lock); | 177 base::AutoLock lock(state_.lock); |
172 return state_.bitmap; | 178 return state_.bitmap; |
173 } | 179 } |
174 | 180 |
175 gfx::PointF DriCursor::GetLocation() { | 181 gfx::PointF DriCursor::GetLocation() { |
176 base::AutoLock lock(state_.lock); | 182 base::AutoLock lock(state_.lock); |
177 return state_.location + state_.bounds.OffsetFromOrigin(); | 183 return state_.location + state_.display_bounds_in_screen.OffsetFromOrigin(); |
178 } | 184 } |
179 | 185 |
180 gfx::Rect DriCursor::GetCursorDisplayBounds() { | 186 gfx::Rect DriCursor::GetCursorConfinedBounds() { |
181 base::AutoLock lock(state_.lock); | 187 base::AutoLock lock(state_.lock); |
182 return state_.bounds; | 188 return state_.confined_bounds + |
189 state_.display_bounds_in_screen.OffsetFromOrigin(); | |
183 } | 190 } |
184 | 191 |
185 void DriCursor::OnChannelEstablished( | 192 void DriCursor::OnChannelEstablished( |
186 int host_id, | 193 int host_id, |
187 scoped_refptr<base::SingleThreadTaskRunner> send_runner, | 194 scoped_refptr<base::SingleThreadTaskRunner> send_runner, |
188 const base::Callback<void(IPC::Message*)>& send_callback) { | 195 const base::Callback<void(IPC::Message*)>& send_callback) { |
189 #if DCHECK_IS_ON() | 196 #if DCHECK_IS_ON() |
190 if (!ui_task_runner_) | 197 if (!ui_task_runner_) |
191 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 198 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
192 #endif | 199 #endif |
193 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 200 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
194 base::AutoLock lock(state_.lock); | 201 base::AutoLock lock(state_.lock); |
195 state_.send_runner = send_runner; | 202 state_.send_runner = send_runner; |
196 state_.send_callback = send_callback; | 203 state_.send_callback = send_callback; |
197 // Initial set for this GPU process will happen after the window | 204 // Initial set for this GPU process will happen after the window |
198 // initializes, in CommitBoundsChange. | 205 // initializes, in ConfineCursorToBounds(). |
199 } | 206 } |
200 | 207 |
201 void DriCursor::OnChannelDestroyed(int host_id) { | 208 void DriCursor::OnChannelDestroyed(int host_id) { |
202 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 209 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
203 base::AutoLock lock(state_.lock); | 210 base::AutoLock lock(state_.lock); |
204 state_.send_runner = NULL; | 211 state_.send_runner = NULL; |
205 state_.send_callback.Reset(); | 212 state_.send_callback.Reset(); |
206 } | 213 } |
207 | 214 |
208 bool DriCursor::OnMessageReceived(const IPC::Message& message) { | 215 bool DriCursor::OnMessageReceived(const IPC::Message& message) { |
209 return false; | 216 return false; |
210 } | 217 } |
211 | 218 |
212 void DriCursor::SetCursorLocationLocked(const gfx::PointF& location) { | 219 void DriCursor::SetCursorLocationLocked(const gfx::PointF& location) { |
213 state_.lock.AssertAcquired(); | 220 state_.lock.AssertAcquired(); |
214 | 221 |
215 const gfx::Size& size = state_.bounds.size(); | |
216 gfx::PointF clamped_location = location; | 222 gfx::PointF clamped_location = location; |
217 clamped_location.SetToMax(gfx::PointF(0, 0)); | 223 clamped_location.SetToMax( |
224 gfx::PointF(state_.confined_bounds.x(), state_.confined_bounds.y())); | |
spang
2015/01/23 18:18:40
Point(rect.x(), rect.y()) is just rect.origin()
| |
218 // Right and bottom edges are exclusive. | 225 // Right and bottom edges are exclusive. |
219 clamped_location.SetToMin(gfx::PointF(size.width() - 1, size.height() - 1)); | 226 clamped_location.SetToMin(gfx::PointF(state_.confined_bounds.right() - 1, |
227 state_.confined_bounds.bottom() - 1)); | |
220 | 228 |
221 state_.location = clamped_location; | 229 state_.location = clamped_location; |
222 } | 230 } |
223 | 231 |
224 gfx::Point DriCursor::GetBitmapLocationLocked() { | 232 gfx::Point DriCursor::GetBitmapLocationLocked() { |
225 return gfx::ToFlooredPoint(state_.location) - | 233 return gfx::ToFlooredPoint(state_.location) - |
226 state_.bitmap->hotspot().OffsetFromOrigin(); | 234 state_.bitmap->hotspot().OffsetFromOrigin(); |
227 } | 235 } |
228 | 236 |
229 bool DriCursor::IsConnectedLocked() { | 237 bool DriCursor::IsConnectedLocked() { |
(...skipping 25 matching lines...) Expand all Loading... | |
255 } | 263 } |
256 | 264 |
257 void DriCursor::SendLocked(IPC::Message* message) { | 265 void DriCursor::SendLocked(IPC::Message* message) { |
258 state_.lock.AssertAcquired(); | 266 state_.lock.AssertAcquired(); |
259 | 267 |
260 if (IsConnectedLocked() && | 268 if (IsConnectedLocked() && |
261 state_.send_runner->PostTask(FROM_HERE, | 269 state_.send_runner->PostTask(FROM_HERE, |
262 base::Bind(state_.send_callback, message))) | 270 base::Bind(state_.send_callback, message))) |
263 return; | 271 return; |
264 | 272 |
265 // Drop disconnected updates. DriWindow will call CommitBoundsChange() | 273 // Drop disconnected updates. DriWindow will call ConfineCursorToBounds() |
266 // when we connect to initialize the cursor location. | 274 // when we connect to initialize the cursor location. |
267 delete message; | 275 delete message; |
268 } | 276 } |
269 | 277 |
270 DriCursor::CursorState::CursorState() : window(gfx::kNullAcceleratedWidget) { | 278 DriCursor::CursorState::CursorState() : window(gfx::kNullAcceleratedWidget) { |
271 } | 279 } |
272 | 280 |
273 DriCursor::CursorState::~CursorState() { | 281 DriCursor::CursorState::~CursorState() { |
274 } | 282 } |
275 | 283 |
276 } // namespace ui | 284 } // namespace ui |
OLD | NEW |