Merge "[SDL_Tizen] Fix rotation issue" 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_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 #include "SDL_tizenopengles.h"
39
40 #include "../../events/SDL_mouse_c.h"
41 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
42
43 #include "../SDL_egl_c.h"
44 #include "../SDL_vulkan_c.h"
45 #include "../SDL_sysvideo.h"
46 #include "../../events/SDL_windowevents_c.h"
47
48 #include <Ecore_Ipc.h>
49 #include <unistd.h>
50 #include <errno.h>
51
52 enum {
53     ROTATION_TYPE_NORMAL_ROTATION = 0,
54     ROTATION_TYPE_PRE_ROTATION,      /* use pre-rotation */
55 };
56
57 #define LOAD_FUNC(NAME) \
58 _this->tizen_pre_rotation_data.NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data.prerotation_dll_handle, #NAME); \
59 if (!_this->tizen_pre_rotation_data.NAME) \
60 { \
61     SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
62     return SDL_FALSE; \
63 }
64
65 /*SDL indicator*/
66 Ecore_Ipc_Server *ipc = NULL;
67
68 #define IPC_HEAD(_type) \
69    Ecore_Ipc_Event_Client_##_type *e = event; \
70    if (ecore_ipc_client_server_get(e->client) != ipc) \
71      return ECORE_CALLBACK_PASS_ON
72
73 void Tizen_ExecuteIndicatorProcess()
74 {
75     _tizen_init_ecore_ipc();
76     unsigned int childPID = fork();
77     if(childPID == 0)
78     {
79         SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[SDL] child process : %d", getpid());
80         int ret = execl("/usr/apps/org.tizen.sdl_indicator/bin/sdl_indicator", "/usr/apps/org.tizen.sdl_indicator/bin/sdl_indicator", NULL);
81         if(ret == -1)
82         {
83             SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[SDL] Failed indicator process error:%s", strerror(errno));
84             kill(getpid(), SIGKILL);
85         }
86     }
87     else if(childPID == -1)
88     {
89         SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[SDL] Failed fork");
90     }
91     else
92     {
93         SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[SDL] parent process : %d", getpid());
94     }
95 }
96
97 void _tizen_ecore_ipc_client_send(int major, int minor, int ref, int ref_to)
98 {
99     Eina_List *ipc_clients = ecore_ipc_server_clients_get(ipc);
100     Eina_List *l;
101     Ecore_Ipc_Client *cl;
102     EINA_LIST_FOREACH(ipc_clients, l, cl)
103     ecore_ipc_client_send(cl, major, minor, ref, ref_to, 0, NULL, 0);
104 }
105
106 static Eina_Bool _cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
107 {
108     IPC_HEAD(Add);
109
110     SDL_Log("[SDL]_cb_client_add");
111
112     SDL_VideoData* videoData = SDL_GetVideoDevice()->driverdata;
113     videoData->indicator_on = SDL_TRUE;
114
115     SDL_Window * window = SDL_GetVideoDevice()->windows;
116     SDL_WindowData *wind = window->driverdata;
117
118     int window_w, window_h;
119     ecore_wl_screen_size_get(&window_w, &window_h);
120
121     _tizen_ecore_ipc_client_send(OP_INDICATOR_SHOW, wind->rotation, 0, videoData->indicator_mode);
122
123     return ECORE_CALLBACK_DONE;
124 }
125
126 static Eina_Bool _cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
127 {
128     IPC_HEAD(Del);
129     SDL_Log("[SDL]_cb_client_del");
130     Eina_List *ipc_clients = ecore_ipc_server_clients_get(ipc);
131     Eina_List *l;
132     Ecore_Ipc_Client *cl;
133     EINA_LIST_FOREACH(ipc_clients, l, cl)
134     {
135         ecore_ipc_client_del(cl);
136     }
137
138     SDL_VideoData* videoData = SDL_GetVideoDevice()->driverdata;
139     videoData->indicator_on = SDL_FALSE;
140
141     return ECORE_CALLBACK_DONE;
142 }
143
144 static Eina_Bool _cb_client_data(void *data, int type EINA_UNUSED, void *event)
145 {
146     IPC_HEAD(Data);
147
148     Ecore_Ipc_Event_Server_Data* epcEvent = (Ecore_Ipc_Event_Server_Data*)event;
149     SDL_Log("[SDL]_cb_client_data: %d -> %d", epcEvent->major, epcEvent->minor);
150     return ECORE_CALLBACK_DONE;
151 }
152
153 int _tizen_init_ecore_ipc()
154 {
155
156     if(!ipc)
157     {
158         if(!ecore_ipc_init())
159             SDL_Log("[SDL]Fail ecore_ipc");
160
161         ipc = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, "sdl_indicator", 0, NULL);
162
163         if(!ipc)
164             ecore_ipc_shutdown();
165
166         ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, _cb_client_add, NULL);
167         ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, _cb_client_del, NULL);
168         ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, _cb_client_data, NULL);
169     }
170     return 0;
171 }
172
173 static int
174 _tizen_rotation_type_get()
175 {
176     static int type = ROTATION_TYPE_PRE_ROTATION;
177     static int checked = 0;
178     char *engine = NULL;
179
180     if (checked) return type;
181
182     engine = getenv("SDL_ROTATION");
183
184     if (engine)
185       {
186          if ((!strcasecmp(engine, "normal")))
187             type = ROTATION_TYPE_NORMAL_ROTATION;
188          else if ((!strcasecmp(engine, "pre_rotation")))
189             type = ROTATION_TYPE_PRE_ROTATION;
190          else
191             type = ROTATION_TYPE_PRE_ROTATION;
192       }
193     checked = 1;
194     return type;
195 }
196
197 int
198 _tizen_PreRotatotion_LoadLibrary(SDL_VideoData *_this, const char *lib_path)
199 {
200     void *lib_dll_handle = NULL;
201     char *path = NULL;
202
203     if (_this->tizen_pre_rotation_data.prerotation_dll_handle
204         && _this->tizen_pre_rotation_data.wl_egl_window_set_rotation
205         && _this->tizen_pre_rotation_data.wl_egl_window_get_capabilities)
206         return SDL_TRUE;
207
208     _this->tizen_pre_rotation_data.prerotation_dll_handle = NULL;
209     _this->tizen_pre_rotation_data.wl_egl_window_set_rotation = NULL;
210     _this->tizen_pre_rotation_data.wl_egl_window_get_capabilities = NULL;
211
212     if (!lib_path)
213         lib_dll_handle = SDL_LoadObject(lib_path);
214
215     if (!lib_dll_handle) {
216         path = "libwayland-egl.so";
217         lib_dll_handle = SDL_LoadObject(path);
218     }
219
220     _this->tizen_pre_rotation_data.prerotation_dll_handle = lib_dll_handle;
221
222     if (lib_dll_handle == NULL)
223         return SDL_FALSE;
224
225     LOAD_FUNC(wl_egl_window_set_rotation);
226     LOAD_FUNC(wl_egl_window_get_capabilities);
227
228     return SDL_TRUE;
229 }
230
231 SDL_bool
232 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
233 {
234     SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
235     info->info.tizen.egl_display = NULL;
236     info->info.tizen.egl_surface = NULL;
237 #if SDL_VIDEO_OPENGL_EGL
238     if (_this->egl_data)
239     {
240        info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
241     }
242     info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
243 #endif
244     info->subsystem = SDL_SYSWM_TIZEN;
245     return SDL_TRUE;
246 }
247
248 int
249 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
250 {
251     return 0;  /* just succeed, the real work is done elsewhere. */
252 }
253
254 void
255 Tizen_SetWindowTitle(_THIS, SDL_Window * window)
256 {
257     SDL_WindowData *wind = window->driverdata;
258     ecore_wl_window_title_set(wind->window, window->title);
259 }
260
261 void
262 Tizen_ShowWindow(_THIS, SDL_Window *window)
263 {
264     SDL_VideoData* videoData = SDL_GetVideoDevice()->driverdata;
265
266     if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && !videoData->indicator_on)
267     {
268         Tizen_ExecuteIndicatorProcess();
269     }
270
271     SDL_WindowData *wind = window->driverdata;
272     ecore_wl_window_show(wind->window);
273 }
274
275 void
276 Tizen_HideWindow(_THIS, SDL_Window *window)
277 {
278     SDL_WindowData *wind = window->driverdata;
279     ecore_wl_window_hide(wind->window);
280 }
281
282 void
283 Tizen_RaiseWindow(_THIS, SDL_Window *window)
284 {
285     SDL_WindowData *wind = window->driverdata;
286     ecore_wl_window_raise(wind->window);
287 }
288
289 void
290 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
291                           SDL_VideoDisplay *_display, SDL_bool fullscreen)
292 {
293     /*DO NOTHING*/
294 }
295
296 void
297 Tizen_pre_rotation_set(SDL_WindowData *wind, int rotation)
298 {
299     tizen_wl_egl_window_rotation rot;
300     if (!wind->egl_window) return;
301
302     switch (rotation) {
303          case 90:
304             rot = TIZEN_ROTATION_270;
305             break;
306          case 180:
307             rot = TIZEN_ROTATION_180;
308             break;
309          case 270:
310             rot = TIZEN_ROTATION_90;
311             break;
312          case 0:
313             rot = TIZEN_ROTATION_0;
314             break;
315          default:
316             rot = TIZEN_ROTATION_0;
317             break;
318       }
319
320     SDL_VideoData* _this = SDL_GetVideoDevice()->driverdata;
321     _this->tizen_pre_rotation_data.wl_egl_window_set_rotation(wind->egl_window, rot);
322 }
323
324 void
325 _tizen_set_window_size(SDL_Window * window, int w, int h)
326 {
327     if(!window)
328     {
329         SDL_SetError("Invalid window");
330         return;
331     }
332
333     SDL_VideoDevice *_this = SDL_GetVideoDevice();
334     if (!_this) {
335         SDL_SetError("Video subsystem has not been initialized");
336         return;
337     }
338
339     if (window->magic != &_this->window_magic) {
340         return;
341     }
342
343     if (w <= 0) {
344         SDL_InvalidParamError("w");
345         return;
346     }
347     if (h <= 0) {
348         SDL_InvalidParamError("h");
349         return;
350     }
351
352     /* Make sure we don't exceed any window size limits */
353     if (window->min_w && w < window->min_w)
354     {
355         w = window->min_w;
356     }
357     if (window->max_w && w > window->max_w)
358     {
359         w = window->max_w;
360     }
361     if (window->min_h && h < window->min_h)
362     {
363         h = window->min_h;
364     }
365     if (window->max_h && h > window->max_h)
366     {
367         h = window->max_h;
368     }
369
370     window->windowed.w = w;
371     window->windowed.h = h;
372
373     window->w = w;
374     window->h = h;
375 }
376
377 void
378 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
379 {
380     SDL_Event event;
381     SDL_WindowData *wind;
382     wind = window->driverdata;
383
384     SDL_memset(&event, 0, sizeof(event));
385     event.type = SDL_ROTATEEVENT;
386     event.user.code = 0;
387     if (wind->support_pre_rotation)
388         event.user.data1 = (void*)0;
389     else
390         event.user.data1 = (void*)angle;
391     event.user.data2 = (void*)-1;
392
393     SDL_PushEvent(&event);
394     return;
395 }
396
397 void
398 _tizen_rotation_do(SDL_Window *window, SDL_WindowData* wind, int rotation)
399 {
400     int window_w, window_h;
401     if(wind->rotation == 0 || wind->rotation == 180)
402         ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
403     else
404         ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
405
406     _tizen_set_window_size(window, window_w, window_h);
407
408     if(wind->support_pre_rotation)
409         Tizen_pre_rotation_set(wind, rotation);
410
411     _tizen_send_rotation_event(window, wind->rotation);
412     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
413
414 }
415
416 void
417 Tizen_rotate_update(SDL_Window *window)
418 {
419     SDL_WindowData *wind = window->driverdata;
420     if(!wind) return;
421
422     int screen_rotation;
423     if (ecore_wl_window_ignore_output_transform_get(wind->window))
424     {
425         screen_rotation = 0;
426     }
427     else
428     {
429         Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
430         screen_rotation = ecore_wl_output_transform_get(output) * 90;
431     }
432
433     //Set Screen Rotation
434     wind->output_rotation = screen_rotation;
435     if(wind->support_pre_rotation)
436         ecore_wl_window_buffer_transform_set(wind->window, wind->output_rotation / 90);
437
438     ecore_wl_window_rotation_set(wind->window, wind->rotation);
439
440     int rotation = (wind->output_rotation + wind->rotation) % 360;
441     _tizen_rotation_do(window, wind, rotation);
442 }
443
444 void
445 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
446 {
447     char *p_str = NULL;
448     char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
449     int checked[4] = {0,};
450     int i;
451     unsigned int j = 0;
452     SDL_WindowData *wind = (SDL_WindowData*)userdata;
453     Ecore_Wl_Window *window = wind->window;
454
455     if (wind->rotation_supported == 0)
456         return;
457
458     SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
459
460     if ((oldValue == NULL) && (newValue == NULL))
461         return;
462
463     for (i=0;i<4;i++) {
464         p_str = SDL_strstr(newValue, orientation_type[i]);
465         if (p_str) {
466             if (p_str == newValue) {
467                 int rot = 0;
468                 if (i == 0) rot = 0;
469                 else if (i == 1) rot = 90;
470                 else if (i == 2) rot = 180;
471                 else if (i == 3) rot = 270;
472                 wind->rotation = rot;
473             }
474
475             if (i == 0) {
476                 checked[j] = 0;
477             }
478             else if (i == 1) {
479                 checked[j] = 90;
480             }
481             else if (i == 2) {
482                 checked[j] = 180;
483             }
484             else if (i == 3) {
485                 checked[j] = 270;
486             }
487             j++;
488         }
489     }
490
491     if (j > 0) {
492         if (j == 1) {
493             ecore_wl_window_rotation_preferred_rotation_set(window, wind->rotation);
494         }else {
495             ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
496         }
497     }
498
499     Tizen_rotate_update(Tizen_FindWindow(SDL_GetVideoDevice(), window));
500 }
501
502 void
503 _tizen_window_orientation_add_hint(void *data)
504 {
505     SDL_WindowData *wind = (SDL_WindowData*)data;
506     if (wind->rotation_supported == 0)
507         return;
508
509     SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
510 }
511
512 static Eina_Bool
513 _tizen_cb_output_transform(void *data, int type EINA_UNUSED, void *event)
514 {
515     SDL_Window * window = SDL_GetVideoDevice()->windows;
516     SDL_WindowData *wind = window->driverdata;
517
518     if(!wind) return ECORE_CALLBACK_PASS_ON;
519
520     Ecore_Wl_Event_Output_Transform *ev = event;
521     Ecore_Wl_Output *output;
522
523     output = ecore_wl_window_output_find(wind->window);
524     if (output != ev->output) return ECORE_CALLBACK_PASS_ON;
525
526     wind->received_rotation = 1;
527
528
529    return ECORE_CALLBACK_PASS_ON;
530 }
531
532 static Eina_Bool
533 _tizen_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
534 {
535     SDL_Window * window = SDL_GetVideoDevice()->windows;
536     SDL_WindowData *wind = window->driverdata;
537
538     if(!wind) return ECORE_CALLBACK_PASS_ON;
539
540     wind->received_rotation = 1;
541
542    return ECORE_CALLBACK_PASS_ON;
543 }
544
545 void
546 _tizen_output_transform_register(SDL_WindowData *wind)
547 {
548     if(!wind) return;
549
550     Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
551     wind->output_rotation = ecore_wl_output_transform_get(output) * 90;
552
553     ecore_event_handler_add(ECORE_WL_EVENT_OUTPUT_TRANSFORM,
554                              _tizen_cb_output_transform, NULL);
555     ecore_event_handler_add(ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM,
556                              _tizen_cb_ignore_output_transform, NULL);
557 }
558
559 void
560 _tizen_indicator_opacity_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
561 {
562     SDL_VideoData *data = (SDL_VideoData *)userdata;
563
564     if ((oldValue == NULL) && (newValue == NULL))
565         return;
566
567     SDL_assert(SDL_strncmp(name, SDL_HINT_TIZEN_INDICATOR_OPACITY, SDL_strlen(SDL_HINT_TIZEN_INDICATOR_OPACITY)) == 0);
568     char indicator_type[4][20] = {"opaque","translucent","transparent","bg_transparent"};
569     for (int i=0;i<4;i++) {
570         if(SDL_strncmp(newValue, indicator_type[i], SDL_strlen(indicator_type[i])) == 0)
571         {
572             data->indicator_mode = i+1;
573             break;
574         }
575     }
576 }
577
578 int
579 Tizen_CreateWindow(_THIS, SDL_Window *window)
580 {
581     SDL_VideoData *data = _this->driverdata;
582     SDL_WindowData *wind;
583     Ecore_Wl_Global *global;
584     Eina_Inlist *globals;
585
586     wind = calloc(1, sizeof * wind);
587     if (!wind) {
588         return SDL_OutOfMemory();
589     }
590
591     window->driverdata = wind;
592     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
593
594 #if SDL_VIDEO_OPENGL_EGL
595     if (window->flags & SDL_WINDOW_OPENGL) {
596         SDL_GL_LoadLibrary(NULL);
597     }
598 #endif
599
600 #if SDL_VIDEO_VULKAN
601     if (window->flags & SDL_WINDOW_VULKAN) {
602         if (!_this->vulkan_GetInstanceExtensions) {
603             SDL_SetError("No Vulkan support in video driver");
604         }
605
606         if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
607             SDL_SetError("Fail to load Vulkan Library");
608         }
609     }
610 #endif
611
612     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
613         window->x = 0;
614     }
615     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
616         window->y = 0;
617     }
618
619     if (!(globals = ecore_wl_globals_get()))
620       {
621          SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
622          return -1;
623       }
624
625     wind->window = ecore_wl_window_new(NULL,
626                                        window->x, window->y, window->w, window->h,
627                                        ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
628     if (!wind->window) {
629         SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window");
630         return -1;
631     }
632     _tizen_output_transform_register(wind);
633
634     wind->surface = ecore_wl_window_surface_create(wind->window);
635     if (!wind->surface) {
636         SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window surface");
637         return -1;
638     }
639     ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
640
641     wind->rotation = 0;
642     wind->rotation_supported = 0;
643     wind->received_rotation = 0;
644
645 #if SDL_VIDEO_OPENGL_EGL
646     if (window->flags & SDL_WINDOW_OPENGL) {
647
648         if(wind->output_rotation == 90 || wind->output_rotation == 270)
649             wind->egl_window = wl_egl_window_create(wind->surface, window->h, window->w);
650         else
651             wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h);
652
653         /* Create the GLES window surface */
654         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
655         if (wind->egl_surface == EGL_NO_SURFACE) {
656             SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
657             return -1;
658         }
659
660         if (!_this->gl_config.alpha_size) {
661             ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
662         }
663         else {
664             wl_surface_set_opaque_region(wind->surface, NULL);
665         }
666
667         //Support PreRotation
668         wind->support_pre_rotation = 0;
669         if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(data, "libwayland-egl.so")) {
670             if (data->tizen_pre_rotation_data.wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
671                 wind->support_pre_rotation = 1;
672             }
673         }
674         else
675         {
676             wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
677         }
678
679     }
680 #endif
681
682     wind->id = ecore_wl_window_id_get(wind->window);
683     eina_hash_add(data->windows, &wind->id, window);
684
685     Tizen_InitKeyboard(_this);
686     SDL_SetMouseFocus(window);
687
688     if (window->flags & 0x00008000) {
689         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
690         ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
691     }
692
693     EINA_INLIST_FOREACH(globals, global) {
694          if (!strcmp(global->interface, "tizen_policy_ext")) {
695               wind->rotation_supported = 1;
696               break;
697            }
698       }
699     // Add orientaiton hint cb
700     _tizen_window_orientation_add_hint((void*)wind);
701     SDL_AddHintCallback(SDL_HINT_TIZEN_INDICATOR_OPACITY, _tizen_indicator_opacity_hint_callback, data);
702
703     Tizen_rotate_update(window);
704
705     return 0;
706 }
707
708 void
709 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
710 {
711     SDL_VideoData* videoData = SDL_GetVideoDevice()->driverdata;
712     if(!videoData->indicator_on)
713         Tizen_ExecuteIndicatorProcess();
714 }
715
716 void
717 Tizen_SetWindowSize(_THIS, SDL_Window *window)
718 {
719     SDL_WindowData *wind = window->driverdata;
720     if (!wind->egl_window)
721         return;
722
723     if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
724         ecore_wl_window_update_size(wind->window, window->h, window->w);
725     else
726         ecore_wl_window_update_size(wind->window, window->w, window->h);
727
728     // TODO : consider to rotation status.
729     #if SDL_VIDEO_OPENGL_EGL
730     if (window->flags & SDL_WINDOW_OPENGL) {
731         if(wind->output_rotation==90 || wind->output_rotation==270)
732             wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
733         else
734             wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
735     }
736     #endif
737
738 }
739
740 void
741 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
742 {
743     SDL_WindowData *wind = window->driverdata;
744     if (!wind->window) {
745         return;
746     }
747
748     if (w) *w = window->w;
749     if (h) *h = window->h;
750 }
751
752 void
753 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
754 {
755     SDL_WindowData *wind = window->driverdata;
756     if (!wind->window) {
757         return;
758     }
759
760     // TODO : consider to rotation status.
761    ecore_wl_window_position_set(wind->window, window->x, window->y);
762 }
763
764 void
765 Tizen_DestroyWindow(_THIS, SDL_Window *window)
766 {
767     SDL_VideoData *data = _this->driverdata;
768     SDL_WindowData *wind = window->driverdata;
769
770     if (data) {
771         eina_hash_del(data->windows, &wind->id, window);
772 #if SDL_VIDEO_OPENGL_EGL
773     if (window->flags & SDL_WINDOW_OPENGL) {
774         SDL_EGL_DestroySurface(_this, wind->egl_surface);
775         wl_egl_window_destroy(wind->egl_window);
776     }
777 #endif
778         ecore_wl_window_free(wind->window);
779         SDL_free(wind);
780     }
781
782     window->driverdata = NULL;
783 }
784
785 SDL_Window*
786 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
787 {
788     SDL_VideoData *data = _this->driverdata;
789     int id;
790
791     id = ecore_wl_window_id_get(ewin);
792     return (SDL_Window*)eina_hash_find(data->windows, &id);
793 }
794
795 Eina_Bool
796 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
797 {
798     _THIS = data;
799     Ecore_Wl_Event_Window_Visibility_Change *ev;
800     Ecore_Wl_Window *ew;
801     SDL_Window *window;
802
803     ev = event;
804     ew = ecore_wl_window_find(ev->win);
805     window = Tizen_FindWindow(_this, ew);
806
807     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
808     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
809     return ECORE_CALLBACK_PASS_ON;
810 }
811
812 Eina_Bool
813 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
814 {
815    _THIS = data;
816    Ecore_Wl_Window *ew;
817    SDL_Window *window;
818    SDL_WindowData *wind;
819    Ecore_Wl_Event_Window_Configure *ev;
820    ev = event;
821    ew = ecore_wl_window_find(ev->win);
822    window = Tizen_FindWindow(_this, ew);
823    wind = window->driverdata;
824
825    if (wind->rotation_supported == 0){
826       return ECORE_CALLBACK_PASS_ON;
827    }
828
829    return ECORE_CALLBACK_PASS_ON;
830 }
831
832 Eina_Bool
833 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
834 {
835     _THIS = data;
836     Ecore_Wl_Event_Window_Rotate *ev;
837     Ecore_Wl_Window *ew;
838     SDL_Window *window;
839     SDL_WindowData *wind;
840
841     ev = event;
842     if (!ev) {
843         return ECORE_CALLBACK_PASS_ON;
844     }
845
846     ew = ecore_wl_window_find(ev->win);
847     window = Tizen_FindWindow(_this, ew);
848     wind = window->driverdata;
849
850     if (wind->rotation != ev->angle) {
851         /* set ecore_wayland window rotation */
852         wind->rotation = ev->angle;
853         wind->received_rotation = 1;
854     }
855
856     return ECORE_CALLBACK_PASS_ON;
857 }
858
859 int
860 Tizen_InitWindow(_THIS)
861 {
862     SDL_VideoData *data = _this->driverdata;
863
864     data->windows = eina_hash_int32_new(NULL);
865
866     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
867                         _tizen_cb_event_window_visibility_change,_this);
868     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
869                         _tizen_cb_event_window_rotate,_this);
870     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
871                         _tizen_cb_window_configure,_this);
872
873     ecore_event_handler_add(ECORE_EVENT_KEY_UP,
874                         _tizen_cb_event_keyup_change,_this);
875     ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
876                         _tizen_cb_event_keydown_change,_this);
877
878     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
879                         _tizen_cb_event_mousedown_change,_this);
880     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
881                         _tizen_cb_event_mouseup_change,_this);
882     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
883                         _tizen_cb_event_mousemove_change,_this);
884     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
885                         _tizen_cb_event_mouse_in,_this);
886     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
887                         _tizen_cb_event_mouse_out,_this);
888
889     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
890                         _tizen_cb_event_focus_in,_this);
891     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
892                         _tizen_cb_event_focus_out,_this);
893
894     ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
895                         _tizen_cb_event_joystick_change,_this);
896
897     return 0;
898 }
899
900 void
901 Tizen_DeinitWindow(_THIS)
902 {
903     SDL_VideoData *data = _this->driverdata;
904
905     eina_hash_free(data->windows);
906 }
907 #endif /* SDL_VIDEO_DRIVER_TIZEN */
908
909 /* vi: set ts=4 sw=4 expandtab: */