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;
145 ecore_wl_window_show(wind->window);
149 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
150 SDL_VideoDisplay *_display, SDL_bool fullscreen)
156 Tizen_pre_rotation_set(SDL_WindowData *_this)
158 tizen_wl_egl_window_rotation rot;
159 if (!_this->egl_window) return;
161 switch (_this->rotation) {
163 rot = TIZEN_ROTATION_270;
166 rot = TIZEN_ROTATION_180;
169 rot = TIZEN_ROTATION_90;
172 rot = TIZEN_ROTATION_0;
175 rot = TIZEN_ROTATION_0;
179 _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
183 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
186 char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
187 int checked[4] = {0,};
190 SDL_WindowData *wind = (SDL_WindowData*)userdata;
191 Ecore_Wl_Window *window = wind->window;
193 if (wind->rotation_supported == 0) {
197 SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
199 if ((oldValue == NULL) && (newValue == NULL)) {
204 p_str = SDL_strstr(newValue, orientation_type[i]);
206 if (p_str == newValue) {
209 else if (i == 1) rot = 90;
210 else if (i == 2) rot = 180;
211 else if (i == 3) rot = 270;
212 wind->rotation = rot;
233 ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
234 if (wind->support_pre_rotation) {
235 Tizen_pre_rotation_set(wind);
238 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
243 _tizen_window_orientation_add_hint(void *data)
245 SDL_WindowData *wind = (SDL_WindowData*)data;
246 if (wind->rotation_supported == 0) {
250 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
254 Tizen_CreateWindow(_THIS, SDL_Window *window)
256 SDL_VideoData *data = _this->driverdata;
257 SDL_WindowData *wind;
258 Ecore_Wl_Global *global;
259 Eina_Inlist *globals;
261 wind = calloc(1, sizeof * wind);
263 return SDL_OutOfMemory();
266 window->driverdata = wind;
267 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
268 window->flags |= SDL_WINDOW_BORDERLESS; /* defalut - not support indicator*/
270 #if SDL_VIDEO_OPENGL_EGL
271 if (window->flags & SDL_WINDOW_OPENGL) {
272 SDL_GL_LoadLibrary(NULL);
277 if (window->flags & SDL_WINDOW_VULKAN) {
278 if (!_this->vulkan_GetInstanceExtensions) {
279 SDL_SetError("No Vulkan support in video driver");
282 if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
283 SDL_SetError("Fail to load Vulkan Library");
288 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
291 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
295 if (!(globals = ecore_wl_globals_get()))
297 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
301 wind->window = ecore_wl_window_new(NULL,
302 window->x, window->y, window->w, window->h,
303 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
304 wind->surface = ecore_wl_window_surface_create(wind->window);
306 wind->rotation_supported = 0;
307 wind->received_rotation = 0;
308 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
310 #if SDL_VIDEO_OPENGL_EGL
311 if (window->flags & SDL_WINDOW_OPENGL) {
312 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
314 /* Create the GLES window surface */
315 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
316 if (wind->egl_surface == EGL_NO_SURFACE) {
317 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
321 //Support PreRotation
322 wind->support_pre_rotation = 0;
323 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
324 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
325 wind->support_pre_rotation = 1;
331 wind->id = ecore_wl_window_id_get(wind->window);
332 eina_hash_add(data->windows, &wind->id, window);
334 Tizen_InitKeyboard(_this);
335 SDL_SetMouseFocus(window);
337 if (window->flags & 0x00008000) {
338 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
339 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
342 EINA_INLIST_FOREACH(globals, global) {
343 if (!strcmp(global->interface, "tizen_policy_ext")) {
344 wind->rotation_supported = 1;
348 // Add orientaiton hint cb
349 _tizen_window_orientation_add_hint((void*)wind);
355 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
357 //Add setting window bordered.
361 _tizen_egl_window_resize(SDL_Window *window)
363 SDL_WindowData *wind = window->driverdata;
364 if (!wind->egl_window) {
368 // TODO : consider to rotation status.
369 #if SDL_VIDEO_OPENGL_EGL
370 if (window->flags & SDL_WINDOW_OPENGL) {
371 // TODO : if window size is not FULL, we need the code about Non FullSize Window.
373 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
374 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
381 _tizen_setwindowsize(SDL_Window *window)
383 SDL_WindowData *wind = window->driverdata;
387 ecore_wl_window_update_size(wind->window, window->w, window->h);
391 Tizen_SetWindowSize(_THIS, SDL_Window *window)
393 // _tizen_setwindowsize(window);
394 // _tizen_egl_window_resize(window);
398 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
400 SDL_WindowData *wind = window->driverdata;
405 if (w) *w = window->w;
406 if (h) *h = window->h;
410 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
412 SDL_WindowData *wind = window->driverdata;
417 // TODO : consider to rotation status.
418 ecore_wl_window_position_set(wind->window, window->x, window->y);
422 Tizen_DestroyWindow(_THIS, SDL_Window *window)
424 SDL_VideoData *data = _this->driverdata;
425 SDL_WindowData *wind = window->driverdata;
428 eina_hash_del(data->windows, &wind->id, window);
429 #if SDL_VIDEO_OPENGL_EGL
430 if (window->flags & SDL_WINDOW_OPENGL) {
431 SDL_EGL_DestroySurface(_this, wind->egl_surface);
432 wl_egl_window_destroy(wind->egl_window);
435 ecore_wl_window_free(wind->window);
439 window->driverdata = NULL;
443 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
445 SDL_VideoData *data = _this->driverdata;
448 id = ecore_wl_window_id_get(ewin);
449 return (SDL_Window*)eina_hash_find(data->windows, &id);
453 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
456 Ecore_Wl_Event_Window_Visibility_Change *ev;
461 ew = ecore_wl_window_find(ev->win);
462 window = Tizen_FindWindow(_this, ew);
464 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
465 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
466 return ECORE_CALLBACK_PASS_ON;
470 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
475 SDL_WindowData *wind;
476 Ecore_Wl_Event_Window_Configure *ev;
478 ew = ecore_wl_window_find(ev->win);
479 window = Tizen_FindWindow(_this, ew);
480 wind = window->driverdata;
482 if (wind->rotation_supported == 0){
483 return ECORE_CALLBACK_PASS_ON;
486 int nx = 0, ny = 0, nw = 0, nh = 0;
487 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
489 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
493 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
494 if ((window->x != nx) || (window->y != ny))
495 ecore_wl_window_position_set(ew, nx, ny);
497 if ((window->w != nw) || (window->h != nh)) {
498 _tizen_setwindowsize(window);
501 return ECORE_CALLBACK_PASS_ON;
506 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
509 SDL_WindowData *wind;
510 wind = window->driverdata;
512 SDL_memset(&event, 0, sizeof(event));
513 event.type = SDL_ROTATEEVENT;
515 if (wind->support_pre_rotation)
516 event.user.data1 = (void*)0;
518 event.user.data1 = (void*)angle;
519 event.user.data2 = (void*)-1;
521 SDL_PushEvent(&event);
526 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
529 Ecore_Wl_Event_Window_Rotate *ev;
532 SDL_WindowData *wind;
536 return ECORE_CALLBACK_PASS_ON;
539 ew = ecore_wl_window_find(ev->win);
540 window = Tizen_FindWindow(_this, ew);
541 wind = window->driverdata;
543 if (wind->rotation != ev->angle) {
544 /* set ecore_wayland window rotation */
545 wind->rotation = ev->angle;
546 ecore_wl_window_rotation_set(ew, ev->angle);
547 // Send Rotation Event
548 _tizen_send_rotation_event(window, ev->angle);
551 wind->received_rotation = 1;
552 return ECORE_CALLBACK_PASS_ON;
556 Tizen_InitWindow(_THIS)
558 SDL_VideoData *data = _this->driverdata;
560 data->windows = eina_hash_int32_new(NULL);
562 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
563 _tizen_cb_event_window_visibility_change,_this);
564 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
565 _tizen_cb_event_keyup_change,_this);
566 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
567 _tizen_cb_event_keydown_change,_this);
568 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
569 _tizen_cb_event_mousedown_change,_this);
570 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
571 _tizen_cb_event_mouseup_change,_this);
572 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
573 _tizen_cb_event_mousemove_change,_this);
574 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
575 _tizen_cb_event_window_rotate,_this);
576 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
577 _tizen_cb_window_configure,_this);
578 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
579 _tizen_cb_event_joystick_change,_this);
580 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
581 _tizen_cb_event_focus_in,_this);
582 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
583 _tizen_cb_event_focus_out,_this);
584 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
585 _tizen_cb_event_mouse_in,_this);
586 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
587 _tizen_cb_event_mouse_out,_this);
589 data->current_thread = SDL_GetThreadID(0);
595 Tizen_DeinitWindow(_THIS)
597 SDL_VideoData *data = _this->driverdata;
599 eina_hash_free(data->windows);
601 #endif /* SDL_VIDEO_DRIVER_TIZEN */
603 /* vi: set ts=4 sw=4 expandtab: */