[SDL_Tizen] Delete using ecore_timer
[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 <sys/mman.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33
34 #include "../../events/SDL_mouse_c.h"
35
36 #include "SDL_log.h"
37 #include "SDL_timer.h"
38 #include "SDL_tizenindicator.h"
39 #include "SDL_tizenmouse.h"
40 #include "SDL_tizentouch.h"
41
42 #include "SDL_tizenvideo.h"
43
44 typedef struct {
45     struct wl_buffer   *buffer;
46     struct wl_surface  *surface;
47     SDL_WindowData     *win_data;
48
49     int                hot_x, hot_y;
50     int                w, h;
51
52     /* Either a preloaded cursor, or one we created ourselves */
53     struct wl_cursor   *cursor;
54     void               *shm_data;
55 } Tizen_CursorData;
56
57 static int
58 wayland_create_tmp_file(off_t size)
59 {
60     static const char template[] = "/sdl-shared-XXXXXX";
61     char *xdg_path;
62     char tmp_path[PATH_MAX];
63     int fd;
64
65     xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
66     if (!xdg_path) {
67         errno = ENOENT;
68         return -1;
69     }
70
71     SDL_strlcpy(tmp_path, xdg_path, PATH_MAX);
72     SDL_strlcat(tmp_path, template, PATH_MAX);
73
74     fd = mkostemp(tmp_path, O_CLOEXEC);
75     if (fd < 0)
76         return -1;
77
78     if (ftruncate(fd, size) < 0) {
79         close(fd);
80         return -1;
81     }
82
83     return fd;
84 }
85
86 static void
87 mouse_buffer_release(void *data, struct wl_buffer *buffer)
88 {
89 }
90
91 static const struct wl_buffer_listener mouse_buffer_listener = {
92     mouse_buffer_release
93 };
94
95 static int
96 create_buffer_from_shm(Tizen_CursorData *d, int width, int height, uint32_t format)
97 {
98     struct wl_shm_pool *shm_pool;
99
100     int stride = width * 4;
101     int size = stride * height;
102
103     int shm_fd;
104
105     shm_fd = wayland_create_tmp_file(size);
106     if (shm_fd < 0)
107     {
108         fprintf(stderr, "creating mouse cursor buffer failed!\n");
109         return -1;
110     }
111
112     d->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
113     if (d->shm_data == MAP_FAILED) {
114         d->shm_data = NULL;
115         fprintf (stderr, "mmap () failed\n");
116         close (shm_fd);
117         return -1;
118     }
119
120     shm_pool = wl_shm_create_pool(ecore_wl_shm_get(), shm_fd, size);
121     d->buffer = wl_shm_pool_create_buffer(shm_pool, 0, width, height, stride, format);
122     wl_buffer_add_listener(d->buffer, &mouse_buffer_listener, d);
123
124     wl_shm_pool_destroy (shm_pool);
125     close (shm_fd);
126
127     return 0;
128 }
129
130 static SDL_Cursor *
131 Tizen_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
132 {
133     SDL_Cursor *cursor;
134
135     cursor = calloc(1, sizeof (*cursor));
136     if (cursor) {
137         SDL_VideoDevice *vd = SDL_GetVideoDevice ();
138         SDL_Window* window = vd->windows;
139
140         Tizen_CursorData *data = calloc (1, sizeof (Tizen_CursorData));
141         data->win_data = window->driverdata;
142         cursor->driverdata = (void *) data;
143
144         /* Assume ARGB8888 */
145         SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
146         SDL_assert(surface->pitch == surface->w * 4);
147
148         /* Allocate shared memory buffer for this cursor */
149         if (create_buffer_from_shm (data,
150                                     surface->w,
151                                     surface->h,
152                                     WL_SHM_FORMAT_XRGB8888) < 0)
153         {
154             free (cursor->driverdata);
155             free (cursor);
156             return NULL;
157         }
158
159         SDL_memcpy(data->shm_data,
160                    surface->pixels,
161                    surface->h * surface->pitch);
162
163         data->surface = wl_compositor_create_surface(ecore_wl_compositor_get());
164
165         data->hot_x = hot_x;
166         data->hot_y = hot_y;
167         data->w = surface->w;
168         data->h = surface->h;
169     }
170
171     return cursor;
172 }
173
174
175 static void
176 Tizen_FreeCursor(SDL_Cursor *cursor)
177 {
178     Tizen_CursorData *d;
179
180     if (!cursor)
181         return;
182
183     d = cursor->driverdata;
184
185     /* Probably not a cursor we own */
186     if (!d)
187         return;
188
189     if (d->buffer && !d->cursor)
190         wl_buffer_destroy(d->buffer);
191
192     if (d->surface)
193         wl_surface_destroy(d->surface);
194
195     /* Not sure what's meant to happen to shm_data */
196     free (cursor->driverdata);
197     SDL_free(cursor);
198 }
199 /*
200 static int
201 Tizen_ShowCursor(SDL_Cursor *cursor)
202 {
203     if (cursor)
204     {
205         Tizen_CursorData *data = cursor->driverdata;
206         SDL_WindowData *win_data = data->win_data;
207         ecore_wl_window_buffer_attach(win_data->window, data->buffer, 0,0);
208         ecore_wl_input_pointer_set(ecore_wl_input_get(), data->surface, data->hot_x, data->hot_y);
209     }
210     else
211     {
212         ecore_wl_input_pointer_set(ecore_wl_input_get(), NULL, 0, 0);
213     }
214
215     return 0;
216 }
217 */
218 void
219 Tizen_InitMouse(void)
220 {
221     SDL_Mouse *mouse = SDL_GetMouse();
222
223     mouse->CreateCursor = Tizen_CreateCursor;
224     mouse->FreeCursor = Tizen_FreeCursor;
225 }
226
227 void
228 Tizen_FiniMouse(void)
229 {
230     /* This effectively assumes that nobody else touches SDL_Mouse which is effectively a singleton */
231     SDL_Mouse *mouse = SDL_GetMouse();
232
233     /* Free the current cursor if not the same pointer as 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 void _tizen_get_mouseXY(SDL_Window* window, int x, int y, int* retX, int* retY)
250 {
251     SDL_WindowData *wind = window->driverdata;
252     if(!wind->support_pre_rotation || wind->rotation==0)
253     {
254         *retX = x;
255         *retY = y;
256         return;
257     };
258
259     switch (wind->rotation)
260     {
261         case 90:
262         *retX = window->w-y;
263         *retY = x;
264         break;
265         case 270:
266         *retX = y;
267         *retY = window->h-x;
268         break;
269     }
270     return;
271 }
272
273 Eina_Bool
274 _tizen_cb_event_mousedown_change(void *data, int type, void *event)
275 {
276     SDL_VideoDevice *_this = SDL_GetVideoDevice();
277
278     if (!event) return ECORE_CALLBACK_PASS_ON;
279
280     Ecore_Event_Mouse_Button *e = event;
281     Ecore_Wl_Window *ew;
282     SDL_Window *window;
283     SDL_WindowData *wind;
284
285     ew = ecore_wl_window_find(e->window);
286     window = Tizen_FindWindow(_this, ew);
287     wind = window->driverdata;
288
289     int x, y;
290     _tizen_get_mouseXY(window, (int)e->x, (int)e->y, &x, &y);
291     SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "mouse down (%d x %d)", x, y);
292     if(Tizen_isTouchIndicator(window, wind->rotation, x, y))
293     {
294         ModelMatrixTranslateInit(window, wind->rotation);
295         wind->indicator_show = SDL_TRUE;
296         wind->last_indicator_showtime = SDL_GetTicks();
297     }
298
299     SDL_SendMouseMotion(window, 0, 0, x, y);
300     SDL_SendMouseButton(window, 0, SDL_PRESSED, SDL_BUTTON_LEFT);
301
302     Tizen_OnTouch(_this, 1, e->multi.device, ACTION_POINTER_DOWN, x, y, 1.0f);
303
304     return ECORE_CALLBACK_PASS_ON;
305 }
306
307 Eina_Bool
308 _tizen_cb_event_mouseup_change(void *data, int type, void *event)
309 {
310     SDL_VideoDevice *_this = SDL_GetVideoDevice();
311     if (!event) return ECORE_CALLBACK_PASS_ON;
312
313     Ecore_Event_Mouse_Button *e = event;
314     Ecore_Wl_Window *ew;
315     SDL_Window *window;
316
317     ew = ecore_wl_window_find(e->window);
318     window = Tizen_FindWindow(_this, ew);
319
320     int x, y;
321     _tizen_get_mouseXY(window, (int)e->x, (int)e->y, &x, &y);
322     SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "mouse up (%d x %d)", x, y);
323     SDL_SendMouseMotion(window, 0, 0, x, y);
324     SDL_SendMouseButton(window, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
325
326     Tizen_OnTouch(_this,1,e->multi.device,ACTION_POINTER_UP, x, y, 1.0f);
327
328     return ECORE_CALLBACK_PASS_ON;
329 }
330
331 Eina_Bool
332 _tizen_cb_event_mousemove_change(void *data, int type, void *event)
333 {
334     SDL_VideoDevice *_this = SDL_GetVideoDevice();
335
336     if (!event) return ECORE_CALLBACK_PASS_ON;
337
338     Ecore_Event_Mouse_Move *e = event;
339     Ecore_Wl_Window *ew;
340     SDL_Window *window;
341
342     ew = ecore_wl_window_find(e->window);
343     window = Tizen_FindWindow(_this, ew);
344
345     int x, y;
346     _tizen_get_mouseXY(window, (int)e->x, (int)e->y, &x, &y);
347     //SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "mouse move (%d x %d)",e->x,e->y);
348     SDL_SendMouseMotion(window, 0, 0, x, y);
349
350     Tizen_OnTouch(_this,1,e->multi.device,ACTION_POINTER_MOVE, x, y, 1.0f);
351
352     return ECORE_CALLBACK_PASS_ON;
353 }
354
355 Eina_Bool
356 _tizen_cb_event_mouse_in(void *data, int type EINA_UNUSED, void *event)
357 {
358     SDL_VideoDevice *_this = SDL_GetVideoDevice();
359     Ecore_Wl_Event_Mouse_In *ev;
360     Ecore_Wl_Window *ew;
361     SDL_Window *window;
362
363     ev = event;
364     ew = ecore_wl_window_find(ev->window);
365     window = Tizen_FindWindow(_this, ew);
366
367     SDL_SetMouseFocus(window);
368     return ECORE_CALLBACK_PASS_ON;
369 }
370
371 Eina_Bool
372 _tizen_cb_event_mouse_out(void *data, int type EINA_UNUSED, void *event)
373 {
374     SDL_SetMouseFocus(NULL);
375     return ECORE_CALLBACK_PASS_ON;
376 }
377