Merge "[SDL_Tizen] Change rotation function position" 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
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     wind->received_rotation = 1;
384
385
386    return ECORE_CALLBACK_PASS_ON;
387 }
388
389 static Eina_Bool
390 _tizen_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
391 {
392     SDL_Window * window = SDL_GetVideoDevice()->windows;
393     SDL_WindowData *wind = window->driverdata;
394
395     if(!wind) return ECORE_CALLBACK_PASS_ON;
396
397     wind->received_rotation = 1;
398
399    return ECORE_CALLBACK_PASS_ON;
400 }
401
402 void
403 _tizen_output_transform_register(SDL_WindowData *wind)
404 {
405     if(!wind) return;
406
407     Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
408     wind->output_rotation = ecore_wl_output_transform_get(output) * 90;
409
410     ecore_event_handler_add(ECORE_WL_EVENT_OUTPUT_TRANSFORM,
411                              _tizen_cb_output_transform, NULL);
412     ecore_event_handler_add(ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM,
413                              _tizen_cb_ignore_output_transform, NULL);
414
415 }
416
417 void
418 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
419 {
420     SDL_Event event;
421     SDL_WindowData *wind;
422     wind = window->driverdata;
423
424     SDL_memset(&event, 0, sizeof(event));
425     event.type = SDL_ROTATEEVENT;
426     event.user.code = 0;
427     if (wind->support_pre_rotation)
428         event.user.data1 = (void*)0;
429     else
430         event.user.data1 = (void*)angle;
431     event.user.data2 = (void*)-1;
432
433     SDL_PushEvent(&event);
434     return;
435 }
436
437 void
438 _tizen_set_window_size(SDL_Window * window, int w, int h)
439 {
440     if(!window)
441     {
442         SDL_SetError("Invalid window");
443         return;
444     }
445
446     SDL_VideoDevice *_this = SDL_GetVideoDevice();
447     if (!_this) {
448         SDL_SetError("Video subsystem has not been initialized");
449         return;
450     }
451
452     if (window->magic != &_this->window_magic) {
453         return;
454     }
455
456     if (w <= 0) {
457         SDL_InvalidParamError("w");
458         return;
459     }
460     if (h <= 0) {
461         SDL_InvalidParamError("h");
462         return;
463     }
464
465     /* Make sure we don't exceed any window size limits */
466     if (window->min_w && w < window->min_w)
467     {
468         w = window->min_w;
469     }
470     if (window->max_w && w > window->max_w)
471     {
472         w = window->max_w;
473     }
474     if (window->min_h && h < window->min_h)
475     {
476         h = window->min_h;
477     }
478     if (window->max_h && h > window->max_h)
479     {
480         h = window->max_h;
481     }
482
483     window->windowed.w = w;
484     window->windowed.h = h;
485
486     window->w = w;
487     window->h = h;
488 }
489
490 void
491 _tizen_rotation_do(SDL_WindowData *wind, int rotation)
492 {
493     if(!wind) return;
494
495     SDL_Window *window = SDL_GetVideoDevice()->windows;
496     if(!window) return;
497
498     int window_w, window_h;
499     if(wind->rotation == 0 || wind->rotation == 180)
500         ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
501     else
502         ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
503
504     _tizen_set_window_size(window, window_w, window_h);
505
506     if(wind->support_pre_rotation)
507         Tizen_pre_rotation_set(wind, rotation);
508
509     _tizen_send_rotation_event(window, wind->rotation);
510     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
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     if(wind->support_pre_rotation)
533         ecore_wl_window_buffer_transform_set(wind->window, wind->output_rotation / 90);
534
535     ecore_wl_window_rotation_set(wind->window, wind->rotation);
536
537     int rotation = (wind->output_rotation + wind->rotation) % 360;
538     _tizen_rotation_do(wind, rotation);
539 }
540
541 int
542 Tizen_CreateWindow(_THIS, SDL_Window *window)
543 {
544     SDL_VideoData *data = _this->driverdata;
545     SDL_WindowData *wind;
546     Ecore_Wl_Global *global;
547     Eina_Inlist *globals;
548
549     wind = calloc(1, sizeof * wind);
550     if (!wind) {
551         return SDL_OutOfMemory();
552     }
553
554     window->driverdata = wind;
555     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
556
557 #if SDL_VIDEO_OPENGL_EGL
558     if (window->flags & SDL_WINDOW_OPENGL) {
559         SDL_GL_LoadLibrary(NULL);
560     }
561 #endif
562
563 #if SDL_VIDEO_VULKAN
564     if (window->flags & SDL_WINDOW_VULKAN) {
565         if (!_this->vulkan_GetInstanceExtensions) {
566             SDL_SetError("No Vulkan support in video driver");
567         }
568
569         if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
570             SDL_SetError("Fail to load Vulkan Library");
571         }
572     }
573 #endif
574
575     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
576         window->x = 0;
577     }
578     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
579         window->y = 0;
580     }
581
582     if (!(globals = ecore_wl_globals_get()))
583       {
584          SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
585          return -1;
586       }
587
588     wind->window = ecore_wl_window_new(NULL,
589                                        window->x, window->y, window->w, window->h,
590                                        ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
591     if (!wind->window) {
592         SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window");
593         return -1;
594     }
595     _tizen_output_transform_register(wind);
596
597     wind->surface = ecore_wl_window_surface_create(wind->window);
598     if (!wind->surface) {
599         SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window surface");
600         return -1;
601     }
602     ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
603
604     wind->rotation = 0;
605     wind->rotation_supported = 0;
606     wind->received_rotation = 0;
607
608 #if SDL_VIDEO_OPENGL_EGL
609     if (window->flags & SDL_WINDOW_OPENGL) {
610
611         if(wind->output_rotation == 90 || wind->output_rotation == 270)
612             wind->egl_window = wl_egl_window_create(wind->surface, window->h, window->w);
613         else
614             wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h);
615
616         /* Create the GLES window surface */
617         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
618         if (wind->egl_surface == EGL_NO_SURFACE) {
619             SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
620             return -1;
621         }
622
623         if (!_this->gl_config.alpha_size) {
624             ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
625         }
626         else {
627             wl_surface_set_opaque_region(wind->surface, NULL);
628         }
629
630         //Support PreRotation
631         wind->support_pre_rotation = 0;
632         if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
633             if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
634                 wind->support_pre_rotation = 1;
635             }
636         }
637         else
638         {
639             wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
640         }
641
642     }
643 #endif
644
645     wind->id = ecore_wl_window_id_get(wind->window);
646     eina_hash_add(data->windows, &wind->id, window);
647
648     Tizen_InitKeyboard(_this);
649     SDL_SetMouseFocus(window);
650
651     if (window->flags & 0x00008000) {
652         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
653         ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
654     }
655
656     EINA_INLIST_FOREACH(globals, global) {
657          if (!strcmp(global->interface, "tizen_policy_ext")) {
658               wind->rotation_supported = 1;
659               break;
660            }
661       }
662     // Add orientaiton hint cb
663     _tizen_window_orientation_add_hint((void*)wind);
664
665     _tizen_rotate_update(wind);
666
667     return 0;
668 }
669
670 void
671 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
672 {
673     SDL_WindowData *wind = window->driverdata;
674     if(!wind->indicator)
675     {
676         SDL_ExecuteIndicatorProcess();
677     }
678 }
679
680 void
681 _tizen_window_resize(SDL_Window *window)
682 {
683     SDL_WindowData *wind = window->driverdata;
684     if (!wind->egl_window) {
685         return;
686     }
687
688     if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
689         ecore_wl_window_update_size(wind->window, window->h, window->w);
690     else
691         ecore_wl_window_update_size(wind->window, window->w, window->h);
692
693     // TODO : consider to rotation status.
694 #if SDL_VIDEO_OPENGL_EGL
695     if (window->flags & SDL_WINDOW_OPENGL) {
696       if(wind->output_rotation==90 || wind->output_rotation==270)
697           wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
698       else
699           wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
700     }
701 #endif
702 }
703
704 void
705 _tizen_setwindowsize(SDL_Window *window)
706 {
707     SDL_WindowData *wind = window->driverdata;
708     if (!wind->window) {
709         return;
710     }
711 }
712
713 void
714 Tizen_SetWindowSize(_THIS, SDL_Window *window)
715 {
716     _tizen_window_resize(window);
717 }
718
719 void
720 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
721 {
722     SDL_WindowData *wind = window->driverdata;
723     if (!wind->window) {
724         return;
725     }
726
727     if (w) *w = window->w;
728     if (h) *h = window->h;
729 }
730
731 void
732 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
733 {
734     SDL_WindowData *wind = window->driverdata;
735     if (!wind->window) {
736         return;
737     }
738
739     // TODO : consider to rotation status.
740    ecore_wl_window_position_set(wind->window, window->x, window->y);
741 }
742
743 void
744 Tizen_DestroyWindow(_THIS, SDL_Window *window)
745 {
746     SDL_VideoData *data = _this->driverdata;
747     SDL_WindowData *wind = window->driverdata;
748
749     if (data) {
750         eina_hash_del(data->windows, &wind->id, window);
751 #if SDL_VIDEO_OPENGL_EGL
752     if (window->flags & SDL_WINDOW_OPENGL) {
753         SDL_EGL_DestroySurface(_this, wind->egl_surface);
754         wl_egl_window_destroy(wind->egl_window);
755     }
756 #endif
757         ecore_wl_window_free(wind->window);
758         SDL_free(wind);
759     }
760
761     window->driverdata = NULL;
762 }
763
764 SDL_Window*
765 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
766 {
767     SDL_VideoData *data = _this->driverdata;
768     int id;
769
770     id = ecore_wl_window_id_get(ewin);
771     return (SDL_Window*)eina_hash_find(data->windows, &id);
772 }
773
774 Eina_Bool
775 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
776 {
777     _THIS = data;
778     Ecore_Wl_Event_Window_Visibility_Change *ev;
779     Ecore_Wl_Window *ew;
780     SDL_Window *window;
781
782     ev = event;
783     ew = ecore_wl_window_find(ev->win);
784     window = Tizen_FindWindow(_this, ew);
785
786     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
787     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
788     return ECORE_CALLBACK_PASS_ON;
789 }
790
791 Eina_Bool
792 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
793 {
794    _THIS = data;
795    Ecore_Wl_Window *ew;
796    SDL_Window *window;
797    SDL_WindowData *wind;
798    Ecore_Wl_Event_Window_Configure *ev;
799    ev = event;
800    ew = ecore_wl_window_find(ev->win);
801    window = Tizen_FindWindow(_this, ew);
802    wind = window->driverdata;
803
804    if (wind->rotation_supported == 0){
805       return ECORE_CALLBACK_PASS_ON;
806    }
807 /*
808    int nx = 0, ny = 0, nw = 0, nh = 0;
809   SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
810
811    ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
812    if (nw < 1) nw = 1;
813    if (nh < 1) nh = 1;
814    
815    SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
816    if ((window->x != nx) || (window->y != ny))
817      ecore_wl_window_position_set(ew, nx, ny);
818
819    if ((window->w != nw) || (window->h != nh)) {
820      _tizen_setwindowsize(window);
821    }
822    */
823    return ECORE_CALLBACK_PASS_ON;
824 }
825
826
827 Eina_Bool
828 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
829 {
830     _THIS = data;
831     Ecore_Wl_Event_Window_Rotate *ev;
832     Ecore_Wl_Window *ew;
833     SDL_Window *window;
834     SDL_WindowData *wind;
835
836     ev = event;
837     if (!ev) {
838         return ECORE_CALLBACK_PASS_ON;
839     }
840
841     ew = ecore_wl_window_find(ev->win);
842     window = Tizen_FindWindow(_this, ew);
843     wind = window->driverdata;
844
845     if (wind->rotation != ev->angle) {
846         /* set ecore_wayland window rotation */
847         wind->rotation = ev->angle;
848         wind->received_rotation = 1;
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: */