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"
39 #include "../../events/SDL_mouse_c.h"
40 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
42 #include "../SDL_egl_c.h"
43 #include "../SDL_vulkan_c.h"
44 #include "../SDL_sysvideo.h"
45 #include "../../events/SDL_windowevents_c.h"
48 ROTATION_TYPE_NORMAL_ROTATION = 0,
49 ROTATION_TYPE_PRE_ROTATION, /* use pre-rotation */
52 #define LOAD_FUNC(NAME) \
53 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
54 if (!_this->tizen_pre_rotation_data->NAME) \
56 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
61 _tizen_rotation_type_get()
63 static int type = ROTATION_TYPE_PRE_ROTATION;
64 static int checked = 0;
67 if (checked) return type;
69 engine = getenv("SDL_ROTATION");
73 if ((!strcasecmp(engine, "normal")))
74 type = ROTATION_TYPE_NORMAL_ROTATION;
75 else if ((!strcasecmp(engine, "pre_rotation")))
76 type = ROTATION_TYPE_PRE_ROTATION;
78 type = ROTATION_TYPE_PRE_ROTATION;
85 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
87 void *lib_dll_handle = NULL;
90 if (_this->isLoaded_pre_rotation)
93 _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
94 if (!_this->tizen_pre_rotation_data) {
95 return SDL_OutOfMemory();
99 lib_dll_handle = SDL_LoadObject(lib_path);
101 if (!lib_dll_handle) {
102 path = "libwayland-egl.so";
103 lib_dll_handle = SDL_LoadObject(path);
106 _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
108 if (lib_dll_handle == NULL)
111 LOAD_FUNC(wl_egl_window_set_rotation);
112 LOAD_FUNC(wl_egl_window_get_capabilities);
113 _this->isLoaded_pre_rotation = 1;
119 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
121 SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
122 info->info.tizen.egl_display = NULL;
123 info->info.tizen.egl_surface = NULL;
124 #if SDL_VIDEO_OPENGL_EGL
127 info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
129 info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
131 info->subsystem = SDL_SYSWM_TIZEN;
136 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
138 return 0; /* just succeed, the real work is done elsewhere. */
142 Tizen_ShowWindow(_THIS, SDL_Window *window)
144 SDL_WindowData *wind = window->driverdata;
146 if((window->flags & SDL_WINDOW_FULLSCREEN) || (window->flags & SDL_WINDOW_BORDERLESS))
148 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_OFF);
149 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_TRANSPARENT);
150 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_HIDDEN);
154 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
155 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
156 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
158 ecore_wl_window_show(wind->window);
162 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
163 SDL_VideoDisplay *_display, SDL_bool fullscreen)
169 Tizen_pre_rotation_set(SDL_WindowData *_this)
171 tizen_wl_egl_window_rotation rot;
172 if (!_this->egl_window) return;
174 switch (_this->rotation) {
176 rot = TIZEN_ROTATION_270;
179 rot = TIZEN_ROTATION_180;
182 rot = TIZEN_ROTATION_90;
185 rot = TIZEN_ROTATION_0;
188 rot = TIZEN_ROTATION_0;
192 _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
196 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
199 char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
200 int checked[4] = {0,};
203 SDL_WindowData *wind = (SDL_WindowData*)userdata;
204 Ecore_Wl_Window *window = wind->window;
206 if (wind->rotation_supported == 0) {
210 SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
212 if ((oldValue == NULL) && (newValue == NULL)) {
217 p_str = SDL_strstr(newValue, orientation_type[i]);
219 if (p_str == newValue) {
222 else if (i == 1) rot = 90;
223 else if (i == 2) rot = 180;
224 else if (i == 3) rot = 270;
225 wind->rotation = rot;
246 ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
247 if (wind->support_pre_rotation)
248 Tizen_pre_rotation_set(wind);
250 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
256 _tizen_window_orientation_add_hint(void *data)
258 SDL_WindowData *wind = (SDL_WindowData*)data;
259 if (wind->rotation_supported == 0) {
263 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
267 Tizen_CreateWindow(_THIS, SDL_Window *window)
269 SDL_VideoData *data = _this->driverdata;
270 SDL_WindowData *wind;
271 Ecore_Wl_Global *global;
272 Eina_Inlist *globals;
274 wind = calloc(1, sizeof * wind);
276 return SDL_OutOfMemory();
279 window->driverdata = wind;
280 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
282 #if SDL_VIDEO_OPENGL_EGL
283 if (window->flags & SDL_WINDOW_OPENGL) {
284 SDL_GL_LoadLibrary(NULL);
289 if (window->flags & SDL_WINDOW_VULKAN) {
290 if (!_this->vulkan_GetInstanceExtensions) {
291 SDL_SetError("No Vulkan support in video driver");
294 if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
295 SDL_SetError("Fail to load Vulkan Library");
300 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
303 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
307 if (!(globals = ecore_wl_globals_get()))
309 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
313 wind->window = ecore_wl_window_new(NULL,
314 window->x, window->y, window->w, window->h,
315 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
316 wind->surface = ecore_wl_window_surface_create(wind->window);
317 ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
320 wind->rotation_supported = 0;
321 wind->received_rotation = 0;
323 #if SDL_VIDEO_OPENGL_EGL
324 if (window->flags & SDL_WINDOW_OPENGL) {
325 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
327 /* Create the GLES window surface */
328 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
329 if (wind->egl_surface == EGL_NO_SURFACE) {
330 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
334 if (!Tizen_GLES_GetAlphaSize(_this)) {
335 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
338 wl_surface_set_opaque_region(ecore_wl_window_surface_get(wind->window), NULL);
341 //Support PreRotation
342 wind->support_pre_rotation = 0;
343 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
344 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
345 wind->support_pre_rotation = 1;
351 wind->id = ecore_wl_window_id_get(wind->window);
352 eina_hash_add(data->windows, &wind->id, window);
354 Tizen_InitKeyboard(_this);
355 SDL_SetMouseFocus(window);
357 if (window->flags & 0x00008000) {
358 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
359 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
362 EINA_INLIST_FOREACH(globals, global) {
363 if (!strcmp(global->interface, "tizen_policy_ext")) {
364 wind->rotation_supported = 1;
368 // Add orientaiton hint cb
369 _tizen_window_orientation_add_hint((void*)wind);
376 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
378 //Add setting window bordered.
382 _tizen_window_resize(SDL_Window *window)
384 SDL_WindowData *wind = window->driverdata;
385 if (!wind->egl_window) {
389 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
390 ecore_wl_window_update_size(wind->window, window->h, window->w);
392 ecore_wl_window_update_size(wind->window, window->w, window->h);
394 // TODO : consider to rotation status.
395 #if SDL_VIDEO_OPENGL_EGL
396 if (window->flags & SDL_WINDOW_OPENGL) {
397 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
398 wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
400 wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
406 _tizen_setwindowsize(SDL_Window *window)
408 SDL_WindowData *wind = window->driverdata;
415 Tizen_SetWindowSize(_THIS, SDL_Window *window)
417 _tizen_window_resize(window);
421 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
423 SDL_WindowData *wind = window->driverdata;
428 if (w) *w = window->w;
429 if (h) *h = window->h;
433 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
435 SDL_WindowData *wind = window->driverdata;
440 // TODO : consider to rotation status.
441 ecore_wl_window_position_set(wind->window, window->x, window->y);
445 Tizen_DestroyWindow(_THIS, SDL_Window *window)
447 SDL_VideoData *data = _this->driverdata;
448 SDL_WindowData *wind = window->driverdata;
451 eina_hash_del(data->windows, &wind->id, window);
452 #if SDL_VIDEO_OPENGL_EGL
453 if (window->flags & SDL_WINDOW_OPENGL) {
454 SDL_EGL_DestroySurface(_this, wind->egl_surface);
455 wl_egl_window_destroy(wind->egl_window);
458 ecore_wl_window_free(wind->window);
462 window->driverdata = NULL;
466 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
468 SDL_VideoData *data = _this->driverdata;
471 id = ecore_wl_window_id_get(ewin);
472 return (SDL_Window*)eina_hash_find(data->windows, &id);
476 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
479 Ecore_Wl_Event_Window_Visibility_Change *ev;
484 ew = ecore_wl_window_find(ev->win);
485 window = Tizen_FindWindow(_this, ew);
487 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
488 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
489 return ECORE_CALLBACK_PASS_ON;
493 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
498 SDL_WindowData *wind;
499 Ecore_Wl_Event_Window_Configure *ev;
501 ew = ecore_wl_window_find(ev->win);
502 window = Tizen_FindWindow(_this, ew);
503 wind = window->driverdata;
505 if (wind->rotation_supported == 0){
506 return ECORE_CALLBACK_PASS_ON;
509 int nx = 0, ny = 0, nw = 0, nh = 0;
510 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
512 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
516 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
517 if ((window->x != nx) || (window->y != ny))
518 ecore_wl_window_position_set(ew, nx, ny);
520 if ((window->w != nw) || (window->h != nh)) {
521 _tizen_setwindowsize(window);
524 return ECORE_CALLBACK_PASS_ON;
529 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
532 SDL_WindowData *wind;
533 wind = window->driverdata;
535 SDL_memset(&event, 0, sizeof(event));
536 event.type = SDL_ROTATEEVENT;
538 if (wind->support_pre_rotation)
539 event.user.data1 = (void*)0;
541 event.user.data1 = (void*)angle;
542 event.user.data2 = (void*)-1;
544 SDL_PushEvent(&event);
549 _tizen_set_window_size(SDL_Window * window, int w, int h)
553 SDL_SetError("Invalid window");
557 SDL_VideoDevice *_this = SDL_GetVideoDevice();
559 SDL_SetError("Video subsystem has not been initialized");
563 if (window->magic != &_this->window_magic) {
568 SDL_InvalidParamError("w");
572 SDL_InvalidParamError("h");
576 /* Make sure we don't exceed any window size limits */
577 if (window->min_w && w < window->min_w)
581 if (window->max_w && w > window->max_w)
585 if (window->min_h && h < window->min_h)
589 if (window->max_h && h > window->max_h)
594 window->windowed.w = w;
595 window->windowed.h = h;
602 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
605 Ecore_Wl_Event_Window_Rotate *ev;
608 SDL_WindowData *wind;
612 return ECORE_CALLBACK_PASS_ON;
615 ew = ecore_wl_window_find(ev->win);
616 window = Tizen_FindWindow(_this, ew);
617 wind = window->driverdata;
619 if (wind->rotation != ev->angle) {
620 /* set ecore_wayland window rotation */
621 wind->rotation = ev->angle;
622 ecore_wl_window_rotation_set(ew, ev->angle);
623 if(wind->support_pre_rotation) {
624 int window_w, window_h;
625 if(wind->rotation==90 || wind->rotation==270)
626 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
628 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
630 _tizen_set_window_size(window, window_w, window_h);
631 Tizen_pre_rotation_set(wind);
633 _tizen_send_rotation_event(window, ev->angle);
634 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
635 wind->received_rotation = 1;
638 return ECORE_CALLBACK_PASS_ON;
642 Tizen_InitWindow(_THIS)
644 SDL_VideoData *data = _this->driverdata;
646 data->windows = eina_hash_int32_new(NULL);
648 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
649 _tizen_cb_event_window_visibility_change,_this);
650 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
651 _tizen_cb_event_keyup_change,_this);
652 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
653 _tizen_cb_event_keydown_change,_this);
654 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
655 _tizen_cb_event_mousedown_change,_this);
656 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
657 _tizen_cb_event_mouseup_change,_this);
658 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
659 _tizen_cb_event_mousemove_change,_this);
660 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
661 _tizen_cb_event_window_rotate,_this);
662 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
663 _tizen_cb_window_configure,_this);
664 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
665 _tizen_cb_event_joystick_change,_this);
666 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
667 _tizen_cb_event_focus_in,_this);
668 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
669 _tizen_cb_event_focus_out,_this);
670 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
671 _tizen_cb_event_mouse_in,_this);
672 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
673 _tizen_cb_event_mouse_out,_this);
675 data->current_thread = SDL_GetThreadID(0);
681 Tizen_DeinitWindow(_THIS)
683 SDL_VideoData *data = _this->driverdata;
685 eina_hash_free(data->windows);
687 #endif /* SDL_VIDEO_DRIVER_TIZEN */
689 /* vi: set ts=4 sw=4 expandtab: */