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);
318 wind->rotation_supported = 0;
319 wind->received_rotation = 0;
320 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
322 #if SDL_VIDEO_OPENGL_EGL
323 if (window->flags & SDL_WINDOW_OPENGL) {
324 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
326 /* Create the GLES window surface */
327 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
328 if (wind->egl_surface == EGL_NO_SURFACE) {
329 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
333 //Support PreRotation
334 wind->support_pre_rotation = 0;
335 if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
336 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
337 wind->support_pre_rotation = 1;
343 wind->id = ecore_wl_window_id_get(wind->window);
344 eina_hash_add(data->windows, &wind->id, window);
346 Tizen_InitKeyboard(_this);
347 SDL_SetMouseFocus(window);
349 if (window->flags & 0x00008000) {
350 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
351 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
354 EINA_INLIST_FOREACH(globals, global) {
355 if (!strcmp(global->interface, "tizen_policy_ext")) {
356 wind->rotation_supported = 1;
360 // Add orientaiton hint cb
361 _tizen_window_orientation_add_hint((void*)wind);
368 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
370 //Add setting window bordered.
374 _tizen_egl_window_resize(SDL_Window *window)
376 SDL_WindowData *wind = window->driverdata;
377 if (!wind->egl_window) {
381 // TODO : consider to rotation status.
382 #if SDL_VIDEO_OPENGL_EGL
383 if (window->flags & SDL_WINDOW_OPENGL) {
384 // TODO : if window size is not FULL, we need the code about Non FullSize Window.
386 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
387 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
394 _tizen_setwindowsize(SDL_Window *window)
396 SDL_WindowData *wind = window->driverdata;
400 ecore_wl_window_update_size(wind->window, window->w, window->h);
404 Tizen_SetWindowSize(_THIS, SDL_Window *window)
406 // _tizen_setwindowsize(window);
407 // _tizen_egl_window_resize(window);
411 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
413 SDL_WindowData *wind = window->driverdata;
418 if (w) *w = window->w;
419 if (h) *h = window->h;
423 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
425 SDL_WindowData *wind = window->driverdata;
430 // TODO : consider to rotation status.
431 ecore_wl_window_position_set(wind->window, window->x, window->y);
435 Tizen_DestroyWindow(_THIS, SDL_Window *window)
437 SDL_VideoData *data = _this->driverdata;
438 SDL_WindowData *wind = window->driverdata;
441 eina_hash_del(data->windows, &wind->id, window);
442 #if SDL_VIDEO_OPENGL_EGL
443 if (window->flags & SDL_WINDOW_OPENGL) {
444 SDL_EGL_DestroySurface(_this, wind->egl_surface);
445 wl_egl_window_destroy(wind->egl_window);
448 ecore_wl_window_free(wind->window);
452 window->driverdata = NULL;
456 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
458 SDL_VideoData *data = _this->driverdata;
461 id = ecore_wl_window_id_get(ewin);
462 return (SDL_Window*)eina_hash_find(data->windows, &id);
466 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
469 Ecore_Wl_Event_Window_Visibility_Change *ev;
474 ew = ecore_wl_window_find(ev->win);
475 window = Tizen_FindWindow(_this, ew);
477 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
478 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
479 return ECORE_CALLBACK_PASS_ON;
483 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
488 SDL_WindowData *wind;
489 Ecore_Wl_Event_Window_Configure *ev;
491 ew = ecore_wl_window_find(ev->win);
492 window = Tizen_FindWindow(_this, ew);
493 wind = window->driverdata;
495 if (wind->rotation_supported == 0){
496 return ECORE_CALLBACK_PASS_ON;
499 int nx = 0, ny = 0, nw = 0, nh = 0;
500 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
502 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
506 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
507 if ((window->x != nx) || (window->y != ny))
508 ecore_wl_window_position_set(ew, nx, ny);
510 if ((window->w != nw) || (window->h != nh)) {
511 _tizen_setwindowsize(window);
514 return ECORE_CALLBACK_PASS_ON;
519 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
522 SDL_WindowData *wind;
523 wind = window->driverdata;
525 SDL_memset(&event, 0, sizeof(event));
526 event.type = SDL_ROTATEEVENT;
528 if (wind->support_pre_rotation)
529 event.user.data1 = (void*)0;
531 event.user.data1 = (void*)angle;
532 event.user.data2 = (void*)-1;
534 SDL_PushEvent(&event);
539 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
542 Ecore_Wl_Event_Window_Rotate *ev;
545 SDL_WindowData *wind;
549 return ECORE_CALLBACK_PASS_ON;
552 ew = ecore_wl_window_find(ev->win);
553 window = Tizen_FindWindow(_this, ew);
554 wind = window->driverdata;
556 if (wind->rotation != ev->angle) {
557 /* set ecore_wayland window rotation */
558 wind->rotation = ev->angle;
559 ecore_wl_window_rotation_set(ew, ev->angle);
560 // Send Rotation Event
561 _tizen_send_rotation_event(window, ev->angle);
562 wind->received_rotation = 1;
565 return ECORE_CALLBACK_PASS_ON;
569 Tizen_InitWindow(_THIS)
571 SDL_VideoData *data = _this->driverdata;
573 data->windows = eina_hash_int32_new(NULL);
575 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
576 _tizen_cb_event_window_visibility_change,_this);
577 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
578 _tizen_cb_event_keyup_change,_this);
579 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
580 _tizen_cb_event_keydown_change,_this);
581 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
582 _tizen_cb_event_mousedown_change,_this);
583 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
584 _tizen_cb_event_mouseup_change,_this);
585 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
586 _tizen_cb_event_mousemove_change,_this);
587 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
588 _tizen_cb_event_window_rotate,_this);
589 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
590 _tizen_cb_window_configure,_this);
591 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
592 _tizen_cb_event_joystick_change,_this);
593 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
594 _tizen_cb_event_focus_in,_this);
595 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
596 _tizen_cb_event_focus_out,_this);
597 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
598 _tizen_cb_event_mouse_in,_this);
599 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
600 _tizen_cb_event_mouse_out,_this);
602 data->current_thread = SDL_GetThreadID(0);
608 Tizen_DeinitWindow(_THIS)
610 SDL_VideoData *data = _this->driverdata;
612 eina_hash_free(data->windows);
614 #endif /* SDL_VIDEO_DRIVER_TIZEN */
616 /* vi: set ts=4 sw=4 expandtab: */