[SDL_Tizen] Add SDL_Window function
[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_SetWindowTitle(_THIS, SDL_Window * window)
255 {
256     SDL_WindowData *wind = window->driverdata;
257     ecore_wl_window_title_set(wind->window, window->title);
258 }
259
260 void
261 Tizen_ShowWindow(_THIS, SDL_Window *window)
262 {
263     SDL_WindowData *wind = window->driverdata;
264
265     if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && !wind->indicator)
266     {
267         SDL_ExecuteIndicatorProcess();
268     }
269     ecore_wl_window_show(wind->window);
270 }
271
272 void
273 Tizen_HideWindow(_THIS, SDL_Window *window)
274 {
275     SDL_WindowData *wind = window->driverdata;
276     ecore_wl_window_hide(wind->window);
277 }
278
279 void
280 Tizen_RaiseWindow(_THIS, SDL_Window *window)
281 {
282     SDL_WindowData *wind = window->driverdata;
283     ecore_wl_window_raise(wind->window);
284 }
285
286 void
287 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
288                           SDL_VideoDisplay *_display, SDL_bool fullscreen)
289 {
290     /*DO NOTHING*/
291 }
292
293 void
294 Tizen_pre_rotation_set(SDL_WindowData *_this, int rotation)
295 {
296     tizen_wl_egl_window_rotation rot;
297     if (!_this->egl_window) return;
298
299     switch (rotation) {
300          case 90:
301             rot = TIZEN_ROTATION_270;
302             break;
303          case 180:
304             rot = TIZEN_ROTATION_180;
305             break;
306          case 270:
307             rot = TIZEN_ROTATION_90;
308             break;
309          case 0:
310             rot = TIZEN_ROTATION_0;
311             break;
312          default:
313             rot = TIZEN_ROTATION_0;
314             break;
315       }
316
317       _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
318 }
319
320 void
321 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
322 {
323     char *p_str = NULL;
324     char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
325     int checked[4] = {0,};
326     int i;
327     unsigned int j = 0;
328     SDL_WindowData *wind = (SDL_WindowData*)userdata;
329     Ecore_Wl_Window *window = wind->window;
330
331     if (wind->rotation_supported == 0) {
332         return;
333     }
334
335     SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
336
337     if ((oldValue == NULL) && (newValue == NULL)) {
338         return;
339     }
340
341     for (i=0;i<4;i++) {
342         p_str = SDL_strstr(newValue, orientation_type[i]);
343         if (p_str) {
344             if (p_str == newValue) {
345                 int rot = 0;
346                 if (i == 0) rot = 0;
347                 else if (i == 1) rot = 90;
348                 else if (i == 2) rot = 180;
349                 else if (i == 3) rot = 270;
350                 wind->rotation = rot;
351             }
352
353             if (i == 0) {
354                 checked[j] = 0;
355             }
356             else if (i == 1) {
357                 checked[j] = 90;
358             }
359             else if (i == 2) {
360                 checked[j] = 180;
361             }
362             else if (i == 3) {
363                 checked[j] = 270;
364             }
365             j++;
366         }
367     }
368
369     if (j > 0) {
370         if (j == 1) {
371             ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
372         }else {
373             ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
374         }
375     }
376 }
377
378 void
379 _tizen_window_orientation_add_hint(void *data)
380 {
381     SDL_WindowData *wind = (SDL_WindowData*)data;
382     if (wind->rotation_supported == 0) {
383         return;
384     }
385
386     SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
387 }
388
389 static Eina_Bool
390 _tizen_cb_output_transform(void *data, int type EINA_UNUSED, void *event)
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     Ecore_Wl_Event_Output_Transform *ev = event;
398     Ecore_Wl_Output *output;
399
400     output = ecore_wl_window_output_find(wind->window);
401     if (output != ev->output) return ECORE_CALLBACK_PASS_ON;
402
403     wind->received_rotation = 1;
404
405
406    return ECORE_CALLBACK_PASS_ON;
407 }
408
409 static Eina_Bool
410 _tizen_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
411 {
412     SDL_Window * window = SDL_GetVideoDevice()->windows;
413     SDL_WindowData *wind = window->driverdata;
414
415     if(!wind) return ECORE_CALLBACK_PASS_ON;
416
417     wind->received_rotation = 1;
418
419    return ECORE_CALLBACK_PASS_ON;
420 }
421
422 void
423 _tizen_output_transform_register(SDL_WindowData *wind)
424 {
425     if(!wind) return;
426
427     Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
428     wind->output_rotation = ecore_wl_output_transform_get(output) * 90;
429
430     ecore_event_handler_add(ECORE_WL_EVENT_OUTPUT_TRANSFORM,
431                              _tizen_cb_output_transform, NULL);
432     ecore_event_handler_add(ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM,
433                              _tizen_cb_ignore_output_transform, NULL);
434
435 }
436
437 void
438 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
439 {
440     SDL_Event event;
441     SDL_WindowData *wind;
442     wind = window->driverdata;
443
444     SDL_memset(&event, 0, sizeof(event));
445     event.type = SDL_ROTATEEVENT;
446     event.user.code = 0;
447     if (wind->support_pre_rotation)
448         event.user.data1 = (void*)0;
449     else
450         event.user.data1 = (void*)angle;
451     event.user.data2 = (void*)-1;
452
453     SDL_PushEvent(&event);
454     return;
455 }
456
457 void
458 _tizen_set_window_size(SDL_Window * window, int w, int h)
459 {
460     if(!window)
461     {
462         SDL_SetError("Invalid window");
463         return;
464     }
465
466     SDL_VideoDevice *_this = SDL_GetVideoDevice();
467     if (!_this) {
468         SDL_SetError("Video subsystem has not been initialized");
469         return;
470     }
471
472     if (window->magic != &_this->window_magic) {
473         return;
474     }
475
476     if (w <= 0) {
477         SDL_InvalidParamError("w");
478         return;
479     }
480     if (h <= 0) {
481         SDL_InvalidParamError("h");
482         return;
483     }
484
485     /* Make sure we don't exceed any window size limits */
486     if (window->min_w && w < window->min_w)
487     {
488         w = window->min_w;
489     }
490     if (window->max_w && w > window->max_w)
491     {
492         w = window->max_w;
493     }
494     if (window->min_h && h < window->min_h)
495     {
496         h = window->min_h;
497     }
498     if (window->max_h && h > window->max_h)
499     {
500         h = window->max_h;
501     }
502
503     window->windowed.w = w;
504     window->windowed.h = h;
505
506     window->w = w;
507     window->h = h;
508 }
509
510 void
511 _tizen_rotation_do(SDL_WindowData *wind, int rotation)
512 {
513     if(!wind) return;
514
515     SDL_Window *window = SDL_GetVideoDevice()->windows;
516     if(!window) return;
517
518     int window_w, window_h;
519     if(wind->rotation == 0 || wind->rotation == 180)
520         ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
521     else
522         ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
523
524     _tizen_set_window_size(window, window_w, window_h);
525
526     if(wind->support_pre_rotation)
527         Tizen_pre_rotation_set(wind, rotation);
528
529     _tizen_send_rotation_event(window, wind->rotation);
530     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
531
532 }
533
534 void
535 _tizen_rotate_update(SDL_WindowData *wind)
536 {
537     if(!wind) return;
538
539     int screen_rotation;
540     if (ecore_wl_window_ignore_output_transform_get(wind->window))
541     {
542         screen_rotation = 0;
543     }
544     else
545     {
546         Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
547         screen_rotation = ecore_wl_output_transform_get(output) * 90;
548     }
549
550     //Set Screen Rotation
551     wind->output_rotation = screen_rotation;
552     if(wind->support_pre_rotation)
553         ecore_wl_window_buffer_transform_set(wind->window, wind->output_rotation / 90);
554
555     ecore_wl_window_rotation_set(wind->window, wind->rotation);
556
557     int rotation = (wind->output_rotation + wind->rotation) % 360;
558     _tizen_rotation_do(wind, rotation);
559 }
560
561 int
562 Tizen_CreateWindow(_THIS, SDL_Window *window)
563 {
564     SDL_VideoData *data = _this->driverdata;
565     SDL_WindowData *wind;
566     Ecore_Wl_Global *global;
567     Eina_Inlist *globals;
568
569     wind = calloc(1, sizeof * wind);
570     if (!wind) {
571         return SDL_OutOfMemory();
572     }
573
574     window->driverdata = wind;
575     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
576
577 #if SDL_VIDEO_OPENGL_EGL
578     if (window->flags & SDL_WINDOW_OPENGL) {
579         SDL_GL_LoadLibrary(NULL);
580     }
581 #endif
582
583 #if SDL_VIDEO_VULKAN
584     if (window->flags & SDL_WINDOW_VULKAN) {
585         if (!_this->vulkan_GetInstanceExtensions) {
586             SDL_SetError("No Vulkan support in video driver");
587         }
588
589         if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
590             SDL_SetError("Fail to load Vulkan Library");
591         }
592     }
593 #endif
594
595     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
596         window->x = 0;
597     }
598     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
599         window->y = 0;
600     }
601
602     if (!(globals = ecore_wl_globals_get()))
603       {
604          SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
605          return -1;
606       }
607
608     wind->window = ecore_wl_window_new(NULL,
609                                        window->x, window->y, window->w, window->h,
610                                        ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
611     if (!wind->window) {
612         SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window");
613         return -1;
614     }
615     _tizen_output_transform_register(wind);
616
617     wind->surface = ecore_wl_window_surface_create(wind->window);
618     if (!wind->surface) {
619         SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window surface");
620         return -1;
621     }
622     ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
623
624     wind->rotation = 0;
625     wind->rotation_supported = 0;
626     wind->received_rotation = 0;
627
628 #if SDL_VIDEO_OPENGL_EGL
629     if (window->flags & SDL_WINDOW_OPENGL) {
630
631         if(wind->output_rotation == 90 || wind->output_rotation == 270)
632             wind->egl_window = wl_egl_window_create(wind->surface, window->h, window->w);
633         else
634             wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h);
635
636         /* Create the GLES window surface */
637         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
638         if (wind->egl_surface == EGL_NO_SURFACE) {
639             SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
640             return -1;
641         }
642
643         if (!_this->gl_config.alpha_size) {
644             ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
645         }
646         else {
647             wl_surface_set_opaque_region(wind->surface, NULL);
648         }
649
650         //Support PreRotation
651         wind->support_pre_rotation = 0;
652         if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
653             if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
654                 wind->support_pre_rotation = 1;
655             }
656         }
657         else
658         {
659             wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
660         }
661
662     }
663 #endif
664
665     wind->id = ecore_wl_window_id_get(wind->window);
666     eina_hash_add(data->windows, &wind->id, window);
667
668     Tizen_InitKeyboard(_this);
669     SDL_SetMouseFocus(window);
670
671     if (window->flags & 0x00008000) {
672         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
673         ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
674     }
675
676     EINA_INLIST_FOREACH(globals, global) {
677          if (!strcmp(global->interface, "tizen_policy_ext")) {
678               wind->rotation_supported = 1;
679               break;
680            }
681       }
682     // Add orientaiton hint cb
683     _tizen_window_orientation_add_hint((void*)wind);
684
685     _tizen_rotate_update(wind);
686
687     return 0;
688 }
689
690 void
691 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
692 {
693     SDL_WindowData *wind = window->driverdata;
694     if(!wind->indicator)
695     {
696         SDL_ExecuteIndicatorProcess();
697     }
698 }
699
700 void
701 _tizen_window_resize(SDL_Window *window)
702 {
703     SDL_WindowData *wind = window->driverdata;
704     if (!wind->egl_window) {
705         return;
706     }
707
708     if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
709         ecore_wl_window_update_size(wind->window, window->h, window->w);
710     else
711         ecore_wl_window_update_size(wind->window, window->w, window->h);
712
713     // TODO : consider to rotation status.
714 #if SDL_VIDEO_OPENGL_EGL
715     if (window->flags & SDL_WINDOW_OPENGL) {
716       if(wind->output_rotation==90 || wind->output_rotation==270)
717           wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
718       else
719           wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
720     }
721 #endif
722 }
723
724 void
725 _tizen_setwindowsize(SDL_Window *window)
726 {
727     SDL_WindowData *wind = window->driverdata;
728     if (!wind->window) {
729         return;
730     }
731 }
732
733 void
734 Tizen_SetWindowSize(_THIS, SDL_Window *window)
735 {
736     _tizen_window_resize(window);
737 }
738
739 void
740 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
741 {
742     SDL_WindowData *wind = window->driverdata;
743     if (!wind->window) {
744         return;
745     }
746
747     if (w) *w = window->w;
748     if (h) *h = window->h;
749 }
750
751 void
752 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
753 {
754     SDL_WindowData *wind = window->driverdata;
755     if (!wind->window) {
756         return;
757     }
758
759     // TODO : consider to rotation status.
760    ecore_wl_window_position_set(wind->window, window->x, window->y);
761 }
762
763 void
764 Tizen_DestroyWindow(_THIS, SDL_Window *window)
765 {
766     SDL_VideoData *data = _this->driverdata;
767     SDL_WindowData *wind = window->driverdata;
768
769     if (data) {
770         eina_hash_del(data->windows, &wind->id, window);
771 #if SDL_VIDEO_OPENGL_EGL
772     if (window->flags & SDL_WINDOW_OPENGL) {
773         SDL_EGL_DestroySurface(_this, wind->egl_surface);
774         wl_egl_window_destroy(wind->egl_window);
775     }
776 #endif
777         ecore_wl_window_free(wind->window);
778         SDL_free(wind);
779     }
780
781     window->driverdata = NULL;
782 }
783
784 SDL_Window*
785 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
786 {
787     SDL_VideoData *data = _this->driverdata;
788     int id;
789
790     id = ecore_wl_window_id_get(ewin);
791     return (SDL_Window*)eina_hash_find(data->windows, &id);
792 }
793
794 Eina_Bool
795 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
796 {
797     _THIS = data;
798     Ecore_Wl_Event_Window_Visibility_Change *ev;
799     Ecore_Wl_Window *ew;
800     SDL_Window *window;
801
802     ev = event;
803     ew = ecore_wl_window_find(ev->win);
804     window = Tizen_FindWindow(_this, ew);
805
806     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
807     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
808     return ECORE_CALLBACK_PASS_ON;
809 }
810
811 Eina_Bool
812 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
813 {
814    _THIS = data;
815    Ecore_Wl_Window *ew;
816    SDL_Window *window;
817    SDL_WindowData *wind;
818    Ecore_Wl_Event_Window_Configure *ev;
819    ev = event;
820    ew = ecore_wl_window_find(ev->win);
821    window = Tizen_FindWindow(_this, ew);
822    wind = window->driverdata;
823
824    if (wind->rotation_supported == 0){
825       return ECORE_CALLBACK_PASS_ON;
826    }
827 /*
828    int nx = 0, ny = 0, nw = 0, nh = 0;
829   SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
830
831    ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
832    if (nw < 1) nw = 1;
833    if (nh < 1) nh = 1;
834    
835    SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
836    if ((window->x != nx) || (window->y != ny))
837      ecore_wl_window_position_set(ew, nx, ny);
838
839    if ((window->w != nw) || (window->h != nh)) {
840      _tizen_setwindowsize(window);
841    }
842    */
843    return ECORE_CALLBACK_PASS_ON;
844 }
845
846
847 Eina_Bool
848 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
849 {
850     _THIS = data;
851     Ecore_Wl_Event_Window_Rotate *ev;
852     Ecore_Wl_Window *ew;
853     SDL_Window *window;
854     SDL_WindowData *wind;
855
856     ev = event;
857     if (!ev) {
858         return ECORE_CALLBACK_PASS_ON;
859     }
860
861     ew = ecore_wl_window_find(ev->win);
862     window = Tizen_FindWindow(_this, ew);
863     wind = window->driverdata;
864
865     if (wind->rotation != ev->angle) {
866         /* set ecore_wayland window rotation */
867         wind->rotation = ev->angle;
868         wind->received_rotation = 1;
869     }
870
871     return ECORE_CALLBACK_PASS_ON;
872 }
873
874 int
875 Tizen_InitWindow(_THIS)
876 {
877     SDL_VideoData *data = _this->driverdata;
878
879     data->windows = eina_hash_int32_new(NULL);
880
881     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
882                         _tizen_cb_event_window_visibility_change,_this);
883     ecore_event_handler_add(ECORE_EVENT_KEY_UP,
884                         _tizen_cb_event_keyup_change,_this);
885     ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
886                         _tizen_cb_event_keydown_change,_this);
887     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
888                         _tizen_cb_event_mousedown_change,_this);
889     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
890                         _tizen_cb_event_mouseup_change,_this);
891     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
892                         _tizen_cb_event_mousemove_change,_this);
893     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
894                         _tizen_cb_event_window_rotate,_this);
895     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
896                         _tizen_cb_window_configure,_this);
897     ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
898                         _tizen_cb_event_joystick_change,_this);
899     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
900                         _tizen_cb_event_focus_in,_this);
901     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
902                         _tizen_cb_event_focus_out,_this);
903     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
904                         _tizen_cb_event_mouse_in,_this);
905     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
906                         _tizen_cb_event_mouse_out,_this);
907
908     return 0;
909 }
910
911 void
912 Tizen_DeinitWindow(_THIS)
913 {
914     SDL_VideoData *data = _this->driverdata;
915
916     eina_hash_free(data->windows);
917 }
918 #endif /* SDL_VIDEO_DRIVER_TIZEN */
919
920 /* vi: set ts=4 sw=4 expandtab: */