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