blob: f81eeecf5c6b866de8d61f07530af221e1d6f50e [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/dri/dri_cursor.h"
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h"
#include "ui/ozone/platform/dri/dri_window.h"
#include "ui/ozone/platform/dri/dri_window_manager.h"
#if defined(OS_CHROMEOS)
#include "ui/events/ozone/chromeos/cursor_controller.h"
#endif
namespace ui {
DriCursor::DriCursor(DriWindowManager* window_manager,
DriGpuPlatformSupportHost* sender)
: window_manager_(window_manager),
sender_(sender),
cursor_window_(gfx::kNullAcceleratedWidget) {
}
DriCursor::~DriCursor() {
}
void DriCursor::SetCursor(gfx::AcceleratedWidget widget,
PlatformCursor platform_cursor) {
DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
scoped_refptr<BitmapCursorOzone> cursor =
BitmapCursorFactoryOzone::GetBitmapCursor(platform_cursor);
if (cursor_ == cursor || cursor_window_ != widget)
return;
cursor_ = cursor;
ShowCursor();
}
void DriCursor::ShowCursor() {
DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget);
if (cursor_.get())
sender_->SetHardwareCursor(cursor_window_, cursor_->bitmaps(),
bitmap_location(), cursor_->frame_delay_ms());
else
HideCursor();
}
void DriCursor::HideCursor() {
DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget);
sender_->SetHardwareCursor(cursor_window_, std::vector<SkBitmap>(),
gfx::Point(), 0);
}
void DriCursor::MoveCursorTo(gfx::AcceleratedWidget widget,
const gfx::PointF& location) {
if (widget != cursor_window_ && cursor_window_ != gfx::kNullAcceleratedWidget)
HideCursor();
DriWindow* window = window_manager_->GetWindow(widget);
cursor_window_ = widget;
cursor_location_ = location;
cursor_display_bounds_ = window->GetBounds();
const gfx::Size& size = cursor_display_bounds_.size();
cursor_location_.SetToMax(gfx::PointF(0, 0));
// Right and bottom edges are exclusive.
cursor_location_.SetToMin(gfx::PointF(size.width() - 1, size.height() - 1));
if (cursor_.get())
sender_->MoveHardwareCursor(cursor_window_, bitmap_location());
}
void DriCursor::MoveCursorTo(const gfx::PointF& location) {
DriWindow* window =
window_manager_->GetWindowAt(gfx::ToFlooredPoint(location));
if (!window)
return;
MoveCursorTo(window->GetAcceleratedWidget(),
location - window->GetBounds().OffsetFromOrigin());
}
void DriCursor::MoveCursor(const gfx::Vector2dF& delta) {
if (cursor_window_ == gfx::kNullAcceleratedWidget)
return;
#if defined(OS_CHROMEOS)
gfx::Vector2dF transformed_delta = delta;
ui::CursorController::GetInstance()->ApplyCursorConfigForWindow(
cursor_window_, &transformed_delta);
MoveCursorTo(cursor_window_, cursor_location_ + transformed_delta);
#else
MoveCursorTo(cursor_window_, cursor_location_ + delta);
#endif
}
gfx::Rect DriCursor::GetCursorDisplayBounds() {
return cursor_display_bounds_;
}
gfx::AcceleratedWidget DriCursor::GetCursorWindow() {
return cursor_window_;
}
bool DriCursor::IsCursorVisible() {
return cursor_.get();
}
gfx::PointF DriCursor::GetLocation() {
return cursor_location_;
}
gfx::Point DriCursor::bitmap_location() {
return gfx::ToFlooredPoint(cursor_location_) -
cursor_->hotspot().OffsetFromOrigin();
}
} // namespace ui