1 // Copyright 2013 Intel Corporation. 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.
5 #include "ozone/wayland/input/cursor.h"
9 #include "base/logging.h"
10 #include "ozone/wayland/display.h"
12 namespace ozonewayland {
13 // This number should be equal to size of array defined in WaylandCursorData
15 const unsigned TotalCursorTypes = 24;
17 class WaylandCursorData {
19 explicit WaylandCursorData(wl_shm* shm);
22 static WaylandCursorData* GetInstance() {
26 static void InitializeCursorData(wl_shm* shm) {
28 impl_ = new WaylandCursorData(shm);
31 static void DestroyCursorData() {
38 struct wl_cursor_image* GetCursorImage(WaylandCursor::CursorType index);
41 wl_cursor_theme* cursor_theme_;
42 // All supported Cursor types.
43 std::vector<wl_cursor*> cursors_;
44 static WaylandCursorData* impl_;
45 DISALLOW_COPY_AND_ASSIGN(WaylandCursorData);
48 WaylandCursorData* WaylandCursorData::impl_ = NULL;
50 WaylandCursorData::WaylandCursorData(wl_shm* shm)
51 : cursor_theme_(NULL),
52 cursors_(std::vector<wl_cursor*>(TotalCursorTypes)) {
53 // This list should be always in sync with WaylandCursor::CursorType
54 const char* cursor_names[] = {
57 "bottom_right_corner",
81 // (kalyan) We should be able to configure the size of cursor and theme name.
82 cursor_theme_ = wl_cursor_theme_load(NULL, 24, shm);
83 DCHECK(cursor_theme_);
85 for (unsigned i = 0; i < TotalCursorTypes; i++)
86 cursors_[i] = wl_cursor_theme_get_cursor(cursor_theme_, cursor_names[i]);
89 struct wl_cursor_image* WaylandCursorData::GetCursorImage(
90 WaylandCursor::CursorType type) {
92 const struct wl_cursor* cursor = cursors_.at(index);
96 return cursor->images[0];
99 WaylandCursorData::~WaylandCursorData() {
100 wl_cursor_theme_destroy(cursor_theme_);
102 if (!cursors_.empty())
106 WaylandCursor::WaylandCursor(wl_shm* shm) : input_pointer_(NULL),
107 pointer_surface_(NULL),
108 current_cursor_(CURSOR_UNSET) {
109 DCHECK(WaylandCursorData::GetInstance());
110 WaylandDisplay* display = WaylandDisplay::GetInstance();
111 pointer_surface_ = wl_compositor_create_surface(display->GetCompositor());
114 WaylandCursor::~WaylandCursor() {
115 DCHECK(pointer_surface_);
116 wl_surface_destroy(pointer_surface_);
119 void WaylandCursor::Clear() {
120 WaylandCursorData::DestroyCursorData();
123 void WaylandCursor::InitializeCursorData(wl_shm* shm) {
124 WaylandCursorData::InitializeCursorData(shm);
127 void WaylandCursor::Update(CursorType type, uint32_t serial) {
131 DCHECK(type != CURSOR_UNSET);
132 CursorType cursor_type = type;
133 wl_cursor_image* image = WaylandCursorData::GetInstance()->GetCursorImage(
137 LOG(INFO) << "The current cursor theme does not have a cursor for type "
138 << cursor_type << ". Falling back to the default cursor.";
139 // The cursor currently being displayed is already the default one, so we
140 // can just continue showing it.
141 if (current_cursor_ == CURSOR_LEFT_PTR)
144 cursor_type = CURSOR_LEFT_PTR;
145 image = WaylandCursorData::GetInstance()->GetCursorImage(cursor_type);
149 current_cursor_ = cursor_type;
150 struct wl_buffer* buffer = wl_cursor_image_get_buffer(image);
151 int width = image->width;
152 int height = image->height;
153 wl_pointer_set_cursor(input_pointer_,
159 struct wl_surface* surface = pointer_surface_;
160 wl_surface_attach(surface, buffer, 0, 0);
161 wl_surface_damage(surface, 0, 0, width, height);
162 wl_surface_commit(surface);
165 void WaylandCursor::SetInputPointer(wl_pointer* pointer) {
166 if (input_pointer_ == pointer)
170 wl_pointer_destroy(input_pointer_);
172 input_pointer_ = pointer;
175 } // namespace ozonewayland