[SDL_Tizen] Add Screen Rotation 15/131615/4 accepted/tizen/unified/20170609.054234 submit/tizen/20170607.021940
authorhuiyu.eun <huiyu.eun@samsung.com>
Tue, 30 May 2017 07:48:48 +0000 (16:48 +0900)
committerhuiyu.eun <huiyu.eun@samsung.com>
Wed, 31 May 2017 07:44:12 +0000 (16:44 +0900)
Add Screen Rotation

Change-Id: I6f5a3243984ac9194ae11494d51f037f01375407
Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
src/video/tizen/SDL_tizenwindow.c
src/video/tizen/SDL_tizenwindow.h

index 03fa91f..d34fb4e 100755 (executable)
@@ -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;
index 23eb9cc..6b0c14f 100755 (executable)
@@ -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 */