[access] support back gesture
[framework/uifw/elementary.git] / src / lib / elm_win.c
old mode 100644 (file)
new mode 100755 (executable)
index 9fc6f73..a141514
@@ -43,6 +43,7 @@ static const Elm_Win_Trap *trap = NULL;
 
 #define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : (_elm_config->engine ? _elm_config->engine : ""))
 #define ENGINE_COMPARE(name) (!strcmp(ENGINE_GET(), name))
+#define EE_ENGINE_COMPARE(ee, name) (!strcmp(ecore_evas_engine_name_get(ee), name))
 
 typedef struct _Elm_Win_Smart_Data Elm_Win_Smart_Data;
 
@@ -81,6 +82,7 @@ struct _Elm_Win_Smart_Data
    Elm_Win_Keyboard_Mode          kbdmode;
    Elm_Win_Indicator_Mode         indmode;
    Elm_Win_Indicator_Opacity_Mode ind_o_mode;
+   Elm_Win_Indicator_Type_Mode ind_t_mode;
    struct
    {
       const char  *info;
@@ -90,7 +92,6 @@ struct _Elm_Win_Smart_Data
    } shot;
    int                            resize_location;
    int                           *autodel_clear, rot;
-   int                            show_count;
    struct
    {
       int x, y;
@@ -127,6 +128,14 @@ struct _Elm_Win_Smart_Data
       Ecore_Timer *timer;
       Eina_List   *names;
    } profile;
+   struct
+   {
+      int          preferred_rot; // specified by app
+      int         *rots;          // available rotations
+      unsigned int count;         // number of elements in available rotations
+      Eina_Bool    wm_supported : 1;
+      Eina_Bool    use : 1;
+   } wm_rot;
 
    Evas_Object *icon;
    const char  *title;
@@ -171,6 +180,7 @@ static const char SIG_IOERR[] = "ioerr";
 static const char SIG_INDICATOR_PROP_CHANGED[] = "indicator,prop,changed";
 static const char SIG_ROTATION_CHANGED[] = "rotation,changed";
 static const char SIG_PROFILE_CHANGED[] = "profile,changed";
+static const char SIG_WM_ROTATION_CHANGED[] = "wm,rotation,changed";
 
 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_DELETE_REQUEST, ""},
@@ -190,6 +200,7 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_INDICATOR_PROP_CHANGED, ""},
    {SIG_ROTATION_CHANGED, ""},
    {SIG_PROFILE_CHANGED, ""},
+   {SIG_WM_ROTATION_CHANGED, ""},
    {NULL, NULL}
 };
 
@@ -206,25 +217,11 @@ static Eina_Bool _elm_win_auto_throttled = EINA_FALSE;
 
 static Ecore_Job *_elm_win_state_eval_job = NULL;
 
-static void
-_elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y)
-{
-   Elm_Win_Smart_Data *sd = data;
+static void _elm_win_resize_objects_eval(Evas_Object *obj);
 
-   if (sd->img_obj)
-     {
-        if ((x != sd->screen.x) || (y != sd->screen.y))
-          {
-             sd->screen.x = x;
-             sd->screen.y = y;
-             evas_object_smart_callback_call(obj, SIG_MOVED, NULL);
-          }
-     }
-   else
-     {
-        evas_object_move(obj, x, y);
-     }
-}
+#ifdef HAVE_ELEMENTARY_X
+static void _elm_win_xwin_update(Elm_Win_Smart_Data *sd);
+#endif
 
 static void
 _elm_win_obj_intercept_show(void *data, Evas_Object *obj)
@@ -580,7 +577,7 @@ _elm_win_obj_intercept_layer_set(void *data, Evas_Object *obj __UNUSED__, int l)
    TRAP(sd, layer_set, l);
 }
 
-    static void
+static void
 _ecore_evas_move_(void *data, Evas_Object *obj __UNUSED__, int a, int b)
 {
    printf("[%s][%d] a=%d, b=%d\n", __FUNCTION__, __LINE__, a, b);
@@ -588,7 +585,6 @@ _ecore_evas_move_(void *data, Evas_Object *obj __UNUSED__, int a, int b)
    TRAP(sd, move, a, b);
 }
 
-
 /* Event Callbacks */
 
 static void
@@ -722,18 +718,18 @@ _elm_win_focus_highlight_anim_setup(Elm_Win_Smart_Data *sd,
    evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, NULL, NULL, &w, &h);
    evas_object_geometry_get(target, &tx, &ty, &tw, &th);
    evas_object_geometry_get(previous, &px, &py, &pw, &ph);
-   evas_object_move(obj, 0, 0);
+   evas_object_move(obj, tx, ty);
    evas_object_resize(obj, tw, th);
    evas_object_clip_unset(obj);
 
    m = alloca(sizeof(*m) + (sizeof(int) * 8));
    m->count = 8;
-   m->val[0] = px;
-   m->val[1] = py;
+   m->val[0] = px - tx;
+   m->val[1] = py - ty;
    m->val[2] = pw;
    m->val[3] = ph;
-   m->val[4] = tx;
-   m->val[5] = ty;
+   m->val[4] = 0;
+   m->val[5] = 0;
    m->val[6] = tw;
    m->val[7] = th;
    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
@@ -848,16 +844,17 @@ _elm_win_focus_in(Ecore_Evas *ee)
 {
    Elm_Win_Smart_Data *sd = _elm_win_associate_get(ee);
    Evas_Object *obj;
+   unsigned int order = 0;
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
 
    obj = ELM_WIDGET_DATA(sd)->obj;
 
    _elm_widget_top_win_focused_set(obj, EINA_TRUE);
-   if (!elm_widget_focus_order_get(obj))
+   if (!elm_widget_focus_order_get(obj)
+       || (obj == elm_widget_newest_focus_order_get(obj, &order, EINA_TRUE)))
      {
         elm_widget_focus_steal(obj);
-        sd->show_count++;
      }
    else
      elm_widget_focus_restore(obj);
@@ -895,6 +892,9 @@ _elm_win_focus_out(Ecore_Evas *ee)
         edje_object_signal_emit(sd->frame_obj, "elm,action,unfocus", "elm");
      }
 
+   /* access */
+   _elm_access_object_hilight_disable(evas_object_evas_get(obj));
+
    /* do nothing */
    /* if (sd->img_obj) */
    /*   { */
@@ -962,6 +962,7 @@ _elm_win_state_change(Ecore_Evas *ee)
    Eina_Bool ch_fullscreen = EINA_FALSE;
    Eina_Bool ch_maximized = EINA_FALSE;
    Eina_Bool ch_profile = EINA_FALSE;
+   Eina_Bool ch_wm_rotation = EINA_FALSE;
    const char *profile;
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
@@ -1011,6 +1012,14 @@ _elm_win_state_change(Ecore_Evas *ee)
              ch_profile = EINA_TRUE;
           }
      }
+   if (sd->wm_rot.use)
+     {
+        if (sd->rot != ecore_evas_rotation_get(sd->ee))
+          {
+             sd->rot = ecore_evas_rotation_get(sd->ee);
+             ch_wm_rotation = EINA_TRUE;
+          }
+     }
 
    _elm_win_state_eval_queue();
 
@@ -1048,6 +1057,18 @@ _elm_win_state_change(Ecore_Evas *ee)
      {
         _elm_win_profile_update(ee);
      }
+   if (ch_wm_rotation)
+     {
+        evas_object_size_hint_min_set(obj, -1, -1);
+        evas_object_size_hint_max_set(obj, -1, -1);
+        _elm_win_resize_objects_eval(obj);
+#ifdef HAVE_ELEMENTARY_X
+        _elm_win_xwin_update(sd);
+#endif
+        elm_widget_orientation_set(obj, sd->rot);
+        evas_object_smart_callback_call(obj, SIG_ROTATION_CHANGED, NULL);
+        evas_object_smart_callback_call(obj, SIG_WM_ROTATION_CHANGED, NULL);
+     }
 }
 
 static Eina_Bool
@@ -1213,7 +1234,6 @@ _elm_win_smart_show(Evas_Object *obj)
 
    TRAP(sd, show);
 
-   if (!sd->show_count) sd->show_count++;
    if (sd->shot.info) _shot_handle(sd);
 }
 
@@ -1418,9 +1438,81 @@ _elm_win_on_img_obj_del(void *data,
 }
 
 static void
+_elm_win_resize_objects_eval(Evas_Object *obj)
+{
+   const Eina_List *l;
+   const Evas_Object *child;
+
+   ELM_WIN_DATA_GET(obj, sd);
+   Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
+   int xx = 1, xy = 1;
+   double wx, wy;
+
+   EINA_LIST_FOREACH(sd->resize_objs, l, child)
+     {
+        evas_object_size_hint_weight_get(child, &wx, &wy);
+        if (wx == 0.0) xx = 0;
+        if (wy == 0.0) xy = 0;
+
+        evas_object_size_hint_min_get(child, &w, &h);
+        if (w < 1) w = 1;
+        if (h < 1) h = 1;
+        if (w > minw) minw = w;
+        if (h > minh) minh = h;
+
+        evas_object_size_hint_max_get(child, &w, &h);
+        if (w < 1) w = -1;
+        if (h < 1) h = -1;
+        if (maxw == -1) maxw = w;
+        else if ((w > 0) && (w < maxw))
+          maxw = w;
+        if (maxh == -1) maxh = h;
+        else if ((h > 0) && (h < maxh))
+          maxh = h;
+     }
+   if (!xx) maxw = minw;
+   else maxw = 32767;
+   if (!xy) maxh = minh;
+   else maxh = 32767;
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w < minw) w = minw;
+   if (h < minh) h = minh;
+   if ((maxw >= 0) && (w > maxw)) w = maxw;
+   if ((maxh >= 0) && (h > maxh)) h = maxh;
+   evas_object_resize(obj, w, h);
+}
+
+static void
+_elm_win_on_resize_obj_del(void *data,
+                           Evas *e __UNUSED__,
+                           Evas_Object *obj __UNUSED__,
+                           void *event_info __UNUSED__)
+{
+   ELM_WIN_DATA_GET(data, sd);
+
+   sd->resize_objs = eina_list_remove(sd->resize_objs, obj);
+
+   _elm_win_resize_objects_eval(data);
+}
+
+static void
+_elm_win_on_resize_obj_changed_size_hints(void *data,
+                                          Evas *e __UNUSED__,
+                                          Evas_Object *obj __UNUSED__,
+                                          void *event_info __UNUSED__)
+{
+   _elm_win_resize_objects_eval(data);
+}
+
+static void
 _elm_win_smart_del(Evas_Object *obj)
 {
    const char *str;
+   const Eina_List *l;
+   const Evas_Object *child;
+
    ELM_WIN_DATA_GET(obj, sd);
 
    /* NB: child deletion handled by parent's smart del */
@@ -1435,6 +1527,15 @@ _elm_win_smart_del(Evas_Object *obj)
         sd->parent = NULL;
      }
 
+   EINA_LIST_FOREACH(sd->resize_objs, l, child)
+     {
+        evas_object_event_callback_del_full
+           (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+            _elm_win_on_resize_obj_changed_size_hints, obj);
+        evas_object_event_callback_del_full
+           (child, EVAS_CALLBACK_DEL, _elm_win_on_resize_obj_del, obj);
+     }
+
    if (sd->autodel_clear) *(sd->autodel_clear) = -1;
 
    _elm_win_list = eina_list_remove(_elm_win_list, obj);
@@ -1485,6 +1586,9 @@ _elm_win_smart_del(Evas_Object *obj)
    if (sd->profile.name) eina_stringshare_del(sd->profile.name);
    if (sd->profile.timer) ecore_timer_del(sd->profile.timer);
 
+   if (sd->wm_rot.rots) free(sd->wm_rot.rots);
+   sd->wm_rot.rots = NULL;
+
    /* Don't let callback in the air that point to sd */
    ecore_evas_callback_delete_request_set(sd->ee, NULL);
    ecore_evas_callback_resize_set(sd->ee, NULL);
@@ -1607,31 +1711,31 @@ _elm_ee_xwin_get(const Ecore_Evas *ee)
    Ecore_X_Window xwin = 0;
 
    if (!ee) return 0;
-   if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
+   if (EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_X11))
      {
         if (ee) xwin = ecore_evas_software_x11_window_get(ee);
      }
-   else if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
-            ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) ||
-            ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
-            ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
-            ENGINE_COMPARE(ELM_OPENGL_SDL) ||
-            ENGINE_COMPARE(ELM_OPENGL_COCOA))
+   else if (EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_FB) ||
+            EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_16_WINCE) ||
+            EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_SDL) ||
+            EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_16_SDL) ||
+            EE_ENGINE_COMPARE(ee, ELM_OPENGL_SDL) ||
+            EE_ENGINE_COMPARE(ee, ELM_OPENGL_COCOA))
      {
      }
-   else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
+   else if (EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_16_X11))
      {
         if (ee) xwin = ecore_evas_software_x11_16_window_get(ee);
      }
-   else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
+   else if (EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_8_X11))
      {
         if (ee) xwin = ecore_evas_software_x11_8_window_get(ee);
      }
-   else if (ENGINE_COMPARE(ELM_OPENGL_X11))
+   else if (EE_ENGINE_COMPARE(ee, ELM_OPENGL_X11))
      {
         if (ee) xwin = ecore_evas_gl_x11_window_get(ee);
      }
-   else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
+   else if (EE_ENGINE_COMPARE(ee, ELM_SOFTWARE_WIN32))
      {
         if (ee) xwin = (long)ecore_evas_win32_window_get(ee);
      }
@@ -1799,74 +1903,6 @@ _elm_win_xwin_update(Elm_Win_Smart_Data *sd)
 
 #endif
 
-static void
-_elm_win_resize_objects_eval(Evas_Object *obj)
-{
-   const Eina_List *l;
-   const Evas_Object *child;
-
-   ELM_WIN_DATA_GET(obj, sd);
-   Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
-   int xx = 1, xy = 1;
-   double wx, wy;
-
-   EINA_LIST_FOREACH(sd->resize_objs, l, child)
-     {
-        evas_object_size_hint_weight_get(child, &wx, &wy);
-        if (wx == 0.0) xx = 0;
-        if (wy == 0.0) xy = 0;
-
-        evas_object_size_hint_min_get(child, &w, &h);
-        if (w < 1) w = 1;
-        if (h < 1) h = 1;
-        if (w > minw) minw = w;
-        if (h > minh) minh = h;
-
-        evas_object_size_hint_max_get(child, &w, &h);
-        if (w < 1) w = -1;
-        if (h < 1) h = -1;
-        if (maxw == -1) maxw = w;
-        else if ((w > 0) && (w < maxw))
-          maxw = w;
-        if (maxh == -1) maxh = h;
-        else if ((h > 0) && (h < maxh))
-          maxh = h;
-     }
-   if (!xx) maxw = minw;
-   else maxw = 32767;
-   if (!xy) maxh = minh;
-   else maxh = 32767;
-   evas_object_size_hint_min_set(obj, minw, minh);
-   evas_object_size_hint_max_set(obj, maxw, maxh);
-   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
-   if (w < minw) w = minw;
-   if (h < minh) h = minh;
-   if ((maxw >= 0) && (w > maxw)) w = maxw;
-   if ((maxh >= 0) && (h > maxh)) h = maxh;
-   evas_object_resize(obj, w, h);
-}
-
-static void
-_elm_win_on_resize_obj_del(void *data,
-                           Evas *e __UNUSED__,
-                           Evas_Object *obj __UNUSED__,
-                           void *event_info __UNUSED__)
-{
-   ELM_WIN_DATA_GET(data, sd);
-
-   sd->resize_objs = eina_list_remove(sd->resize_objs, obj);
-
-   _elm_win_resize_objects_eval(data);
-}
-
-static void
-_elm_win_on_resize_obj_changed_size_hints(void *data,
-                                          Evas *e __UNUSED__,
-                                          Evas_Object *obj __UNUSED__,
-                                          void *event_info __UNUSED__)
-{
-   _elm_win_resize_objects_eval(data);
-}
 
 void
 _elm_win_shutdown(void)
@@ -1924,6 +1960,8 @@ _elm_win_client_message(void *data,
                         int type __UNUSED__,
                         void *event)
 {
+   Elm_Access_Action_Info *a;
+   Ecore_X_Atom atom_scroll, atom_back, atom_control_panel_open;
    Elm_Win_Smart_Data *sd = data;
    Ecore_X_Event_Client_Message *e = event;
 
@@ -1961,6 +1999,10 @@ _elm_win_client_message(void *data,
      {
         if ((unsigned int)e->data.l[0] == sd->x.xwin)
           {
+             atom_scroll = ecore_x_atom_get("_E_MOD_SCREEN_READER_ACTION_SCROLL_");
+             atom_back = ecore_x_atom_get("_E_MOD_SCREEN_READER_ACTION_BACK_");
+             atom_control_panel_open = ecore_x_atom_get("_E_MOD_SCREEN_READER_ACTION_CONTROL_PANEL_OPEN_");
+
              if ((unsigned int)e->data.l[1] ==
                  ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
                {
@@ -1981,8 +2023,15 @@ _elm_win_client_message(void *data,
                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
                {
                   /* there would be better way to read highlight object */
-                  ecore_x_mouse_in_send(sd->x.xwin, e->data.l[2], e->data.l[3]);
-                  ecore_x_mouse_move_send(sd->x.xwin, e->data.l[2], e->data.l[3]);
+                  Evas *evas;
+                  evas = evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj);
+                  if (!evas) return ECORE_CALLBACK_PASS_ON;
+
+                  a = calloc(1, sizeof(Elm_Access_Action_Info));
+                  a->x = e->data.l[2];
+                  a->y = e->data.l[3];
+                  elm_access_action(ELM_WIDGET_DATA(sd)->obj, ELM_ACCESS_ACTION_HIGHLIGHT, a);
+                  free(a);
                }
              else if ((unsigned int)e->data.l[1] ==
                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
@@ -2006,6 +2055,19 @@ _elm_win_client_message(void *data,
                   _elm_access_highlight_object_activate
                     (ELM_WIDGET_DATA(sd)->obj, ELM_ACTIVATE_DOWN);
                }
+             else if ((unsigned int)e->data.l[1] == atom_scroll)
+               {
+                  _elm_access_highlight_object_scroll(ELM_WIDGET_DATA(sd)->obj,
+                    e->data.l[2], e->data.l[3], e->data.l[4]);
+               }
+             else if ((unsigned int)e->data.l[1] == atom_back)
+               {
+                  _elm_access_highlight_object_activate
+                    (ELM_WIDGET_DATA(sd)->obj, ELM_ACTIVATE_BACK);
+               }
+             else if ((unsigned int)e->data.l[1] == atom_control_panel_open)
+               {
+               }
           }
      }
    return ECORE_CALLBACK_PASS_ON;
@@ -2027,6 +2089,13 @@ _elm_win_property_change(void *data,
              evas_object_smart_callback_call(ELM_WIDGET_DATA(sd)->obj, SIG_INDICATOR_PROP_CHANGED, NULL);
           }
      }
+   if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
+     {
+        if (e->win == sd->x.xwin)
+          {
+             sd->kbdmode = ecore_x_e_virtual_keyboard_state_get(e->win);
+          }
+     }
    return ECORE_CALLBACK_PASS_ON;
 }
 #endif
@@ -2611,6 +2680,7 @@ elm_win_add(Evas_Object *parent,
                   opt_i++;
                   opt[opt_i] = 1;
                   opt_i++;
+                                 opt[opt_i] = 0;
                }
              if (opt_i > 0)
                tmp_sd.ee = ecore_evas_gl_x11_options_new
@@ -2830,11 +2900,11 @@ elm_win_add(Evas_Object *parent,
      (obj, _elm_win_obj_intercept_stack_below, sd);
    evas_object_intercept_layer_set_callback_add
      (obj, _elm_win_obj_intercept_layer_set, sd);
-//   evas_object_intercept_show_callback_add
-//     (obj, _elm_win_obj_intercept_show, sd);
+   evas_object_intercept_show_callback_add
+     (obj, _elm_win_obj_intercept_show, sd);
+   evas_object_intercept_move_callback_add
+     (obj, _ecore_evas_move_, sd);
 
-   evas_object_intercept_move_callback_add(obj,
-                                             _ecore_evas_move_, sd);
    TRAP(sd, name_class_set, name, _elm_appname);
    ecore_evas_callback_delete_request_set(sd->ee, _elm_win_delete_request);
    ecore_evas_callback_resize_set(sd->ee, _elm_win_resize);
@@ -2914,6 +2984,9 @@ elm_win_add(Evas_Object *parent,
         // do nothing
      }
 
+   sd->wm_rot.wm_supported = ecore_evas_wm_rotation_supported_get(sd->ee);
+   sd->wm_rot.preferred_rot = -1; // it means that elm_win doesn't use preferred rotation.
+
    return obj;
 }
 
@@ -3660,47 +3733,52 @@ elm_win_render(Evas_Object *obj)
    ecore_evas_manual_render(sd->ee);
 }
 
-EAPI void
-elm_win_rotation_set(Evas_Object *obj,
-                     int rotation)
+static int
+_win_rotation_degree_check(int rotation)
 {
-   ELM_WIN_CHECK(obj);
-   ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
+   if ((rotation > 360) || (rotation < 0))
+     {
+        WRN("Rotation degree should be 0 ~ 360 (passed degree: %d)", rotation);
+        rotation %= 360;
+        if (rotation < 0) rotation += 360;
+     }
+   return rotation;
+}
 
-   rotation %= 360;
-   if (rotation < 0) rotation += 360;
+static void
+_win_rotate(Evas_Object *obj, Elm_Win_Smart_Data *sd, int rotation, Eina_Bool resize)
+{
+   rotation = _win_rotation_degree_check(rotation);
    if (sd->rot == rotation) return;
    sd->rot = rotation;
-   TRAP(sd, rotation_set, rotation);
+   if (resize) TRAP(sd, rotation_with_resize_set, rotation);
+   else TRAP(sd, rotation_set, rotation);
    evas_object_size_hint_min_set(obj, -1, -1);
    evas_object_size_hint_max_set(obj, -1, -1);
    _elm_win_resize_objects_eval(obj);
 #ifdef HAVE_ELEMENTARY_X
    _elm_win_xwin_update(sd);
 #endif
+   elm_widget_orientation_set(obj, rotation);
    evas_object_smart_callback_call(obj, SIG_ROTATION_CHANGED, NULL);
 }
 
 EAPI void
+elm_win_rotation_set(Evas_Object *obj,
+                     int rotation)
+{
+   ELM_WIN_CHECK(obj);
+   ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
+   _win_rotate(obj, sd, rotation, EINA_FALSE);
+}
+
+EAPI void
 elm_win_rotation_with_resize_set(Evas_Object *obj,
                                  int rotation)
 {
    ELM_WIN_CHECK(obj);
    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
-
-   rotation %= 360;
-   if (rotation < 0) rotation += 360;
-   if (sd->rot == rotation) return;
-   sd->rot = rotation;
-   TRAP(sd, rotation_with_resize_set, rotation);
-   evas_object_size_hint_min_set(obj, -1, -1);
-   evas_object_size_hint_max_set(obj, -1, -1);
-   _elm_win_resize_objects_eval(obj);
-
-#ifdef HAVE_ELEMENTARY_X
-   _elm_win_xwin_update(sd);
-#endif
-   evas_object_smart_callback_call(obj, SIG_ROTATION_CHANGED, NULL);
+   _win_rotate(obj, sd, rotation, EINA_TRUE);
 }
 
 EAPI int
@@ -3712,6 +3790,114 @@ elm_win_rotation_get(const Evas_Object *obj)
    return sd->rot;
 }
 
+EAPI Eina_Bool
+elm_win_wm_rotation_supported_get(const Evas_Object *obj)
+{
+   ELM_WIN_CHECK(obj) EINA_FALSE;
+   ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
+   return sd->wm_rot.wm_supported;
+}
+
+/* This will unset a preferred rotation, if given preferred rotation is '-1'.
+ */
+EAPI void
+elm_win_wm_rotation_preferred_rotation_set(Evas_Object *obj,
+                                           const int rotation)
+{
+   int rot;
+
+   ELM_WIN_CHECK(obj);
+   ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
+
+   if (!sd->wm_rot.use)
+     sd->wm_rot.use = EINA_TRUE;
+
+   // '-1' means that elm_win doesn't use preferred rotation.
+   if (rotation == -1)
+     rot = -1;
+   else
+     rot = _win_rotation_degree_check(rotation);
+
+   if (sd->wm_rot.preferred_rot == rot) return;
+   sd->wm_rot.preferred_rot = rot;
+
+   ecore_evas_wm_rotation_preferred_rotation_set(sd->ee, rot);
+}
+
+EAPI int
+elm_win_wm_rotation_preferred_rotation_get(const Evas_Object *obj)
+{
+   ELM_WIN_CHECK(obj) -1;
+   ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1);
+   if (!sd->wm_rot.use) return -1;
+   return sd->wm_rot.preferred_rot;
+}
+
+EAPI void
+elm_win_wm_rotation_available_rotations_set(Evas_Object *obj,
+                                            const int   *rotations,
+                                            unsigned int count)
+{
+   unsigned int i;
+   int r;
+
+   ELM_WIN_CHECK(obj);
+   ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
+
+   if (!sd->wm_rot.use)
+     sd->wm_rot.use = EINA_TRUE;
+
+   if (sd->wm_rot.rots) free(sd->wm_rot.rots);
+
+   sd->wm_rot.rots = NULL;
+   sd->wm_rot.count = 0;
+
+   if (count > 0)
+     {
+        sd->wm_rot.rots = calloc(count, sizeof(int));
+        if (!sd->wm_rot.rots) return;
+        for (i = 0; i < count; i++)
+          {
+             r = _win_rotation_degree_check(rotations[i]);
+             sd->wm_rot.rots[i] = r;
+          }
+     }
+
+   sd->wm_rot.count = count;
+
+   ecore_evas_wm_rotation_available_rotations_set(sd->ee,
+                                                  sd->wm_rot.rots,
+                                                  sd->wm_rot.count);
+}
+
+EAPI Eina_Bool
+elm_win_wm_rotation_available_rotations_get(const Evas_Object *obj,
+                                            int              **rotations,
+                                            unsigned int      *count)
+{
+   ELM_WIN_CHECK(obj) EINA_FALSE;
+   ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
+   if (!sd->wm_rot.use) return EINA_FALSE;
+
+   if (sd->wm_rot.count > 0)
+     {
+        if ((rotations) && (*rotations))
+          {
+             *rotations = calloc(sd->wm_rot.count, sizeof(int));
+             if (*rotations)
+               {
+                  memcpy(*rotations,
+                         sd->wm_rot.rots,
+                         sizeof(int) * sd->wm_rot.count);
+               }
+          }
+     }
+
+   if (count) *count = sd->wm_rot.count;
+
+   return EINA_TRUE;
+}
+
 EAPI void
 elm_win_sticky_set(Evas_Object *obj,
                    Eina_Bool sticky)
@@ -3865,6 +4051,38 @@ elm_win_indicator_opacity_get(const Evas_Object *obj)
 }
 
 EAPI void
+elm_win_indicator_type_set(Evas_Object *obj,
+                              Elm_Win_Indicator_Type_Mode mode)
+{
+   ELM_WIN_CHECK(obj);
+   ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
+
+   if (mode == sd->ind_t_mode) return;
+   sd->ind_t_mode = mode;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(sd);
+   if (sd->x.xwin)
+     {
+        if (sd->ind_t_mode == ELM_WIN_INDICATOR_TYPE_1)
+          ecore_x_e_illume_indicator_type_set
+            (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TYPE_1);
+        else if (sd->ind_t_mode == ELM_WIN_INDICATOR_TYPE_2)
+          ecore_x_e_illume_indicator_type_set
+            (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TYPE_2);
+     }
+#endif
+   //evas_object_smart_callback_call(obj, SIG_INDICATOR_PROP_CHANGED, NULL);
+}
+
+EAPI Elm_Win_Indicator_Type_Mode
+elm_win_indicator_type_get(const Evas_Object *obj)
+{
+   ELM_WIN_CHECK(obj) ELM_WIN_INDICATOR_TYPE_UNKNOWN;
+   ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_WIN_INDICATOR_TYPE_UNKNOWN);
+
+   return sd->ind_t_mode;
+}
+EAPI void
 elm_win_screen_position_get(const Evas_Object *obj,
                             int *x,
                             int *y)