Merge "Remove Profile Build Dependency" into tizen
[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 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
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     wind->indicator_type = 0;
195     ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
196
197 #if SDL_VIDEO_OPENGL_EGL
198     if (window->flags & SDL_WINDOW_OPENGL) {
199         wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
200
201         /* Create the GLES window surface */
202         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
203         if (wind->egl_surface == EGL_NO_SURFACE) {
204             SDL_SetError("failed to create a window surface");
205             return -1;
206         }
207     }
208 #endif
209
210     wind->id = ecore_wl_window_id_get(wind->window);
211     eina_hash_add(data->windows, &wind->id, window);
212
213     Tizen_InitKeyboard(_this);
214
215     SDL_SetMouseFocus(window);
216
217     if (window->flags & 0x00008000) {
218         SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "---------------------------------------");
219         SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[SDL] touch bypass setting is done!\n");
220         SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "---------------------------------------");
221         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
222         ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
223     }
224
225     EINA_INLIST_FOREACH(globals, global) {
226          if (!strcmp(global->interface, "tizen_policy_ext")) {
227               wind->rotation_supported = 1;
228               SDL_Log("SDL can support rotation in this device!!!!!!!!!!!");
229               break;
230            }
231       }
232     // Add orientaiton hint cb
233     _tizen_window_orientation_add_hint((void*)wind);
234     return 0;
235 }
236
237 void
238 _tizen_setwindowsize(SDL_Window *window, int update_egl)
239 {
240     SDL_WindowData *wind = window->driverdata;
241     if (!wind->window)
242     {
243         return;
244     }
245
246     // TODO : consider to rotation status.
247 #if SDL_VIDEO_OPENGL_EGL
248     if ((window->flags & SDL_WINDOW_OPENGL) && (update_egl == 1)) {
249         int aw, ah, dx = 0, dy = 0;
250
251         if ((wind->rotation == 90) || (wind->rotation == 270))
252             wl_egl_window_get_attached_size(wind->egl_window, &ah, &aw);
253         else
254             wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
255
256         SDL_Log("SDL %s:wl_egl_window_get_attached_size:rot(%i)%ix%i",__FUNCTION__,wind->rotation,aw,ah);
257
258         // TODO : if window size is not FULL, we need the code about Non FullSize Window.
259         wl_egl_window_resize(wind->egl_window, window->w, window->h, dx, dy);
260     }
261 #endif
262     ecore_wl_window_update_size(wind->window, window->w, window->h);
263 }
264
265 void
266 Tizen_SetWindowSize(_THIS, SDL_Window *window)
267 {
268     _tizen_setwindowsize(window, 1);
269 }
270
271 void
272 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
273 {
274     SDL_WindowData *wind = window->driverdata;
275     int tmp_w, tmp_h;
276     if (!wind->window) {
277         return;
278     }
279
280     tmp_w = window->w;
281     tmp_h = window->h;
282     if (wind->rotation == 90 || wind->rotation == 270) {
283         tmp_w = window->h;
284         tmp_h = window->w;
285     }
286
287     if (w) {
288         *w = tmp_w;
289     }
290     if (h) {
291         *h = tmp_h;
292     }
293 }
294
295
296 void
297 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
298 {
299     SDL_WindowData *wind = window->driverdata;
300     if (!wind->window) {
301         return;
302     }
303
304     // TODO : consider to rotation status.
305    ecore_wl_window_position_set(wind->window, window->x, window->y);
306 }
307
308 void
309 Tizen_DestroyWindow(_THIS, SDL_Window *window)
310 {
311     SDL_VideoData *data = _this->driverdata;
312     SDL_WindowData *wind = window->driverdata;
313
314     if (data) {
315         eina_hash_del(data->windows, &wind->id, window);
316 #if SDL_VIDEO_OPENGL_EGL
317     if (window->flags & SDL_WINDOW_OPENGL) {
318         SDL_EGL_DestroySurface(_this, wind->egl_surface);
319         wl_egl_window_destroy(wind->egl_window);
320     }
321 #endif
322         ecore_wl_window_free(wind->window);
323         SDL_free(wind);
324     }
325
326     window->driverdata = NULL;
327 }
328
329 SDL_Window*
330 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
331 {
332     SDL_VideoData *data = _this->driverdata;
333     int id;
334
335     id = ecore_wl_window_id_get(ewin);
336     return (SDL_Window*)eina_hash_find(data->windows, &id);
337 }
338
339 static Eina_Bool
340 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
341 {
342     _THIS = data;
343     Ecore_Wl_Event_Window_Visibility_Change *ev;
344     Ecore_Wl_Window *ew;
345     SDL_Window *window;
346
347     ev = event;
348     ew = ecore_wl_window_find(ev->win);
349     window = Tizen_FindWindow(_this, ew);
350
351     SDL_Log( "visibility window: %p, ecore_wl_window: %p\n", window, ew);
352
353     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
354     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
355     return ECORE_CALLBACK_PASS_ON;
356 }
357
358 static Eina_Bool
359 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
360 {
361    _THIS = data;
362    Ecore_Wl_Window *ew;
363    SDL_Window *window;
364    SDL_WindowData *wind;
365    Ecore_Wl_Event_Window_Configure *ev;
366    int nx = 0, ny = 0, nw = 0, nh = 0;
367    ev = event;
368    ew = ecore_wl_window_find(ev->win);
369    window = Tizen_FindWindow(_this, ew);
370    wind = window->driverdata;
371
372    if (wind->rotation_supported == 0){
373       return ECORE_CALLBACK_PASS_ON;
374    }
375
376   SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
377
378    ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
379    if (nw < 1) nw = 1;
380    if (nh < 1) nh = 1;
381
382    if ((window->x != nx) || (window->y != ny))
383      ecore_wl_window_position_set(ew, nx, ny);
384
385    if ((window->w != nw) || (window->h != nh)) {
386      window->w = nw;
387      window->h = nh;
388
389      _tizen_setwindowsize(window, 0);
390    }
391    return ECORE_CALLBACK_PASS_ON;
392 }
393
394 static Eina_Bool
395 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
396 {
397     _THIS = data;
398     Ecore_Wl_Event_Window_Rotate *ev;
399     Ecore_Wl_Window *ew;
400     SDL_Window *window;
401     SDL_WindowData *wind;
402
403     ev = event;
404     if (!ev) {
405         return ECORE_CALLBACK_PASS_ON;
406     }
407
408     ew = ecore_wl_window_find(ev->win);
409     window = Tizen_FindWindow(_this, ew);
410     wind = window->driverdata;
411
412     if (wind->rotation != ev->angle) {
413         /* set ecore_wayland window rotation */
414         wind->rotation = ev->angle;
415         ecore_wl_window_rotation_set(ew, ev->angle);
416        _tizen_setwindowsize(window, 1);
417        if (wind->rotation == 0 || wind->rotation == 180)
418           SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
419        else if (wind->rotation == 90 || wind->rotation == 270)
420           SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->h, window->w);
421     }
422     wind->received_rotation = 1;
423     return ECORE_CALLBACK_PASS_ON;
424 }
425
426 int
427 Tizen_InitWindow(_THIS)
428 {
429     SDL_VideoData *data = _this->driverdata;
430
431     data->windows = eina_hash_int32_new(NULL);
432
433     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
434                         _tizen_cb_event_window_visibility_change,_this);
435     ecore_event_handler_add(ECORE_EVENT_KEY_UP,
436                         _tizen_cb_event_keyup_change,_this);
437     ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
438                         _tizen_cb_event_keydown_change,_this);
439     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
440                         _tizen_cb_event_mousedown_change,_this);
441     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
442                         _tizen_cb_event_mouseup_change,_this);
443     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
444                         _tizen_cb_event_mousemove_change,_this);
445     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
446                         _tizen_cb_event_window_rotate,_this);
447     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
448                         _tizen_cb_window_configure,_this);
449     ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
450                         _tizen_cb_event_joystick_change,_this);
451     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
452                         _tizen_cb_event_focus_in,_this);
453     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
454                         _tizen_cb_event_focus_out,_this);
455     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
456                         _tizen_cb_event_mouse_in,_this);
457     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
458                         _tizen_cb_event_mouse_out,_this);
459
460     return 0;
461 }
462
463 void
464 Tizen_DeinitWindow(_THIS)
465 {
466     SDL_VideoData *data = _this->driverdata;
467
468     eina_hash_free(data->windows);
469 }
470 #endif /* SDL_VIDEO_DRIVER_TIZEN */
471
472 /* vi: set ts=4 sw=4 expandtab: */