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_tizenvideo.h"
32 #include "SDL_tizentouch.h"
33 #include "SDL_tizenkeyboard.h"
34 #include "SDL_tizenmouse.h"
35 #include "SDL_tizenevents_c.h"
37 #include "SDL_tizenwindow.h"
38 #include "SDL_tizenopengles.h"
40 #include "../../events/SDL_mouse_c.h"
41 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
43 #include "../SDL_egl_c.h"
44 #include "../SDL_vulkan_c.h"
45 #include "../SDL_sysvideo.h"
46 #include "../../events/SDL_windowevents_c.h"
49 ROTATION_TYPE_NORMAL_ROTATION = 0,
50 ROTATION_TYPE_PRE_ROTATION, /* use pre-rotation */
53 #define LOAD_FUNC(NAME) \
54 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
55 if (!_this->tizen_pre_rotation_data->NAME) \
57 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
62 _tizen_rotation_type_get()
64 static int type = ROTATION_TYPE_PRE_ROTATION;
65 static int checked = 0;
68 if (checked) return type;
70 engine = getenv("SDL_ROTATION");
74 if ((!strcasecmp(engine, "normal")))
75 type = ROTATION_TYPE_NORMAL_ROTATION;
76 else if ((!strcasecmp(engine, "pre_rotation")))
77 type = ROTATION_TYPE_PRE_ROTATION;
79 type = ROTATION_TYPE_PRE_ROTATION;
86 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
88 void *lib_dll_handle = NULL;
91 if (_this->isLoaded_pre_rotation)
94 _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
95 if (!_this->tizen_pre_rotation_data) {
96 return SDL_OutOfMemory();
100 lib_dll_handle = SDL_LoadObject(lib_path);
102 if (!lib_dll_handle) {
103 path = "libwayland-egl.so";
104 lib_dll_handle = SDL_LoadObject(path);
107 _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
109 if (lib_dll_handle == NULL)
112 LOAD_FUNC(wl_egl_window_set_rotation);
113 LOAD_FUNC(wl_egl_window_get_capabilities);
114 _this->isLoaded_pre_rotation = 1;
120 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
122 SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
123 info->info.tizen.egl_display = NULL;
124 info->info.tizen.egl_surface = NULL;
125 #if SDL_VIDEO_OPENGL_EGL
128 info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
130 info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
132 info->subsystem = SDL_SYSWM_TIZEN;
137 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
139 return 0; /* just succeed, the real work is done elsewhere. */
143 Tizen_ShowWindow(_THIS, SDL_Window *window)
145 SDL_WindowData *wind = window->driverdata;
147 if((window->flags & SDL_WINDOW_FULLSCREEN) || (window->flags & SDL_WINDOW_BORDERLESS))
149 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_OFF);
150 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_TRANSPARENT);
151 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_HIDDEN);
155 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
156 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
157 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
159 ecore_wl_window_show(wind->window);
163 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
164 SDL_VideoDisplay *_display, SDL_bool fullscreen)
170 Tizen_pre_rotation_set(SDL_WindowData *_this, int rotation)
172 tizen_wl_egl_window_rotation rot;
173 if (!_this->egl_window) return;
177 rot = TIZEN_ROTATION_270;
180 rot = TIZEN_ROTATION_180;
183 rot = TIZEN_ROTATION_90;
186 rot = TIZEN_ROTATION_0;
189 rot = TIZEN_ROTATION_0;
193 _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
197 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
200 char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
201 int checked[4] = {0,};
204 SDL_WindowData *wind = (SDL_WindowData*)userdata;
205 Ecore_Wl_Window *window = wind->window;
207 if (wind->rotation_supported == 0) {
211 SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
213 if ((oldValue == NULL) && (newValue == NULL)) {
218 p_str = SDL_strstr(newValue, orientation_type[i]);
220 if (p_str == newValue) {
223 else if (i == 1) rot = 90;
224 else if (i == 2) rot = 180;
225 else if (i == 3) rot = 270;
226 wind->rotation = rot;
247 ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
249 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
255 _tizen_window_orientation_add_hint(void *data)
257 SDL_WindowData *wind = (SDL_WindowData*)data;
258 if (wind->rotation_supported == 0) {
262 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
266 _tizen_cb_output_transform(void *data, int type EINA_UNUSED, void *event)
268 SDL_Window * window = SDL_GetVideoDevice()->windows;
269 SDL_WindowData *wind = window->driverdata;
271 if(!wind) return ECORE_CALLBACK_PASS_ON;
273 Ecore_Wl_Event_Output_Transform *ev = event;
274 Ecore_Wl_Output *output;
276 output = ecore_wl_window_output_find(wind->window);
277 if (output != ev->output) return ECORE_CALLBACK_PASS_ON;
279 _tizen_rotate_update(wind);
281 return ECORE_CALLBACK_PASS_ON;
285 _tizen_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
287 SDL_Window * window = SDL_GetVideoDevice()->windows;
288 SDL_WindowData *wind = window->driverdata;
290 if(!wind) return ECORE_CALLBACK_PASS_ON;
292 _tizen_rotate_update(wind);
294 return ECORE_CALLBACK_PASS_ON;
298 _tizen_output_transform_register(SDL_WindowData *wind)
302 Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
303 wind->output_rotation = ecore_wl_output_transform_get(output) * 90;
305 ecore_event_handler_add(ECORE_WL_EVENT_OUTPUT_TRANSFORM,
306 _tizen_cb_output_transform, NULL);
307 ecore_event_handler_add(ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM,
308 _tizen_cb_ignore_output_transform, NULL);
313 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
316 SDL_WindowData *wind;
317 wind = window->driverdata;
319 SDL_memset(&event, 0, sizeof(event));
320 event.type = SDL_ROTATEEVENT;
322 if (wind->support_pre_rotation)
323 event.user.data1 = (void*)0;
325 event.user.data1 = (void*)angle;
326 event.user.data2 = (void*)-1;
328 SDL_PushEvent(&event);
333 _tizen_set_window_size(SDL_Window * window, int w, int h)
337 SDL_SetError("Invalid window");
341 SDL_VideoDevice *_this = SDL_GetVideoDevice();
343 SDL_SetError("Video subsystem has not been initialized");
347 if (window->magic != &_this->window_magic) {
352 SDL_InvalidParamError("w");
356 SDL_InvalidParamError("h");
360 /* Make sure we don't exceed any window size limits */
361 if (window->min_w && w < window->min_w)
365 if (window->max_w && w > window->max_w)
369 if (window->min_h && h < window->min_h)
373 if (window->max_h && h > window->max_h)
378 window->windowed.w = w;
379 window->windowed.h = h;
386 _tizen_rotation_do(SDL_WindowData *wind, int rotation)
390 SDL_Window *window = SDL_GetVideoDevice()->windows;
393 int window_w, window_h;
394 if(wind->rotation == 0 || wind->rotation == 180)
395 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
397 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
399 _tizen_set_window_size(window, window_w, window_h);
401 if(wind->support_pre_rotation)
402 Tizen_pre_rotation_set(wind, rotation);
404 _tizen_send_rotation_event(window, rotation);
405 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
406 wind->received_rotation = 1;
411 _tizen_rotate_update(SDL_WindowData *wind)
416 if (ecore_wl_window_ignore_output_transform_get(wind->window))
422 Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window);
423 screen_rotation = ecore_wl_output_transform_get(output) * 90;
426 //Set Screen Rotation
427 wind->output_rotation = screen_rotation;
428 ecore_wl_window_buffer_transform_set(wind->window, wind->output_rotation / 90);
430 int rotation = (wind->output_rotation + wind->rotation) % 360;
431 _tizen_rotation_do(wind, rotation);
435 Tizen_CreateWindow(_THIS, SDL_Window *window)
437 SDL_VideoData *data = _this->driverdata;
438 SDL_WindowData *wind;
439 Ecore_Wl_Global *global;
440 Eina_Inlist *globals;
442 wind = calloc(1, sizeof * wind);
444 return SDL_OutOfMemory();
447 window->driverdata = wind;
448 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
450 #if SDL_VIDEO_OPENGL_EGL
451 if (window->flags & SDL_WINDOW_OPENGL) {
452 SDL_GL_LoadLibrary(NULL);
457 if (window->flags & SDL_WINDOW_VULKAN) {
458 if (!_this->vulkan_GetInstanceExtensions) {
459 SDL_SetError("No Vulkan support in video driver");
462 if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
463 SDL_SetError("Fail to load Vulkan Library");
468 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
471 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
475 if (!(globals = ecore_wl_globals_get()))
477 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
481 wind->window = ecore_wl_window_new(NULL,
482 window->x, window->y, window->w, window->h,
483 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
485 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window");
488 _tizen_output_transform_register(wind);
490 wind->surface = ecore_wl_window_surface_create(wind->window);
491 if (!wind->surface) {
492 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window surface");
495 ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
498 wind->rotation_supported = 0;
499 wind->received_rotation = 0;
501 #if SDL_VIDEO_OPENGL_EGL
502 if (window->flags & SDL_WINDOW_OPENGL) {
503 if(wind->output_rotation == 90 || wind->output_rotation == 270)
504 wind->egl_window = wl_egl_window_create(wind->surface, window->h, window->w);
506 wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h);
508 /* Create the GLES window surface */
509 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
510 if (wind->egl_surface == EGL_NO_SURFACE) {
511 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
515 if (!_this->gl_config.alpha_size) {
516 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
519 wl_surface_set_opaque_region(wind->surface, NULL);
522 //Support PreRotation
523 wind->support_pre_rotation = 0;
524 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
525 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
526 wind->support_pre_rotation = 1;
532 wind->id = ecore_wl_window_id_get(wind->window);
533 eina_hash_add(data->windows, &wind->id, window);
535 Tizen_InitKeyboard(_this);
536 SDL_SetMouseFocus(window);
538 if (window->flags & 0x00008000) {
539 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
540 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
543 EINA_INLIST_FOREACH(globals, global) {
544 if (!strcmp(global->interface, "tizen_policy_ext")) {
545 wind->rotation_supported = 1;
549 // Add orientaiton hint cb
550 _tizen_window_orientation_add_hint((void*)wind);
552 _tizen_rotate_update(wind);
558 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
560 //Add setting window bordered.
564 _tizen_window_resize(SDL_Window *window)
566 SDL_WindowData *wind = window->driverdata;
567 if (!wind->egl_window) {
571 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
572 ecore_wl_window_update_size(wind->window, window->h, window->w);
574 ecore_wl_window_update_size(wind->window, window->w, window->h);
576 // TODO : consider to rotation status.
577 #if SDL_VIDEO_OPENGL_EGL
578 if (window->flags & SDL_WINDOW_OPENGL) {
579 if(wind->output_rotation==90 || wind->output_rotation==270)
580 wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
582 wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
588 _tizen_setwindowsize(SDL_Window *window)
590 SDL_WindowData *wind = window->driverdata;
597 Tizen_SetWindowSize(_THIS, SDL_Window *window)
599 _tizen_window_resize(window);
603 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
605 SDL_WindowData *wind = window->driverdata;
610 if (w) *w = window->w;
611 if (h) *h = window->h;
615 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
617 SDL_WindowData *wind = window->driverdata;
622 // TODO : consider to rotation status.
623 ecore_wl_window_position_set(wind->window, window->x, window->y);
627 Tizen_DestroyWindow(_THIS, SDL_Window *window)
629 SDL_VideoData *data = _this->driverdata;
630 SDL_WindowData *wind = window->driverdata;
633 eina_hash_del(data->windows, &wind->id, window);
634 #if SDL_VIDEO_OPENGL_EGL
635 if (window->flags & SDL_WINDOW_OPENGL) {
636 SDL_EGL_DestroySurface(_this, wind->egl_surface);
637 wl_egl_window_destroy(wind->egl_window);
640 ecore_wl_window_free(wind->window);
644 window->driverdata = NULL;
648 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
650 SDL_VideoData *data = _this->driverdata;
653 id = ecore_wl_window_id_get(ewin);
654 return (SDL_Window*)eina_hash_find(data->windows, &id);
658 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
661 Ecore_Wl_Event_Window_Visibility_Change *ev;
666 ew = ecore_wl_window_find(ev->win);
667 window = Tizen_FindWindow(_this, ew);
669 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
670 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
671 return ECORE_CALLBACK_PASS_ON;
675 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
680 SDL_WindowData *wind;
681 Ecore_Wl_Event_Window_Configure *ev;
683 ew = ecore_wl_window_find(ev->win);
684 window = Tizen_FindWindow(_this, ew);
685 wind = window->driverdata;
687 if (wind->rotation_supported == 0){
688 return ECORE_CALLBACK_PASS_ON;
691 int nx = 0, ny = 0, nw = 0, nh = 0;
692 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
694 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
698 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
699 if ((window->x != nx) || (window->y != ny))
700 ecore_wl_window_position_set(ew, nx, ny);
702 if ((window->w != nw) || (window->h != nh)) {
703 _tizen_setwindowsize(window);
706 return ECORE_CALLBACK_PASS_ON;
711 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
714 Ecore_Wl_Event_Window_Rotate *ev;
717 SDL_WindowData *wind;
721 return ECORE_CALLBACK_PASS_ON;
724 ew = ecore_wl_window_find(ev->win);
725 window = Tizen_FindWindow(_this, ew);
726 wind = window->driverdata;
728 if (wind->rotation != ev->angle) {
729 /* set ecore_wayland window rotation */
730 wind->rotation = ev->angle;
731 ecore_wl_window_rotation_set(wind->window, wind->rotation);
732 _tizen_rotate_update(wind);
735 return ECORE_CALLBACK_PASS_ON;
739 Tizen_InitWindow(_THIS)
741 SDL_VideoData *data = _this->driverdata;
743 data->windows = eina_hash_int32_new(NULL);
745 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
746 _tizen_cb_event_window_visibility_change,_this);
747 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
748 _tizen_cb_event_keyup_change,_this);
749 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
750 _tizen_cb_event_keydown_change,_this);
751 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
752 _tizen_cb_event_mousedown_change,_this);
753 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
754 _tizen_cb_event_mouseup_change,_this);
755 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
756 _tizen_cb_event_mousemove_change,_this);
757 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
758 _tizen_cb_event_window_rotate,_this);
759 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
760 _tizen_cb_window_configure,_this);
761 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
762 _tizen_cb_event_joystick_change,_this);
763 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
764 _tizen_cb_event_focus_in,_this);
765 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
766 _tizen_cb_event_focus_out,_this);
767 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
768 _tizen_cb_event_mouse_in,_this);
769 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
770 _tizen_cb_event_mouse_out,_this);
772 data->current_thread = SDL_GetThreadID(0);
778 Tizen_DeinitWindow(_THIS)
780 SDL_VideoData *data = _this->driverdata;
782 eina_hash_free(data->windows);
784 #endif /* SDL_VIDEO_DRIVER_TIZEN */
786 /* vi: set ts=4 sw=4 expandtab: */