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_tizenindicator.h"
33 #include "SDL_tizenvideo.h"
34 #include "SDL_tizentouch.h"
35 #include "SDL_tizenkeyboard.h"
36 #include "SDL_tizenmouse.h"
37 #include "SDL_tizenevents_c.h"
39 #include "SDL_tizenwindow.h"
41 #include "../../events/SDL_mouse_c.h"
42 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
44 #include "../SDL_egl_c.h"
45 #include "../SDL_vulkan_c.h"
46 #include "../SDL_sysvideo.h"
47 #include "../../events/SDL_windowevents_c.h"
50 ROTATION_TYPE_NORMAL_ROTATION = 0,
51 ROTATION_TYPE_PRE_ROTATION, /* use pre-rotation */
54 #define LOAD_FUNC(NAME) \
55 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
56 if (!_this->tizen_pre_rotation_data->NAME) \
58 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
63 _tizen_rotation_type_get()
65 static int type = ROTATION_TYPE_PRE_ROTATION;
66 static int checked = 0;
69 if (checked) return type;
71 engine = getenv("SDL_ROTATION");
75 if ((!strcasecmp(engine, "normal")))
76 type = ROTATION_TYPE_NORMAL_ROTATION;
77 else if ((!strcasecmp(engine, "pre_rotation")))
78 type = ROTATION_TYPE_PRE_ROTATION;
80 type = ROTATION_TYPE_PRE_ROTATION;
87 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
89 void *lib_dll_handle = NULL;
92 if (_this->isLoaded_pre_rotation)
95 _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
96 if (!_this->tizen_pre_rotation_data) {
97 return SDL_OutOfMemory();
101 lib_dll_handle = SDL_LoadObject(lib_path);
103 if (!lib_dll_handle) {
104 path = "libwayland-egl.so";
105 lib_dll_handle = SDL_LoadObject(path);
108 _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
110 if (lib_dll_handle == NULL)
113 LOAD_FUNC(wl_egl_window_set_rotation);
114 LOAD_FUNC(wl_egl_window_get_capabilities);
115 _this->isLoaded_pre_rotation = 1;
121 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
123 SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
124 info->info.tizen.egl_display = NULL;
125 info->info.tizen.egl_surface = NULL;
126 #if SDL_VIDEO_OPENGL_EGL
129 info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
131 info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
133 info->subsystem = SDL_SYSWM_TIZEN;
138 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
140 return 0; /* just succeed, the real work is done elsewhere. */
144 Tizen_ShowWindow(_THIS, SDL_Window *window)
146 SDL_WindowData *wind = window->driverdata;
147 ecore_wl_window_show(wind->window);
151 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
152 SDL_VideoDisplay *_display, SDL_bool fullscreen)
158 Tizen_pre_rotation_set(SDL_WindowData *_this)
160 tizen_wl_egl_window_rotation rot;
161 if (!_this->egl_window) return;
163 switch (_this->rotation) {
165 rot = TIZEN_ROTATION_270;
168 rot = TIZEN_ROTATION_180;
171 rot = TIZEN_ROTATION_90;
174 rot = TIZEN_ROTATION_0;
177 rot = TIZEN_ROTATION_0;
181 _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
185 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
188 char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
189 int checked[4] = {0,};
192 SDL_WindowData *wind = (SDL_WindowData*)userdata;
193 Ecore_Wl_Window *window = wind->window;
195 if (wind->rotation_supported == 0) {
199 SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
201 if ((oldValue == NULL) && (newValue == NULL)) {
206 p_str = SDL_strstr(newValue, orientation_type[i]);
208 if (p_str == newValue) {
211 else if (i == 1) rot = 90;
212 else if (i == 2) rot = 180;
213 else if (i == 3) rot = 270;
214 wind->rotation = rot;
235 ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
236 if (wind->support_pre_rotation) {
237 Tizen_pre_rotation_set(wind);
240 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
245 _tizen_window_orientation_add_hint(void *data)
247 SDL_WindowData *wind = (SDL_WindowData*)data;
248 if (wind->rotation_supported == 0) {
252 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
256 Tizen_CreateWindow(_THIS, SDL_Window *window)
258 SDL_VideoData *data = _this->driverdata;
259 SDL_WindowData *wind;
260 Ecore_Wl_Global *global;
261 Eina_Inlist *globals;
263 wind = calloc(1, sizeof * wind);
265 return SDL_OutOfMemory();
268 window->driverdata = wind;
269 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
270 window->flags |= SDL_WINDOW_BORDERLESS; /* defalut - not support indicator*/
272 #if SDL_VIDEO_OPENGL_EGL
273 if (window->flags & SDL_WINDOW_OPENGL) {
274 SDL_GL_LoadLibrary(NULL);
279 if (window->flags & SDL_WINDOW_VULKAN) {
280 if (!_this->vulkan_GetInstanceExtensions) {
281 SDL_SetError("No Vulkan support in video driver");
284 if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
285 SDL_SetError("Fail to load Vulkan Library");
290 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
293 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
297 if (!(globals = ecore_wl_globals_get()))
299 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
303 wind->window = ecore_wl_window_new(NULL,
304 window->x, window->y, window->w, window->h,
305 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
306 wind->surface = ecore_wl_window_surface_create(wind->window);
308 wind->rotation_supported = 0;
309 wind->received_rotation = 0;
310 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
312 #if SDL_VIDEO_OPENGL_EGL
313 if (window->flags & SDL_WINDOW_OPENGL) {
314 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
316 /* Create the GLES window surface */
317 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
318 if (wind->egl_surface == EGL_NO_SURFACE) {
319 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
323 //Support PreRotation
324 wind->support_pre_rotation = 0;
325 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
326 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
327 wind->support_pre_rotation = 1;
333 wind->id = ecore_wl_window_id_get(wind->window);
334 eina_hash_add(data->windows, &wind->id, window);
336 Tizen_InitKeyboard(_this);
337 SDL_SetMouseFocus(window);
339 if (window->flags & 0x00008000) {
340 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
341 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
344 EINA_INLIST_FOREACH(globals, global) {
345 if (!strcmp(global->interface, "tizen_policy_ext")) {
346 wind->rotation_supported = 1;
350 // Add orientaiton hint cb
351 _tizen_window_orientation_add_hint((void*)wind);
357 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
359 //Add setting window bordered.
363 _tizen_egl_window_resize(SDL_Window *window)
365 SDL_WindowData *wind = window->driverdata;
366 if (!wind->egl_window) {
370 // TODO : consider to rotation status.
371 #if SDL_VIDEO_OPENGL_EGL
372 if (window->flags & SDL_WINDOW_OPENGL) {
373 // TODO : if window size is not FULL, we need the code about Non FullSize Window.
375 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
376 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
383 _tizen_setwindowsize(SDL_Window *window)
385 SDL_WindowData *wind = window->driverdata;
389 ecore_wl_window_update_size(wind->window, window->w, window->h);
393 Tizen_SetWindowSize(_THIS, SDL_Window *window)
395 // _tizen_setwindowsize(window);
396 // _tizen_egl_window_resize(window);
400 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
402 SDL_WindowData *wind = window->driverdata;
407 if (w) *w = window->w;
408 if (h) *h = window->h;
412 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
414 SDL_WindowData *wind = window->driverdata;
419 // TODO : consider to rotation status.
420 ecore_wl_window_position_set(wind->window, window->x, window->y);
424 Tizen_DestroyWindow(_THIS, SDL_Window *window)
426 SDL_VideoData *data = _this->driverdata;
427 SDL_WindowData *wind = window->driverdata;
430 eina_hash_del(data->windows, &wind->id, window);
431 #if SDL_VIDEO_OPENGL_EGL
432 if (window->flags & SDL_WINDOW_OPENGL) {
433 SDL_EGL_DestroySurface(_this, wind->egl_surface);
434 wl_egl_window_destroy(wind->egl_window);
437 ecore_wl_window_free(wind->window);
441 window->driverdata = NULL;
445 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
447 SDL_VideoData *data = _this->driverdata;
450 id = ecore_wl_window_id_get(ewin);
451 return (SDL_Window*)eina_hash_find(data->windows, &id);
455 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
458 Ecore_Wl_Event_Window_Visibility_Change *ev;
463 ew = ecore_wl_window_find(ev->win);
464 window = Tizen_FindWindow(_this, ew);
466 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
467 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
468 return ECORE_CALLBACK_PASS_ON;
472 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
477 SDL_WindowData *wind;
478 Ecore_Wl_Event_Window_Configure *ev;
480 ew = ecore_wl_window_find(ev->win);
481 window = Tizen_FindWindow(_this, ew);
482 wind = window->driverdata;
484 if (wind->rotation_supported == 0){
485 return ECORE_CALLBACK_PASS_ON;
488 int nx = 0, ny = 0, nw = 0, nh = 0;
489 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
491 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
495 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
496 if ((window->x != nx) || (window->y != ny))
497 ecore_wl_window_position_set(ew, nx, ny);
499 if ((window->w != nw) || (window->h != nh)) {
500 _tizen_setwindowsize(window);
503 return ECORE_CALLBACK_PASS_ON;
508 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
511 SDL_WindowData *wind;
512 wind = window->driverdata;
514 SDL_memset(&event, 0, sizeof(event));
515 event.type = SDL_ROTATEEVENT;
517 if (wind->support_pre_rotation)
518 event.user.data1 = (void*)0;
520 event.user.data1 = (void*)angle;
521 event.user.data2 = (void*)-1;
523 SDL_PushEvent(&event);
528 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
531 Ecore_Wl_Event_Window_Rotate *ev;
534 SDL_WindowData *wind;
538 return ECORE_CALLBACK_PASS_ON;
541 ew = ecore_wl_window_find(ev->win);
542 window = Tizen_FindWindow(_this, ew);
543 wind = window->driverdata;
545 if (wind->rotation != ev->angle) {
546 /* set ecore_wayland window rotation */
547 wind->rotation = ev->angle;
548 ecore_wl_window_rotation_set(ew, ev->angle);
549 // Send Rotation Event
550 _tizen_send_rotation_event(window, ev->angle);
553 wind->received_rotation = 1;
554 return ECORE_CALLBACK_PASS_ON;
558 Tizen_InitWindow(_THIS)
560 SDL_VideoData *data = _this->driverdata;
562 data->windows = eina_hash_int32_new(NULL);
564 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
565 _tizen_cb_event_window_visibility_change,_this);
566 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
567 _tizen_cb_event_keyup_change,_this);
568 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
569 _tizen_cb_event_keydown_change,_this);
570 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
571 _tizen_cb_event_mousedown_change,_this);
572 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
573 _tizen_cb_event_mouseup_change,_this);
574 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
575 _tizen_cb_event_mousemove_change,_this);
576 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
577 _tizen_cb_event_window_rotate,_this);
578 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
579 _tizen_cb_window_configure,_this);
580 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
581 _tizen_cb_event_joystick_change,_this);
582 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
583 _tizen_cb_event_focus_in,_this);
584 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
585 _tizen_cb_event_focus_out,_this);
586 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
587 _tizen_cb_event_mouse_in,_this);
588 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
589 _tizen_cb_event_mouse_out,_this);
591 data->current_thread = SDL_GetThreadID(0);
597 Tizen_DeinitWindow(_THIS)
599 SDL_VideoData *data = _this->driverdata;
601 eina_hash_free(data->windows);
603 #endif /* SDL_VIDEO_DRIVER_TIZEN */
605 /* vi: set ts=4 sw=4 expandtab: */