- add sources.
[platform/framework/web/crosswalk.git] / src / ozone / wayland / input / cursor.cc
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.
4
5 #include "ozone/wayland/input/cursor.h"
6 #include "ozone/wayland/surface.h"
7
8 namespace ozonewayland {
9
10 class WaylandCursorData {
11  public:
12   explicit WaylandCursorData(wl_shm* shm);
13   virtual ~WaylandCursorData();
14
15   static WaylandCursorData* GetInstance() {
16     return impl_;
17   }
18
19   static void InitializeCursorData(wl_shm* shm) {
20     if (!impl_)
21       impl_ = new WaylandCursorData(shm);
22   }
23
24   static void DestroyCursorData() {
25     if (impl_) {
26       delete impl_;
27       impl_ = NULL;
28     }
29   }
30
31   struct wl_cursor_image* GetCursorImage(int index);
32
33  private:
34   wl_cursor_theme *cursor_theme_;
35   wl_cursor **cursors_;
36   static WaylandCursorData* impl_;
37 };
38
39 WaylandCursorData* WaylandCursorData::impl_ = NULL;
40
41 WaylandCursorData::WaylandCursorData(wl_shm* shm) {
42   const char *cursor_names[] = {
43     "bottom_left_corner",
44     "bottom_right_corner",
45     "bottom_side",
46     "grabbing",
47     "left_ptr",
48     "left_side",
49     "right_side",
50     "top_left_corner",
51     "top_right_corner",
52     "top_side",
53     "xterm",
54     "hand1",
55   };
56
57   // (kalyan) We should be able to configure the size of cursor and theme name.
58   unsigned int i, array_size =
59       (sizeof(cursor_names) / sizeof(cursor_names[0]));
60   cursor_theme_ = wl_cursor_theme_load(NULL, 24, shm);
61   cursors_ = new wl_cursor*[array_size];
62   memset(cursors_, 0, sizeof(cursors_) * array_size);
63
64   for (i = 0; i < array_size; i++)
65     cursors_[i] = wl_cursor_theme_get_cursor(cursor_theme_, cursor_names[i]);
66 }
67
68 struct wl_cursor_image* WaylandCursorData::GetCursorImage(int index) {
69     struct wl_cursor *cursor = cursors_[index];
70     if (!cursor)
71       return 0;
72
73     return cursor->images[0];
74 }
75
76 WaylandCursorData::~WaylandCursorData() {
77   if (cursor_theme_) {
78     wl_cursor_theme_destroy(cursor_theme_);
79     cursor_theme_ = NULL;
80   }
81
82   if (cursors_) {
83     delete[] cursors_;
84     cursors_ = NULL;
85   }
86 }
87
88 WaylandCursor::WaylandCursor(wl_shm* shm) : input_pointer_(NULL),
89     buffer_(NULL),
90     width_(0),
91     height_(0),
92     type_(CURSOR_UNSET) {
93   pointer_surface_ = new WaylandSurface();
94   WaylandCursorData::InitializeCursorData(shm);
95 }
96
97 WaylandCursor::~WaylandCursor() {
98   if (pointer_surface_) {
99     delete pointer_surface_;
100     pointer_surface_ = NULL;
101   }
102 }
103
104 void WaylandCursor::Update(CursorType type, uint32_t serial) {
105   if (!input_pointer_)
106     return;
107
108   ValidateBuffer(type, serial);
109   struct wl_surface* surface = pointer_surface_->wlSurface();
110   wl_surface_attach(surface, buffer_, 0, 0);
111   wl_surface_damage(surface, 0, 0, width_, height_);
112   wl_surface_commit(surface);
113 }
114
115 void WaylandCursor::SetInputPointer(wl_pointer* pointer) {
116   input_pointer_ = pointer;
117 }
118
119 void WaylandCursor::ValidateBuffer(CursorType type, uint32_t serial) {
120   if (type_ == type)
121     return;
122
123   struct wl_cursor_image* image = WaylandCursorData::GetInstance()->
124       GetCursorImage(type - 1);
125   buffer_ = wl_cursor_image_get_buffer(image);
126   width_ = image->width;
127   height_ = image->height;
128   wl_pointer_set_cursor(input_pointer_,
129                         serial,
130                         pointer_surface_->wlSurface(),
131                         image->hotspot_x,
132                         image->hotspot_y);
133 }
134
135 void WaylandCursor::Clear() {
136   WaylandCursorData::DestroyCursorData();
137 }
138
139 }  // namespace ozonewayland