[SDL_Tizen] Disable indicator
[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_log.h"
28 #include "SDL_hints.h"
29 #include "SDL_loadso.h"
30
31 #include "SDL_tizenvideo.h"
32 #include "SDL_tizentouch.h"
33 #include "SDL_tizenkeyboard.h"
34 #include "SDL_tizenmouse.h"
35 #include "SDL_tizenevents_c.h"
36
37 #include "SDL_tizenwindow.h"
38
39 #include "../../events/SDL_mouse_c.h"
40 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
41
42 #include "../SDL_egl_c.h"
43 #include "../SDL_vulkan_c.h"
44 #include "../SDL_sysvideo.h"
45 #include "../../events/SDL_windowevents_c.h"
46
47 enum {
48     ROTATION_TYPE_NORMAL_ROTATION = 0,
49     ROTATION_TYPE_PRE_ROTATION,      /* use pre-rotation */
50 };
51
52 #define LOAD_FUNC(NAME) \
53 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
54 if (!_this->tizen_pre_rotation_data->NAME) \
55 { \
56     SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
57     return SDL_FALSE; \
58 }
59
60 static int
61 _tizen_rotation_type_get()
62 {
63     static int type = ROTATION_TYPE_PRE_ROTATION;
64     static int checked = 0;
65     char *engine = NULL;
66
67     if (checked) return type;
68
69     engine = getenv("SDL_ROTATION");
70
71     if (engine)
72       {
73          if ((!strcasecmp(engine, "normal")))
74             type = ROTATION_TYPE_NORMAL_ROTATION;
75          else if ((!strcasecmp(engine, "pre_rotation")))
76             type = ROTATION_TYPE_PRE_ROTATION;
77          else
78             type = ROTATION_TYPE_PRE_ROTATION;
79       }
80     checked = 1;
81     return type;
82 }
83
84 int
85 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
86 {
87     void *lib_dll_handle = NULL;
88     char *path = NULL;
89
90     if (_this->isLoaded_pre_rotation)
91         return SDL_TRUE;
92
93     _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
94     if (!_this->tizen_pre_rotation_data) {
95         return SDL_OutOfMemory();
96     }
97
98     if (!lib_path)
99         lib_dll_handle = SDL_LoadObject(lib_path);
100
101     if (!lib_dll_handle) {
102         path = "libwayland-egl.so";
103         lib_dll_handle = SDL_LoadObject(path);
104     }
105
106     _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
107
108     if (lib_dll_handle == NULL)
109         return SDL_FALSE;
110
111     LOAD_FUNC(wl_egl_window_set_rotation);
112     LOAD_FUNC(wl_egl_window_get_capabilities);
113     _this->isLoaded_pre_rotation = 1;
114
115     return SDL_TRUE;
116 }
117
118 SDL_bool
119 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
120 {
121     SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
122     info->info.tizen.egl_display = NULL;
123     info->info.tizen.egl_surface = NULL;
124 #if SDL_VIDEO_OPENGL_EGL
125     if (_this->egl_data)
126     {
127        info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
128     }
129     info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
130 #endif
131     info->subsystem = SDL_SYSWM_TIZEN;
132     return SDL_TRUE;
133 }
134
135 int
136 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
137 {
138     return 0;  /* just succeed, the real work is done elsewhere. */
139 }
140
141 void
142 Tizen_ShowWindow(_THIS, SDL_Window *window)
143 {
144     SDL_WindowData *wind = window->driverdata;
145     ecore_wl_window_show(wind->window);
146 }
147
148 void
149 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
150                           SDL_VideoDisplay *_display, SDL_bool fullscreen)
151 {
152     /*DO NOTHING*/
153 }
154
155 void
156 Tizen_pre_rotation_set(SDL_WindowData *_this)
157 {
158     tizen_wl_egl_window_rotation rot;
159     if (!_this->egl_window) return;
160
161     switch (_this->rotation) {
162          case 90:
163             rot = TIZEN_ROTATION_270;
164             break;
165          case 180:
166             rot = TIZEN_ROTATION_180;
167             break;
168          case 270:
169             rot = TIZEN_ROTATION_90;
170             break;
171          case 0:
172             rot = TIZEN_ROTATION_0;
173             break;
174          default:
175             rot = TIZEN_ROTATION_0;
176             break;
177       }
178
179       _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
180 }
181
182 void
183 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
184 {
185     char *p_str = NULL;
186     char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
187     int checked[4] = {0,};
188     int i;
189     unsigned int j = 0;
190     SDL_WindowData *wind = (SDL_WindowData*)userdata;
191     Ecore_Wl_Window *window = wind->window;
192
193     if (wind->rotation_supported == 0) {
194         return;
195     }
196
197     SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
198
199     if ((oldValue == NULL) && (newValue == NULL)) {
200         return;
201     }
202
203     for (i=0;i<4;i++) {
204         p_str = SDL_strstr(newValue, orientation_type[i]);
205         if (p_str) {
206             if (p_str == newValue) {
207                 int rot = 0;
208                 if (i == 0) rot = 0;
209                 else if (i == 1) rot = 90;
210                 else if (i == 2) rot = 180;
211                 else if (i == 3) rot = 270;
212                 wind->rotation = rot;
213             }
214
215             if (i == 0) {
216                 checked[j] = 0;
217             }
218             else if (i == 1) {
219                 checked[j] = 90;
220             }
221             else if (i == 2) {
222                 checked[j] = 180;
223             }
224             else if (i == 3) {
225                 checked[j] = 270;
226             }
227             j++;
228         }
229     }
230
231     if (j > 0) {
232         if (j == 1) {
233             ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
234             if (wind->support_pre_rotation) {
235                 Tizen_pre_rotation_set(wind);
236             }
237         }
238         ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
239     }
240 }
241
242 void
243 _tizen_window_orientation_add_hint(void *data)
244 {
245     SDL_WindowData *wind = (SDL_WindowData*)data;
246     if (wind->rotation_supported == 0) {
247         return;
248     }
249
250     SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
251 }
252
253 int
254 Tizen_CreateWindow(_THIS, SDL_Window *window)
255 {
256     SDL_VideoData *data = _this->driverdata;
257     SDL_WindowData *wind;
258     Ecore_Wl_Global *global;
259     Eina_Inlist *globals;
260
261     wind = calloc(1, sizeof * wind);
262     if (!wind) {
263         return SDL_OutOfMemory();
264     }
265
266     window->driverdata = wind;
267     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
268     window->flags |= SDL_WINDOW_BORDERLESS;     /* defalut - not support indicator*/
269
270 #if SDL_VIDEO_OPENGL_EGL
271     if (window->flags & SDL_WINDOW_OPENGL) {
272         SDL_GL_LoadLibrary(NULL);
273     }
274 #endif
275
276 #if SDL_VIDEO_VULKAN
277     if (window->flags & SDL_WINDOW_VULKAN) {
278         if (!_this->vulkan_GetInstanceExtensions) {
279             SDL_SetError("No Vulkan support in video driver");
280         }
281
282         if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
283             SDL_SetError("Fail to load Vulkan Library");
284         }
285     }
286 #endif
287
288     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
289         window->x = 0;
290     }
291     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
292         window->y = 0;
293     }
294
295     if (!(globals = ecore_wl_globals_get()))
296       {
297          SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
298          return -1;
299       }
300
301     wind->window = ecore_wl_window_new(NULL,
302                                        window->x, window->y, window->w, window->h,
303                                        ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
304     wind->surface = ecore_wl_window_surface_create(wind->window);
305     wind->rotation = 0;
306     wind->rotation_supported = 0;
307     wind->received_rotation = 0;
308     ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
309
310 #if SDL_VIDEO_OPENGL_EGL
311     if (window->flags & SDL_WINDOW_OPENGL) {
312         wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
313
314         /* Create the GLES window surface */
315         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
316         if (wind->egl_surface == EGL_NO_SURFACE) {
317             SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
318             return -1;
319         }
320
321         //Support PreRotation
322         wind->support_pre_rotation = 0;
323         if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
324             if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
325                 wind->support_pre_rotation = 1;
326             }
327         }
328     }
329 #endif
330
331     wind->id = ecore_wl_window_id_get(wind->window);
332     eina_hash_add(data->windows, &wind->id, window);
333
334     Tizen_InitKeyboard(_this);
335     SDL_SetMouseFocus(window);
336
337     if (window->flags & 0x00008000) {
338         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
339         ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
340     }
341
342     EINA_INLIST_FOREACH(globals, global) {
343          if (!strcmp(global->interface, "tizen_policy_ext")) {
344               wind->rotation_supported = 1;
345               break;
346            }
347       }
348     // Add orientaiton hint cb
349     _tizen_window_orientation_add_hint((void*)wind);
350
351     return 0;
352 }
353
354 void
355 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
356 {
357 //Add setting window bordered.
358 }
359
360 void
361 _tizen_egl_window_resize(SDL_Window *window)
362 {
363     SDL_WindowData *wind = window->driverdata;
364     if (!wind->egl_window) {
365         return;
366     }
367
368     // TODO : consider to rotation status.
369 #if SDL_VIDEO_OPENGL_EGL
370     if (window->flags & SDL_WINDOW_OPENGL) {
371         // TODO : if window size is not FULL, we need the code about Non FullSize Window.
372         int aw, ah;
373         wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
374         wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
375     }
376 #endif
377
378 }
379
380 void
381 _tizen_setwindowsize(SDL_Window *window)
382 {
383     SDL_WindowData *wind = window->driverdata;
384     if (!wind->window) {
385         return;
386     }
387     ecore_wl_window_update_size(wind->window, window->w, window->h);
388 }
389
390 void
391 Tizen_SetWindowSize(_THIS, SDL_Window *window)
392 {
393 //    _tizen_setwindowsize(window);
394 //    _tizen_egl_window_resize(window);
395 }
396
397 void
398 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
399 {
400     SDL_WindowData *wind = window->driverdata;
401     if (!wind->window) {
402         return;
403     }
404
405     if (w) *w = window->w;
406     if (h) *h = window->h;
407 }
408
409 void
410 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
411 {
412     SDL_WindowData *wind = window->driverdata;
413     if (!wind->window) {
414         return;
415     }
416
417     // TODO : consider to rotation status.
418    ecore_wl_window_position_set(wind->window, window->x, window->y);
419 }
420
421 void
422 Tizen_DestroyWindow(_THIS, SDL_Window *window)
423 {
424     SDL_VideoData *data = _this->driverdata;
425     SDL_WindowData *wind = window->driverdata;
426
427     if (data) {
428         eina_hash_del(data->windows, &wind->id, window);
429 #if SDL_VIDEO_OPENGL_EGL
430     if (window->flags & SDL_WINDOW_OPENGL) {
431         SDL_EGL_DestroySurface(_this, wind->egl_surface);
432         wl_egl_window_destroy(wind->egl_window);
433     }
434 #endif
435         ecore_wl_window_free(wind->window);
436         SDL_free(wind);
437     }
438
439     window->driverdata = NULL;
440 }
441
442 SDL_Window*
443 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
444 {
445     SDL_VideoData *data = _this->driverdata;
446     int id;
447
448     id = ecore_wl_window_id_get(ewin);
449     return (SDL_Window*)eina_hash_find(data->windows, &id);
450 }
451
452 Eina_Bool
453 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
454 {
455     _THIS = data;
456     Ecore_Wl_Event_Window_Visibility_Change *ev;
457     Ecore_Wl_Window *ew;
458     SDL_Window *window;
459
460     ev = event;
461     ew = ecore_wl_window_find(ev->win);
462     window = Tizen_FindWindow(_this, ew);
463
464     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
465     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
466     return ECORE_CALLBACK_PASS_ON;
467 }
468
469 Eina_Bool
470 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
471 {
472    _THIS = data;
473    Ecore_Wl_Window *ew;
474    SDL_Window *window;
475    SDL_WindowData *wind;
476    Ecore_Wl_Event_Window_Configure *ev;
477    ev = event;
478    ew = ecore_wl_window_find(ev->win);
479    window = Tizen_FindWindow(_this, ew);
480    wind = window->driverdata;
481
482    if (wind->rotation_supported == 0){
483       return ECORE_CALLBACK_PASS_ON;
484    }
485 /*
486    int nx = 0, ny = 0, nw = 0, nh = 0;
487   SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
488
489    ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
490    if (nw < 1) nw = 1;
491    if (nh < 1) nh = 1;
492    
493    SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
494    if ((window->x != nx) || (window->y != ny))
495      ecore_wl_window_position_set(ew, nx, ny);
496
497    if ((window->w != nw) || (window->h != nh)) {
498      _tizen_setwindowsize(window);
499    }
500    */
501    return ECORE_CALLBACK_PASS_ON;
502 }
503
504
505 void
506 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
507 {
508     SDL_Event event;
509     SDL_WindowData *wind;
510     wind = window->driverdata;
511
512     SDL_memset(&event, 0, sizeof(event));
513     event.type = SDL_ROTATEEVENT;
514     event.user.code = 0;
515     if (wind->support_pre_rotation)
516         event.user.data1 = (void*)0;
517     else
518         event.user.data1 = (void*)angle;
519     event.user.data2 = (void*)-1;
520
521     SDL_PushEvent(&event);
522     return;
523 }
524
525 Eina_Bool
526 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
527 {
528     _THIS = data;
529     Ecore_Wl_Event_Window_Rotate *ev;
530     Ecore_Wl_Window *ew;
531     SDL_Window *window;
532     SDL_WindowData *wind;
533
534     ev = event;
535     if (!ev) {
536         return ECORE_CALLBACK_PASS_ON;
537     }
538
539     ew = ecore_wl_window_find(ev->win);
540     window = Tizen_FindWindow(_this, ew);
541     wind = window->driverdata;
542
543     if (wind->rotation != ev->angle) {
544         /* set ecore_wayland window rotation */
545         wind->rotation = ev->angle;
546         ecore_wl_window_rotation_set(ew, ev->angle);
547         // Send Rotation Event
548         _tizen_send_rotation_event(window, ev->angle);
549     }
550
551     wind->received_rotation = 1;
552     return ECORE_CALLBACK_PASS_ON;
553 }
554
555 int
556 Tizen_InitWindow(_THIS)
557 {
558     SDL_VideoData *data = _this->driverdata;
559
560     data->windows = eina_hash_int32_new(NULL);
561
562     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
563                         _tizen_cb_event_window_visibility_change,_this);
564     ecore_event_handler_add(ECORE_EVENT_KEY_UP,
565                         _tizen_cb_event_keyup_change,_this);
566     ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
567                         _tizen_cb_event_keydown_change,_this);
568     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
569                         _tizen_cb_event_mousedown_change,_this);
570     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
571                         _tizen_cb_event_mouseup_change,_this);
572     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
573                         _tizen_cb_event_mousemove_change,_this);
574     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
575                         _tizen_cb_event_window_rotate,_this);
576     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
577                         _tizen_cb_window_configure,_this);
578     ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
579                         _tizen_cb_event_joystick_change,_this);
580     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
581                         _tizen_cb_event_focus_in,_this);
582     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
583                         _tizen_cb_event_focus_out,_this);
584     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
585                         _tizen_cb_event_mouse_in,_this);
586     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
587                         _tizen_cb_event_mouse_out,_this);
588
589     data->current_thread = SDL_GetThreadID(0);
590
591     return 0;
592 }
593
594 void
595 Tizen_DeinitWindow(_THIS)
596 {
597     SDL_VideoData *data = _this->driverdata;
598
599     eina_hash_free(data->windows);
600 }
601 #endif /* SDL_VIDEO_DRIVER_TIZEN */
602
603 /* vi: set ts=4 sw=4 expandtab: */