| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 base::AutoLock lock(state_.lock); | 45 base::AutoLock lock(state_.lock); |
| 46 if (state_.window != window || state_.bitmap == bitmap) | 46 if (state_.window != window || state_.bitmap == bitmap) |
| 47 return; | 47 return; |
| 48 | 48 |
| 49 state_.bitmap = bitmap; | 49 state_.bitmap = bitmap; |
| 50 | 50 |
| 51 SendCursorShowLocked(); | 51 SendCursorShowLocked(); |
| 52 } | 52 } |
| 53 | 53 |
| 54 void DriCursor::OnWindowAdded(gfx::AcceleratedWidget window, | 54 void DriCursor::OnWindowAdded(gfx::AcceleratedWidget window, |
| 55 const gfx::Rect& bounds) { | 55 const gfx::Rect& bounds_in_screen, |
| 56 const gfx::Rect& cursor_confined_bounds) { |
| 56 #if DCHECK_IS_ON() | 57 #if DCHECK_IS_ON() |
| 57 if (!ui_task_runner_) | 58 if (!ui_task_runner_) |
| 58 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 59 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 59 #endif | 60 #endif |
| 60 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 61 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 61 base::AutoLock lock(state_.lock); | 62 base::AutoLock lock(state_.lock); |
| 62 | 63 |
| 63 if (state_.window == gfx::kNullAcceleratedWidget) { | 64 if (state_.window == gfx::kNullAcceleratedWidget) { |
| 64 // First window added & cursor is not placed. Place it. | 65 // First window added & cursor is not placed. Place it. |
| 65 state_.window = window; | 66 state_.window = window; |
| 66 state_.bounds = bounds; | 67 state_.display_bounds_in_screen = bounds_in_screen; |
| 67 SetCursorLocationLocked(bounds.CenterPoint() - bounds.OffsetFromOrigin()); | 68 state_.confined_bounds = cursor_confined_bounds; |
| 69 SetCursorLocationLocked(cursor_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 |
| 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(state_.confined_bounds.origin()); |
| 218 // Right and bottom edges are exclusive. | 224 // Right and bottom edges are exclusive. |
| 219 clamped_location.SetToMin(gfx::PointF(size.width() - 1, size.height() - 1)); | 225 clamped_location.SetToMin(gfx::PointF(state_.confined_bounds.right() - 1, |
| 226 state_.confined_bounds.bottom() - 1)); |
| 220 | 227 |
| 221 state_.location = clamped_location; | 228 state_.location = clamped_location; |
| 222 } | 229 } |
| 223 | 230 |
| 224 gfx::Point DriCursor::GetBitmapLocationLocked() { | 231 gfx::Point DriCursor::GetBitmapLocationLocked() { |
| 225 return gfx::ToFlooredPoint(state_.location) - | 232 return gfx::ToFlooredPoint(state_.location) - |
| 226 state_.bitmap->hotspot().OffsetFromOrigin(); | 233 state_.bitmap->hotspot().OffsetFromOrigin(); |
| 227 } | 234 } |
| 228 | 235 |
| 229 bool DriCursor::IsConnectedLocked() { | 236 bool DriCursor::IsConnectedLocked() { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 255 } | 262 } |
| 256 | 263 |
| 257 void DriCursor::SendLocked(IPC::Message* message) { | 264 void DriCursor::SendLocked(IPC::Message* message) { |
| 258 state_.lock.AssertAcquired(); | 265 state_.lock.AssertAcquired(); |
| 259 | 266 |
| 260 if (IsConnectedLocked() && | 267 if (IsConnectedLocked() && |
| 261 state_.send_runner->PostTask(FROM_HERE, | 268 state_.send_runner->PostTask(FROM_HERE, |
| 262 base::Bind(state_.send_callback, message))) | 269 base::Bind(state_.send_callback, message))) |
| 263 return; | 270 return; |
| 264 | 271 |
| 265 // Drop disconnected updates. DriWindow will call CommitBoundsChange() | 272 // Drop disconnected updates. DriWindow will call ConfineCursorToBounds() |
| 266 // when we connect to initialize the cursor location. | 273 // when we connect to initialize the cursor location. |
| 267 delete message; | 274 delete message; |
| 268 } | 275 } |
| 269 | 276 |
| 270 DriCursor::CursorState::CursorState() : window(gfx::kNullAcceleratedWidget) { | 277 DriCursor::CursorState::CursorState() : window(gfx::kNullAcceleratedWidget) { |
| 271 } | 278 } |
| 272 | 279 |
| 273 DriCursor::CursorState::~CursorState() { | 280 DriCursor::CursorState::~CursorState() { |
| 274 } | 281 } |
| 275 | 282 |
| 276 } // namespace ui | 283 } // namespace ui |
| OLD | NEW |