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