Adding elm_win_wm_rotation support
authorRusty Lynch <rusty.lynch@intel.com>
Wed, 22 May 2013 17:08:09 +0000 (10:08 -0700)
committerEduardo Lima (Etrunko) <eduardo.lima@intel.com>
Tue, 13 Aug 2013 20:49:39 +0000 (17:49 -0300)
src/lib/elm_widget.c
src/lib/elm_widget.h
src/lib/elm_win.c
src/lib/elm_win.h

index 951862c..b12f727 100644 (file)
@@ -400,6 +400,7 @@ _elm_widget_sub_object_add_func(Evas_Object *obj,
                return EINA_FALSE;
           }
         sdc->parent_obj = obj;
+        sdc->orient_mode = sd->orient_mode;
         _elm_widget_top_win_focused_set(sobj, sd->top_win_focused);
 
         /* update child focusable-ness on self and parents, now that a
@@ -3523,7 +3524,18 @@ elm_widget_theme_object_set(Evas_Object *obj,
                             const char  *wstyle)
 {
    API_ENTRY return EINA_FALSE;
-   return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
+   char buf[128];
+
+   if (!_elm_theme_object_set(obj, edj, wname, welement, wstyle))
+     return EINA_FALSE;
+
+   if (sd->orient_mode != -1)
+     {
+        snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode);
+        elm_widget_signal_emit(obj, buf, "elm");
+
+     }
+   return EINA_TRUE;
 }
 
 EAPI Eina_Bool
@@ -3616,6 +3628,62 @@ elm_widget_name_find(const Evas_Object *obj, const char *name, int recurse)
    return _widget_name_find(obj, name, recurse);
 }
 
+EAPI void
+elm_widget_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+{
+   int orient_mode = -1;
+
+   API_ENTRY return;
+
+   if (disabled && (sd->orient_mode == -1)) return;
+   if (!disabled && (sd->orient_mode != -1)) return;
+
+   if (!disabled)
+     {
+        //Get current orient mode from it's parent otherwise, 0.
+        sd->orient_mode = 0;
+        ELM_WIDGET_DATA_GET(sd->parent_obj, sd_parent);
+        if (!sd_parent) orient_mode = 0;
+        else orient_mode = sd_parent->orient_mode;
+     }
+   elm_widget_orientation_set(obj, orient_mode);
+}
+
+EAPI Eina_Bool
+elm_widget_orientation_mode_disabled_get(const Evas_Object *obj)
+{
+   Eina_Bool ret;
+
+   API_ENTRY return EINA_FALSE;
+
+   if (sd->orient_mode == -1) ret = EINA_TRUE;
+   else ret = EINA_FALSE;
+   return ret;
+}
+
+EAPI void
+elm_widget_orientation_set(Evas_Object *obj, int rotation)
+{
+   Evas_Object *child;
+   Eina_List *l;
+
+   API_ENTRY return;
+
+   if ((sd->orient_mode == rotation) || (sd->orient_mode == -1)) return;
+
+   sd->orient_mode = rotation;
+
+   EINA_LIST_FOREACH (sd->subobjs, l, child)
+     elm_widget_orientation_set(child, rotation);
+
+   if (rotation != -1)
+     {
+        char buf[128];
+        snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode);
+        elm_widget_signal_emit(obj, buf, "elm");
+     }
+}
+
 /**
  * @internal
  *
index f0444ae..9c12a9a 100644 (file)
@@ -488,6 +488,7 @@ typedef struct _Elm_Widget_Smart_Data
                                                   Evas_Coord *h);
 
    int                           frozen;
+   int                           orient_mode; /* -1 is disabled */
 
    Eina_Bool                     drag_x_locked : 1;
    Eina_Bool                     drag_y_locked : 1;
@@ -780,6 +781,9 @@ EAPI Evas_Object     *elm_widget_content_part_get(const Evas_Object *obj, const
 EAPI Evas_Object     *elm_widget_content_part_unset(Evas_Object *obj, const char *part);
 EAPI void             elm_widget_access_info_set(Evas_Object *obj, const char *txt);
 EAPI const char      *elm_widget_access_info_get(const Evas_Object *obj);
+EAPI void             elm_widget_orientation_set(Evas_Object *obj, int rotation);
+EAPI void             elm_widget_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled);
+EAPI Eina_Bool        elm_widget_orientation_mode_disabled_get(const Evas_Object *obj);
 EAPI Elm_Widget_Item *_elm_widget_item_new(Evas_Object *parent, size_t alloc_size);
 EAPI void             _elm_widget_item_free(Elm_Widget_Item *item);
 EAPI Evas_Object     *_elm_widget_item_widget_get(const Elm_Widget_Item *item);
index 5dfa5cd..958d1f8 100644 (file)
@@ -120,6 +120,15 @@ struct _Elm_Win_Smart_Data
       Eina_Bool    top_animate : 1;
       Eina_Bool    geometry_changed : 1;
    } focus_highlight;
+   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;
@@ -160,6 +169,8 @@ static const char SIG_UNFULLSCREEN[] = "unfullscreen";
 static const char SIG_MAXIMIZED[] = "maximized";
 static const char SIG_UNMAXIMIZED[] = "unmaximized";
 static const char SIG_IOERR[] = "ioerr";
+static const char SIG_ROTATION_CHANGED[] = "rotation,changed";
+static const char SIG_WM_ROTATION_CHANGED[] = "wm,rotation,changed";
 
 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_DELETE_REQUEST, ""},
@@ -176,6 +187,8 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_MAXIMIZED, ""},
    {SIG_UNMAXIMIZED, ""},
    {SIG_IOERR, ""},
+   {SIG_ROTATION_CHANGED, ""},
+   {SIG_WM_ROTATION_CHANGED, ""},
    {NULL, NULL}
 };
 
@@ -195,6 +208,8 @@ static Eina_Bool _elm_win_auto_throttled = EINA_FALSE;
 
 static Ecore_Job *_elm_win_state_eval_job = NULL;
 
+static void _elm_win_resize_objects_eval(Evas_Object *obj);
+
 static void
 _elm_win_state_eval(void *data __UNUSED__)
 {
@@ -835,6 +850,8 @@ _elm_win_state_change(Ecore_Evas *ee)
    Eina_Bool ch_iconified = EINA_FALSE;
    Eina_Bool ch_fullscreen = EINA_FALSE;
    Eina_Bool ch_maximized = EINA_FALSE;
+   Eina_Bool ch_rotation = EINA_FALSE;
+   Eina_Bool ch_wm_rotation = EINA_FALSE;
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
 
@@ -868,6 +885,14 @@ _elm_win_state_change(Ecore_Evas *ee)
         sd->maximized = ecore_evas_maximized_get(sd->ee);
         ch_maximized = 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;
+          }
+     }
 
    if (sd->withdrawn) _elm_win_count_withdrawn++;
    if (sd->iconified) _elm_win_count_iconified++;
@@ -903,6 +928,19 @@ _elm_win_state_change(Ecore_Evas *ee)
         else
           evas_object_smart_callback_call(obj, SIG_UNMAXIMIZED, NULL);
      }
+   if (ch_rotation)
+     {
+       // TODO: Implement me
+     }
+   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);
+        elm_widget_orientation_set(obj, sd->rot);
+
+        evas_object_smart_callback_call(obj, SIG_WM_ROTATION_CHANGED, NULL);
+     }
 }
 
 static Eina_Bool
@@ -1315,6 +1353,9 @@ _elm_win_smart_del(Evas_Object *obj)
    if (sd->shot.info) eina_stringshare_del(sd->shot.info);
    if (sd->shot.timer) ecore_timer_del(sd->shot.timer);
 
+   if (sd->wm_rot.rots) free(sd->wm_rot.rots);
+   sd->wm_rot.rots = NULL;
+
 #ifdef HAVE_ELEMENTARY_X
    if (sd->x.client_message_handler)
      ecore_event_handler_del(sd->x.client_message_handler);
@@ -2766,6 +2807,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;
 }
 
@@ -3451,6 +3495,18 @@ elm_win_render(Evas_Object *obj)
    ecore_evas_manual_render(sd->ee);
 }
 
+static int
+_win_rotation_degree_check(int rotation)
+{
+   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;
+}
+
 EAPI void
 elm_win_rotation_set(Evas_Object *obj,
                      int rotation)
@@ -3467,6 +3523,8 @@ elm_win_rotation_set(Evas_Object *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
@@ -3497,6 +3555,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)
index 5e88009..185395e 100644 (file)
@@ -82,6 +82,7 @@
  * @li "unfullscreen": window has stopped being fullscreen
  * @li "maximized": window has been maximized
  * @li "unmaximized": window has stopped being maximized
+ * @li "wm,rotation,changed": rotation of window has been changed by window manager
  * @li "ioerr": there has been a low-level I/O error with the display system
  *
  * Examples:
@@ -1483,6 +1484,12 @@ EAPI Eina_Bool elm_win_trap_set(const Elm_Win_Trap *trap);
 // Wrapper that only exist in the Tizen 2.0 elementary tree
 EAPI void elm_win_indicator_state_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode);
 
+EAPI Eina_Bool             elm_win_wm_rotation_supported_get(const Evas_Object *obj);
+EAPI void                  elm_win_wm_rotation_preferred_rotation_set(Evas_Object *obj, const int rotation);
+EAPI int                   elm_win_wm_rotation_preferred_rotation_get(const Evas_Object *obj);
+EAPI void                  elm_win_wm_rotation_available_rotations_set(Evas_Object *obj, const int *rotations, unsigned int count);
+EAPI Eina_Bool             elm_win_wm_rotation_available_rotations_get(const Evas_Object *obj, int **rotations, unsigned int *count);
+
 /**
  * @}
  */