From 7007f850dcd8e7acda3a852e63119b2943fb797b Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Tue, 30 May 2017 16:48:48 +0900 Subject: [PATCH] [SDL_Tizen] Add Screen Rotation Add Screen Rotation Change-Id: I6f5a3243984ac9194ae11494d51f037f01375407 Signed-off-by: huiyu.eun --- src/video/tizen/SDL_tizenwindow.c | 280 +++++++++++++++++++++++++------------- src/video/tizen/SDL_tizenwindow.h | 3 +- 2 files changed, 187 insertions(+), 96 deletions(-) diff --git a/src/video/tizen/SDL_tizenwindow.c b/src/video/tizen/SDL_tizenwindow.c index 03fa91f..d34fb4e 100755 --- a/src/video/tizen/SDL_tizenwindow.c +++ b/src/video/tizen/SDL_tizenwindow.c @@ -167,12 +167,12 @@ Tizen_SetWindowFullscreen(_THIS, SDL_Window *window, } void -Tizen_pre_rotation_set(SDL_WindowData *_this) +Tizen_pre_rotation_set(SDL_WindowData *_this, int rotation) { tizen_wl_egl_window_rotation rot; if (!_this->egl_window) return; - switch (_this->rotation) { + switch (rotation) { case 90: rot = TIZEN_ROTATION_270; break; @@ -245,8 +245,6 @@ _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const if (j > 0) { if (j == 1) { ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation); - if (wind->support_pre_rotation) - Tizen_pre_rotation_set(wind); }else { ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j); } @@ -264,6 +262,175 @@ _tizen_window_orientation_add_hint(void *data) SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data); } +static Eina_Bool +_tizen_cb_output_transform(void *data, int type EINA_UNUSED, void *event) +{ + SDL_Window * window = SDL_GetVideoDevice()->windows; + SDL_WindowData *wind = window->driverdata; + + if(!wind) return ECORE_CALLBACK_PASS_ON; + + Ecore_Wl_Event_Output_Transform *ev = event; + Ecore_Wl_Output *output; + + output = ecore_wl_window_output_find(wind->window); + if (output != ev->output) return ECORE_CALLBACK_PASS_ON; + + _tizen_rotate_update(wind); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_tizen_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + SDL_Window * window = SDL_GetVideoDevice()->windows; + SDL_WindowData *wind = window->driverdata; + + if(!wind) return ECORE_CALLBACK_PASS_ON; + + _tizen_rotate_update(wind); + + return ECORE_CALLBACK_PASS_ON; +} + +void +_tizen_output_transform_register(SDL_WindowData *wind) +{ + if(!wind) return; + + Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window); + wind->output_rotation = ecore_wl_output_transform_get(output) * 90; + + ecore_event_handler_add(ECORE_WL_EVENT_OUTPUT_TRANSFORM, + _tizen_cb_output_transform, NULL); + ecore_event_handler_add(ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM, + _tizen_cb_ignore_output_transform, NULL); + +} + +void +_tizen_send_rotation_event(SDL_Window *window, unsigned int angle) +{ + SDL_Event event; + SDL_WindowData *wind; + wind = window->driverdata; + + SDL_memset(&event, 0, sizeof(event)); + event.type = SDL_ROTATEEVENT; + event.user.code = 0; + if (wind->support_pre_rotation) + event.user.data1 = (void*)0; + else + event.user.data1 = (void*)angle; + event.user.data2 = (void*)-1; + + SDL_PushEvent(&event); + return; +} + +void +_tizen_set_window_size(SDL_Window * window, int w, int h) +{ + if(!window) + { + SDL_SetError("Invalid window"); + return; + } + + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + if (!_this) { + SDL_SetError("Video subsystem has not been initialized"); + return; + } + + if (window->magic != &_this->window_magic) { + return; + } + + if (w <= 0) { + SDL_InvalidParamError("w"); + return; + } + if (h <= 0) { + SDL_InvalidParamError("h"); + return; + } + + /* Make sure we don't exceed any window size limits */ + if (window->min_w && w < window->min_w) + { + w = window->min_w; + } + if (window->max_w && w > window->max_w) + { + w = window->max_w; + } + if (window->min_h && h < window->min_h) + { + h = window->min_h; + } + if (window->max_h && h > window->max_h) + { + h = window->max_h; + } + + window->windowed.w = w; + window->windowed.h = h; + + window->w = w; + window->h = h; +} + +void +_tizen_rotation_do(SDL_WindowData *wind, int rotation) +{ + if(!wind) return; + + SDL_Window *window = SDL_GetVideoDevice()->windows; + if(!window) return; + + int window_w, window_h; + if(wind->rotation == 0 || wind->rotation == 180) + ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h); + else + ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w); + + _tizen_set_window_size(window, window_w, window_h); + + if(wind->support_pre_rotation) + Tizen_pre_rotation_set(wind, rotation); + + _tizen_send_rotation_event(window, rotation); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); + wind->received_rotation = 1; + +} + +void +_tizen_rotate_update(SDL_WindowData *wind) +{ + if(!wind) return; + + int screen_rotation; + if (ecore_wl_window_ignore_output_transform_get(wind->window)) + { + screen_rotation = 0; + } + else + { + Ecore_Wl_Output *output = ecore_wl_window_output_find(wind->window); + screen_rotation = ecore_wl_output_transform_get(output) * 90; + } + + //Set Screen Rotation + wind->output_rotation = screen_rotation; + ecore_wl_window_buffer_transform_set(wind->window, wind->output_rotation / 90); + + int rotation = (wind->output_rotation + wind->rotation) % 360; + _tizen_rotation_do(wind, rotation); +} + int Tizen_CreateWindow(_THIS, SDL_Window *window) { @@ -314,12 +481,16 @@ Tizen_CreateWindow(_THIS, SDL_Window *window) wind->window = ecore_wl_window_new(NULL, window->x, window->y, window->w, window->h, ECORE_WL_WINDOW_BUFFER_TYPE_SHM); - if (wind->window) { + if (!wind->window) { SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window"); + return -1; } + _tizen_output_transform_register(wind); + wind->surface = ecore_wl_window_surface_create(wind->window); - if (wind->surface) { + if (!wind->surface) { SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to create wayland window surface"); + return -1; } ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY); @@ -329,7 +500,10 @@ Tizen_CreateWindow(_THIS, SDL_Window *window) #if SDL_VIDEO_OPENGL_EGL if (window->flags & SDL_WINDOW_OPENGL) { - wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h); + if(wind->output_rotation == 90 || wind->output_rotation == 270) + wind->egl_window = wl_egl_window_create(wind->surface, window->h, window->w); + else + wind->egl_window = wl_egl_window_create(wind->surface, window->w, window->h); /* Create the GLES window surface */ wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window); @@ -375,6 +549,7 @@ Tizen_CreateWindow(_THIS, SDL_Window *window) // Add orientaiton hint cb _tizen_window_orientation_add_hint((void*)wind); + _tizen_rotate_update(wind); return 0; } @@ -401,7 +576,7 @@ _tizen_window_resize(SDL_Window *window) // TODO : consider to rotation status. #if SDL_VIDEO_OPENGL_EGL if (window->flags & SDL_WINDOW_OPENGL) { - if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270)) + if(wind->output_rotation==90 || wind->output_rotation==270) wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0); else wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0); @@ -532,79 +707,6 @@ _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event) } -void -_tizen_send_rotation_event(SDL_Window *window, unsigned int angle) -{ - SDL_Event event; - SDL_WindowData *wind; - wind = window->driverdata; - - SDL_memset(&event, 0, sizeof(event)); - event.type = SDL_ROTATEEVENT; - event.user.code = 0; - if (wind->support_pre_rotation) - event.user.data1 = (void*)0; - else - event.user.data1 = (void*)angle; - event.user.data2 = (void*)-1; - - SDL_PushEvent(&event); - return; -} - -void -_tizen_set_window_size(SDL_Window * window, int w, int h) -{ - if(!window) - { - SDL_SetError("Invalid window"); - return; - } - - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - if (!_this) { - SDL_SetError("Video subsystem has not been initialized"); - return; - } - - if (window->magic != &_this->window_magic) { - return; - } - - if (w <= 0) { - SDL_InvalidParamError("w"); - return; - } - if (h <= 0) { - SDL_InvalidParamError("h"); - return; - } - - /* Make sure we don't exceed any window size limits */ - if (window->min_w && w < window->min_w) - { - w = window->min_w; - } - if (window->max_w && w > window->max_w) - { - w = window->max_w; - } - if (window->min_h && h < window->min_h) - { - h = window->min_h; - } - if (window->max_h && h > window->max_h) - { - h = window->max_h; - } - - window->windowed.w = w; - window->windowed.h = h; - - window->w = w; - window->h = h; -} - Eina_Bool _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event) { @@ -626,20 +728,8 @@ _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event) if (wind->rotation != ev->angle) { /* set ecore_wayland window rotation */ wind->rotation = ev->angle; - ecore_wl_window_rotation_set(ew, ev->angle); - if(wind->support_pre_rotation) { - int window_w, window_h; - if(wind->rotation==90 || wind->rotation==270) - ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w); - else - ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h); - - _tizen_set_window_size(window, window_w, window_h); - Tizen_pre_rotation_set(wind); - } - _tizen_send_rotation_event(window, ev->angle); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); - wind->received_rotation = 1; + ecore_wl_window_rotation_set(wind->window, wind->rotation); + _tizen_rotate_update(wind); } return ECORE_CALLBACK_PASS_ON; diff --git a/src/video/tizen/SDL_tizenwindow.h b/src/video/tizen/SDL_tizenwindow.h index 23eb9cc..6b0c14f 100755 --- a/src/video/tizen/SDL_tizenwindow.h +++ b/src/video/tizen/SDL_tizenwindow.h @@ -49,6 +49,7 @@ typedef struct { int rotation_supported; int received_rotation; void *indicator_timer; + int output_rotation; SDL_bool need_indicator; SDL_bool indicator_show; @@ -93,7 +94,7 @@ extern void Tizen_SetWindowPosition(_THIS, SDL_Window * window); extern int Tizen_InitWindow(_THIS); extern void Tizen_DeinitWindow(_THIS); -extern void Tizen_pre_rotation_set(SDL_WindowData *_this); +extern void Tizen_pre_rotation_set(SDL_WindowData *_this, int rotation); #endif /* _SDL_tizenwindow_h */ -- 2.7.4