2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
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.
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:
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.
23 #include "../../SDL_internal.h"
25 #if SDL_VIDEO_DRIVER_TIZEN
28 #include "SDL_hints.h"
29 #include "SDL_loadso.h"
31 #include "SDL_tizenindicator.h"
33 #include "SDL_tizenvideo.h"
34 #include "SDL_tizentouch.h"
35 #include "SDL_tizenkeyboard.h"
36 #include "SDL_tizenmouse.h"
37 #include "SDL_tizenevents_c.h"
39 #include "SDL_tizenwindow.h"
41 #include "../../events/SDL_mouse_c.h"
42 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
44 #include "../SDL_egl_c.h"
45 #include "../SDL_vulkan_c.h"
46 #include "../SDL_sysvideo.h"
47 #include "../../events/SDL_windowevents_c.h"
49 #define LOAD_FUNC(NAME) \
50 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
51 if (!_this->tizen_pre_rotation_data->NAME) \
53 SDL_SetError("Could not retrieve pre-rotation function " #NAME); \
58 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
60 void *lib_dll_handle = NULL;
63 if (_this->isLoaded_pre_rotation)
66 _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
67 if (!_this->tizen_pre_rotation_data) {
68 return SDL_OutOfMemory();
72 lib_dll_handle = SDL_LoadObject(lib_path);
74 if (!lib_dll_handle) {
75 path = "libwayland-egl.so";
76 lib_dll_handle = SDL_LoadObject(path);
79 _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
81 if (lib_dll_handle == NULL)
84 LOAD_FUNC(wl_egl_window_set_rotation);
85 LOAD_FUNC(wl_egl_window_get_capabilities);
86 _this->isLoaded_pre_rotation = 1;
92 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
94 SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
95 info->info.tizen.egl_display = NULL;
96 info->info.tizen.egl_surface = NULL;
97 #if SDL_VIDEO_OPENGL_EGL
100 info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
102 info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
104 info->subsystem = SDL_SYSWM_TIZEN;
109 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
111 return 0; /* just succeed, the real work is done elsewhere. */
115 Tizen_ShowWindow(_THIS, SDL_Window *window)
117 SDL_WindowData *wind = window->driverdata;
118 ecore_wl_window_show(wind->window);
122 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
123 SDL_VideoDisplay *_display, SDL_bool fullscreen)
129 _tizen_pre_rotation_set(SDL_WindowData *_this)
131 tizen_wl_egl_window_rotation rot;
132 if (!_this->egl_window) return;
134 SDL_Log("%s with angle %d",__FUNCTION__, _this->rotation);
135 switch (_this->rotation) {
137 rot = TIZEN_ROTATION_270;
140 rot = TIZEN_ROTATION_180;
143 rot = TIZEN_ROTATION_90;
146 rot = TIZEN_ROTATION_0;
149 rot = TIZEN_ROTATION_0;
153 SDL_SetError("call wl_egl_win_set_rotation with rot %d",rot);
154 _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
158 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
161 char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
162 int checked[4] = {0,};
165 SDL_WindowData *wind = (SDL_WindowData*)userdata;
166 Ecore_Wl_Window *window = wind->window;
168 if (wind->rotation_supported == 0) {
172 SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
174 if ((oldValue == NULL) && (newValue == NULL)) {
179 p_str = SDL_strstr(newValue, orientation_type[i]);
181 if (p_str == newValue) {
184 else if (i == 1) rot = 90;
185 else if (i == 2) rot = 180;
186 else if (i == 3) rot = 270;
187 wind->rotation = rot;
192 SDL_Log("SDL %s: avaiable rotation: 0", __FUNCTION__);
196 SDL_Log("SDL %s: avaiable rotation: 90", __FUNCTION__);
200 SDL_Log("SDL %s: avaiable rotation: 180", __FUNCTION__);
204 SDL_Log("SDL %s: avaiable rotation: 270", __FUNCTION__);
212 ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
213 SDL_Log("SDL %s: support pre_rotation %d", __FUNCTION__,wind->support_pre_rotation);
214 if (wind->support_pre_rotation) {
215 SDL_Log("SDL %s: set pre rotation %d", __FUNCTION__,wind->rotation);
216 _tizen_pre_rotation_set(wind);
219 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
224 _tizen_window_orientation_add_hint(void *data)
226 SDL_WindowData *wind = (SDL_WindowData*)data;
227 if (wind->rotation_supported == 0) {
231 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
235 Tizen_CreateWindow(_THIS, SDL_Window *window)
237 SDL_VideoData *data = _this->driverdata;
238 SDL_WindowData *wind;
239 Ecore_Wl_Global *global;
240 Eina_Inlist *globals;
242 wind = calloc(1, sizeof * wind);
244 return SDL_OutOfMemory();
247 window->driverdata = wind;
248 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
250 #if SDL_VIDEO_OPENGL_EGL
251 if (window->flags & SDL_WINDOW_OPENGL) {
252 SDL_GL_LoadLibrary(NULL);
257 if (window->flags & SDL_WINDOW_VULKAN) {
258 if (!_this->vulkan_GetInstanceExtensions) {
259 SDL_SetError("No Vulkan support in video driver");
262 if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
263 SDL_SetError("Fail to load Vulkan Library");
268 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
271 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
275 if (!(globals = ecore_wl_globals_get()))
277 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get wayland globals");
281 wind->window = ecore_wl_window_new(NULL,
282 window->x, window->y, window->w, window->h,
283 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
284 wind->surface = ecore_wl_window_surface_create(wind->window);
286 wind->rotation_supported = 0;
287 wind->received_rotation = 0;
288 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
290 #if SDL_VIDEO_OPENGL_EGL
291 if (window->flags & SDL_WINDOW_OPENGL) {
292 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
294 /* Create the GLES window surface */
295 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
296 if (wind->egl_surface == EGL_NO_SURFACE) {
297 SDL_SetError("failed to create a window surface");
301 //Support PreRotation
302 wind->support_pre_rotation = 0;
303 if (_tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
304 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
305 wind->support_pre_rotation = 1;
306 SDL_Log("Can support PreRotation");
309 SDL_Log("can not support PreRotation !!");
313 SDL_Log("can not support PreRotation !!");
318 wind->id = ecore_wl_window_id_get(wind->window);
319 eina_hash_add(data->windows, &wind->id, window);
321 Tizen_InitKeyboard(_this);
322 SDL_SetMouseFocus(window);
324 if (window->flags & 0x00008000) {
325 SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "---------------------------------------");
326 SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[SDL] touch bypass setting is done!\n");
327 SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "---------------------------------------");
328 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
329 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
332 EINA_INLIST_FOREACH(globals, global) {
333 if (!strcmp(global->interface, "tizen_policy_ext")) {
334 wind->rotation_supported = 1;
335 SDL_Log("SDL can support rotation in this device!!!!!!!!!!!");
339 // Add orientaiton hint cb
340 _tizen_window_orientation_add_hint((void*)wind);
345 _tizen_egl_window_resize(SDL_Window *window)
347 SDL_WindowData *wind = window->driverdata;
348 if (!wind->egl_window) {
352 // TODO : consider to rotation status.
353 #if SDL_VIDEO_OPENGL_EGL
354 if (window->flags & SDL_WINDOW_OPENGL) {
355 // TODO : if window size is not FULL, we need the code about Non FullSize Window.
357 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
358 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
365 _tizen_setwindowsize(SDL_Window *window)
367 SDL_WindowData *wind = window->driverdata;
371 ecore_wl_window_update_size(wind->window, window->w, window->h);
375 Tizen_SetWindowSize(_THIS, SDL_Window *window)
377 SDL_Log("[SDL_Size] Tizen_SetWindowSize");
378 // _tizen_setwindowsize(window);
379 // _tizen_egl_window_resize(window);
383 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
385 SDL_WindowData *wind = window->driverdata;
390 if (w) *w = window->w;
391 if (h) *h = window->h;
395 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
397 SDL_WindowData *wind = window->driverdata;
402 // TODO : consider to rotation status.
403 ecore_wl_window_position_set(wind->window, window->x, window->y);
407 Tizen_DestroyWindow(_THIS, SDL_Window *window)
409 SDL_VideoData *data = _this->driverdata;
410 SDL_WindowData *wind = window->driverdata;
413 eina_hash_del(data->windows, &wind->id, window);
414 #if SDL_VIDEO_OPENGL_EGL
415 if (window->flags & SDL_WINDOW_OPENGL) {
416 SDL_EGL_DestroySurface(_this, wind->egl_surface);
417 wl_egl_window_destroy(wind->egl_window);
420 ecore_wl_window_free(wind->window);
424 window->driverdata = NULL;
428 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
430 SDL_VideoData *data = _this->driverdata;
433 id = ecore_wl_window_id_get(ewin);
434 return (SDL_Window*)eina_hash_find(data->windows, &id);
438 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
441 Ecore_Wl_Event_Window_Visibility_Change *ev;
446 ew = ecore_wl_window_find(ev->win);
447 window = Tizen_FindWindow(_this, ew);
449 SDL_Log( "visibility window: %p, ecore_wl_window: %p\n", window, ew);
451 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
452 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
453 return ECORE_CALLBACK_PASS_ON;
457 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
462 SDL_WindowData *wind;
463 Ecore_Wl_Event_Window_Configure *ev;
465 ew = ecore_wl_window_find(ev->win);
466 window = Tizen_FindWindow(_this, ew);
467 wind = window->driverdata;
469 if (wind->rotation_supported == 0){
470 return ECORE_CALLBACK_PASS_ON;
473 int nx = 0, ny = 0, nw = 0, nh = 0;
474 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
476 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
480 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
481 if ((window->x != nx) || (window->y != ny))
482 ecore_wl_window_position_set(ew, nx, ny);
484 if ((window->w != nw) || (window->h != nh)) {
485 _tizen_setwindowsize(window);
488 return ECORE_CALLBACK_PASS_ON;
493 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
496 SDL_WindowData *wind;
497 wind = window->driverdata;
499 SDL_memset(&event, 0, sizeof(event));
500 event.type = SDL_ROTATEEVENT;
502 if (wind->support_pre_rotation)
503 event.user.data1 = (void*)0;
505 event.user.data1 = (void*)angle;
506 event.user.data2 = (void*)-1;
508 SDL_PushEvent(&event);
513 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
516 Ecore_Wl_Event_Window_Rotate *ev;
519 SDL_WindowData *wind;
523 return ECORE_CALLBACK_PASS_ON;
526 ew = ecore_wl_window_find(ev->win);
527 window = Tizen_FindWindow(_this, ew);
528 wind = window->driverdata;
530 if (wind->rotation != ev->angle) {
531 /* set ecore_wayland window rotation */
532 wind->rotation = ev->angle;
533 ecore_wl_window_rotation_set(ew, ev->angle);
535 if(wind->support_pre_rotation) {
536 _tizen_pre_rotation_set(wind);
539 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
540 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
542 SDL_Log("[SDL_Size] * _tizen_cb_event_window_rotate aw ah : %d, %d", aw, ah);
544 if(wind->rotation == 90 || wind->rotation == 270) {
545 SDL_SetWindowSize(window, ah, aw);
546 window->w = ah;//for Fullscreen
549 SDL_SetWindowSize(window, aw, ah);//->call wl_egl_window_resize()
550 window->w = aw;//for Fullscreen
553 SDL_Log("[SDL_Size] * _tizen_cb_event_window_rotate aw ah : %d, %d", window->w, window->h);
556 // Send Rotation Event
557 _tizen_send_rotation_event(window, ev->angle);
558 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
561 wind->received_rotation = 1;
562 const char* hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
563 if(hint && *hint != '\0')
564 Tizen_IndicatorProcessEvent(_this->current_glwin, wind->rotation);
566 return ECORE_CALLBACK_PASS_ON;
570 Tizen_InitWindow(_THIS)
572 SDL_VideoData *data = _this->driverdata;
574 data->windows = eina_hash_int32_new(NULL);
576 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
577 _tizen_cb_event_window_visibility_change,_this);
578 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
579 _tizen_cb_event_keyup_change,_this);
580 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
581 _tizen_cb_event_keydown_change,_this);
582 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
583 _tizen_cb_event_mousedown_change,_this);
584 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
585 _tizen_cb_event_mouseup_change,_this);
586 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
587 _tizen_cb_event_mousemove_change,_this);
588 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
589 _tizen_cb_event_window_rotate,_this);
590 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
591 _tizen_cb_window_configure,_this);
592 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
593 _tizen_cb_event_joystick_change,_this);
594 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
595 _tizen_cb_event_focus_in,_this);
596 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
597 _tizen_cb_event_focus_out,_this);
598 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
599 _tizen_cb_event_mouse_in,_this);
600 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
601 _tizen_cb_event_mouse_out,_this);
603 data->current_thread = SDL_GetThreadID(0);
609 Tizen_DeinitWindow(_THIS)
611 SDL_VideoData *data = _this->driverdata;
613 eina_hash_free(data->windows);
615 #endif /* SDL_VIDEO_DRIVER_TIZEN */
617 /* vi: set ts=4 sw=4 expandtab: */