--- /dev/null
+From: Rusty Lynch <rusty.lynch@intel.com>
+Date: Wed, 22 May 2013 10:08:09 -0700
+Subject: Adding elm_win_wm_rotation support
+
+---
+ src/lib/elm_widget.c | 70 +++++++++++++++++++++-
+ src/lib/elm_widget.h | 4 +
+ src/lib/elm_win.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/lib/elm_win.h | 7 ++
+ 4 files changed, 246 insertions(+), 1 deletions(-)
+
+diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c
+index 951862c..b12f727 100644
+--- a/src/lib/elm_widget.c
++++ b/src/lib/elm_widget.c
+@@ -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
+ *
+diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h
+index f0444ae..9c12a9a 100644
+--- a/src/lib/elm_widget.h
++++ b/src/lib/elm_widget.h
+@@ -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);
+diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c
+index 5dfa5cd..958d1f8 100644
+--- a/src/lib/elm_win.c
++++ b/src/lib/elm_win.c
+@@ -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)
+diff --git a/src/lib/elm_win.h b/src/lib/elm_win.h
+index 5e88009..185395e 100644
+--- a/src/lib/elm_win.h
++++ b/src/lib/elm_win.h
+@@ -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);
++
+ /**
+ * @}
+ */