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)
172 tizen_wl_egl_window_rotation rot;
173 if (!_this->egl_window) return;
175 switch (_this->rotation) {
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);
248 if (wind->support_pre_rotation)
249 Tizen_pre_rotation_set(wind);
251 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
257 _tizen_window_orientation_add_hint(void *data)
259 SDL_WindowData *wind = (SDL_WindowData*)data;
260 if (wind->rotation_supported == 0) {
264 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
268 Tizen_CreateWindow(_THIS, SDL_Window *window)
270 SDL_VideoData *data = _this->driverdata;
271 SDL_WindowData *wind;
272 Ecore_Wl_Global *global;
273 Eina_Inlist *globals;
275 wind = calloc(1, sizeof * wind);
277 return SDL_OutOfMemory();
280 window->driverdata = wind;
281 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
283 #if SDL_VIDEO_OPENGL_EGL
284 if (window->flags & SDL_WINDOW_OPENGL) {
285 SDL_GL_LoadLibrary(NULL);
290 if (window->flags & SDL_WINDOW_VULKAN) {
291 if (!_this->vulkan_GetInstanceExtensions) {
292 SDL_SetError("No Vulkan support in video driver");
295 if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
296 SDL_SetError("Fail to load Vulkan Library");
301 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
304 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
308 if (!(globals = ecore_wl_globals_get()))
310 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
314 wind->window = ecore_wl_window_new(NULL,
315 window->x, window->y, window->w, window->h,
316 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
317 wind->surface = ecore_wl_window_surface_create(wind->window);
318 ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
321 wind->rotation_supported = 0;
322 wind->received_rotation = 0;
324 #if SDL_VIDEO_OPENGL_EGL
325 if (window->flags & SDL_WINDOW_OPENGL) {
326 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
328 /* Create the GLES window surface */
329 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
330 if (wind->egl_surface == EGL_NO_SURFACE) {
331 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
335 if (!Tizen_GLES_GetAlphaSize(_this)) {
336 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
339 wl_surface_set_opaque_region(ecore_wl_window_surface_get(wind->window), NULL);
342 //Support PreRotation
343 wind->support_pre_rotation = 0;
344 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
345 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
346 wind->support_pre_rotation = 1;
352 wind->id = ecore_wl_window_id_get(wind->window);
353 eina_hash_add(data->windows, &wind->id, window);
355 Tizen_InitKeyboard(_this);
356 SDL_SetMouseFocus(window);
358 if (window->flags & 0x00008000) {
359 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
360 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
363 EINA_INLIST_FOREACH(globals, global) {
364 if (!strcmp(global->interface, "tizen_policy_ext")) {
365 wind->rotation_supported = 1;
369 // Add orientaiton hint cb
370 _tizen_window_orientation_add_hint((void*)wind);
377 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
379 //Add setting window bordered.
383 _tizen_window_resize(SDL_Window *window)
385 SDL_WindowData *wind = window->driverdata;
386 if (!wind->egl_window) {
390 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
391 ecore_wl_window_update_size(wind->window, window->h, window->w);
393 ecore_wl_window_update_size(wind->window, window->w, window->h);
395 // TODO : consider to rotation status.
396 #if SDL_VIDEO_OPENGL_EGL
397 if (window->flags & SDL_WINDOW_OPENGL) {
398 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
399 wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
401 wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
407 _tizen_setwindowsize(SDL_Window *window)
409 SDL_WindowData *wind = window->driverdata;
416 Tizen_SetWindowSize(_THIS, SDL_Window *window)
418 _tizen_window_resize(window);
422 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
424 SDL_WindowData *wind = window->driverdata;
429 if (w) *w = window->w;
430 if (h) *h = window->h;
434 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
436 SDL_WindowData *wind = window->driverdata;
441 // TODO : consider to rotation status.
442 ecore_wl_window_position_set(wind->window, window->x, window->y);
446 Tizen_DestroyWindow(_THIS, SDL_Window *window)
448 SDL_VideoData *data = _this->driverdata;
449 SDL_WindowData *wind = window->driverdata;
452 eina_hash_del(data->windows, &wind->id, window);
453 #if SDL_VIDEO_OPENGL_EGL
454 if (window->flags & SDL_WINDOW_OPENGL) {
455 SDL_EGL_DestroySurface(_this, wind->egl_surface);
456 wl_egl_window_destroy(wind->egl_window);
459 ecore_wl_window_free(wind->window);
463 window->driverdata = NULL;
467 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
469 SDL_VideoData *data = _this->driverdata;
472 id = ecore_wl_window_id_get(ewin);
473 return (SDL_Window*)eina_hash_find(data->windows, &id);
477 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
480 Ecore_Wl_Event_Window_Visibility_Change *ev;
485 ew = ecore_wl_window_find(ev->win);
486 window = Tizen_FindWindow(_this, ew);
488 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
489 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
490 return ECORE_CALLBACK_PASS_ON;
494 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
499 SDL_WindowData *wind;
500 Ecore_Wl_Event_Window_Configure *ev;
502 ew = ecore_wl_window_find(ev->win);
503 window = Tizen_FindWindow(_this, ew);
504 wind = window->driverdata;
506 if (wind->rotation_supported == 0){
507 return ECORE_CALLBACK_PASS_ON;
510 int nx = 0, ny = 0, nw = 0, nh = 0;
511 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
513 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
517 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
518 if ((window->x != nx) || (window->y != ny))
519 ecore_wl_window_position_set(ew, nx, ny);
521 if ((window->w != nw) || (window->h != nh)) {
522 _tizen_setwindowsize(window);
525 return ECORE_CALLBACK_PASS_ON;
530 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
533 SDL_WindowData *wind;
534 wind = window->driverdata;
536 SDL_memset(&event, 0, sizeof(event));
537 event.type = SDL_ROTATEEVENT;
539 if (wind->support_pre_rotation)
540 event.user.data1 = (void*)0;
542 event.user.data1 = (void*)angle;
543 event.user.data2 = (void*)-1;
545 SDL_PushEvent(&event);
550 _tizen_set_window_size(SDL_Window * window, int w, int h)
554 SDL_SetError("Invalid window");
558 SDL_VideoDevice *_this = SDL_GetVideoDevice();
560 SDL_SetError("Video subsystem has not been initialized");
564 if (window->magic != &_this->window_magic) {
569 SDL_InvalidParamError("w");
573 SDL_InvalidParamError("h");
577 /* Make sure we don't exceed any window size limits */
578 if (window->min_w && w < window->min_w)
582 if (window->max_w && w > window->max_w)
586 if (window->min_h && h < window->min_h)
590 if (window->max_h && h > window->max_h)
595 window->windowed.w = w;
596 window->windowed.h = h;
603 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
606 Ecore_Wl_Event_Window_Rotate *ev;
609 SDL_WindowData *wind;
613 return ECORE_CALLBACK_PASS_ON;
616 ew = ecore_wl_window_find(ev->win);
617 window = Tizen_FindWindow(_this, ew);
618 wind = window->driverdata;
620 if (wind->rotation != ev->angle) {
621 /* set ecore_wayland window rotation */
622 wind->rotation = ev->angle;
623 ecore_wl_window_rotation_set(ew, ev->angle);
624 if(wind->support_pre_rotation) {
625 int window_w, window_h;
626 if(wind->rotation==90 || wind->rotation==270)
627 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
629 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
631 _tizen_set_window_size(window, window_w, window_h);
632 Tizen_pre_rotation_set(wind);
634 _tizen_send_rotation_event(window, ev->angle);
635 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
636 wind->received_rotation = 1;
639 return ECORE_CALLBACK_PASS_ON;
643 Tizen_InitWindow(_THIS)
645 SDL_VideoData *data = _this->driverdata;
647 data->windows = eina_hash_int32_new(NULL);
649 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
650 _tizen_cb_event_window_visibility_change,_this);
651 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
652 _tizen_cb_event_keyup_change,_this);
653 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
654 _tizen_cb_event_keydown_change,_this);
655 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
656 _tizen_cb_event_mousedown_change,_this);
657 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
658 _tizen_cb_event_mouseup_change,_this);
659 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
660 _tizen_cb_event_mousemove_change,_this);
661 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
662 _tizen_cb_event_window_rotate,_this);
663 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
664 _tizen_cb_window_configure,_this);
665 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
666 _tizen_cb_event_joystick_change,_this);
667 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
668 _tizen_cb_event_focus_in,_this);
669 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
670 _tizen_cb_event_focus_out,_this);
671 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
672 _tizen_cb_event_mouse_in,_this);
673 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
674 _tizen_cb_event_mouse_out,_this);
676 data->current_thread = SDL_GetThreadID(0);
682 Tizen_DeinitWindow(_THIS)
684 SDL_VideoData *data = _this->driverdata;
686 eina_hash_free(data->windows);
688 #endif /* SDL_VIDEO_DRIVER_TIZEN */
690 /* vi: set ts=4 sw=4 expandtab: */