Add indicator
[platform/upstream/SDL.git] / src / video / tizen / SDL_tizenmouse.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4   Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
5
6   This software is provided 'as-is', without any express or implied
7   warranty.  In no event will the authors be held liable for any damages
8   arising from the use of this software.
9
10   Permission is granted to anyone to use this software for any purpose,
11   including commercial applications, and to alter it and redistribute it
12   freely, subject to the following restrictions:
13
14   1. The origin of this software must not be misrepresented; you must not
15      claim that you wrote the original software. If you use this software
16      in a product, an acknowledgment in the product documentation would be
17      appreciated but is not required.
18   2. Altered source versions must be plainly marked as such, and must not be
19      misrepresented as being the original software.
20   3. This notice may not be removed or altered from any source distribution.
21 */
22
23 #include "../../SDL_internal.h"
24
25 #ifndef _GNU_SOURCE
26 #define _GNU_SOURCE
27 #endif
28
29 #include "../../events/SDL_mouse_c.h"
30
31 #include "SDL_tizenmouse.h"
32 #include "SDL_log.h"
33 #include "SDL_tizentouch.h"
34
35 #include <sys/mman.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39
40
41 typedef struct {
42     struct wl_buffer   *buffer;
43     struct wl_surface  *surface;
44     SDL_WindowData     *win_data;
45
46     int                hot_x, hot_y;
47     int                w, h;
48
49     /* Either a preloaded cursor, or one we created ourselves */
50     struct wl_cursor   *cursor;
51     void               *shm_data;
52 } Tizen_CursorData;
53
54 static int
55 wayland_create_tmp_file(off_t size)
56 {
57     static const char template[] = "/sdl-shared-XXXXXX";
58     char *xdg_path;
59     char tmp_path[PATH_MAX];
60     int fd;
61
62     xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
63     if (!xdg_path) {
64         errno = ENOENT;
65         return -1;
66     }
67
68     SDL_strlcpy(tmp_path, xdg_path, PATH_MAX);
69     SDL_strlcat(tmp_path, template, PATH_MAX);
70
71     fd = mkostemp(tmp_path, O_CLOEXEC);
72     if (fd < 0)
73         return -1;
74
75     if (ftruncate(fd, size) < 0) {
76         close(fd);
77         return -1;
78     }
79
80     return fd;
81 }
82
83 static void
84 mouse_buffer_release(void *data, struct wl_buffer *buffer)
85 {
86 }
87
88 static const struct wl_buffer_listener mouse_buffer_listener = {
89     mouse_buffer_release
90 };
91
92 static int
93 create_buffer_from_shm(Tizen_CursorData *d, int width, int height, uint32_t format)
94 {
95     //SDL_VideoDevice *vd = SDL_GetVideoDevice();
96     //SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
97     struct wl_shm_pool *shm_pool;
98
99     int stride = width * 4;
100     int size = stride * height;
101
102     int shm_fd;
103
104     shm_fd = wayland_create_tmp_file(size);
105     if (shm_fd < 0)
106     {
107         fprintf(stderr, "creating mouse cursor buffer failed!\n");
108         return -1;
109     }
110
111     d->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
112     if (d->shm_data == MAP_FAILED) {
113         d->shm_data = NULL;
114         fprintf (stderr, "mmap () failed\n");
115         close (shm_fd);
116         return -1;
117     }
118
119     shm_pool = wl_shm_create_pool(ecore_wl_shm_get(), shm_fd, size);
120     d->buffer = wl_shm_pool_create_buffer(shm_pool, 0, width, height, stride, format);
121     wl_buffer_add_listener(d->buffer, &mouse_buffer_listener, d);
122
123     wl_shm_pool_destroy (shm_pool);
124     close (shm_fd);
125
126     return 0;
127 }
128
129 static SDL_Cursor *
130 Tizen_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
131 {
132     SDL_Cursor *cursor;
133
134     cursor = calloc(1, sizeof (*cursor));
135     if (cursor) {
136         SDL_VideoDevice *vd = SDL_GetVideoDevice ();
137         SDL_Window* window = vd->windows;
138
139         Tizen_CursorData *data = calloc (1, sizeof (Tizen_CursorData));
140         data->win_data = window->driverdata;
141         cursor->driverdata = (void *) data;
142
143         /* Assume ARGB8888 */
144         SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
145         SDL_assert(surface->pitch == surface->w * 4);
146
147         /* Allocate shared memory buffer for this cursor */
148         if (create_buffer_from_shm (data,
149                                     surface->w,
150                                     surface->h,
151                                     WL_SHM_FORMAT_XRGB8888) < 0)
152         {
153             free (cursor->driverdata);
154             free (cursor);
155             return NULL;
156         }
157
158         SDL_memcpy(data->shm_data,
159                    surface->pixels,
160                    surface->h * surface->pitch);
161
162         data->surface = wl_compositor_create_surface(ecore_wl_compositor_get());
163
164         data->hot_x = hot_x;
165         data->hot_y = hot_y;
166         data->w = surface->w;
167         data->h = surface->h;
168     }
169
170     return cursor;
171 }
172
173
174 static void
175 Tizen_FreeCursor(SDL_Cursor *cursor)
176 {
177     Tizen_CursorData *d;
178
179     if (!cursor)
180         return;
181
182     d = cursor->driverdata;
183
184     /* Probably not a cursor we own */
185     if (!d)
186         return;
187
188     if (d->buffer && !d->cursor)
189         wl_buffer_destroy(d->buffer);
190
191     if (d->surface)
192         wl_surface_destroy(d->surface);
193
194     /* Not sure what's meant to happen to shm_data */
195     free (cursor->driverdata);
196     SDL_free(cursor);
197 }
198 /*
199 static int
200 Tizen_ShowCursor(SDL_Cursor *cursor)
201 {
202     if (cursor)
203     {
204         Tizen_CursorData *data = cursor->driverdata;
205         SDL_WindowData *win_data = data->win_data;
206         ecore_wl_window_buffer_attach(win_data->window, data->buffer, 0,0);
207         ecore_wl_input_pointer_set(ecore_wl_input_get(), data->surface, data->hot_x, data->hot_y);
208     }
209     else
210     {
211         ecore_wl_input_pointer_set(ecore_wl_input_get(), NULL, 0, 0);
212     }
213
214     return 0;
215 }
216 */
217 void
218 Tizen_InitMouse(void)
219 {
220     SDL_Mouse *mouse = SDL_GetMouse();
221
222     mouse->CreateCursor = Tizen_CreateCursor;
223     mouse->FreeCursor = Tizen_FreeCursor;
224 }
225
226 void
227 Tizen_FiniMouse(void)
228 {
229     /* This effectively assumes that nobody else touches SDL_Mouse which is effectively a singleton */
230     SDL_Mouse *mouse = SDL_GetMouse();
231
232     /* Free the current cursor if not the same pointer as
233      * the default cursor */
234     if (mouse->def_cursor != mouse->cur_cursor)
235         Tizen_FreeCursor (mouse->cur_cursor);
236
237     Tizen_FreeCursor (mouse->def_cursor);
238     mouse->def_cursor = NULL;
239     mouse->cur_cursor = NULL;
240
241     mouse->CreateCursor =  NULL;
242     mouse->CreateSystemCursor = NULL;
243     mouse->ShowCursor = NULL;
244     mouse->FreeCursor = NULL;
245     mouse->WarpMouse = NULL;
246     mouse->SetRelativeMouseMode = NULL;
247 }
248
249 Eina_Bool
250 _tizen_cb_event_mousedown_change(void *data, int type, void *event)
251 {
252     SDL_VideoDevice *_this = SDL_GetVideoDevice();
253
254     if (!event) return ECORE_CALLBACK_PASS_ON;
255
256     Ecore_Event_Mouse_Button *e = event;
257     SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "mouse down (%d x %d)",e->x,e->y);
258     if(_this->current_glwin->indicator_type == 0)
259     {
260         if(e->x > _this->current_glwin->x && e->x <  _this->current_glwin->x + _this->current_glwin->w &&
261             e->y > _this->current_glwin->y && e->y < _this->current_glwin->y + 52)
262         {
263             _this->current_glwin->indicator_show = SDL_TRUE;
264             _this->current_glwin->last_indicator_showtime = SDL_GetTicks();
265         }
266     }
267     else if(_this->current_glwin->indicator_type == 1)
268     {
269         if(e->x > _this->current_glwin->x && e->x <  _this->current_glwin->x + 52 &&
270             e->y > _this->current_glwin->y && e->y < _this->current_glwin->y + _this->current_glwin->h)
271         {
272             _this->current_glwin->indicator_show = SDL_TRUE;
273             _this->current_glwin->last_indicator_showtime = SDL_GetTicks();
274         }
275     }
276     else if(_this->current_glwin->indicator_type == 2)
277     {
278         if(e->x > _this->current_glwin->x && e->x <  _this->current_glwin->x + _this->current_glwin->w  &&
279             e->y > _this->current_glwin->y + _this->current_glwin->h -52 && e->y < _this->current_glwin->y + _this->current_glwin->h)
280         {
281             _this->current_glwin->indicator_show = SDL_TRUE;
282             _this->current_glwin->last_indicator_showtime = SDL_GetTicks();
283         }
284     }
285     else if(_this->current_glwin->indicator_type == 3)
286     {
287         if(e->x > _this->current_glwin->x + _this->current_glwin->w -52 && e->x <  _this->current_glwin->x + _this->current_glwin->w  &&
288             e->y > _this->current_glwin->y && e->y < _this->current_glwin->y + _this->current_glwin->h)
289         {
290             _this->current_glwin->indicator_show = SDL_TRUE;
291             _this->current_glwin->last_indicator_showtime = SDL_GetTicks();
292         }
293     }
294
295     SDL_SendMouseMotion(_this->current_glwin, 0, 0,  e->x, e->y);
296     SDL_SendMouseButton(_this->current_glwin, 0, SDL_PRESSED, SDL_BUTTON_LEFT);
297
298     Tizen_OnTouch(_this,1,e->multi.device,ACTION_POINTER_DOWN,e->x,e->y,1.0f);
299
300     return ECORE_CALLBACK_PASS_ON;
301 }
302
303 Eina_Bool
304 _tizen_cb_event_mouseup_change(void *data, int type, void *event)
305 {
306     SDL_VideoDevice *_this = SDL_GetVideoDevice();
307     if (!event) return ECORE_CALLBACK_PASS_ON;
308
309     Ecore_Event_Mouse_Button *e = event;
310     SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "mouse up (%d x %d)",e->x,e->y);
311     SDL_SendMouseMotion(_this->current_glwin, 0, 0,  e->x, e->y);
312     SDL_SendMouseButton(_this->current_glwin, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
313
314     Tizen_OnTouch(_this,1,e->multi.device,ACTION_POINTER_UP,e->x,e->y,1.0f);
315
316     return ECORE_CALLBACK_PASS_ON;
317 }
318
319 Eina_Bool
320 _tizen_cb_event_mousemove_change(void *data, int type, void *event)
321 {
322     SDL_VideoDevice *_this = SDL_GetVideoDevice();
323
324     if (!event) return ECORE_CALLBACK_PASS_ON;
325
326     Ecore_Event_Mouse_Move *e = event;
327     //SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "mouse move (%d x %d)",e->x,e->y);
328     SDL_SendMouseMotion(_this->current_glwin, 0, 0,  e->x, e->y);
329
330     Tizen_OnTouch(_this,1,e->multi.device,ACTION_POINTER_MOVE,e->x,e->y,1.0f);
331
332     return ECORE_CALLBACK_PASS_ON;
333 }
334
335
336
337