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);
318 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window");
320 wind->surface = ecore_wl_window_surface_create(wind->window);
322 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window surface");
324 ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
327 wind->rotation_supported = 0;
328 wind->received_rotation = 0;
330 #if SDL_VIDEO_OPENGL_EGL
331 if (window->flags & SDL_WINDOW_OPENGL) {
332 wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h);
334 /* Create the GLES window surface */
335 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
336 if (wind->egl_surface == EGL_NO_SURFACE) {
337 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
341 if (!Tizen_GLES_GetAlphaSize(_this)) {
342 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
345 wl_surface_set_opaque_region(wind->surface, NULL);
348 //Support PreRotation
349 wind->support_pre_rotation = 0;
350 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
351 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
352 wind->support_pre_rotation = 1;
358 wind->id = ecore_wl_window_id_get(wind->window);
359 eina_hash_add(data->windows, &wind->id, window);
361 Tizen_InitKeyboard(_this);
362 SDL_SetMouseFocus(window);
364 if (window->flags & 0x00008000) {
365 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
366 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
369 EINA_INLIST_FOREACH(globals, global) {
370 if (!strcmp(global->interface, "tizen_policy_ext")) {
371 wind->rotation_supported = 1;
375 // Add orientaiton hint cb
376 _tizen_window_orientation_add_hint((void*)wind);
383 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
385 //Add setting window bordered.
389 _tizen_window_resize(SDL_Window *window)
391 SDL_WindowData *wind = window->driverdata;
392 if (!wind->egl_window) {
396 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
397 ecore_wl_window_update_size(wind->window, window->h, window->w);
399 ecore_wl_window_update_size(wind->window, window->w, window->h);
401 // TODO : consider to rotation status.
402 #if SDL_VIDEO_OPENGL_EGL
403 if (window->flags & SDL_WINDOW_OPENGL) {
404 if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
405 wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
407 wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
413 _tizen_setwindowsize(SDL_Window *window)
415 SDL_WindowData *wind = window->driverdata;
422 Tizen_SetWindowSize(_THIS, SDL_Window *window)
424 _tizen_window_resize(window);
428 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
430 SDL_WindowData *wind = window->driverdata;
435 if (w) *w = window->w;
436 if (h) *h = window->h;
440 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
442 SDL_WindowData *wind = window->driverdata;
447 // TODO : consider to rotation status.
448 ecore_wl_window_position_set(wind->window, window->x, window->y);
452 Tizen_DestroyWindow(_THIS, SDL_Window *window)
454 SDL_VideoData *data = _this->driverdata;
455 SDL_WindowData *wind = window->driverdata;
458 eina_hash_del(data->windows, &wind->id, window);
459 #if SDL_VIDEO_OPENGL_EGL
460 if (window->flags & SDL_WINDOW_OPENGL) {
461 SDL_EGL_DestroySurface(_this, wind->egl_surface);
462 wl_egl_window_destroy(wind->egl_window);
465 ecore_wl_window_free(wind->window);
469 window->driverdata = NULL;
473 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
475 SDL_VideoData *data = _this->driverdata;
478 id = ecore_wl_window_id_get(ewin);
479 return (SDL_Window*)eina_hash_find(data->windows, &id);
483 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
486 Ecore_Wl_Event_Window_Visibility_Change *ev;
491 ew = ecore_wl_window_find(ev->win);
492 window = Tizen_FindWindow(_this, ew);
494 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
495 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
496 return ECORE_CALLBACK_PASS_ON;
500 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
505 SDL_WindowData *wind;
506 Ecore_Wl_Event_Window_Configure *ev;
508 ew = ecore_wl_window_find(ev->win);
509 window = Tizen_FindWindow(_this, ew);
510 wind = window->driverdata;
512 if (wind->rotation_supported == 0){
513 return ECORE_CALLBACK_PASS_ON;
516 int nx = 0, ny = 0, nw = 0, nh = 0;
517 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
519 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
523 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
524 if ((window->x != nx) || (window->y != ny))
525 ecore_wl_window_position_set(ew, nx, ny);
527 if ((window->w != nw) || (window->h != nh)) {
528 _tizen_setwindowsize(window);
531 return ECORE_CALLBACK_PASS_ON;
536 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
539 SDL_WindowData *wind;
540 wind = window->driverdata;
542 SDL_memset(&event, 0, sizeof(event));
543 event.type = SDL_ROTATEEVENT;
545 if (wind->support_pre_rotation)
546 event.user.data1 = (void*)0;
548 event.user.data1 = (void*)angle;
549 event.user.data2 = (void*)-1;
551 SDL_PushEvent(&event);
556 _tizen_set_window_size(SDL_Window * window, int w, int h)
560 SDL_SetError("Invalid window");
564 SDL_VideoDevice *_this = SDL_GetVideoDevice();
566 SDL_SetError("Video subsystem has not been initialized");
570 if (window->magic != &_this->window_magic) {
575 SDL_InvalidParamError("w");
579 SDL_InvalidParamError("h");
583 /* Make sure we don't exceed any window size limits */
584 if (window->min_w && w < window->min_w)
588 if (window->max_w && w > window->max_w)
592 if (window->min_h && h < window->min_h)
596 if (window->max_h && h > window->max_h)
601 window->windowed.w = w;
602 window->windowed.h = h;
609 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
612 Ecore_Wl_Event_Window_Rotate *ev;
615 SDL_WindowData *wind;
619 return ECORE_CALLBACK_PASS_ON;
622 ew = ecore_wl_window_find(ev->win);
623 window = Tizen_FindWindow(_this, ew);
624 wind = window->driverdata;
626 if (wind->rotation != ev->angle) {
627 /* set ecore_wayland window rotation */
628 wind->rotation = ev->angle;
629 ecore_wl_window_rotation_set(ew, ev->angle);
630 if(wind->support_pre_rotation) {
631 int window_w, window_h;
632 if(wind->rotation==90 || wind->rotation==270)
633 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
635 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
637 _tizen_set_window_size(window, window_w, window_h);
638 Tizen_pre_rotation_set(wind);
640 _tizen_send_rotation_event(window, ev->angle);
641 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
642 wind->received_rotation = 1;
645 return ECORE_CALLBACK_PASS_ON;
649 Tizen_InitWindow(_THIS)
651 SDL_VideoData *data = _this->driverdata;
653 data->windows = eina_hash_int32_new(NULL);
655 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
656 _tizen_cb_event_window_visibility_change,_this);
657 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
658 _tizen_cb_event_keyup_change,_this);
659 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
660 _tizen_cb_event_keydown_change,_this);
661 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
662 _tizen_cb_event_mousedown_change,_this);
663 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
664 _tizen_cb_event_mouseup_change,_this);
665 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
666 _tizen_cb_event_mousemove_change,_this);
667 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
668 _tizen_cb_event_window_rotate,_this);
669 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
670 _tizen_cb_window_configure,_this);
671 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
672 _tizen_cb_event_joystick_change,_this);
673 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
674 _tizen_cb_event_focus_in,_this);
675 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
676 _tizen_cb_event_focus_out,_this);
677 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
678 _tizen_cb_event_mouse_in,_this);
679 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
680 _tizen_cb_event_mouse_out,_this);
682 data->current_thread = SDL_GetThreadID(0);
688 Tizen_DeinitWindow(_THIS)
690 SDL_VideoData *data = _this->driverdata;
692 eina_hash_free(data->windows);
694 #endif /* SDL_VIDEO_DRIVER_TIZEN */
696 /* vi: set ts=4 sw=4 expandtab: */