Wayland Rotation: Add Geometry hint protocol 20/45220/6
authorMun, Gwan-gyeong <kk.moon@samsung.com>
Mon, 27 Jul 2015 06:09:52 +0000 (15:09 +0900)
committerGwan-gyeong Mun <elongbug@gmail.com>
Tue, 8 Sep 2015 12:43:34 +0000 (05:43 -0700)
                  Add Rotation with resize protocol

Change-Id: Ibb6d1bc4d27aaf17e1dddd264160274a0958c048

src/e_mod_rotation.c
src/e_mod_rotation_wl.c
src/e_mod_rotation_wl.h
src/tizen_policy_ext-protocol.c
src/tizen_policy_ext-server-protocol.h
src/tizen_policy_ext.xml

index baea1d1..6729116 100644 (file)
 #include "e_mod_rotation.h"
 #include "e_mod_utils.h"
 
-
 #ifdef HAVE_WAYLAND_ONLY
 #include "e_mod_rotation_wl.h"
 #else
 #include "e_mod_atoms.h"
 #endif
 
+#ifndef HAVE_WAYLAND_ONLY
 typedef struct _E_Client_Rotation E_Client_Rotation;
 
 struct _E_Client_Rotation
@@ -160,11 +160,9 @@ static Eina_Bool _rot_hook_new_client_intern(E_Client *ec);
 static Eina_Bool _rot_cb_zone_rotation_change_begin_intern(E_Event_Zone_Rotation_Change_Begin *ev);
 static Eina_Bool _rot_intercept_hook_show_helper_intern(E_Client *ec);
 static Eina_Bool _rot_intercept_hook_hide_intern(E_Client *ec);
-#ifndef HAVE_WAYLAND_ONLY
 static Eina_Bool _rot_cb_window_configure_intern(Ecore_X_Event_Window_Configure *ev);
 static Eina_Bool _rot_cb_window_property_intern(Ecore_X_Event_Window_Property *ev);
 static Eina_Bool _rot_cb_window_message_intern(Ecore_X_Event_Client_Message *ev);
-#endif
 static Eina_Bool _rot_hook_eval_fetch_intern(E_Client *ec);
 
 /* e_client event, hook, intercept callbacks */
@@ -175,11 +173,9 @@ static void      _rot_hook_eval_end(void *d EINA_UNUSED, E_Client *ec);
 static void      _rot_hook_eval_fetch(void *d EINA_UNUSED, E_Client *ec);
 static Eina_Bool _rot_intercept_hook_show_helper(void *d EINA_UNUSED, E_Client *ec);
 static Eina_Bool _rot_intercept_hook_hide(void *d EINA_UNUSED, E_Client *ec);
-#ifndef HAVE_WAYLAND_ONLY
 static Eina_Bool _rot_cb_window_property(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Window_Property *ev);
 static Eina_Bool _rot_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Window_Configure *ev);
 static Eina_Bool _rot_cb_window_message(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Client_Message *ev);
-#endif
 static Eina_Bool _rot_cb_zone_rotation_change_begin(void *data EINA_UNUSED, int ev_type EINA_UNUSED, E_Event_Zone_Rotation_Change_Begin *ev);
 static Eina_Bool _rot_cb_idle_enterer(void *data EINA_UNUSED);
 static void      _rot_cb_evas_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
@@ -189,7 +185,6 @@ static Eina_Bool
 _e_client_vkbd_state_check(E_Client *ec,
                            Eina_Bool show)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Eina_Bool res = EINA_TRUE;
    if ((rot.vkbd) && (rot.vkbd == ec))
      {
@@ -207,15 +202,11 @@ _e_client_vkbd_state_check(E_Client *ec,
           }
      }
    return res;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static Eina_Bool
 _e_client_vkbd_show_timeout(void *data)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Client *ec = data;
    if ((ec) && ((E_OBJECT(ec)->type) == (E_CLIENT_TYPE)))
      {
@@ -238,7 +229,6 @@ _e_client_vkbd_show_timeout(void *data)
    if (rot.vkbd_show_timer)
      ecore_timer_del(rot.vkbd_show_timer);
    rot.vkbd_show_timer = NULL;
-#endif
 
    return ECORE_CALLBACK_CANCEL;
 }
@@ -246,7 +236,6 @@ _e_client_vkbd_show_timeout(void *data)
 static Eina_Bool
 _e_client_vkbd_hide_timeout(void *data)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Client *ec = data;
    int unref_count = 0;
 
@@ -277,14 +266,12 @@ _e_client_vkbd_hide_timeout(void *data)
         unref_count--;
      }
 
-#endif
    return ECORE_CALLBACK_CANCEL;
 }
 
 static void
 _e_client_vkbd_show(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    rot.vkbd_show_prepare_done = EINA_TRUE;
    if (rot.vkbd_show_prepare_timer)
      ecore_timer_del(rot.vkbd_show_prepare_timer);
@@ -297,13 +284,11 @@ _e_client_vkbd_show(E_Client *ec)
         evas_object_show(ec->frame);// e_client_show(ec)
         rot.vkbd_show_timer = ecore_timer_add(1.0f, _e_client_vkbd_show_timeout, ec);
      }
-#endif
 }
 
 static void
 _e_client_vkbd_hide(E_Client *ec, Eina_Bool clean)
 {
-#ifndef HAVE_WAYLAND_ONLY
    int unref_count = 0;
 
    rot.vkbd_hide_prepare_done = EINA_TRUE;
@@ -349,26 +334,22 @@ _e_client_vkbd_hide(E_Client *ec, Eina_Bool clean)
         e_object_unref(E_OBJECT(ec));
         unref_count--;
      }
-#endif
 }
 
 static Eina_Bool
 _e_client_vkbd_show_prepare_timeout(void *data)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Client *ec = data;
    if ((ec) && (!e_object_is_del(E_OBJECT(ec))))
      {
         _e_client_vkbd_show(ec);
      }
-#endif
    return ECORE_CALLBACK_CANCEL;
 }
 
 static Eina_Bool
 _e_client_vkbd_hide_prepare_timeout(void *data)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Client *ec = data;
    int unref_count = 0;
 
@@ -390,7 +371,6 @@ _e_client_vkbd_hide_prepare_timeout(void *data)
         unref_count--;
      }
 
-#endif
    return ECORE_CALLBACK_CANCEL;
 }
 
@@ -401,20 +381,15 @@ _e_client_vkbd_hide_prepare_timeout(void *data)
 static int
 _e_client_rotation_curr_next_get(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (!ec) return -1;
 
    return ((ec->e.state.rot.ang.next == -1) ?
            ec->e.state.rot.ang.curr : ec->e.state.rot.ang.next);
-#else
-   return -1;
-#endif
 }
 
 static int
 _prev_angle_get(Ecore_Window win)
 {
-#ifndef HAVE_WAYLAND_ONLY
    int ret, count = 0, ang = -1;
    unsigned char* data = NULL;
 
@@ -426,16 +401,12 @@ _prev_angle_get(Ecore_Window win)
      ang = ((int *)data)[0];
    if (data) free(data);
    return ang;
-#else
-   return -1;
-#endif
 }
 
 /* check whether virtual keyboard is visible on the zone */
 static Eina_Bool
 _e_client_is_vkbd(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if ((rot.vkbd_ctrl_win) &&
        (rot.vkbd == ec) &&
        (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
@@ -447,30 +418,22 @@ _e_client_is_vkbd(E_Client *ec)
      {
         return EINA_TRUE;
      }
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static Eina_Bool
 _e_client_rotation_is_dependent_parent(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (!ec) return EINA_FALSE;
    if ((!ec->parent) || (!evas_object_visible_get(ec->parent->frame))) return EINA_FALSE;
    if (ec->netwm.type == E_WINDOW_TYPE_NORMAL) return EINA_FALSE;
    if ((!ec->e.state.rot.support) &&
        (!ec->e.state.rot.app_set)) return EINA_FALSE;
    return EINA_TRUE;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static Eina_Bool
 _e_client_rotation_zone_set(E_Zone *zone)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Client *ec = NULL;
    Eina_Bool res = EINA_FALSE;
    Eina_Bool ret = EINA_FALSE;
@@ -514,15 +477,11 @@ _e_client_rotation_zone_set(E_Zone *zone)
      }
 
    return ret;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static void
 _e_client_rotation_change_message_send(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    int rotation;
    Eina_Bool resize = EINA_FALSE;
 
@@ -549,13 +508,11 @@ _e_client_rotation_change_message_send(E_Client *ec)
              e_client_rotation_change_request(ec, rotation);
           }
      }
-#endif
 }
 
 static void
 _e_client_rotation_list_send(void)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Eina_List *l;
    E_Client *ec;
 
@@ -569,13 +526,11 @@ _e_client_rotation_list_send(void)
 
         _e_client_rotation_change_message_send(ec);
      }
-#endif
 }
 
 static Eina_Bool
 _e_client_rotation_change_prepare_timeout(void *data)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Zone *zone = data;
 
    if ((zone) && (rot.wait_prepare_done))
@@ -589,23 +544,19 @@ _e_client_rotation_change_prepare_timeout(void *data)
              rot.wait_prepare_done = EINA_FALSE;
           }
      }
-#endif
    return ECORE_CALLBACK_CANCEL;
 }
 
 static Eina_Bool
 _e_client_rotation_change_done_timeout(void *data __UNUSED__)
 {
-#ifndef HAVE_WAYLAND_ONLY
    _e_client_rotation_change_done();
-#endif
    return ECORE_CALLBACK_CANCEL;
 }
 
 static void
 _e_client_rotation_list_remove(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Client_Rotation_Change_End *ev = NULL;
    Eina_Bool found = EINA_FALSE;
 
@@ -644,13 +595,11 @@ _e_client_rotation_list_remove(E_Client *ec)
      }
    ec->e.state.rot.ang.next = -1;
    ec->changes.rotation = 0;
-#endif
 }
 
 static void
 _e_client_rotation_change_done(void)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Manager *m = NULL;
    E_Client *ec;
 
@@ -688,30 +637,29 @@ _e_client_rotation_change_done(void)
         rot.screen_lock = EINA_FALSE;
      }
    e_zone_rotation_update_done(e_util_zone_current_get(m));
-#endif
 }
 
 static Eina_Bool
 _e_client_rotation_prepare_send(E_Client *ec, int rotation)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Zone *zone = ec->zone;
    int x, y, w, h;
+   int cw = ec->client.w, ch = ec->client.h;
    Eina_Bool move = EINA_FALSE;
    Eina_Bool hint = EINA_FALSE;
    Eina_Bool resize = EINA_FALSE;
 
    x = ec->x;
    y = ec->y;
-   w = ec->w;
-   h = ec->h;
+   w = cw;
+   h = ch;
 
    if (SIZE_EQUAL_TO_ZONE(ec, zone)) goto end;
 
    hint = _e_client_rotation_geom_get(ec, ec->zone, rotation,
                                       &x, &y, &w, &h, &move);
 
-   if ((!hint) || (ec->w != w) || (ec->h != h)) resize = EINA_TRUE;
+   if ((!hint) || (cw != w) || (ch != h)) resize = EINA_TRUE;
 
 end:
 
@@ -719,18 +667,13 @@ end:
       (e_client_util_win_get(ec), rotation, resize, w, h);
 
    if (((move) && ((ec->x !=x) || (ec->y !=y))) ||
-       ((resize) && ((ec->w != w) || (ec->h != h))))
+       ((resize) && ((cw != w) || (ch != h))))
      {
-#if 0
-     // need call: _e_comp_x_client_move_resize_send(); ?
-        _e_client_move_resize_internal(ec, x, y, w, h, EINA_TRUE, move);
-#endif
-        e_client_util_move_resize_without_frame(ec, x, y, w, h); //check: this function work correct or not.
+        //e_client_util_move_resize_without_frame(ec, x, y, w, h); //check: this function work correct or not.
+        evas_object_move(ec->frame, x, y);
+        e_client_util_resize_without_frame(ec, w, h);
      }
    return resize;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static Eina_Bool
@@ -743,17 +686,19 @@ _e_client_rotation_geom_get(E_Client  *ec,
                             int       *h,
                             Eina_Bool *move)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Eina_Bool res = EINA_FALSE;
-   int _x = ec->x;
-   int _y = ec->y;
-   int _w = ec->w;
-   int _h = ec->h;
+   int _x, _y, _w, _h;
+   int cw = ec->client.w, ch = ec->client.h;
+
+   _x = ec->x;
+   _y = ec->y;
+   _w = cw;
+   _h = ch;
 
    if (x) *x = ec->x;
    if (y) *y = ec->y;
-   if (w) *w = ec->w;
-   if (h) *h = ec->h;
+   if (w) *w = _w;
+   if (h) *h = _h;
    if (move) *move = EINA_TRUE;
 
    if (ec->e.state.rot.geom_hint)
@@ -763,29 +708,29 @@ _e_client_rotation_geom_get(E_Client  *ec,
            case   0:
               _w = ec->e.state.rot.geom[0].w;
               _h = ec->e.state.rot.geom[0].h;
-              if (_w == 0) _w = ec->w;
-              if (_h == 0) _h = ec->h;
+              if (_w == 0) _w = cw;
+              if (_h == 0) _h = ch;
               _x = 0; _y = zone->h - _h;
               break;
            case  90:
               _w = ec->e.state.rot.geom[1].w;
               _h = ec->e.state.rot.geom[1].h;
-              if (_w == 0) _w = ec->w;
-              if (_h == 0) _h = ec->h;
+              if (_w == 0) _w = cw;
+              if (_h == 0) _h = ch;
               _x = zone->w - _w; _y = 0;
               break;
            case 180:
               _w = ec->e.state.rot.geom[2].w;
               _h = ec->e.state.rot.geom[2].h;
-              if (_w == 0) _w = ec->w;
-              if (_h == 0) _h = ec->h;
+              if (_w == 0) _w = cw;
+              if (_h == 0) _h = ch;
               _x = 0; _y = 0;
               break;
            case 270:
               _w = ec->e.state.rot.geom[3].w;
               _h = ec->e.state.rot.geom[3].h;
-              if (_w == 0) _w = ec->w;
-              if (_h == 0) _h = ec->h;
+              if (_w == 0) _w = cw;
+              if (_h == 0) _h = ch;
               _x = 0; _y = 0;
               break;
           }
@@ -815,39 +760,31 @@ _e_client_rotation_geom_get(E_Client  *ec,
      }
 
    return res;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static void
 _e_client_event_client_rotation_change_begin_free(void *data __UNUSED__,
                                                   void      *ev)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Client_Rotation_Change_Begin *e;
    e = ev;
    e_object_unref(E_OBJECT(e->ec));
    E_FREE(e);
-#endif
 }
 
 static void
 _e_client_event_client_rotation_change_end_free(void *data __UNUSED__,
                                                 void      *ev)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Client_Rotation_Change_End *e;
    e = ev;
    e_object_unref(E_OBJECT(e->ec));
    E_FREE(e);
-#endif
 }
 
 static void
 _e_client_event_client_rotation_change_begin_send(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Client_Rotation_Change_Begin *ev = NULL;
    ev = E_NEW(E_Event_Client_Rotation_Change_End, 1);
    if (ev)
@@ -859,14 +796,12 @@ _e_client_event_client_rotation_change_begin_send(E_Client *ec)
                         _e_client_event_client_rotation_change_begin_free,
                         NULL);
      }
-#endif
 }
 
 /* local subsystem e_zone_rotation related functions */
 static void
 _e_zone_rotation_set_internal(E_Zone *zone, int rot)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_Begin *ev;
 
    E_OBJECT_CHECK(zone);
@@ -894,47 +829,39 @@ _e_zone_rotation_set_internal(E_Zone *zone, int rot)
         ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
                         ev, _e_zone_event_rotation_change_begin_free, NULL);
      }
-#endif
 }
 
 static void
 _e_zone_event_rotation_change_begin_free(void *data __UNUSED__,
                                          void      *ev)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_Begin *e = ev;
    e_object_unref(E_OBJECT(e->zone));
    E_FREE(e);
-#endif
 }
 
 static void
 _e_zone_event_rotation_change_cancel_free(void *data __UNUSED__,
                                           void      *ev)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_Cancel *e = ev;
    e_object_unref(E_OBJECT(e->zone));
    E_FREE(e);
-#endif
 }
 
 static void
 _e_zone_event_rotation_change_end_free(void *data __UNUSED__,
                                        void      *ev)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_End *e = ev;
    e_object_unref(E_OBJECT(e->zone));
    E_FREE(e);
-#endif
 }
 
 /* e_client_roation functions */
 static void
 e_client_rotation_change_request(E_Client *ec, int rotation)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (!ec) return;
    if (rotation < 0) return;
 
@@ -946,10 +873,6 @@ e_client_rotation_change_request(E_Client *ec, int rotation)
 
    ecore_x_e_window_rotation_change_request_send(e_client_util_win_get(ec), rotation);
 
-#if 0
-   if (ec->e.state.deiconify_approve.pending)
-     _e_client_deiconify_approve_send_pending_end(ec);
-#endif
    ec->e.state.rot.wait_for_done = 1;
 
    if ((!rot.async_list) ||
@@ -961,7 +884,6 @@ e_client_rotation_change_request(E_Client *ec, int rotation)
                                          _e_client_rotation_change_done_timeout,
                                          NULL);
      }
-#endif
 }
 
 /**
@@ -974,16 +896,12 @@ e_client_rotation_change_request(E_Client *ec, int rotation)
 static Eina_Bool
 e_client_rotation_is_progress(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (!ec) return EINA_FALSE;
 
    if (ec->e.state.rot.ang.next == -1)
      return EINA_FALSE;
    else
      return EINA_TRUE;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 /**
@@ -997,7 +915,6 @@ e_client_rotation_is_progress(const E_Client *ec)
 static Eina_Bool
 e_client_rotation_is_available(const E_Client *ec, int ang)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (!ec) return EINA_FALSE;
 
    if (ang < 0) goto fail;
@@ -1035,9 +952,6 @@ fail:
    return EINA_FALSE;
 success:
    return EINA_TRUE;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 /**
@@ -1050,7 +964,6 @@ success:
 static Eina_List*
 e_client_rotation_available_list_get(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Eina_List *list = NULL;
    int *element;
    unsigned int i;
@@ -1079,9 +992,6 @@ e_client_rotation_available_list_get(const E_Client *ec)
           }
      }
    return list;
-#else
-   return NULL;
-#endif
 }
 
 
@@ -1094,14 +1004,10 @@ e_client_rotation_available_list_get(const E_Client *ec)
 static int
 e_client_rotation_next_angle_get(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_OBJECT_CHECK_RETURN(ec, -1);
    E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, -1);
 
    return ec->e.state.rot.ang.next;
-#else
-   return -1;
-#endif
 }
 
 /**
@@ -1113,14 +1019,10 @@ e_client_rotation_next_angle_get(const E_Client *ec)
 static int
 e_client_rotation_prev_angle_get(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_OBJECT_CHECK_RETURN(ec, -1);
    E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, -1);
 
    return ec->e.state.rot.ang.prev;
-#else
-   return -1;
-#endif
 }
 
 /**
@@ -1133,7 +1035,6 @@ e_client_rotation_prev_angle_get(const E_Client *ec)
 static int
 e_client_rotation_recommend_angle_get(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Zone *zone = NULL;
    int ret_ang = -1;
 
@@ -1190,9 +1091,6 @@ e_client_rotation_recommend_angle_get(const E_Client *ec)
 
 end:
    return ret_ang;
-#else
-   return -1;
-#endif
 }
 
 /**
@@ -1206,7 +1104,6 @@ end:
 static Eina_Bool
 e_client_rotation_set(E_Client *ec, int rotation)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Eina_List *list, *l;
    E_Client *child;
    int curr_rot;
@@ -1233,11 +1130,6 @@ e_client_rotation_set(E_Client *ec, int rotation)
                        if (!e_object_is_del(E_OBJECT(ec)))
                          evas_object_show(ec->frame); // e_client_show(ec);
                     }
-#if 0 //force rendering?
-                  if (ec->e.state.deiconify_approve.pending)
-                    _e_client_deiconify_approve_send_pending_end(ec);
-#endif
-
                   return EINA_FALSE;
                }
              else
@@ -1319,10 +1211,6 @@ finish:
         rot.cancel.zone = NULL;
      }
    return EINA_TRUE;
-#else
-   e_mod_rot_wl_angle_change_send(ec, rotation);
-   return EINA_TRUE;
-#endif
 }
 
 /* e_zone_rotation related functions */
@@ -1330,7 +1218,6 @@ static void
 e_zone_rotation_set(E_Zone *zone,
                     int     rot)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_OBJECT_CHECK(zone);
    E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
 
@@ -1343,13 +1230,11 @@ e_zone_rotation_set(E_Zone *zone,
      zone->rot.unknown_state = EINA_FALSE;
 
    _e_zone_rotation_set_internal(zone, rot);
-#endif
 }
 
 static void
 e_zone_rotation_sub_set(E_Zone *zone, int rotation)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_OBJECT_CHECK(zone);
    E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
 
@@ -1358,26 +1243,20 @@ e_zone_rotation_sub_set(E_Zone *zone, int rotation)
    if ((zone->rot.unknown_state) &&
        (zone->rot.curr != rotation))
      _e_zone_rotation_set_internal(zone, rotation);
-#endif
 }
 
 static int
 e_zone_rotation_get(E_Zone *zone)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_OBJECT_CHECK_RETURN(zone, -1);
    E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, -1);
    if (!zone->rot.unknown_state) return zone->rot.curr;
    else return zone->rot.sub;
-#else
-   return -1;
-#endif
 }
 
 static Eina_Bool
 e_zone_rotation_block_set(E_Zone *zone, const char *name_hint, Eina_Bool set)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_Begin *ev;
 
    E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
@@ -1409,15 +1288,11 @@ e_zone_rotation_block_set(E_Zone *zone, const char *name_hint, Eina_Bool set)
      }
 
    return EINA_TRUE;
-#else
-   return EINA_FALSE;
-#endif
 }
 
 static void
 e_zone_rotation_update_done(E_Zone *zone)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_End *ev;
 
    E_OBJECT_CHECK(zone);
@@ -1451,13 +1326,11 @@ e_zone_rotation_update_done(E_Zone *zone)
                              ev2, _e_zone_event_rotation_change_begin_free, NULL);
           }
      }
-#endif
 }
 
 static void
 e_zone_rotation_update_cancel(E_Zone *zone)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_Event_Zone_Rotation_Change_Cancel *ev;
 
    E_OBJECT_CHECK(zone);
@@ -1479,14 +1352,12 @@ e_zone_rotation_update_cancel(E_Zone *zone)
         ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE_CANCEL,
                         ev, _e_zone_event_rotation_change_cancel_free, NULL);
      }
-#endif
 }
 
 /* e_client rotation internal callbacks */
 static Eina_Bool
 _rot_hook_client_free_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Eina_Bool rm_vkbd_parent = EINA_FALSE;
    int unref_count = 0;
 
@@ -1552,24 +1423,20 @@ _rot_hook_client_free_intern(E_Client *ec)
         unref_count--;
      }
 
-#endif
    return EINA_TRUE;
 }
 
 static Eina_Bool
 _rot_hook_client_del_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    _e_client_rotation_list_remove(ec);
    if (rot.async_list) rot.async_list = eina_list_remove(rot.async_list, ec);
-#endif
    return EINA_TRUE;
 }
 
 static void
 _rot_cb_evas_show_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (!ec->hidden)
      {
         if (rot.vkbd == ec)
@@ -1587,13 +1454,11 @@ _rot_cb_evas_show_intern(E_Client *ec)
                }
           }
      }
-#endif
 }
 
 static Eina_Bool
 _rot_hook_eval_end_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (ec->changes.rotation)
      {
         E_Zone *zone = ec->zone;
@@ -1617,14 +1482,12 @@ _rot_hook_eval_end_intern(E_Client *ec)
         rot.fetch = EINA_TRUE;
         ec->changes.rotation = 0;
      }
-#endif
    return EINA_TRUE;
 }
 
 static Eina_Bool
 _rot_cb_idle_enterer_intern(void)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if (rot.cancel.state)
      {
         /* there is no border which supports window manager rotation */
@@ -1743,14 +1606,12 @@ _rot_cb_idle_enterer_intern(void)
         rot.fetch = EINA_FALSE;
      }
 
-#endif
    return EINA_TRUE;
 }
 
 static Eina_Bool
 _rot_hook_new_client_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    Ecore_X_Window win = e_client_util_win_get(ec);
    int at_num = 0, i;
    Ecore_X_Atom *atoms;
@@ -1796,14 +1657,12 @@ _rot_hook_new_client_intern(E_Client *ec)
         free(atoms);
      }
 
-#endif
    return EINA_TRUE;
 }
 
 static Eina_Bool
 _rot_cb_zone_rotation_change_begin_intern(E_Event_Zone_Rotation_Change_Begin *ev)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if ((!ev) || (!ev->zone)) return EINA_FALSE;
 
    if (!_e_client_rotation_zone_set(ev->zone))
@@ -1814,14 +1673,12 @@ _rot_cb_zone_rotation_change_begin_intern(E_Event_Zone_Rotation_Change_Begin *ev
         rot.cancel.state = EINA_TRUE;
         rot.cancel.zone = ev->zone;
      }
-#endif
    return EINA_TRUE;
 }
 
 static Eina_Bool
 _rot_intercept_hook_hide_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    if ((rot.vkbd_ctrl_win) && (rot.vkbd) &&
        (ec == rot.vkbd) &&
        (!rot.vkbd_hide_prepare_done) &&
@@ -1916,14 +1773,12 @@ _rot_intercept_hook_hide_intern(E_Client *ec)
    // clear pending_show, because this window is hidden now.
    ec->e.state.rot.pending_show = 0;
 
-#endif
    return EINA_TRUE;
 }
 
 static Eina_Bool
 _rot_intercept_hook_show_helper_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    // newly created window that has to be rotated will be shown after rotation done.
    // so, skip at this time. it will be called again after GETTING ROT_DONE.
    if (ec->e.state.rot.ang.next != -1)
@@ -1946,11 +1801,9 @@ _rot_intercept_hook_show_helper_intern(E_Client *ec)
         return EINA_FALSE;
      }
 
-#endif
     return EINA_TRUE;
 }
 
-#ifndef HAVE_WAYLAND_ONLY
 static Eina_Bool
 _rot_cb_window_configure_intern(Ecore_X_Event_Window_Configure *ev)
 {
@@ -1962,7 +1815,7 @@ _rot_cb_window_configure_intern(Ecore_X_Event_Window_Configure *ev)
    if ((ec->e.state.rot.pending_change_request) &&
        (ec->e.state.rot.geom_hint))
      {
-        if ((ev->w == ec->w) && (ev->h == ec->h))
+        if ((ev->w == ec->client.w) && (ev->h == ec->client.h))
           {
              ec->e.state.rot.pending_change_request = 0;
              if (!ec->e.state.rot.wait_for_done)
@@ -2075,30 +1928,10 @@ _rot_cb_window_message_intern(Ecore_X_Event_Client_Message *ev)
      }
    return ECORE_CALLBACK_PASS_ON;
 }
-#endif
 
 static Eina_Bool
 _rot_hook_eval_fetch_intern(E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
-#if 0
-   //TODO: add vkbd fetch_transient_for flag
-   /* workaround: since transient_for is fetched by illume in hook,
-    * added below flag to know this state in this eval time
-    */
-   Eina_Bool fetch_transient_for = EINA_FALSE;
-
-   if (ec->icccm.fetch.transient_for)
-     {
-        if (((rot.vkbd) && (rot.vkbd == ec)) ||
-            ((rot.vkbd_prediction) && (rot.vkbd_prediction == ec)))
-          {
-             ec->e.fetch.rot.need_rotation = EINA_TRUE;
-          }
-
-        fetch_transient_for = EINA_TRUE;
-     }
-#endif
    //TODO: Add fetch flag for VKBD
    if ((ec->icccm.name) && (ec->icccm.class))
      {
@@ -2280,27 +2113,7 @@ _rot_hook_eval_fetch_intern(E_Client *ec)
 
         ec->e.fetch.rot.available_rots = 0;
      }
-#if 0
-   if (fetch_transient_for)
-     {
-        Eina_Bool need_fetch = EINA_FALSE;
-
-        if (rot.vkbd)
-          {
-             if (rot.vkbd == bd) need_fetch = EINA_TRUE;
-          }
-        else if ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd))
-          need_fetch = EINA_TRUE;
 
-        if (need_fetch)
-          {
-             if (bd->parent != rot.vkbd_parent)
-               {
-                  ;
-               }
-          }
-     }
-#endif
    if ((ec->e.fetch.rot.need_rotation) &&
        (ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_NORMAL))
      {
@@ -2319,11 +2132,9 @@ _rot_hook_eval_fetch_intern(E_Client *ec)
              hint = _e_client_rotation_geom_get(ec, ec->zone, ang, &x, &y, &w, &h, &move);
              if (hint)
                {
-#if 0
-                  /// need to change api to _e_comp_x_client_move_resize_send();
-                  _e_client_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);//?
-#endif
-                  e_client_util_move_resize_without_frame(ec, x, y, w, h); //check: this function work correct or not.
+                  //e_client_util_move_resize_without_frame(ec, x, y, w, h); //check: this function work correct or not.
+                  evas_object_move(ec->frame, x, y);
+                  e_client_util_resize_without_frame(ec, w, h);
                }
           }
         else
@@ -2334,7 +2145,6 @@ _rot_hook_eval_fetch_intern(E_Client *ec)
    if (ec->e.fetch.rot.need_rotation)
      ec->e.fetch.rot.need_rotation = EINA_FALSE;
 
-#endif
    return EINA_TRUE;
 }
 
@@ -2375,7 +2185,6 @@ _rot_intercept_hook_hide(void *d EINA_UNUSED, E_Client *ec)
    return _rot_intercept_hook_hide_intern(ec);
 }
 
-#ifndef HAVE_WAYLAND_ONLY
 static Eina_Bool
 _rot_cb_window_property(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Window_Property *ev)
 {
@@ -2410,7 +2219,6 @@ _rot_cb_window_message(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Eve
 
    return ECORE_CALLBACK_RENEW;
 }
-#endif
 
 static Eina_Bool
 _rot_cb_zone_rotation_change_begin(void *data EINA_UNUSED, int ev_type EINA_UNUSED, E_Event_Zone_Rotation_Change_Begin *ev)
@@ -2445,6 +2253,7 @@ _rot_hook_new_client_post(void *d EINA_UNUSED, E_Client *ec)
 
    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _rot_cb_evas_show, ec);
 }
+#endif //#ifndef HAVE_WAYLAND_ONLY
 
 /* externally accessible functions */
 /**
@@ -2456,16 +2265,13 @@ _rot_hook_new_client_post(void *d EINA_UNUSED, E_Client *ec)
 EINTERN int
 e_client_rotation_curr_angle_get(const E_Client *ec)
 {
-#ifndef HAVE_WAYLAND_ONLY
    E_OBJECT_CHECK_RETURN(ec, -1);
    E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, -1);
 
    return ec->e.state.rot.ang.curr;
-#else
-   return -1;
-#endif
 }
 
+#ifndef HAVE_WAYLAND_ONLY
 #undef E_CLIENT_HOOK_APPEND
 #define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
   do                                      \
@@ -2487,6 +2293,7 @@ e_client_rotation_curr_angle_get(const E_Client *ec)
        l = eina_list_append(l, _h);                      \
     }                                                    \
   while (0)
+#endif
 
 EINTERN void
 e_mod_pol_rotation_init(void)
@@ -2498,7 +2305,6 @@ e_mod_pol_rotation_init(void)
                          _rot_cb_window_configure, NULL);
    E_LIST_HANDLER_APPEND(rot_handlers, ECORE_X_EVENT_CLIENT_MESSAGE,
                          _rot_cb_window_message, NULL);
-#endif
    E_LIST_HANDLER_APPEND(rot_handlers, E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
                          _rot_cb_zone_rotation_change_begin, NULL);
 
@@ -2522,6 +2328,8 @@ e_mod_pol_rotation_init(void)
 
 
    rot_idle_enterer = ecore_idle_enterer_add(_rot_cb_idle_enterer, NULL);
+#endif
+
 #ifdef HAVE_WAYLAND_ONLY
    e_mod_rot_wl_init();
 #endif
@@ -2530,6 +2338,7 @@ e_mod_pol_rotation_init(void)
 EINTERN void
 e_mod_pol_rotation_shutdown(void)
 {
+#ifndef HAVE_WAYLAND_ONLY
    E_FREE_LIST(rot_hooks, e_client_hook_del);
    E_FREE_LIST(rot_handlers, ecore_event_handler_del);
    E_FREE_LIST(rot_intercept_hooks, e_comp_object_intercept_hook_del);
@@ -2539,6 +2348,7 @@ e_mod_pol_rotation_shutdown(void)
          ecore_idle_enterer_del(rot_idle_enterer);
          rot_idle_enterer = NULL;
      }
+#endif
 #ifdef HAVE_WAYLAND_ONLY
   e_mod_rot_wl_shutdown();
 #endif
index 2b74d94..7176750 100644 (file)
  */
 #include "e_mod_rotation_wl.h"
 
+#ifdef HAVE_WAYLAND_ONLY
+
 #include <wayland-server.h>
 #include "tizen_policy_ext-server-protocol.h"
 
-static Eina_Hash *hash_policy_ext_rotation = NULL;
+#define TIZEN_ROTATION_ANGLE_TO_INT(angle) ((angle == TIZEN_ROTATION_ANGLE_0) ? 0 :        \
+                                            (angle == TIZEN_ROTATION_ANGLE_90) ? 90 :      \
+                                            (angle == TIZEN_ROTATION_ANGLE_180) ? 180 :    \
+                                            (angle == TIZEN_ROTATION_ANGLE_270) ? 270 : -1)
+
+typedef struct _Geometry_Hint Geometry_Hint;
+typedef struct _Policy_Ext_Rotation Policy_Ext_Rotation;
+typedef struct _E_Client_Rotation E_Client_Rotation;
+
+struct _Geometry_Hint
+{
+   enum tizen_rotation_angle angle;
+   int x, y, w, h;
+};
+
+struct _Policy_Ext_Rotation
+{
+   E_Pixmap *ep;
+   uint32_t available_angles, preferred_angle;
+   enum tizen_rotation_angle cur_angle, prev_angle;
+   Eina_List *rotation_list;
+   Eina_Bool angle_change_done;
+
+   struct
+   {
+      enum tizen_rotation_angle angle;
+      int x, y, w, h;
+      Eina_Bool valid;
+   } geometry_hint[4];
+
+   uint32_t serial;
+
+};
 
-typedef struct _Policy_Ext_Rototation
+struct _E_Client_Rotation
 {
-  E_Pixmap *ep;
-  uint32_t available_angles, preferred_angles;
-  enum tizen_rotation_angle cur_angle, prev_angle;
-  Eina_List *rotation_list;
-  Eina_Bool angle_change_done;
-} Policy_Ext_Rototation;
+   Eina_List     *list;
+   Eina_List     *async_list;
+   Ecore_Timer   *done_timer;
+   Eina_Bool      screen_lock;
+   Eina_Bool      fetch;
+
+   struct
+   {
+      Eina_Bool    state;
+      E_Zone      *zone;
+   } cancel;
+};
+
+/* local subsystem variables */
+static E_Client_Rotation rot =
+{
+   NULL,
+   NULL,
+   NULL,
+   EINA_FALSE,
+   EINA_FALSE,
+   {
+      EINA_FALSE,
+      NULL,
+   }
+};
+static Eina_Hash *hash_policy_ext_rotation = NULL;
+static Eina_List *rot_handlers = NULL;
+static Eina_List *rot_hooks = NULL;
+static Eina_List *rot_intercept_hooks = NULL;
+static Ecore_Idle_Enterer *rot_idle_enterer = NULL;
 
 /* local subsystem functions */
-static void _e_tizen_rotation_send_angle_change(E_Client *ec, enum tizen_rotation_angle angle);
+static Policy_Ext_Rotation* _policy_ext_rotation_get(E_Pixmap *ep);
+
+/* local subsystem wayland rotation protocol related functions */
+static void _e_tizen_rotation_set_available_angles_cb(struct wl_client *client, struct wl_resource *resource, uint32_t angles);
+static void _e_tizen_rotation_set_preferred_angle_cb(struct wl_client *client, struct wl_resource *resource, uint32_t angle);
+static void _e_tizen_rotation_ack_angle_change_cb(struct wl_client *client, struct wl_resource *resource, uint32_t serial);
+static void _e_tizen_rotation_set_geometry_hints_cb(struct wl_client *client, struct wl_resource *resource, struct wl_array *geometry_hints);
+static void _e_tizen_rotation_destroy(struct wl_resource *resource);
+static void _e_tizen_rotation_send_angle_change(E_Client *ec, int angle);
+static void _e_tizen_policy_ext_get_rotation_cb(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface);
+static void _e_tizen_policy_ext_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id);
 
-static Policy_Ext_Rototation*
+/* local subsystem wayland rotation protocol related variables */
+static const struct tizen_rotation_interface _e_tizen_rotation_interface =
+{
+   _e_tizen_rotation_set_available_angles_cb,
+   _e_tizen_rotation_set_preferred_angle_cb,
+   _e_tizen_rotation_ack_angle_change_cb,
+   _e_tizen_rotation_set_geometry_hints_cb,
+   /* need rotation destroy request? */
+};
+static const struct tizen_policy_ext_interface _e_tizen_policy_ext_interface =
+{
+   _e_tizen_policy_ext_get_rotation_cb
+};
+
+/* local subsystem e_client_rotation related functions */
+static void      _e_client_rotation_list_remove(E_Client *ec);
+static Eina_Bool _e_client_rotation_zone_set(E_Zone *zone);
+static void      _e_client_rotation_change_done(void);
+static Eina_Bool _e_client_rotation_change_done_timeout(void *data);
+static void      _e_client_rotation_change_message_send(E_Client *ec);
+static Eina_Bool _e_client_rotation_is_dependent_parent(const E_Client *ec);
+static int       _e_client_rotation_curr_next_get(const E_Client *ec);
+static void      _e_client_event_client_rotation_change_begin_send(E_Client *ec);
+static void      _e_client_event_client_rotation_change_begin_free(void *data, void *ev);
+static void      _e_client_event_client_rotation_change_end_free(void *data, void *ev);
+
+/* local subsystem e_zone_rotation related functions */
+static void      _e_zone_event_rotation_change_begin_free(void *data, void *ev);
+static void      _e_zone_event_rotation_change_end_free(void *data, void *ev);
+static void      _e_zone_event_rotation_change_cancel_free(void *data, void *ev);
+
+/* e_client_roation functions */
+static Eina_Bool  e_client_rotation_is_progress(const E_Client *ec);
+static int        e_client_rotation_curr_angle_get(const E_Client *ec);
+static int        e_client_rotation_next_angle_get(const E_Client *ec);
+static Eina_Bool  e_client_rotation_is_available(const E_Client *ec, int ang);
+static Eina_Bool  e_client_rotation_set(E_Client *ec, int rotation);
+static void       e_client_rotation_change_request(E_Client *ec, int rotation);
+static int        e_client_rotation_recommend_angle_get(const E_Client *ec);
+
+/* e_zone_roation functions */
+static int        e_zone_rotation_get(E_Zone *zone);
+static void       e_zone_rotation_update_done(E_Zone *zone);
+static void       e_zone_rotation_update_cancel(E_Zone *zone);
+
+/* e_client event, hook, intercept callbacks */
+static Eina_Bool _rot_cb_zone_rotation_change_begin(void *data EINA_UNUSED, int ev_type EINA_UNUSED, E_Event_Zone_Rotation_Change_Begin *ev);
+static void      _rot_hook_new_client(void *d EINA_UNUSED, E_Client *ec);
+static void      _rot_hook_new_client_post(void *d EINA_UNUSED, E_Client *ec);
+static void      _rot_hook_client_del(void *d EINA_UNUSED, E_Client *ec);
+static void      _rot_hook_eval_end(void *d EINA_UNUSED, E_Client *ec);
+static void      _rot_hook_eval_fetch(void *d EINA_UNUSED, E_Client *ec);
+static Eina_Bool _rot_intercept_hook_show_helper(void *d EINA_UNUSED, E_Client *ec);
+static Eina_Bool _rot_intercept_hook_hide(void *d EINA_UNUSED, E_Client *ec);
+static Eina_Bool _rot_cb_idle_enterer(void *data EINA_UNUSED);
+static void      _rot_cb_evas_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
+
+/* local subsystem functions */
+static Policy_Ext_Rotation*
 _policy_ext_rotation_get(E_Pixmap *ep)
 {
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(hash_policy_ext_rotation, NULL);
 
    rot = eina_hash_find(hash_policy_ext_rotation, &ep);
    if (!rot)
      {
-        rot = E_NEW(Policy_Ext_Rototation, 1);
+        rot = E_NEW(Policy_Ext_Rotation, 1);
         EINA_SAFETY_ON_NULL_RETURN_VAL(rot, NULL);
 
         rot->ep = ep;
@@ -61,9 +188,9 @@ _e_tizen_rotation_set_available_angles_cb(struct wl_client *client,
                                           struct wl_resource *resource,
                                           uint32_t angles)
 {
-   // implementation;
+   E_Client *ec;
    E_Pixmap *ep;
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
 
    ep = wl_resource_get_user_data(resource);
    EINA_SAFETY_ON_NULL_RETURN(ep);
@@ -72,18 +199,23 @@ _e_tizen_rotation_set_available_angles_cb(struct wl_client *client,
    EINA_SAFETY_ON_NULL_RETURN(rot);
 
    rot->available_angles = angles;
+
+   ec = e_pixmap_client_get(ep);
+   if (ec)
+     {
+        ec->e.fetch.rot.available_rots = 1;
+        EC_CHANGED(ec);
+     }
 }
 
 static void
-_e_tizen_rotation_set_preferred_angles_cb(struct wl_client *client,
-                                          struct wl_resource *resource,
-                                          uint32_t angles)
+_e_tizen_rotation_set_preferred_angle_cb(struct wl_client *client,
+                                         struct wl_resource *resource,
+                                         uint32_t angle)
 {
-   // implementation;
    E_Pixmap *ep;
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
    E_Client *ec;
-   Eina_Bool rotation_change = EINA_FALSE;
 
    ep = wl_resource_get_user_data(resource);
    EINA_SAFETY_ON_NULL_RETURN(ep);
@@ -91,31 +223,14 @@ _e_tizen_rotation_set_preferred_angles_cb(struct wl_client *client,
    rot = _policy_ext_rotation_get(ep);
    EINA_SAFETY_ON_NULL_RETURN(rot);
 
-   rot->preferred_angles = angles;
+   rot->preferred_angle = angle;
 
-   //FIXME: move processing preferred angle logic to e-mod-rotation
    ec = e_pixmap_client_get(ep);
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-
-   switch ((angles & rot->available_angles))
+   if (ec)
      {
-        case TIZEN_ROTATION_ANGLE_0:
-          rotation_change = EINA_TRUE;
-          break;
-        case TIZEN_ROTATION_ANGLE_90:
-          rotation_change = EINA_TRUE;
-          break;
-        case TIZEN_ROTATION_ANGLE_180:
-          rotation_change = EINA_TRUE;
-          break;
-        case TIZEN_ROTATION_ANGLE_270:
-          rotation_change = EINA_TRUE;
-          break;
-        default:
-          break;
+        ec->e.fetch.rot.preferred_rot = 1;
+        EC_CHANGED(ec);
      }
-
-   if (rotation_change) _e_tizen_rotation_send_angle_change(ec, angles);
 }
 
 static void
@@ -123,9 +238,9 @@ _e_tizen_rotation_ack_angle_change_cb(struct wl_client *client,
                                       struct wl_resource *resource,
                                       uint32_t serial)
 {
-   // implementation;
+   E_Client *ec;
    E_Pixmap *ep;
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
 
    ep = wl_resource_get_user_data(resource);
    EINA_SAFETY_ON_NULL_RETURN(ep);
@@ -133,23 +248,112 @@ _e_tizen_rotation_ack_angle_change_cb(struct wl_client *client,
    rot = _policy_ext_rotation_get(ep);
    EINA_SAFETY_ON_NULL_RETURN(rot);
 
+   ec = e_pixmap_client_get(ep);
+   if (ec)
+     {
+        if (rot->serial == serial) // rotation success
+          {
+             ec->e.state.rot.ang.prev = ec->e.state.rot.ang.curr;
+             ec->e.state.rot.ang.curr = TIZEN_ROTATION_ANGLE_TO_INT(rot->cur_angle);
+
+             if (TIZEN_ROTATION_ANGLE_TO_INT(rot->cur_angle) == ec->e.state.rot.ang.next)
+               {
+                  ec->e.state.rot.ang.next = -1;
+                  _e_client_rotation_list_remove(ec);
+
+                  if (ec->e.state.rot.ang.reserve != -1)
+                    {
+                       e_client_rotation_set(ec, ec->e.state.rot.ang.reserve);
+                       ec->e.state.rot.ang.reserve = -1;
+                    }
+                  else if (ec->e.state.rot.pending_show)
+                    {
+                       ec->e.state.rot.pending_show = 0;
+                       evas_object_show(ec->frame);
+                    }
+               }
+          }
+        else // rotation fail
+          {
+             int angle = e_client_rotation_recommend_angle_get(ec);
+             if (angle != -1) e_client_rotation_set(ec, angle);
+          }
+     }
    // check angle change serial
    rot->angle_change_done = EINA_TRUE;
 }
 
-static const struct tizen_rotation_interface _e_tizen_rotation_interface =
+static void
+_e_tizen_rotation_set_geometry_hints_cb(struct wl_client *client,
+                                        struct wl_resource *resource,
+                                        struct wl_array *geometry_hints)
 {
-   _e_tizen_rotation_set_available_angles_cb,
-   _e_tizen_rotation_set_preferred_angles_cb,
-   _e_tizen_rotation_ack_angle_change_cb,
-   /* need rotation destroy request? */
-};
+   E_Client *ec;
+   E_Pixmap *ep;
+   Policy_Ext_Rotation *rot;
+   Geometry_Hint *geo_hint;
+   Eina_Bool geo_hint_change = EINA_FALSE;
+
+   ep = wl_resource_get_user_data(resource);
+   EINA_SAFETY_ON_NULL_RETURN(ep);
+
+   rot = _policy_ext_rotation_get(ep);
+   EINA_SAFETY_ON_NULL_RETURN(rot);
+
+   wl_array_for_each(geo_hint, geometry_hints)
+     {
+        Eina_Bool valid = EINA_FALSE;
+        int i;
+        switch(geo_hint->angle)
+          {
+             case TIZEN_ROTATION_ANGLE_0:
+               valid = EINA_TRUE;
+               i = 0;
+               break;
+             case TIZEN_ROTATION_ANGLE_90:
+               valid = EINA_TRUE;
+               i = 1;
+               break;
+             case TIZEN_ROTATION_ANGLE_180:
+               valid = EINA_TRUE;
+               i = 2;
+               break;
+             case TIZEN_ROTATION_ANGLE_270:
+               valid = EINA_TRUE;
+               i = 3;
+               break;
+             default:
+               break;
+          }
+
+        if (valid)
+          {
+             rot->geometry_hint[i].angle = geo_hint->angle;
+             rot->geometry_hint[i].x = geo_hint->x;
+             rot->geometry_hint[i].y = geo_hint->y;
+             rot->geometry_hint[i].w = geo_hint->w;
+             rot->geometry_hint[i].h = geo_hint->h;
+             rot->geometry_hint[i].valid = valid;
+             geo_hint_change = EINA_TRUE;
+          }
+     }
+
+   if (geo_hint_change)
+     {
+        ec = e_pixmap_client_get(ep);
+        if (ec)
+          {
+             ec->e.fetch.rot.geom_hint = 1;
+             EC_CHANGED(ec);
+          }
+     }
+}
 
 static void
 _e_tizen_rotation_destroy(struct wl_resource *resource)
 {
    E_Pixmap *ep;
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
 
    ep = wl_resource_get_user_data(resource);
    EINA_SAFETY_ON_NULL_RETURN(ep);
@@ -166,11 +370,11 @@ _e_tizen_policy_ext_get_rotation_cb(struct wl_client *client,
                                     uint32_t id,
                                     struct wl_resource *surface)
 {
-   // implementation;
    int version = wl_resource_get_version(resource); // resource is tizen_policy_ext resource
    struct wl_resource *res;
+   E_Client *ec;
    E_Pixmap *ep;
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
 
    ep = wl_resource_get_user_data(surface);
    EINA_SAFETY_ON_NULL_RETURN(ep);
@@ -186,16 +390,18 @@ _e_tizen_policy_ext_get_rotation_cb(struct wl_client *client,
         return;
      }
 
-  rot->rotation_list = eina_list_append(rot->rotation_list, res);
+   rot->rotation_list = eina_list_append(rot->rotation_list, res);
 
-  wl_resource_set_implementation(res, &_e_tizen_rotation_interface,
-                                 ep, _e_tizen_rotation_destroy);
-}
+   wl_resource_set_implementation(res, &_e_tizen_rotation_interface,
+                                  ep, _e_tizen_rotation_destroy);
 
-static const struct tizen_policy_ext_interface _e_tizen_policy_ext_interface =
-{
-   _e_tizen_policy_ext_get_rotation_cb
-};
+   ec = e_pixmap_client_get(ep);
+   if (ec)
+     {
+        ec->e.fetch.rot.support = 1;
+        EC_CHANGED(ec);
+     }
+}
 
 static void
 _e_tizen_policy_ext_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id)
@@ -220,14 +426,14 @@ _e_tizen_policy_ext_bind_cb(struct wl_client *client, void *data, uint32_t versi
 }
 
 static void
-_e_tizen_rotation_send_angle_change(E_Client *ec,
-                                    enum tizen_rotation_angle angle)
+_e_tizen_rotation_send_angle_change(E_Client *ec, int angle)
 {
    Eina_List *l;
-   Policy_Ext_Rototation *rot;
+   Policy_Ext_Rotation *rot;
+   int32_t width, height;
    uint32_t serial;
-
    struct wl_resource *resource;
+   enum tizen_rotation_angle tz_angle = TIZEN_ROTATION_ANGLE_0;
 
    EINA_SAFETY_ON_NULL_RETURN(ec);
    EINA_SAFETY_ON_NULL_RETURN(ec->pixmap);
@@ -236,22 +442,1083 @@ _e_tizen_rotation_send_angle_change(E_Client *ec,
    rot = eina_hash_find(hash_policy_ext_rotation, &ec->pixmap);
    if (!rot) return;
 
+   switch (angle)
+     {
+        case 0:
+          tz_angle = TIZEN_ROTATION_ANGLE_0;
+          break;
+        case 90:
+          tz_angle = TIZEN_ROTATION_ANGLE_90;
+          break;
+        case 180:
+          tz_angle = TIZEN_ROTATION_ANGLE_180;
+          break;
+        case 270:
+          tz_angle = TIZEN_ROTATION_ANGLE_270;
+          break;
+        default:
+          break;
+     }
+
    serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
 
    rot->angle_change_done = EINA_FALSE;
-   // set angle info moves to ack_change_angle_cb?
    rot->prev_angle = rot->cur_angle;
-   rot->cur_angle = angle;
+   rot->cur_angle = tz_angle;
+   rot->serial = serial;
+
+   //set default width, height
+   width = ec->w;
+   height = ec->h;
+   //check geometry hint for resize
+   if (ec->e.state.rot.geom_hint)
+     {
+        int i = angle / 90;
+
+        if ((ec->e.state.rot.geom[i].w != 0) &&
+            (ec->e.state.rot.geom[i].h != 0))
+          {
+             width = ec->e.state.rot.geom[i].w;
+             height = ec->e.state.rot.geom[i].h;
+          }
+     }
 
    EINA_LIST_FOREACH(rot->rotation_list, l, resource)
      {
-        tizen_rotation_send_angle_change(resource, angle, serial);
+        tizen_rotation_send_angle_change(resource, tz_angle, width, height, serial);
+     }
+}
+
+/* local subsystem e_client_rotation related functions */
+static void
+_e_client_rotation_list_remove(E_Client *ec)
+{
+   E_Event_Client_Rotation_Change_End *ev = NULL;
+   Eina_Bool found = EINA_FALSE;
+
+   if (eina_list_data_find(rot.list, ec) == ec)
+     {
+        found = EINA_TRUE;
+        rot.list = eina_list_remove(rot.list, ec);
+     }
+
+   if (ec->e.state.rot.wait_for_done)
+     {
+        ec->e.state.rot.wait_for_done = 0;
+
+        /* if we make the e_client event in the _e_client_free function,
+         * then we may meet a crash problem, only work this at least e_client_hide.
+         */
+        if (!e_object_is_del(E_OBJECT(ec)))
+          {
+             ev = E_NEW(E_Event_Client_Rotation_Change_End, 1);
+             if (ev)
+               {
+                  ev->ec = ec;
+                  e_object_ref(E_OBJECT(ec));
+                  ecore_event_add(E_EVENT_CLIENT_ROTATION_CHANGE_END,
+                                  ev,
+                                  _e_client_event_client_rotation_change_end_free,
+                                  NULL);
+               }
+          }
+
+        if ((found) &&
+            (eina_list_count(rot.list) == 0))
+          {
+             _e_client_rotation_change_done();
+          }
+     }
+   ec->e.state.rot.ang.next = -1;
+   ec->changes.rotation = 0;
+}
+
+static Eina_Bool
+_e_client_rotation_zone_set(E_Zone *zone)
+{
+   E_Client *ec = NULL;
+   Eina_Bool res = EINA_FALSE;
+   Eina_Bool ret = EINA_FALSE;
+   E_Zone *ez;
+   Eina_List *zl;
+
+   /* step 1. make the list needs to be rotated. */
+   EINA_LIST_FOREACH(e_comp->zones, zl, ez)
+     {
+        Eina_List *l;
+
+        if (ez != zone) continue;
+
+        EINA_LIST_REVERSE_FOREACH(zone->comp->clients, l, ec)
+          {
+             if(ec->zone != zone) continue;
+
+             // if this window has parent and window type isn't "E_WINDOW_TYPE_NORMAL",
+             // it will be rotated when parent do rotate itself.
+             // so skip here.
+             if ((ec->parent) &&
+                 (ec->netwm.type != E_WINDOW_TYPE_NORMAL)) continue;
+
+             // default type is "E_CLIENT_ROTATION_TYPE_NORMAL",
+             // but it can be changed to "E_CLIENT_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
+             // if it's not normal type window, will be rotated by illume.
+             // so skip here.
+             if (ec->e.state.rot.type != E_CLIENT_ROTATION_TYPE_NORMAL) continue;
+
+             if ((!evas_object_visible_get(ec->frame)) ||
+                 (!E_INTERSECTS(ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h,
+                                ec->x, ec->y, ec->w, ec->h))) continue;
+
+             res = e_client_rotation_set(ec, zone->rot.curr);
+             if (!res)
+               {
+                  ;
+               }
+             else ret = EINA_TRUE;
+          }
+     }
+
+   return ret;
+}
+
+static void
+_e_client_rotation_change_done(void)
+{
+   E_Manager *m = NULL;
+   E_Client *ec;
+
+   if (rot.done_timer) ecore_timer_del(rot.done_timer);
+   rot.done_timer = NULL;
+
+   EINA_LIST_FREE(rot.list, ec)
+     {
+        if (ec->e.state.rot.pending_show)
+          {
+             ec->e.state.rot.pending_show = 0;
+             evas_object_show(ec->frame); // e_client_show(ec);
+          }
+        ec->e.state.rot.ang.next = -1;
+        ec->e.state.rot.wait_for_done = 0;
+     }
+
+   EINA_LIST_FREE(rot.async_list, ec)
+     {
+        _e_client_rotation_change_message_send(ec);
+     }
+
+   rot.list = NULL;
+   rot.async_list = NULL;
+
+   m = e_manager_current_get();
+   if (rot.screen_lock)
+     {
+        // do call comp_wl's screen unlock
+        rot.screen_lock = EINA_FALSE;
+     }
+   e_zone_rotation_update_done(e_util_zone_current_get(m));
+}
+
+static Eina_Bool
+_e_client_rotation_change_done_timeout(void *data __UNUSED__)
+{
+   _e_client_rotation_change_done();
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_e_client_rotation_change_message_send(E_Client *ec)
+{
+   int rotation;
+
+   if (!ec) return;
+
+   rotation = ec->e.state.rot.ang.next;
+   if (rotation == -1) return;
+   if (ec->e.state.rot.wait_for_done) return;
+
+   e_client_rotation_change_request(ec, rotation);
+}
+
+static Eina_Bool
+_e_client_rotation_is_dependent_parent(const E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+   if ((!ec->parent) || (!evas_object_visible_get(ec->parent->frame))) return EINA_FALSE;
+   if (ec->netwm.type == E_WINDOW_TYPE_NORMAL) return EINA_FALSE;
+   if ((!ec->e.state.rot.support) &&
+       (!ec->e.state.rot.app_set)) return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static int
+_e_client_rotation_curr_next_get(const E_Client *ec)
+{
+   if (!ec) return -1;
+
+   return ((ec->e.state.rot.ang.next == -1) ?
+           ec->e.state.rot.ang.curr : ec->e.state.rot.ang.next);
+}
+
+static void
+_e_client_event_client_rotation_change_begin_send(E_Client *ec)
+{
+   E_Event_Client_Rotation_Change_Begin *ev = NULL;
+   ev = E_NEW(E_Event_Client_Rotation_Change_End, 1);
+   if (ev)
+     {
+        ev->ec = ec;
+        e_object_ref(E_OBJECT(ec));
+        ecore_event_add(E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN,
+                        ev,
+                        _e_client_event_client_rotation_change_begin_free,
+                        NULL);
+     }
+}
+
+static void
+_e_client_event_client_rotation_change_begin_free(void *data __UNUSED__,
+                                                  void      *ev)
+{
+   E_Event_Client_Rotation_Change_Begin *e;
+   e = ev;
+   e_object_unref(E_OBJECT(e->ec));
+   E_FREE(e);
+}
+
+static void
+_e_client_event_client_rotation_change_end_free(void *data __UNUSED__,
+                                                void      *ev)
+{
+   E_Event_Client_Rotation_Change_End *e;
+   e = ev;
+   e_object_unref(E_OBJECT(e->ec));
+   E_FREE(e);
+}
+
+static void
+_e_zone_event_rotation_change_begin_free(void *data __UNUSED__,
+                                         void      *ev)
+{
+   E_Event_Zone_Rotation_Change_Begin *e = ev;
+   e_object_unref(E_OBJECT(e->zone));
+   E_FREE(e);
+}
+
+static void
+_e_zone_event_rotation_change_end_free(void *data __UNUSED__,
+                                       void      *ev)
+{
+   E_Event_Zone_Rotation_Change_End *e = ev;
+   e_object_unref(E_OBJECT(e->zone));
+   E_FREE(e);
+}
+
+static void
+_e_zone_event_rotation_change_cancel_free(void *data __UNUSED__,
+                                          void      *ev)
+{
+   E_Event_Zone_Rotation_Change_Cancel *e = ev;
+   e_object_unref(E_OBJECT(e->zone));
+   E_FREE(e);
+}
+
+/* e_client_roation functions */
+/**
+ * @describe
+ *  Get current rotoation state.
+ * @param      ec             e_client
+ * @return     EINA_FALSE     the state that does not rotating.
+ *             EINA_TRUE      the state that rotating.
+ */
+static Eina_Bool
+e_client_rotation_is_progress(const E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+
+   if (ec->e.state.rot.ang.next == -1)
+     return EINA_FALSE;
+   else
+     return EINA_TRUE;
+}
+
+/**
+ * @describe
+ *  Get current rotation angle.
+ * @param      ec             e_client
+ * @return     int            current angle
+ */
+static int
+e_client_rotation_curr_angle_get(const E_Client *ec)
+{
+   E_OBJECT_CHECK_RETURN(ec, -1);
+   E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, -1);
+
+   return ec->e.state.rot.ang.curr;
+}
+
+/**
+ * @describe
+ *  Get being replaced rotation angle.
+ * @param      ec             e_client
+ * @return     int            be replaced angle.
+ */
+static int
+e_client_rotation_next_angle_get(const E_Client *ec)
+{
+   E_OBJECT_CHECK_RETURN(ec, -1);
+   E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, -1);
+
+   return ec->e.state.rot.ang.next;
+}
+
+/**
+ * @describe
+ *  Check if this e_client is rotatable to given angle.
+ * @param      ec             e_client
+ * @param      ang            test angle.
+ * @return     EINA_FALSE     can't be rotated.
+ *             EINA_TRUE      can be rotated.
+ */
+static Eina_Bool
+e_client_rotation_is_available(const E_Client *ec, int ang)
+{
+   if (!ec) return EINA_FALSE;
+
+   if (ang < 0) goto fail;
+   if ((!ec->e.state.rot.support) && (!ec->e.state.rot.app_set)) goto fail;
+   if (e_object_is_del(E_OBJECT(ec))) goto fail;
+
+   if (ec->e.state.rot.preferred_rot == -1)
+     {
+        unsigned int i;
+
+        if (ec->e.state.rot.app_set)
+          {
+             if (ec->e.state.rot.available_rots &&
+                 ec->e.state.rot.count)
+               {
+                  Eina_Bool found = EINA_FALSE;
+                  for (i = 0; i < ec->e.state.rot.count; i++)
+                    {
+                       if (ec->e.state.rot.available_rots[i] == ang)
+                         {
+                            found = EINA_TRUE;
+                         }
+                    }
+                  if (found) goto success;
+               }
+          }
+        else
+          {
+             goto success;
+          }
+     }
+   else if (ec->e.state.rot.preferred_rot == ang) goto success;
+
+fail:
+   return EINA_FALSE;
+success:
+   return EINA_TRUE;
+}
+
+/**
+ * @describe
+ *  Set the rotation of the e_client given angle.
+ * @param      ec             e_client
+ * *param      rotation       angle
+ * @return     EINA_TRUE      rotation starts or is already in progress.
+ *             EINA_FALSE     fail
+ */
+static Eina_Bool
+e_client_rotation_set(E_Client *ec, int rotation)
+{
+   Eina_List *list, *l;
+   E_Client *child;
+   int curr_rot;
+
+   if (!ec) return EINA_FALSE;
+
+   if (rotation < 0) return EINA_FALSE;
+   if (!e_client_rotation_is_available(ec, rotation)) return EINA_FALSE;
+
+   // in case same with current angle.
+   curr_rot = e_client_rotation_curr_angle_get(ec);
+   if (curr_rot == rotation)
+     {
+        if (e_client_rotation_is_progress(ec))
+          {
+             // cancel the changes in case only doesn't send request.
+             if ((!ec->e.state.rot.pending_change_request) &&
+                 (!ec->e.state.rot.wait_for_done))
+               {
+                  _e_client_rotation_list_remove(ec);
+                  if (ec->e.state.rot.pending_show)
+                    {
+                       ec->e.state.rot.pending_show = 0;
+                       if (!e_object_is_del(E_OBJECT(ec)))
+                         evas_object_show(ec->frame); // e_client_show(ec);
+                    }
+
+                  return EINA_FALSE;
+               }
+             else
+               ;
+          }
+        else
+          return EINA_FALSE;
+     }
+
+   // in case same with next angle.
+   curr_rot = e_client_rotation_next_angle_get(ec);
+   if (curr_rot == rotation)
+     {
+        // if there is reserve angle, remove it.
+        if (ec->e.state.rot.ang.reserve != -1)
+          {
+             ec->e.state.rot.ang.reserve = -1;
+          }
+        goto finish;
+     }
+
+   /* if this e_client is rotating now,
+    * it will be rotated to this angle after rotation done.
+    */
+   if ((ec->e.state.rot.pending_change_request) ||
+       (ec->e.state.rot.wait_for_done))
+     {
+        ec->e.state.rot.ang.reserve = rotation;
+        goto finish;
+     }
+
+   /* search rotatable window in this window's child */
+   list = eina_list_clone(ec->transients);
+   EINA_LIST_FOREACH(list, l, child)
+     {
+        // the window which type is "E_WINDOW_TYPE_NORMAL" will be rotated itself.
+        // it shouldn't be rotated by rotation state of parent window.
+        if (child->netwm.type == E_WINDOW_TYPE_NORMAL) continue;
+        if (e_client_rotation_set(child, rotation))
+          {
+             ;
+          }
+        else
+          {
+             ;
+          }
+     }
+   eina_list_free(list);
+
+   _e_client_event_client_rotation_change_begin_send(ec);
+
+   ec->e.state.rot.pending_change_request = 0;
+   ec->e.state.rot.ang.next = rotation;
+   ec->changes.rotation = 1;
+   EC_CHANGED(ec);
+
+finish:
+   /* Now the WM has a rotatable window thus we unset variables about zone rotation cancel */
+   if (rot.cancel.state)
+     {
+        rot.cancel.state = EINA_FALSE;
+        rot.cancel.zone = NULL;
+     }
+
+   return EINA_TRUE;
+}
+
+static void
+e_client_rotation_change_request(E_Client *ec, int rotation)
+{
+   if (!ec) return;
+   if (rotation < 0) return;
+
+   // if this window is in withdrawn state, change the state to NORMAL.
+   // that's because the window in withdrawn state can't render its canvas.
+   // eventually, this window will not send the message of rotation done,
+   // even if e request to rotation this window.
+
+   //TODO: e_hint set is really neeed?.
+   e_hints_window_visible_set(ec);
+
+   _e_tizen_rotation_send_angle_change(ec, rotation);
+
+   ec->e.state.rot.wait_for_done = 1;
+
+   if ((!rot.async_list) ||
+       (!eina_list_data_find(rot.async_list, ec)))
+     {
+        if (rot.done_timer)
+          ecore_timer_del(rot.done_timer);
+        rot.done_timer = ecore_timer_add(4.0f,
+                                         _e_client_rotation_change_done_timeout,
+                                         NULL);
+     }
+}
+
+/**
+ * @describe
+ *  Get the angle that this e_client should be rotated.
+ * @param      ec             e_client
+ * @return     Eina_Bool      -1: There is no need to be rotated.
+ *                            != -1: The angle that this e_client should be rotated.
+ */
+static int
+e_client_rotation_recommend_angle_get(const E_Client *ec)
+{
+   E_Zone *zone = NULL;
+   int ret_ang = -1;
+
+   E_OBJECT_CHECK_RETURN(ec, ret_ang);
+   E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, ret_ang);
+
+   zone = ec->zone;
+
+   if (ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_DEPENDENT) goto end;
+   if ((!ec->e.state.rot.app_set) && (!ec->e.state.rot.support)) goto end;
+
+   if (ec->e.state.rot.preferred_rot != -1)
+     {
+        ret_ang = ec->e.state.rot.preferred_rot;
+     }
+   else if ((ec->e.state.rot.available_rots) &&
+            (ec->e.state.rot.count))
+     {
+        unsigned int i;
+        int current_ang = _e_client_rotation_curr_next_get(ec);
+        Eina_Bool found = EINA_FALSE;
+        Eina_Bool found_curr_ang = EINA_FALSE;
+
+        if (_e_client_rotation_is_dependent_parent(ec))
+          {
+             ret_ang = _e_client_rotation_curr_next_get(ec->parent);
+          }
+        else
+          {
+             ret_ang = e_zone_rotation_get(zone);
+          }
+
+        for (i = 0; i < ec->e.state.rot.count; i++)
+          {
+             if (ec->e.state.rot.available_rots[i] == ret_ang)
+               {
+                  found = EINA_TRUE;
+                  break;
+               }
+             if (ec->e.state.rot.available_rots[i] == current_ang)
+               found_curr_ang = EINA_TRUE;
+          }
+
+        if (!found)
+          {
+             if (found_curr_ang)
+               ret_ang = current_ang;
+             else
+               ret_ang = ec->e.state.rot.available_rots[0];
+          }
+     }
+   else
+     ;
+
+end:
+   return ret_ang;
+}
+
+/* e_zone_roation functions */
+static int
+e_zone_rotation_get(E_Zone *zone)
+{
+   E_OBJECT_CHECK_RETURN(zone, -1);
+   E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, -1);
+   if (!zone->rot.unknown_state) return zone->rot.curr;
+   else return zone->rot.sub;
+}
+
+static void
+e_zone_rotation_update_done(E_Zone *zone)
+{
+   E_Event_Zone_Rotation_Change_End *ev;
+
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   ev = E_NEW(E_Event_Zone_Rotation_Change_End, 1);
+   if (ev)
+     {
+        ev->zone = zone;
+        e_object_ref(E_OBJECT(ev->zone));
+        ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE_END,
+                        ev, _e_zone_event_rotation_change_end_free, NULL);
+     }
+
+   zone->rot.wait_for_done = EINA_FALSE;
+   if ((zone->rot.pending) &&
+       (zone->rot.block_count == 0))
+     {
+        zone->rot.prev = zone->rot.curr;
+        zone->rot.curr = zone->rot.next;
+        zone->rot.wait_for_done = EINA_TRUE;
+        zone->rot.pending = EINA_FALSE;
+
+        E_Event_Zone_Rotation_Change_Begin *ev2;
+        ev2 = E_NEW(E_Event_Zone_Rotation_Change_Begin, 1);
+        if (ev2)
+          {
+             ev2->zone = zone;
+             e_object_ref(E_OBJECT(ev2->zone));
+             ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
+                             ev2, _e_zone_event_rotation_change_begin_free, NULL);
+          }
+     }
+}
+
+static void
+e_zone_rotation_update_cancel(E_Zone *zone)
+{
+   E_Event_Zone_Rotation_Change_Cancel *ev;
+
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   zone->rot.wait_for_done = EINA_FALSE;
+   if (zone->rot.pending)
+     {
+        zone->rot.prev = zone->rot.curr;
+        zone->rot.curr = zone->rot.next;
+        zone->rot.pending = EINA_FALSE;
+     }
+
+   ev = E_NEW(E_Event_Zone_Rotation_Change_Cancel, 1);
+   if (ev)
+     {
+        ev->zone = zone;
+        e_object_ref(E_OBJECT(ev->zone));
+        ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE_CANCEL,
+                        ev, _e_zone_event_rotation_change_cancel_free, NULL);
+     }
+}
+
+static Eina_Bool
+_rot_cb_zone_rotation_change_begin(void *data EINA_UNUSED, int ev_type EINA_UNUSED, E_Event_Zone_Rotation_Change_Begin *ev)
+{
+   if ((!ev) || (!ev->zone)) return ECORE_CALLBACK_PASS_ON;
+
+   if (!_e_client_rotation_zone_set(ev->zone))
+     {
+        /* The WM will decide to cancel zone rotation at idle time.
+         * Because, the policy module can make list of rotation windows
+         */
+        rot.cancel.state = EINA_TRUE;
+        rot.cancel.zone = ev->zone;
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_rot_hook_new_client(void *d EINA_UNUSED, E_Client *ec)
+{
+   Policy_Ext_Rotation *rot;
+   int i = 0;
+
+   ec->e.state.rot.preferred_rot = -1;
+   ec->e.state.rot.type = E_CLIENT_ROTATION_TYPE_NORMAL;
+   ec->e.state.rot.ang.next = -1;
+   ec->e.state.rot.ang.reserve = -1;
+   ec->e.state.rot.pending_show = 0;
+   ec->e.state.rot.ang.curr = 0;
+   ec->e.state.rot.ang.prev = 0;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec->pixmap);
+   EINA_SAFETY_ON_NULL_RETURN(hash_policy_ext_rotation);
+
+   rot = eina_hash_find(hash_policy_ext_rotation, &ec->pixmap);
+   if (!rot) return;
+
+   ec->e.fetch.rot.support = 1;
+
+   for (i = 0; i < 4; i++)
+      {
+         if (rot->geometry_hint[i].valid)
+           {
+              ec->e.fetch.rot.geom_hint = 1;
+              break;
+           }
+      }
+
+   if (rot->preferred_angle)
+     {
+        ec->e.fetch.rot.app_set = 1;
+        ec->e.fetch.rot.preferred_rot = 1;
+     }
+
+   if (rot->available_angles)
+     {
+        ec->e.fetch.rot.app_set = 1;
+        ec->e.fetch.rot.available_rots = 1;
+     }
+}
+
+static void
+_rot_hook_new_client_post(void *d EINA_UNUSED, E_Client *ec)
+{
+   if (!ec->frame)
+      return;
+
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _rot_cb_evas_show, ec);
+}
+
+static void
+_rot_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
+{
+   _e_client_rotation_list_remove(ec);
+   if (rot.async_list) rot.async_list = eina_list_remove(rot.async_list, ec);
+
+   ec->e.fetch.rot.app_set = 0;
+   ec->e.state.rot.preferred_rot = -1;
+
+   if (ec->e.state.rot.available_rots)
+     E_FREE(ec->e.state.rot.available_rots);
+}
+
+static void
+_rot_hook_eval_end(void *d EINA_UNUSED, E_Client *ec)
+{
+   if (ec->changes.rotation)
+     {
+        E_Zone *zone = ec->zone;
+
+        if (ec->moving) e_client_act_move_end(ec, NULL);
+
+        if ((!zone->rot.block_count) &&
+            ((!evas_object_visible_get(ec->frame)) ||
+             (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))))
+          {
+             // async list add
+             rot.async_list = eina_list_append(rot.async_list, ec);
+          }
+        else
+          {
+             // sync list add
+             rot.list = eina_list_append(rot.list, ec);
+             _e_client_rotation_change_message_send(ec);
+          }
+        rot.fetch = EINA_TRUE;
+        ec->changes.rotation = 0;
+     }
+}
+
+static void
+_rot_hook_eval_fetch(void *d EINA_UNUSED, E_Client *ec)
+{
+   Policy_Ext_Rotation *rot;
+
+   if (!ec) return;
+   if (!ec->pixmap) return;
+
+   rot = eina_hash_find(hash_policy_ext_rotation, &ec->pixmap);
+   if (!rot) return;
+
+   if(ec->e.fetch.rot.support)
+     {
+        ec->e.state.rot.support = 1;
+
+        ec->e.fetch.rot.need_rotation = EINA_TRUE;
+        ec->e.fetch.rot.support = 0;
+     }
+   if (ec->e.fetch.rot.geom_hint)
+     {
+        Eina_Rectangle r[4];
+        int i;
+        ec->e.state.rot.geom_hint = 0;
+        for (i = 0; i < 4; i++)
+          {
+             r[i].x = ec->e.state.rot.geom[i].x;
+             r[i].y = ec->e.state.rot.geom[i].y;
+             r[i].w = ec->e.state.rot.geom[i].w;
+             r[i].h = ec->e.state.rot.geom[i].h;
+
+             ec->e.state.rot.geom[i].x = 0;
+             ec->e.state.rot.geom[i].y = 0;
+             ec->e.state.rot.geom[i].w = 0;
+             ec->e.state.rot.geom[i].h = 0;
+          }
+
+        for (i = 0; i < 4; i++)
+          {
+             if (rot->geometry_hint[i].valid)
+               {
+                  ec->e.state.rot.geom_hint = 1;
+                  ec->e.state.rot.geom[i].x = rot->geometry_hint[i].x;
+                  ec->e.state.rot.geom[i].y = rot->geometry_hint[i].y;
+                  ec->e.state.rot.geom[i].w = rot->geometry_hint[i].w;
+                  ec->e.state.rot.geom[i].h = rot->geometry_hint[i].h;
+
+                  if (!((r[i].x == rot->geometry_hint[i].x) &&
+                        (r[i].y == rot->geometry_hint[i].y) &&
+                        (r[i].w == rot->geometry_hint[i].w) &&
+                        (r[i].h == rot->geometry_hint[i].h)))
+                    {
+                       ec->e.fetch.rot.need_rotation = EINA_TRUE;
+                    }
+               }
+          }
+        ec->e.fetch.rot.geom_hint = 0;
+     }
+   if (ec->e.fetch.rot.preferred_rot)
+     {
+        int _prev_preferred_rot;
+        _prev_preferred_rot = ec->e.state.rot.preferred_rot;
+        ec->e.state.rot.preferred_rot = -1;
+
+        switch (rot->preferred_angle)
+          {
+             case TIZEN_ROTATION_ANGLE_0:
+                ec->e.state.rot.preferred_rot = 0;
+                break;
+             case TIZEN_ROTATION_ANGLE_90:
+                ec->e.state.rot.preferred_rot = 90;
+                break;
+             case TIZEN_ROTATION_ANGLE_180:
+                ec->e.state.rot.preferred_rot = 180;
+                break;
+             case TIZEN_ROTATION_ANGLE_270:
+                ec->e.state.rot.preferred_rot = 270;
+                break;
+             default:
+                break;
+          }
+
+        if (_prev_preferred_rot != ec->e.state.rot.preferred_rot)
+          ec->e.fetch.rot.need_rotation = EINA_TRUE;
+
+        ec->e.fetch.rot.preferred_rot = 0;
+     }
+   if (ec->e.fetch.rot.available_rots)
+     {
+        Eina_Bool diff = EINA_FALSE;
+        int *rots = NULL;
+        unsigned int _prev_count = 0, count = 0, i = 0;
+        int _prev_rots[4] = { -1, };
+        uint32_t available_angles = 0;
+
+        if (ec->e.state.rot.available_rots)
+          {
+             memcpy(_prev_rots,
+                    ec->e.state.rot.available_rots,
+                    (sizeof(int) * ec->e.state.rot.count));
+             E_FREE(ec->e.state.rot.available_rots);
+          }
+
+        _prev_count = ec->e.state.rot.count;
+        ec->e.state.rot.count = 0;
+
+        /* check avilable_angles */
+        if (rot->available_angles & TIZEN_ROTATION_ANGLE_0) count++;
+        if (rot->available_angles & TIZEN_ROTATION_ANGLE_90) count++;
+        if (rot->available_angles & TIZEN_ROTATION_ANGLE_180) count++;
+        if (rot->available_angles & TIZEN_ROTATION_ANGLE_270) count++;
+
+        available_angles = rot->available_angles;
+        rots = (int*)E_NEW(int, count);
+
+        if ((count > 0) && (rots))
+          {
+             for (i = 0; i < count; i++)
+              {
+                  if (available_angles & TIZEN_ROTATION_ANGLE_0)
+                    {
+                       rots[i] = 0;
+                       available_angles = available_angles & ~TIZEN_ROTATION_ANGLE_0;
+                    }
+                  else if (available_angles & TIZEN_ROTATION_ANGLE_90)
+                    {
+                       rots[i] = 90;
+                       available_angles = available_angles & ~TIZEN_ROTATION_ANGLE_90;
+                    }
+                  else if (available_angles & TIZEN_ROTATION_ANGLE_180)
+                    {
+                       rots[i] = 180;
+                       available_angles = available_angles & ~TIZEN_ROTATION_ANGLE_180;
+                    }
+                  else if (available_angles & TIZEN_ROTATION_ANGLE_270)
+                    {
+                       rots[i] = 270;
+                       available_angles = available_angles & ~TIZEN_ROTATION_ANGLE_270;
+                    }
+               }
+
+             ec->e.state.rot.available_rots = rots;
+             ec->e.state.rot.count = count;
+
+             if (_prev_count != count) diff = EINA_TRUE;
+
+             for (i = 0; i < count; i++)
+               {
+                  if ((!diff) && (_prev_rots[i] != rots[i]))
+                    {
+                       diff = EINA_TRUE;
+                       break;
+                    }
+               }
+           }
+        /* check avilable_angles end*/
+
+        if (diff) ec->e.fetch.rot.need_rotation = EINA_TRUE;
+        ec->e.fetch.rot.available_rots = 0;
+     }
+
+   if ((ec->e.fetch.rot.need_rotation) &&
+       (ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_NORMAL))
+     {
+        int ang = 0;
+
+        ang = e_client_rotation_recommend_angle_get(ec);
+        e_client_rotation_set(ec, ang);
+     }
+
+   if (ec->e.fetch.rot.need_rotation)
+     ec->e.fetch.rot.need_rotation = EINA_FALSE;
+}
+
+static Eina_Bool
+_rot_intercept_hook_show_helper(void *d EINA_UNUSED, E_Client *ec)
+{
+   // newly created window that has to be rotated will be shown after rotation done.
+   // so, skip at this time. it will be called again after GETTING ROT_DONE.
+
+   //TODO: Check below code is really need?
+   if (ec->e.state.rot.ang.next != -1)
+     {
+        ec->e.state.rot.pending_show = 1;
+        return EINA_FALSE;
+     }
+
+    return EINA_TRUE;
+}
+
+static Eina_Bool
+_rot_intercept_hook_hide(void *d EINA_UNUSED, E_Client *ec)
+{
+   // TODO: Add VKBD Hide, VKBD Parent Hide routine.
+   // clear pending_show, because this window is hidden now.
+   ec->e.state.rot.pending_show = 0;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_rot_cb_idle_enterer(void *data EINA_UNUSED)
+{
+   if (rot.cancel.state)
+     {
+        /* there is no border which supports window manager rotation */
+        e_zone_rotation_update_cancel(rot.cancel.zone);
+        rot.cancel.state = EINA_FALSE;
+        rot.cancel.zone = NULL;
+     }
+
+   if (rot.fetch)
+     {
+        //TODO: consider rot.msgs , X WM use it for e_client message
+
+        // if there is windows over 2 that has to be rotated or is existed window needs resizing,
+        // lock the screen.
+        // but, DO NOT lock the screen when rotation block state
+        if (eina_list_count(rot.list) > 1)
+          {
+             Eina_List *l;
+             E_Client *ec;
+             Eina_Bool rot_block = EINA_FALSE;
+
+             EINA_LIST_FOREACH(rot.list, l, ec)
+               {
+                  if (!ec->zone) continue;
+                  if (ec->zone->rot.block_count)
+                    {
+                       rot_block = EINA_TRUE;
+                    }
+               }
+             if ((!rot.screen_lock) && (!rot_block))
+               {
+                  //Do implement screen lock api on e_comp.
+                  //do call comp_wl's screen lock
+                  rot.screen_lock = EINA_TRUE;
+               }
+          }
+        else if (eina_list_count(rot.list) == 0)
+          {
+             E_Client *ec;
+             Eina_List *zlist = NULL;
+             Eina_List *l = NULL;
+             E_Zone *zone = NULL;
+
+             if (rot.async_list)
+               {
+                  EINA_LIST_FREE(rot.async_list, ec)
+                    {
+                       if (!eina_list_data_find(zlist, ec->zone))
+                         zlist = eina_list_append(zlist, ec->zone);
+                       _e_client_rotation_change_message_send(ec);
+                    }
+
+                  EINA_LIST_FOREACH(zlist, l, zone)
+                    e_zone_rotation_update_cancel(zone);
+                  if (zlist)
+                    eina_list_free(zlist);
+               }
+          }
+
+        rot.fetch = EINA_FALSE;
      }
+
+   return ECORE_CALLBACK_RENEW;
 }
 
+static void
+_rot_cb_evas_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   E_Client *ec = data;
+   if (!ec->iconic)
+     {
+        if ((ec->e.state.rot.support) || (ec->e.state.rot.app_set))
+          {
+             if (ec->e.state.rot.ang.next == -1)
+               {
+                  int rotation = e_client_rotation_recommend_angle_get(ec);
+                  if (rotation != -1) e_client_rotation_set(ec, rotation);
+               }
+          }
+     }
+}
+
+#undef E_CLIENT_HOOK_APPEND
+#define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
+  do                                      \
+    {                                     \
+       E_Client_Hook *_h;                 \
+       _h = e_client_hook_add(t, cb, d);  \
+       assert(_h);                        \
+       l = eina_list_append(l, _h);       \
+    }                                     \
+  while (0)
+
+#undef E_COMP_OBJECT_INTERCEPT_HOOK_APPEND
+#define E_COMP_OBJECT_INTERCEPT_HOOK_APPEND(l, t, cb, d) \
+  do                                                     \
+    {                                                    \
+       E_Comp_Object_Intercept_Hook *_h;                 \
+       _h = e_comp_object_intercept_hook_add(t, cb, d);  \
+       assert(_h);                                       \
+       l = eina_list_append(l, _h);                      \
+    }                                                    \
+  while (0)
+
+#endif //#ifdef HAVE_WAYLAND_ONLY
+
 Eina_Bool
 e_mod_rot_wl_init(void)
 {
+#ifdef HAVE_WAYLAND_ONLY
    E_Comp_Data *cdata;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
@@ -269,39 +1536,46 @@ e_mod_rot_wl_init(void)
 
    hash_policy_ext_rotation = eina_hash_pointer_new(free);
 
+   E_LIST_HANDLER_APPEND(rot_handlers, E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
+                         _rot_cb_zone_rotation_change_begin, NULL);
+
+   E_CLIENT_HOOK_APPEND(rot_hooks, E_CLIENT_HOOK_NEW_CLIENT,
+                        _rot_hook_new_client, NULL);
+   E_CLIENT_HOOK_APPEND(rot_hooks, E_CLIENT_HOOK_NEW_CLIENT_POST,
+                        _rot_hook_new_client_post, NULL);
+   E_CLIENT_HOOK_APPEND(rot_hooks, E_CLIENT_HOOK_DEL,
+                        _rot_hook_client_del, NULL);
+   E_CLIENT_HOOK_APPEND(rot_hooks, E_CLIENT_HOOK_EVAL_END,
+                        _rot_hook_eval_end, NULL);
+   E_CLIENT_HOOK_APPEND(rot_hooks, E_CLIENT_HOOK_EVAL_FETCH,
+                        _rot_hook_eval_fetch, NULL);
+
+   E_COMP_OBJECT_INTERCEPT_HOOK_APPEND(rot_intercept_hooks,
+                                       E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER,
+                                       _rot_intercept_hook_show_helper, NULL);
+   E_COMP_OBJECT_INTERCEPT_HOOK_APPEND(rot_intercept_hooks,
+                                       E_COMP_OBJECT_INTERCEPT_HOOK_HIDE,
+                                       _rot_intercept_hook_hide, NULL);
+
+   rot_idle_enterer = ecore_idle_enterer_add(_rot_cb_idle_enterer, NULL);
+#endif
    return EINA_TRUE;
 }
 
-
 void
 e_mod_rot_wl_shutdown(void)
 {
+#ifdef HAVE_WAYLAND_ONLY
    E_FREE_FUNC(hash_policy_ext_rotation, eina_hash_free);
-}
 
-void
-e_mod_rot_wl_angle_change_send(E_Client *ec,
-                               int angle)
-{
-   enum tizen_rotation_angle ang;
-   switch (angle)
+   E_FREE_LIST(rot_hooks, e_client_hook_del);
+   E_FREE_LIST(rot_handlers, ecore_event_handler_del);
+   E_FREE_LIST(rot_intercept_hooks, e_comp_object_intercept_hook_del);
+
+   if (rot_idle_enterer)
      {
-        case 0:
-          ang = TIZEN_ROTATION_ANGLE_0;
-          break;
-        case 90:
-          ang = TIZEN_ROTATION_ANGLE_90;
-          break;
-        case 180:
-          ang = TIZEN_ROTATION_ANGLE_180;
-          break;
-        case 270:
-          ang = TIZEN_ROTATION_ANGLE_270;
-          break;
-        default:
-          ang = TIZEN_ROTATION_ANGLE_0;
-          break;
+         ecore_idle_enterer_del(rot_idle_enterer);
+         rot_idle_enterer = NULL;
      }
-
-   _e_tizen_rotation_send_angle_change(ec, ang);
+#endif
 }
index 3c898bf..ca41e6d 100644 (file)
@@ -10,7 +10,5 @@
 Eina_Bool e_mod_rot_wl_init(void);
 void e_mod_rot_wl_shutdown(void);
 
-void e_mod_rot_wl_angle_change_send(E_Client *ec, int angle);
-
 #endif /* HAVE_WAYLAND_ONLY */
 #endif /* E_MOD_ROTATION_WL_H */
index 008ac93..6b54618 100644 (file)
@@ -8,12 +8,14 @@ extern const struct wl_interface wl_surface_interface;
 static const struct wl_interface *types[] = {
        NULL,
        NULL,
+       NULL,
+       NULL,
        &tizen_rotation_interface,
        &wl_surface_interface,
 };
 
 static const struct wl_message tizen_policy_ext_requests[] = {
-       { "get_rotation", "no", types + 2 },
+       { "get_rotation", "no", types + 4 },
 };
 
 WL_EXPORT const struct wl_interface tizen_policy_ext_interface = {
@@ -24,19 +26,20 @@ WL_EXPORT const struct wl_interface tizen_policy_ext_interface = {
 
 static const struct wl_message tizen_rotation_requests[] = {
        { "set_available_angles", "u", types + 0 },
-       { "set_preferred_angles", "u", types + 0 },
+       { "set_preferred_angle", "u", types + 0 },
        { "ack_angle_change", "u", types + 0 },
+       { "set_geometry_hints", "a", types + 0 },
 };
 
 static const struct wl_message tizen_rotation_events[] = {
        { "available_angles_done", "u", types + 0 },
-       { "preferred_angles_done", "u", types + 0 },
-       { "angle_change", "uu", types + 0 },
+       { "preferred_angle_done", "u", types + 0 },
+       { "angle_change", "uiiu", types + 0 },
 };
 
 WL_EXPORT const struct wl_interface tizen_rotation_interface = {
        "tizen_rotation", 1,
-       3, tizen_rotation_requests,
+       4, tizen_rotation_requests,
        3, tizen_rotation_events,
 };
 
index dabb355..0b0f0b6 100644 (file)
@@ -34,6 +34,7 @@ struct tizen_policy_ext_interface {
 #ifndef TIZEN_ROTATION_ANGLE_ENUM
 #define TIZEN_ROTATION_ANGLE_ENUM
 enum tizen_rotation_angle {
+       TIZEN_ROTATION_ANGLE_NONE = 0,
        TIZEN_ROTATION_ANGLE_0 = 1,
        TIZEN_ROTATION_ANGLE_90 = 2,
        TIZEN_ROTATION_ANGLE_180 = 4,
@@ -50,12 +51,12 @@ struct tizen_rotation_interface {
                                     struct wl_resource *resource,
                                     uint32_t angles);
        /**
-        * set_preferred_angles - (none)
-        * @angles: (none)
+        * set_preferred_angle - (none)
+        * @angle: (none)
         */
-       void (*set_preferred_angles)(struct wl_client *client,
-                                    struct wl_resource *resource,
-                                    uint32_t angles);
+       void (*set_preferred_angle)(struct wl_client *client,
+                                   struct wl_resource *resource,
+                                   uint32_t angle);
        /**
         * ack_angle_change - ack a angle_change
         * @serial: a serial to angle_change for
@@ -65,14 +66,21 @@ struct tizen_rotation_interface {
        void (*ack_angle_change)(struct wl_client *client,
                                 struct wl_resource *resource,
                                 uint32_t serial);
+       /**
+        * set_geometry_hints - (none)
+        * @geometry_hints: (none)
+        */
+       void (*set_geometry_hints)(struct wl_client *client,
+                                  struct wl_resource *resource,
+                                  struct wl_array *geometry_hints);
 };
 
 #define TIZEN_ROTATION_AVAILABLE_ANGLES_DONE   0
-#define TIZEN_ROTATION_PREFERRED_ANGLES_DONE   1
+#define TIZEN_ROTATION_PREFERRED_ANGLE_DONE    1
 #define TIZEN_ROTATION_ANGLE_CHANGE    2
 
 #define TIZEN_ROTATION_AVAILABLE_ANGLES_DONE_SINCE_VERSION     1
-#define TIZEN_ROTATION_PREFERRED_ANGLES_DONE_SINCE_VERSION     1
+#define TIZEN_ROTATION_PREFERRED_ANGLE_DONE_SINCE_VERSION      1
 #define TIZEN_ROTATION_ANGLE_CHANGE_SINCE_VERSION      1
 
 static inline void
@@ -82,15 +90,15 @@ tizen_rotation_send_available_angles_done(struct wl_resource *resource_, uint32_
 }
 
 static inline void
-tizen_rotation_send_preferred_angles_done(struct wl_resource *resource_, uint32_t angles)
+tizen_rotation_send_preferred_angle_done(struct wl_resource *resource_, uint32_t angle)
 {
-       wl_resource_post_event(resource_, TIZEN_ROTATION_PREFERRED_ANGLES_DONE, angles);
+       wl_resource_post_event(resource_, TIZEN_ROTATION_PREFERRED_ANGLE_DONE, angle);
 }
 
 static inline void
-tizen_rotation_send_angle_change(struct wl_resource *resource_, uint32_t angle, uint32_t serial)
+tizen_rotation_send_angle_change(struct wl_resource *resource_, uint32_t angle, int32_t width, int32_t height, uint32_t serial)
 {
-       wl_resource_post_event(resource_, TIZEN_ROTATION_ANGLE_CHANGE, angle, serial);
+       wl_resource_post_event(resource_, TIZEN_ROTATION_ANGLE_CHANGE, angle, width, height, serial);
 }
 
 #ifdef  __cplusplus
index 4407d59..ede39b2 100644 (file)
@@ -7,6 +7,7 @@
      </interface>
      <interface name="tizen_rotation" version="1">
         <enum name="angle">
+          <entry name="none" value = "0"/>
           <entry name="0" value = "1"/>
           <entry name="90" value = "2"/>
           <entry name="180" value = "4"/>
         <event name="available_angles_done">
             <arg name="angles" type="uint"/>
         </event>
-        <request name="set_preferred_angles">
-            <arg name="angles" type="uint"/>
+        <request name="set_preferred_angle">
+            <arg name="angle" type="uint"/>
         </request>
-        <event name="preferred_angles_done">
-            <arg name="angles" type="uint"/>
+        <event name="preferred_angle_done">
+            <arg name="angle" type="uint"/>
         </event>
         <event name="angle_change">
             <description summary="suggest a angle_change"/>
             <arg name="angle" type="uint"/>
+            <arg name="width" type="int"/>
+            <arg name="height" type="int"/>
             <arg name="serial" type="uint"/>
         </event>
         <request name="ack_angle_change">
             <description summary="ack a  angle_change"/>
             <arg name="serial" type="uint" summary="a serial to angle_change for"/>
         </request>
+        <request name="set_geometry_hints">
+            <arg name="geometry_hints" type="array"/>
+        </request>
      </interface>
 </protocol>