66180763990b7c5670468b48c0dac28b96eb4872
[platform/upstream/SDL.git] / src / video / tizen / SDL_tizenwindow.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 #if SDL_VIDEO_DRIVER_TIZEN
26
27 #include "../SDL_sysvideo.h"
28 #include "../../events/SDL_windowevents_c.h"
29 #include "../SDL_egl_c.h"
30 #include "SDL_tizenwindow.h"
31 #include "SDL_tizenvideo.h"
32 #include "SDL_tizentouch.h"
33 #include "SDL_tizenkeyboard.h"
34
35 #include "SDL_tizenmouse.h"
36 #include "SDL_tizenevents_c.h"
37 #include "SDL_log.h"
38 #include "SDL_hints.h"
39 #include "../../events/SDL_mouse_c.h"
40
41 #include <wayland-egl.h>
42
43 SDL_bool
44 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
45 {
46     SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
47     info->info.tizen.egl_display = NULL;
48     info->info.tizen.egl_surface = NULL;
49 #if SDL_VIDEO_OPENGL_EGL
50     if (_this->egl_data)
51     {
52        info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
53     }
54     info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
55 #endif
56     info->subsystem = SDL_SYSWM_TIZEN;
57     return SDL_TRUE;
58 }
59
60 int
61 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
62 {
63     return 0;  /* just succeed, the real work is done elsewhere. */
64 }
65
66 void
67 Tizen_ShowWindow(_THIS, SDL_Window *window)
68 {
69     SDL_WindowData *wind = window->driverdata;
70     ecore_wl_window_show(wind->window);
71 }
72
73 void
74 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
75                           SDL_VideoDisplay *_display, SDL_bool fullscreen)
76 {
77     /*DO NOTHING*/
78 }
79
80 static void
81 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
82 {
83     char *p_str = NULL;
84     char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
85     int checked[4] = {0,};
86     int i;
87     unsigned int j = 0;
88     SDL_WindowData *wind = (SDL_WindowData*)userdata;
89     Ecore_Wl_Window *window = wind->window;
90
91     if (wind->rotation_supported == 0)
92     {
93         return;
94     }
95
96     SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
97
98     if ((oldValue == NULL) && (newValue == NULL)) {
99         return;
100     }
101
102     for (i=0;i<4;i++) {
103         p_str = SDL_strstr(newValue, orientation_type[i]);
104         if (p_str) {
105             if (p_str == newValue) {
106                 int rot = 0;
107                 if (i == 0) rot = 0;
108                 else if (i == 1) rot = 90;
109                 else if (i == 2) rot = 180;
110                 else if (i == 3) rot = 270;
111                 wind->rotation = rot;
112             }
113
114             if (i == 0) {
115                 checked[j] = 0;
116                 SDL_Log("SDL  %s: avaiable rotation: 0", __FUNCTION__);
117             }
118             else if (i == 1) {
119                 checked[j] = 90;
120                 SDL_Log("SDL %s: avaiable rotation: 90", __FUNCTION__);
121             }
122             else if (i == 2) {
123                 checked[j] = 180;
124                 SDL_Log("SDL %s: avaiable rotation: 180", __FUNCTION__);
125             }
126             else if (i == 3) {
127                 checked[j] = 270;
128                 SDL_Log("SDL %s: avaiable rotation: 270", __FUNCTION__);
129             }
130             j++;
131         }
132     }
133
134     if (j > 0) {
135         if (j == 1) {
136             ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
137         }
138         ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
139     }
140 }
141
142 static void
143 _tizen_window_orientation_add_hint(void *data)
144 {
145     SDL_WindowData *wind = (SDL_WindowData*)data;
146     if (wind->rotation_supported == 0) {
147         return;
148     }
149
150     SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
151 }
152
153 int
154 Tizen_CreateWindow(_THIS, SDL_Window *window)
155 {
156     SDL_VideoData *data = _this->driverdata;
157     SDL_WindowData *wind;
158     Ecore_Wl_Global *global;
159     Eina_Inlist *globals;
160
161     wind = calloc(1, sizeof * wind);
162     if (!wind) {
163         return SDL_OutOfMemory();
164     }
165
166     window->driverdata = wind;
167
168 #if SDL_VIDEO_OPENGL_EGL
169     if (window->flags & SDL_WINDOW_OPENGL) {
170         SDL_GL_LoadLibrary(NULL);
171     }
172 #endif
173
174     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
175         window->x = 0;
176     }
177     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
178         window->y = 0;
179     }
180
181     if (!(globals = ecore_wl_globals_get()))
182       {
183          SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get wayland globals");
184          return -1;
185       }
186
187     wind->window = ecore_wl_window_new(NULL,
188                                        window->x, window->y, window->w, window->h,
189                                        ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
190     wind->surface = ecore_wl_window_surface_create(wind->window);
191     wind->rotation = 0;
192     wind->rotation_supported = 0;
193     wind->received_rotation = 0;
194     ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
195
196     if (window->flags & 0x00008000)
197     {
198        ecore_wl_window_input_region_set(wind->window, 0, 0, 0, 0);
199        ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
200     }
201
202 #if SDL_VIDEO_OPENGL_EGL
203     if (window->flags & SDL_WINDOW_OPENGL) {
204         wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
205
206         /* Create the GLES window surface */
207         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
208         if (wind->egl_surface == EGL_NO_SURFACE) {
209             SDL_SetError("failed to create a window surface");
210             return -1;
211         }
212     }
213 #endif
214
215     wind->id = ecore_wl_window_id_get(wind->window);
216     eina_hash_add(data->windows, &wind->id, window);
217
218     Tizen_InitKeyboard(_this);
219
220     SDL_SetMouseFocus(window);
221
222     if (window->flags & 0x00008000) {
223         SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "---------------------------------------");
224         SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[SDL] touch bypass setting is done!\n");
225         SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "---------------------------------------");
226         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
227         //ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
228     }
229
230     EINA_INLIST_FOREACH(globals, global) {
231          if (!strcmp(global->interface, "tizen_policy_ext")) {
232               wind->rotation_supported = 1;
233               SDL_Log("SDL can support rotation in this device!!!!!!!!!!!");
234               break;
235            }
236       }
237     // Add orientaiton hint cb
238     _tizen_window_orientation_add_hint((void*)wind);
239     return 0;
240 }
241
242 void
243 _tizen_setwindowsize(SDL_Window *window, int update_egl)
244 {
245     SDL_WindowData *wind = window->driverdata;
246     if (!wind->window)
247     {
248         return;
249     }
250
251     // TODO : consider to rotation status.
252 #if SDL_VIDEO_OPENGL_EGL
253     if ((window->flags & SDL_WINDOW_OPENGL) && (update_egl == 1)) {
254         int aw, ah, dx = 0, dy = 0;
255
256         if ((wind->rotation == 90) || (wind->rotation == 270))
257             wl_egl_window_get_attached_size(wind->egl_window, &ah, &aw);
258         else
259             wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
260
261         SDL_Log("SDL %s:wl_egl_window_get_attached_size:rot(%i)%ix%i",__FUNCTION__,wind->rotation,aw,ah);
262
263         // TODO : if window size is not FULL, we need the code about Non FullSize Window.
264         wl_egl_window_resize(wind->egl_window, window->w, window->h, dx, dy);
265     }
266 #endif
267     ecore_wl_window_update_size(wind->window, window->w, window->h);
268 }
269
270 void
271 Tizen_SetWindowSize(_THIS, SDL_Window *window)
272 {
273     _tizen_setwindowsize(window, 1);
274 }
275
276 void
277 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
278 {
279     SDL_WindowData *wind = window->driverdata;
280     int tmp_w, tmp_h;
281     if (!wind->window) {
282         return;
283     }
284
285     tmp_w = window->w;
286     tmp_h = window->h;
287     if (wind->rotation == 90 || wind->rotation == 270) {
288         tmp_w = window->h;
289         tmp_h = window->w;
290     }
291
292     if (w) {
293         *w = tmp_w;
294     }
295     if (h) {
296         *h = tmp_h;
297     }
298 }
299
300
301 void
302 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
303 {
304     SDL_WindowData *wind = window->driverdata;
305     if (!wind->window) {
306         return;
307     }
308
309     // TODO : consider to rotation status.
310    ecore_wl_window_position_set(wind->window, window->x, window->y);
311 }
312
313 void
314 Tizen_DestroyWindow(_THIS, SDL_Window *window)
315 {
316     SDL_VideoData *data = _this->driverdata;
317     SDL_WindowData *wind = window->driverdata;
318
319     if (data) {
320         eina_hash_del(data->windows, &wind->id, window);
321 #if SDL_VIDEO_OPENGL_EGL
322     if (window->flags & SDL_WINDOW_OPENGL) {
323         SDL_EGL_DestroySurface(_this, wind->egl_surface);
324         wl_egl_window_destroy(wind->egl_window);
325     }
326 #endif
327         ecore_wl_window_free(wind->window);
328         SDL_free(wind);
329     }
330
331     window->driverdata = NULL;
332 }
333
334 static SDL_Window*
335 _tizen_find_window(_THIS, Ecore_Wl_Window *ewin)
336 {
337     SDL_VideoData *data = _this->driverdata;
338     int id;
339
340     id = ecore_wl_window_id_get(ewin);
341     return (SDL_Window*)eina_hash_find(data->windows, &id);
342 }
343
344 static Eina_Bool
345 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
346 {
347     _THIS = data;
348     Ecore_Wl_Event_Window_Visibility_Change *ev;
349     Ecore_Wl_Window *ew;
350     SDL_Window *window;
351
352     ev = event;
353     ew = ecore_wl_window_find(ev->win);
354     window = _tizen_find_window(_this, ew);
355
356     SDL_Log( "visibility window: %p, ecore_wl_window: %p\n", window, ew);
357
358     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
359     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
360     return ECORE_CALLBACK_PASS_ON;
361 }
362
363 static Eina_Bool
364 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
365 {
366    _THIS = data;
367    Ecore_Wl_Window *ew;
368    SDL_Window *window;
369    SDL_WindowData *wind;
370    Ecore_Wl_Event_Window_Configure *ev;
371    int nx = 0, ny = 0, nw = 0, nh = 0;
372    ev = event;
373    ew = ecore_wl_window_find(ev->win);
374    window = _tizen_find_window(_this, ew);
375    wind = window->driverdata;
376
377    if (wind->rotation_supported == 0){
378       return ECORE_CALLBACK_PASS_ON;
379    }
380
381   SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
382
383    ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
384    if (nw < 1) nw = 1;
385    if (nh < 1) nh = 1;
386
387    if ((window->x != nx) || (window->y != ny))
388      ecore_wl_window_position_set(ew, nx, ny);
389
390    if ((window->w != nw) || (window->h != nh)) {
391      window->w = nw;
392      window->h = nh;
393
394      _tizen_setwindowsize(window, 0);
395    }
396    return ECORE_CALLBACK_PASS_ON;
397 }
398
399 static Eina_Bool
400 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
401 {
402     _THIS = data;
403     Ecore_Wl_Event_Window_Rotate *ev;
404     Ecore_Wl_Window *ew;
405     SDL_Window *window;
406     SDL_WindowData *wind;
407
408     ev = event;
409     if (!ev) {
410         return ECORE_CALLBACK_PASS_ON;
411     }
412
413     ew = ecore_wl_window_find(ev->win);
414     window = _tizen_find_window(_this, ew);
415     wind = window->driverdata;
416
417     if (wind->rotation != ev->angle) {
418         /* set ecore_wayland window rotation */
419         wind->rotation = ev->angle;
420         ecore_wl_window_rotation_set(ew, ev->angle);
421        _tizen_setwindowsize(window, 1);
422        if (wind->rotation == 0 || wind->rotation == 180)
423           SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
424        else if (wind->rotation == 90 || wind->rotation == 270)
425           SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->h, window->w);
426     }
427     wind->received_rotation = 1;
428     return ECORE_CALLBACK_PASS_ON;
429 }
430
431 int
432 Tizen_InitWindow(_THIS)
433 {
434     SDL_VideoData *data = _this->driverdata;
435
436     data->windows = eina_hash_int32_new(NULL);
437
438     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
439                         _tizen_cb_event_window_visibility_change,_this);
440     ecore_event_handler_add(ECORE_EVENT_KEY_UP,
441                         _tizen_cb_event_keyup_change,_this);
442     ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
443                         _tizen_cb_event_keydown_change,_this);
444     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
445                         _tizen_cb_event_mousedown_change,_this);
446     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
447                         _tizen_cb_event_mouseup_change,_this);
448     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
449                         _tizen_cb_event_mousemove_change,_this);
450     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
451                         _tizen_cb_event_window_rotate,_this);
452     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
453                         _tizen_cb_window_configure,_this);
454
455     return 0;
456 }
457
458 void
459 Tizen_DeinitWindow(_THIS)
460 {
461     SDL_VideoData *data = _this->driverdata;
462
463     eina_hash_free(data->windows);
464 }
465 #endif /* SDL_VIDEO_DRIVER_TIZEN */
466
467 /* vi: set ts=4 sw=4 expandtab: */