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_sysvideo.h"
46 #include "../../events/SDL_windowevents_c.h"
48 #define LOAD_FUNC(NAME) \
49 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
50 if (!_this->tizen_pre_rotation_data->NAME) \
52 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
57 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
59 void *lib_dll_handle = NULL;
62 if (_this->isLoaded_pre_rotation)
65 _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
66 if (!_this->tizen_pre_rotation_data) {
67 return SDL_OutOfMemory();
71 lib_dll_handle = SDL_LoadObject(lib_path);
73 if (!lib_dll_handle) {
74 path = "libwayland-egl.so";
75 lib_dll_handle = SDL_LoadObject(path);
78 _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
80 if (lib_dll_handle == NULL)
83 LOAD_FUNC(wl_egl_window_set_rotation);
84 LOAD_FUNC(wl_egl_window_get_capabilities);
85 _this->isLoaded_pre_rotation = 1;
91 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
93 SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
94 info->info.tizen.egl_display = NULL;
95 info->info.tizen.egl_surface = NULL;
96 #if SDL_VIDEO_OPENGL_EGL
99 info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
101 info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
103 info->subsystem = SDL_SYSWM_TIZEN;
108 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
110 return 0; /* just succeed, the real work is done elsewhere. */
114 Tizen_ShowWindow(_THIS, SDL_Window *window)
116 SDL_WindowData *wind = window->driverdata;
117 ecore_wl_window_show(wind->window);
121 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
122 SDL_VideoDisplay *_display, SDL_bool fullscreen)
128 _tizen_pre_rotation_set(SDL_WindowData *_this)
130 tizen_wl_egl_window_rotation rot;
131 if (!_this->egl_window) return;
133 switch (_this->rotation) {
135 rot = TIZEN_ROTATION_270;
138 rot = TIZEN_ROTATION_180;
141 rot = TIZEN_ROTATION_90;
144 rot = TIZEN_ROTATION_0;
147 rot = TIZEN_ROTATION_0;
151 _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
155 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
158 char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
159 int checked[4] = {0,};
162 SDL_WindowData *wind = (SDL_WindowData*)userdata;
163 Ecore_Wl_Window *window = wind->window;
165 if (wind->rotation_supported == 0) {
169 SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
171 if ((oldValue == NULL) && (newValue == NULL)) {
176 p_str = SDL_strstr(newValue, orientation_type[i]);
178 if (p_str == newValue) {
181 else if (i == 1) rot = 90;
182 else if (i == 2) rot = 180;
183 else if (i == 3) rot = 270;
184 wind->rotation = rot;
205 ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
206 if (wind->support_pre_rotation) {
207 _tizen_pre_rotation_set(wind);
210 ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
215 _tizen_window_orientation_add_hint(void *data)
217 SDL_WindowData *wind = (SDL_WindowData*)data;
218 if (wind->rotation_supported == 0) {
222 SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
226 Tizen_CreateWindow(_THIS, SDL_Window *window)
228 SDL_VideoData *data = _this->driverdata;
229 SDL_WindowData *wind;
230 Ecore_Wl_Global *global;
231 Eina_Inlist *globals;
233 wind = calloc(1, sizeof * wind);
235 return SDL_OutOfMemory();
238 window->driverdata = wind;
239 window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
241 #if SDL_VIDEO_OPENGL_EGL
242 if (window->flags & SDL_WINDOW_OPENGL) {
243 SDL_GL_LoadLibrary(NULL);
247 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
250 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
254 if (!(globals = ecore_wl_globals_get()))
256 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
260 wind->window = ecore_wl_window_new(NULL,
261 window->x, window->y, window->w, window->h,
262 ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
263 wind->surface = ecore_wl_window_surface_create(wind->window);
265 wind->rotation_supported = 0;
266 wind->received_rotation = 0;
267 ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
269 #if SDL_VIDEO_OPENGL_EGL
270 if (window->flags & SDL_WINDOW_OPENGL) {
271 wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
273 /* Create the GLES window surface */
274 wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
275 if (wind->egl_surface == EGL_NO_SURFACE) {
276 SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
280 //Support PreRotation
281 wind->support_pre_rotation = 0;
282 if (_tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
283 if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
284 wind->support_pre_rotation = 1;
290 wind->id = ecore_wl_window_id_get(wind->window);
291 eina_hash_add(data->windows, &wind->id, window);
293 Tizen_InitKeyboard(_this);
294 SDL_SetMouseFocus(window);
296 if (window->flags & 0x00008000) {
297 ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
298 ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
301 EINA_INLIST_FOREACH(globals, global) {
302 if (!strcmp(global->interface, "tizen_policy_ext")) {
303 wind->rotation_supported = 1;
307 // Add orientaiton hint cb
308 _tizen_window_orientation_add_hint((void*)wind);
314 _tizen_egl_window_resize(SDL_Window *window)
316 SDL_WindowData *wind = window->driverdata;
317 if (!wind->egl_window) {
321 // TODO : consider to rotation status.
322 #if SDL_VIDEO_OPENGL_EGL
323 if (window->flags & SDL_WINDOW_OPENGL) {
324 // TODO : if window size is not FULL, we need the code about Non FullSize Window.
326 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
327 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
334 _tizen_setwindowsize(SDL_Window *window)
336 SDL_WindowData *wind = window->driverdata;
340 ecore_wl_window_update_size(wind->window, window->w, window->h);
344 Tizen_SetWindowSize(_THIS, SDL_Window *window)
346 // _tizen_setwindowsize(window);
347 // _tizen_egl_window_resize(window);
351 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
353 SDL_WindowData *wind = window->driverdata;
358 if (w) *w = window->w;
359 if (h) *h = window->h;
363 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
365 SDL_WindowData *wind = window->driverdata;
370 // TODO : consider to rotation status.
371 ecore_wl_window_position_set(wind->window, window->x, window->y);
375 Tizen_DestroyWindow(_THIS, SDL_Window *window)
377 SDL_VideoData *data = _this->driverdata;
378 SDL_WindowData *wind = window->driverdata;
381 eina_hash_del(data->windows, &wind->id, window);
382 #if SDL_VIDEO_OPENGL_EGL
383 if (window->flags & SDL_WINDOW_OPENGL) {
384 SDL_EGL_DestroySurface(_this, wind->egl_surface);
385 wl_egl_window_destroy(wind->egl_window);
388 ecore_wl_window_free(wind->window);
392 window->driverdata = NULL;
396 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
398 SDL_VideoData *data = _this->driverdata;
401 id = ecore_wl_window_id_get(ewin);
402 return (SDL_Window*)eina_hash_find(data->windows, &id);
406 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
409 Ecore_Wl_Event_Window_Visibility_Change *ev;
414 ew = ecore_wl_window_find(ev->win);
415 window = Tizen_FindWindow(_this, ew);
417 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
418 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
419 return ECORE_CALLBACK_PASS_ON;
423 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
428 SDL_WindowData *wind;
429 Ecore_Wl_Event_Window_Configure *ev;
431 ew = ecore_wl_window_find(ev->win);
432 window = Tizen_FindWindow(_this, ew);
433 wind = window->driverdata;
435 if (wind->rotation_supported == 0){
436 return ECORE_CALLBACK_PASS_ON;
439 int nx = 0, ny = 0, nw = 0, nh = 0;
440 SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
442 ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
446 SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
447 if ((window->x != nx) || (window->y != ny))
448 ecore_wl_window_position_set(ew, nx, ny);
450 if ((window->w != nw) || (window->h != nh)) {
451 _tizen_setwindowsize(window);
454 return ECORE_CALLBACK_PASS_ON;
459 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
462 SDL_WindowData *wind;
463 wind = window->driverdata;
465 SDL_memset(&event, 0, sizeof(event));
466 event.type = SDL_ROTATEEVENT;
468 if (wind->support_pre_rotation)
469 event.user.data1 = (void*)0;
471 event.user.data1 = (void*)angle;
472 event.user.data2 = (void*)-1;
474 SDL_PushEvent(&event);
479 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
482 Ecore_Wl_Event_Window_Rotate *ev;
485 SDL_WindowData *wind;
489 return ECORE_CALLBACK_PASS_ON;
492 ew = ecore_wl_window_find(ev->win);
493 window = Tizen_FindWindow(_this, ew);
494 wind = window->driverdata;
496 if (wind->rotation != ev->angle) {
497 /* set ecore_wayland window rotation */
498 wind->rotation = ev->angle;
499 ecore_wl_window_rotation_set(ew, ev->angle);
501 if(wind->support_pre_rotation) {
502 _tizen_pre_rotation_set(wind);
505 wl_egl_window_get_attached_size(wind->egl_window, &aw, &ah);
506 wl_egl_window_resize(wind->egl_window, aw, ah, 0, 0);
508 if(wind->rotation == 90 || wind->rotation == 270) {
509 SDL_SetWindowSize(window, ah, aw);
510 window->w = ah;//for Fullscreen
513 SDL_SetWindowSize(window, aw, ah);//->call wl_egl_window_resize()
514 window->w = aw;//for Fullscreen
519 // Send Rotation Event
520 _tizen_send_rotation_event(window, ev->angle);
521 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
524 wind->received_rotation = 1;
525 const char* hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
526 if(hint && *hint != '\0')
527 Tizen_IndicatorProcessEvent(_this->current_glwin, wind->rotation);
529 return ECORE_CALLBACK_PASS_ON;
533 Tizen_InitWindow(_THIS)
535 SDL_VideoData *data = _this->driverdata;
537 data->windows = eina_hash_int32_new(NULL);
539 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
540 _tizen_cb_event_window_visibility_change,_this);
541 ecore_event_handler_add(ECORE_EVENT_KEY_UP,
542 _tizen_cb_event_keyup_change,_this);
543 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
544 _tizen_cb_event_keydown_change,_this);
545 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
546 _tizen_cb_event_mousedown_change,_this);
547 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
548 _tizen_cb_event_mouseup_change,_this);
549 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
550 _tizen_cb_event_mousemove_change,_this);
551 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
552 _tizen_cb_event_window_rotate,_this);
553 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
554 _tizen_cb_window_configure,_this);
555 ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
556 _tizen_cb_event_joystick_change,_this);
557 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
558 _tizen_cb_event_focus_in,_this);
559 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
560 _tizen_cb_event_focus_out,_this);
561 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
562 _tizen_cb_event_mouse_in,_this);
563 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
564 _tizen_cb_event_mouse_out,_this);
566 data->current_thread = SDL_GetThreadID(0);
572 Tizen_DeinitWindow(_THIS)
574 SDL_VideoData *data = _this->driverdata;
576 eina_hash_free(data->windows);
578 #endif /* SDL_VIDEO_DRIVER_TIZEN */
580 /* vi: set ts=4 sw=4 expandtab: */