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;
322 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
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 //Support PreRotation
336 wind->support_pre_rotation = 0;
337 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
338 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
339 wind->support_pre_rotation = 1;
345 wind->id = ecore_wl_window_id_get(wind->window);
346 eina_hash_add(data->windows, &wind->id, window);
348 Tizen_InitKeyboard(_this);
349 SDL_SetMouseFocus(window);
351 if (window->flags & 0x00008000) {
352 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
353 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
356 EINA_INLIST_FOREACH(globals, global) {
357 if (!strcmp(global->interface, "tizen_policy_ext")) {
358 wind->rotation_supported = 1;
362 // Add orientaiton hint cb
363 _tizen_window_orientation_add_hint((void*)wind);
370 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
372 //Add setting window bordered.
376 _tizen_window_resize(SDL_Window *window)
378 SDL_WindowData *wind = window->driverdata;
379 if (!wind->egl_window) {
383 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
384 ecore_wl_window_update_size(wind->window, window->h, window->w);
386 ecore_wl_window_update_size(wind->window, window->w, window->h);
388 // TODO : consider to rotation status.
389 #if SDL_VIDEO_OPENGL_EGL
390 if (window->flags & SDL_WINDOW_OPENGL) {
391 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
392 wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
394 wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
400 _tizen_setwindowsize(SDL_Window *window)
402 SDL_WindowData *wind = window->driverdata;
409 Tizen_SetWindowSize(_THIS, SDL_Window *window)
411 _tizen_window_resize(window);
415 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
417 SDL_WindowData *wind = window->driverdata;
422 if (w) *w = window->w;
423 if (h) *h = window->h;
427 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
429 SDL_WindowData *wind = window->driverdata;
434 // TODO : consider to rotation status.
435 ecore_wl_window_position_set(wind->window, window->x, window->y);
439 Tizen_DestroyWindow(_THIS, SDL_Window *window)
441 SDL_VideoData *data = _this->driverdata;
442 SDL_WindowData *wind = window->driverdata;
445 eina_hash_del(data->windows, &wind->id, window);
446 #if SDL_VIDEO_OPENGL_EGL
447 if (window->flags & SDL_WINDOW_OPENGL) {
448 SDL_EGL_DestroySurface(_this, wind->egl_surface);
449 wl_egl_window_destroy(wind->egl_window);
452 ecore_wl_window_free(wind->window);
456 window->driverdata = NULL;
460 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
462 SDL_VideoData *data = _this->driverdata;
465 id = ecore_wl_window_id_get(ewin);
466 return (SDL_Window*)eina_hash_find(data->windows, &id);
470 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
473 Ecore_Wl_Event_Window_Visibility_Change *ev;
478 ew = ecore_wl_window_find(ev->win);
479 window = Tizen_FindWindow(_this, ew);
481 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
482 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
483 return ECORE_CALLBACK_PASS_ON;
487 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
492 SDL_WindowData *wind;
493 Ecore_Wl_Event_Window_Configure *ev;
495 ew = ecore_wl_window_find(ev->win);
496 window = Tizen_FindWindow(_this, ew);
497 wind = window->driverdata;
499 if (wind->rotation_supported == 0){
500 return ECORE_CALLBACK_PASS_ON;
503 int nx = 0, ny = 0, nw = 0, nh = 0;
504 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
506 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
510 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
511 if ((window->x != nx) || (window->y != ny))
512 ecore_wl_window_position_set(ew, nx, ny);
514 if ((window->w != nw) || (window->h != nh)) {
515 _tizen_setwindowsize(window);
518 return ECORE_CALLBACK_PASS_ON;
523 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
526 SDL_WindowData *wind;
527 wind = window->driverdata;
529 SDL_memset(&event, 0, sizeof(event));
530 event.type = SDL_ROTATEEVENT;
532 if (wind->support_pre_rotation)
533 event.user.data1 = (void*)0;
535 event.user.data1 = (void*)angle;
536 event.user.data2 = (void*)-1;
538 SDL_PushEvent(&event);
543 _tizen_set_window_size(SDL_Window * window, int w, int h)
547 SDL_SetError("Invalid window");
551 SDL_VideoDevice *_this = SDL_GetVideoDevice();
553 SDL_SetError("Video subsystem has not been initialized");
557 if (window->magic != &_this->window_magic) {
562 SDL_InvalidParamError("w");
566 SDL_InvalidParamError("h");
570 /* Make sure we don't exceed any window size limits */
571 if (window->min_w && w < window->min_w)
575 if (window->max_w && w > window->max_w)
579 if (window->min_h && h < window->min_h)
583 if (window->max_h && h > window->max_h)
588 window->windowed.w = w;
589 window->windowed.h = h;
596 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
599 Ecore_Wl_Event_Window_Rotate *ev;
602 SDL_WindowData *wind;
606 return ECORE_CALLBACK_PASS_ON;
609 ew = ecore_wl_window_find(ev->win);
610 window = Tizen_FindWindow(_this, ew);
611 wind = window->driverdata;
613 if (wind->rotation != ev->angle) {
614 /* set ecore_wayland window rotation */
615 wind->rotation = ev->angle;
616 ecore_wl_window_rotation_set(ew, ev->angle);
617 if(wind->support_pre_rotation) {
618 int window_w, window_h;
619 if(wind->rotation==90 || wind->rotation==270)
620 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
622 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
624 _tizen_set_window_size(window, window_w, window_h);
625 Tizen_pre_rotation_set(wind);
627 _tizen_send_rotation_event(window, ev->angle);
628 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
629 wind->received_rotation = 1;
632 return ECORE_CALLBACK_PASS_ON;
636 Tizen_InitWindow(_THIS)
638 SDL_VideoData *data = _this->driverdata;
640 data->windows = eina_hash_int32_new(NULL);
642 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
643 _tizen_cb_event_window_visibility_change,_this);
644 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
645 _tizen_cb_event_keyup_change,_this);
646 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
647 _tizen_cb_event_keydown_change,_this);
648 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
649 _tizen_cb_event_mousedown_change,_this);
650 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
651 _tizen_cb_event_mouseup_change,_this);
652 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
653 _tizen_cb_event_mousemove_change,_this);
654 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
655 _tizen_cb_event_window_rotate,_this);
656 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
657 _tizen_cb_window_configure,_this);
658 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
659 _tizen_cb_event_joystick_change,_this);
660 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
661 _tizen_cb_event_focus_in,_this);
662 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
663 _tizen_cb_event_focus_out,_this);
664 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
665 _tizen_cb_event_mouse_in,_this);
666 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
667 _tizen_cb_event_mouse_out,_this);
669 data->current_thread = SDL_GetThreadID(0);
675 Tizen_DeinitWindow(_THIS)
677 SDL_VideoData *data = _this->driverdata;
679 eina_hash_free(data->windows);
681 #endif /* SDL_VIDEO_DRIVER_TIZEN */
683 /* vi: set ts=4 sw=4 expandtab: */