ecore_evas: added window manager rotation to manage the rotation of windows by the WM.

Summary: The window manager rotation allows the WM to controls the rotation of application windows. It is designed to support synchronized rotation for the multiple application windows at same time.

Reviewers: raster, seoz, cedric, Hermet

Reviewed By: raster

CC: cedric

Differential Revision: https://phab.enlightenment.org/D529
This commit is contained in:
Gwanglim Lee 2014-02-09 09:46:51 +09:00 committed by Carsten Haitzler (Rasterman)
parent 259f33679c
commit 77092d94d4
21 changed files with 1302 additions and 79 deletions

View File

@ -1,3 +1,16 @@
2014-02-09 Gwanglim Lee
* Ecore_Evas: Added window manager rotation to manage the rotation of
windows by the WM.
- add ecore_evas_wm_rotation_supported_get
- add ecore_evas_wm_rotation_preferred_rotation_set
- add ecore_evas_wm_rotation_preferred_rotation_get
- add ecore_evas_wm_rotation_available_rotations_set
- add ecore_evas_wm_rotation_available_rotations_get
- add ecore_evas_wm_rotation_manual_rotation_done_set
- add ecore_evas_wm_rotation_manual_rotation_done_get
- add ecore_evas_wm_rotation_manual_rotation_done
2013-12-02 Daniel Juyung Seo (SeoZ)
* Check ecore_x_window_prop_card32_get() return value correctly in ecore_x_e.

View File

@ -683,6 +683,87 @@ EAPI void ecore_evas_window_available_profiles_set(Ecore_Evas *ee, const
* @since 1.8.0
*/
EAPI Eina_Bool ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsigned int *count);
/**
* @brief Query if the underlying windowing system supports the window manager rotation.
*
* @param ee The Ecore_Evas
* @return @c EINA_TRUE if the window manager rotation is supported, @c EINA_FALSE otherwise.
*
* @warning Support for this depends on the underlying windowing system.
* @since 1.9.0
*/
EAPI Eina_Bool ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee);
/**
* @brief Set the preferred rotation hint.
*
* @param ee The Ecore_Evas to set
* @param rotation Value to set the preferred rotation hint
*
* @warning Support for this depends on the underlying windowing system.
* @since 1.9.0
*/
EAPI void ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation);
/**
* @brief Get the preferred rotation hint.
*
* @param ee The Ecore_Evas to get the preferred rotation hint from.
* @return The preferred rotation hint, -1 on failure.
*
* @warning Support for this depends on the underlying windowing system.
* @since 1.9.0
*/
EAPI int ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee);
/**
* @brief Set the array of available window rotations.
*
* @param ee The Ecore_Evas to set
* @param rotations The integer array of available window rotations
* @param count The number of members in rotations
*
* @warning Support for this depends on the underlying windowing system.
* @since 1.9.0
*/
EAPI void ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count);
/**
* @brief Get the array of available window rotations.
*
* @param ee The Ecore_Evas to get available window rotations from.
* @param rotations Where to return the integer array of available window rotations
* @param count Where to return the number of members in rotations
* @return EINA_TRUE if available window rotations exist, EINA_FALSE otherwise
*
* @warning Support for this depends on the underlying windowing system.
* @since 1.9.0
*/
EAPI Eina_Bool ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count);
/**
* @brief Set manual rotation done mode of Ecore_Evas's window
*
* @param ee The Ecore_Evas
* @param set If true, the window manager will not rotate the Ecore_Evas's window until
* the rotation done event is received by ecore_evas_wm_rotation_manual_rotation_done.
* If false, the manual rotation mode is disabled.
*
* @since 1.9.0
*/
EAPI void ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set);
/**
* @brief Get manual rotation done mode of Ecore_Evas's window
*
* @param ee The Ecore_Evas
* @return If true, the manual rotation done mode is enabled
*
* @since 1.9.0
*/
EAPI Eina_Bool ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas *ee);
/**
* @brief Set rotation finish manually
*
* @param ee The Ecore_Evas
*
* @since 1.9.0
*/
EAPI void ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas *ee);
/**
* @brief Send message to parent ecore
*

View File

@ -1946,6 +1946,153 @@ ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsig
return EINA_FALSE;
}
EAPI Eina_Bool
ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_supported_get");
return EINA_FALSE;
}
return ee->prop.wm_rot.supported;
}
EAPI void
ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_preferred_rotation_set");
return;
}
if (rotation != -1)
{
if (ee->prop.wm_rot.available_rots)
{
Eina_Bool found = EINA_FALSE;
unsigned int i;
for (i = 0; i < ee->prop.wm_rot.count; i++)
{
if (ee->prop.wm_rot.available_rots[i] == rotation)
{
found = EINA_TRUE;
break;
}
}
if (!found) return;
}
}
IFC(ee, fn_wm_rot_preferred_rotation_set) (ee, rotation);
IFE;
}
EAPI int
ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_preferred_rotation_get");
return -1;
}
return ee->prop.wm_rot.preferred_rot;
}
EAPI void
ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_available_rotations_set");
return;
}
IFC(ee, fn_wm_rot_available_rotations_set) (ee, rotations, count);
IFE;
}
EAPI Eina_Bool
ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_available_rotations_get");
return EINA_FALSE;
}
if ((!rotations) || (!count))
return EINA_FALSE;
if ((!ee->prop.wm_rot.available_rots) || (ee->prop.wm_rot.count == 0))
return EINA_FALSE;
*rotations = calloc(ee->prop.wm_rot.count, sizeof(int));
if (!*rotations) return EINA_FALSE;
memcpy(*rotations, ee->prop.wm_rot.available_rots, sizeof(int) * ee->prop.wm_rot.count);
*count = ee->prop.wm_rot.count;
return EINA_TRUE;
}
EAPI void
ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_manual_rotation_done_set");
return;
}
if (!ee->prop.wm_rot.app_set)
{
return;
}
IFC(ee, fn_wm_rot_manual_rotation_done_set) (ee, set);
IFE;
}
EAPI Eina_Bool
ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas *ee)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_manual_rotation_done_get");
return EINA_FALSE;
}
if (!ee->prop.wm_rot.app_set)
{
return EINA_FALSE;
}
return ee->prop.wm_rot.manual_mode.set;
}
EAPI void
ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas *ee)
{
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
{
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
"ecore_evas_wm_rotation_manual_rotation_done");
return;
}
if (!ee->prop.wm_rot.app_set)
{
return;
}
IFC(ee, fn_wm_rot_manual_rotation_done) (ee);
IFE;
}
EAPI void
ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
{
@ -2703,6 +2850,11 @@ _ecore_evas_free(Ecore_Evas *ee)
ee->prop.profile.name = NULL;
_ecore_evas_window_available_profiles_free(ee);
ee->prop.profile.available_list = NULL;
if (ee->prop.wm_rot.available_rots) free(ee->prop.wm_rot.available_rots);
ee->prop.wm_rot.available_rots = NULL;
if (ee->prop.wm_rot.manual_mode.timer)
ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
ee->prop.wm_rot.manual_mode.timer = NULL;
if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
ee->prop.cursor.object = NULL;
if (ee->evas) evas_free(ee->evas);

View File

@ -581,7 +581,15 @@ static Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
NULL, // screen_geometry_get
NULL, // screen_dpi_get
_ecore_evas_buffer_msg_parent_send,
_ecore_evas_buffer_msg_send
_ecore_evas_buffer_msg_send,
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
static void *

View File

@ -698,7 +698,15 @@ static const Ecore_Evas_Engine_Func _ecore_ews_engine_func =
_ecore_evas_ews_screen_geometry_get,
NULL, // screen_dpi_get
NULL,
NULL // msg_send
NULL, // msg_send
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
void

View File

@ -115,6 +115,11 @@ struct _Ecore_Evas_Engine_Func
/* 1.8 abstractions */
void (*fn_pointer_xy_get) (const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y);
Eina_Bool (*fn_pointer_warp) (const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y);
void (*fn_wm_rot_preferred_rotation_set) (Ecore_Evas *ee, int rot);
void (*fn_wm_rot_available_rotations_set) (Ecore_Evas *ee, const int *rots, unsigned int count);
void (*fn_wm_rot_manual_rotation_done_set) (Ecore_Evas *ee, Eina_Bool set);
void (*fn_wm_rot_manual_rotation_done) (Ecore_Evas *ee);
};
struct _Ecore_Evas_Interface
@ -186,6 +191,21 @@ struct _Ecore_Evas
int x, y;
} hot;
} cursor;
struct {
Eina_Bool supported; // indicate that the underlying window system supports window manager rotation protocol
Eina_Bool app_set; // indicate that the ee supports window manager rotation protocol
Eina_Bool win_resize; // indicate that the ee will be resized by the WM
int angle; // rotation value which is decided by the WM
int w, h; // window size to rotate
int preferred_rot; // preferred rotation hint
int *available_rots; // array of avaialable rotation values
unsigned int count; // number of elements of available_rots
struct {
Eina_Bool set;
Eina_Bool wait_for_done;
Ecore_Timer *timer;
} manual_mode;
} wm_rot;
int layer;
Ecore_Window window;
unsigned char avoid_damage;

View File

@ -2677,6 +2677,19 @@ EAPI void ecore_x_e_illume_window_state_send(Ec
EAPI void ecore_x_xkb_select_group(int group); /* @since 1.7 */
EAPI void ecore_x_e_window_rotation_supported_set(Ecore_X_Window root, Eina_Bool enabled); /**< @since 1.9 */
EAPI Eina_Bool ecore_x_e_window_rotation_supported_get(Ecore_X_Window root); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_app_set(Ecore_X_Window win, Eina_Bool set); /**< @since 1.9 */
EAPI Eina_Bool ecore_x_e_window_rotation_app_get(Ecore_X_Window win); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_preferred_rotation_set(Ecore_X_Window win, int rot); /**< @since 1.9 */
EAPI Eina_Bool ecore_x_e_window_rotation_preferred_rotation_get(Ecore_X_Window win, int *rot); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_available_rotations_set(Ecore_X_Window win, const int *rots, unsigned int count); /**< @since 1.9 */
EAPI Eina_Bool ecore_x_e_window_rotation_available_rotations_get(Ecore_X_Window win, int **rots, unsigned int *count); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_change_prepare_send(Ecore_X_Window win, int rot, Eina_Bool resize, int w, int h); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_change_prepare_done_send(Ecore_X_Window root, Ecore_X_Window win, int rot); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_change_request_send(Ecore_X_Window win, int rot); /**< @since 1.9 */
EAPI void ecore_x_e_window_rotation_change_done_send(Ecore_X_Window root, Ecore_X_Window win, int rot, int w, int h); /**< @since 1.9 */
#ifdef __cplusplus
}
#endif // ifdef __cplusplus

View File

@ -312,4 +312,14 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT;
/* for deiconify approve protcol */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_DEICONIFY_APPROVE;
/* E window rotation extension */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE;
#endif /* _ECORE_X_ATOMS_H */

View File

@ -342,6 +342,16 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE = 0;
/* for deiconify approve protcol */
EAPI Ecore_X_Atom ECORE_X_ATOM_E_DEICONIFY_APPROVE = 0;
/* E window rotation extension */
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE = 0;
typedef struct _Atom_Item Atom_Item;
struct _Atom_Item
@ -641,6 +651,15 @@ const Atom_Item atom_items[] =
{ "_E_WINDOW_PROFILE_CHANGE_REQUEST", &ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST },
{ "_E_WINDOW_PROFILE_CHANGE_DONE", &ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE },
{ "_E_DEICONIFY_APPROVE", &ECORE_X_ATOM_E_DEICONIFY_APPROVE }
{ "_E_DEICONIFY_APPROVE", &ECORE_X_ATOM_E_DEICONIFY_APPROVE },
{ "_E_WINDOW_ROTATION_SUPPORTED", &ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED },
{ "_E_WINDOW_ROTATION_APP_SUPPORTED", &ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED },
{ "_E_WINDOW_ROTATION_AVAILABLE_LIST", &ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST },
{ "_E_WINDOW_ROTATION_PREFERRED_ROTATION", &ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION },
{ "_E_WINDOW_ROTATION_CHANGE_PREPARE", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE },
{ "_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE },
{ "_E_WINDOW_ROTATION_CHANGE_REQUEST", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST },
{ "_E_WINDOW_ROTATION_CHANGE_DONE", &ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE }
};

View File

@ -1942,3 +1942,292 @@ ecore_x_e_illume_window_state_send(Ecore_X_Window win,
_ecore_x_e_illume_window_state_atom_get(state),
0, 0, 0, 0);
}
EAPI void
ecore_x_e_window_rotation_supported_set(Ecore_X_Window root,
Eina_Bool enabled)
{
Ecore_X_Window win;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
if (enabled)
{
win = ecore_x_window_new(root, 1, 2, 3, 4);
ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW, &win, 1);
ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW, &win, 1);
}
else
{
int ret;
ret =
ecore_x_window_prop_xid_get(root,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW,
&win, 1);
if ((ret == 1) && (win))
{
ecore_x_window_prop_property_del(
root,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED);
ecore_x_window_free(win);
}
}
}
EAPI Eina_Bool
ecore_x_e_window_rotation_supported_get(Ecore_X_Window root)
{
Ecore_X_Window win, win2;
int ret;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
ret =
ecore_x_window_prop_xid_get(root,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW,
&win, 1);
if ((ret == 1) && (win))
{
ret =
ecore_x_window_prop_xid_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW,
&win2, 1);
if ((ret == 1) && (win2 == win))
return EINA_TRUE;
}
return EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_app_set(Ecore_X_Window win,
Eina_Bool set)
{
unsigned int val = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (set) val = 1;
ecore_x_window_prop_card32_set(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED,
&val, 1);
}
EAPI Eina_Bool
ecore_x_e_window_rotation_app_get(Ecore_X_Window win)
{
unsigned int val = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ecore_x_window_prop_card32_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED,
&val, 1))
return EINA_FALSE;
return val ? EINA_TRUE : EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_preferred_rotation_set(Ecore_X_Window win,
int rot)
{
unsigned int val = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (rot != -1)
{
val = (unsigned int)rot;
ecore_x_window_prop_card32_set(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION,
&val, 1);
}
else
{
ecore_x_window_prop_property_del(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION);
}
}
EAPI Eina_Bool
ecore_x_e_window_rotation_preferred_rotation_get(Ecore_X_Window win,
int *rot)
{
unsigned int val = 0;
int ret = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ret = ecore_x_window_prop_card32_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION,
&val, 1);
if (ret == 1)
{
if (rot) *rot = (int)val;
return EINA_TRUE;
}
return EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_available_rotations_set(Ecore_X_Window win,
const int *rots,
unsigned int count)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!win) return;
if ((rots) && (count > 0))
ecore_x_window_prop_card32_set(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST,
(unsigned int *)rots, count);
else
ecore_x_window_prop_property_del(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST);
}
EAPI Eina_Bool
ecore_x_e_window_rotation_available_rotations_get(Ecore_X_Window win,
int **rots,
unsigned int *count)
{
unsigned char *data = NULL;
int num, i;
int *val = NULL;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if ((!win) || (!rots) || (!count))
return EINA_FALSE;
*rots = NULL;
*count = 0;
if (!ecore_x_window_prop_property_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST,
XA_CARDINAL, 32, &data, &num))
return EINA_FALSE;
*count = num;
if ((num >= 1) && (data))
{
val = calloc(num, sizeof(int));
if (!val)
{
*counter = 0;
if (data) free(data);
return EINA_FALSE;
}
for (i = 0; i < num; i++)
val[i] = ((int *)data)[i];
if (data) free(data);
*rots = val;
return EINA_TRUE;
}
if (data) free(data);
return EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_change_prepare_send(Ecore_X_Window win,
int rot,
Eina_Bool resize,
int w,
int h)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ecore_x_client_message32_send(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE,
ECORE_X_EVENT_MASK_NONE,
win, rot, resize, w, h);
}
EAPI void
ecore_x_e_window_rotation_change_prepare_done_send(Ecore_X_Window root,
Ecore_X_Window win,
int rot)
{
xcb_client_message_event_t ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
memset(&ev, 0, sizeof(xcb_client_message_event_t));
ev.response_type = XCB_CLIENT_MESSAGE;
ev.format = 32;
ev.window = win;
ev.type = ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE;
ev.data.data32[0] = win;
ev.data.data32[1] = rot;
ev.data.data32[2] = 0;
ev.data.data32[3] = 0;
ev.data.data32[4] = 0;
xcb_send_event(_ecore_xcb_conn, 0, root,
(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev);
}
EAPI void
ecore_x_e_window_rotation_change_request_send(Ecore_X_Window win,
int rot)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ecore_x_client_message32_send(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST,
ECORE_X_EVENT_MASK_NONE,
win, rot, 0, 0, 0);
}
EAPI void
ecore_x_e_window_rotation_change_done_send(Ecore_X_Window root,
Ecore_X_Window win,
int rot,
int w,
int h)
{
xcb_client_message_event_t ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
memset(&ev, 0, sizeof(xcb_client_message_event_t));
ev.response_type = XCB_CLIENT_MESSAGE;
ev.format = 32;
ev.window = win;
ev.type = ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE;
ev.data.data32[0] = win;
ev.data.data32[1] = rot;
ev.data.data32[2] = w;
ev.data.data32[3] = h;
ev.data.data32[4] = 0;
xcb_send_event(_ecore_xcb_conn, 0, root,
(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev);
}

View File

@ -2027,3 +2027,281 @@ ecore_x_e_illume_window_state_send(Ecore_X_Window win,
_ecore_x_e_illume_window_state_atom_get(state),
0, 0, 0, 0);
}
EAPI void
ecore_x_e_window_rotation_supported_set(Ecore_X_Window root,
Eina_Bool enabled)
{
Ecore_X_Window win;
if (!root)
root = DefaultRootWindow(_ecore_x_disp);
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (enabled)
{
win = ecore_x_window_new(root, 1, 2, 3, 4);
ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW, &win, 1);
ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW, &win, 1);
}
else
{
int ret;
ret =
ecore_x_window_prop_xid_get(root,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW,
&win, 1);
if ((ret == 1) && (win))
{
ecore_x_window_prop_property_del(
root,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED);
ecore_x_window_free(win);
}
}
}
EAPI Eina_Bool
ecore_x_e_window_rotation_supported_get(Ecore_X_Window root)
{
Ecore_X_Window win, win2;
int ret;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!root)
root = DefaultRootWindow(_ecore_x_disp);
ret =
ecore_x_window_prop_xid_get(root,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW,
&win, 1);
if ((ret == 1) && (win))
{
ret =
ecore_x_window_prop_xid_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
ECORE_X_ATOM_WINDOW,
&win2, 1);
if ((ret == 1) && (win2 == win))
return EINA_TRUE;
}
return EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_app_set(Ecore_X_Window win,
Eina_Bool set)
{
unsigned int val = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (set) val = 1;
ecore_x_window_prop_card32_set(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED,
&val, 1);
}
EAPI Eina_Bool
ecore_x_e_window_rotation_app_get(Ecore_X_Window win)
{
unsigned int val = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ecore_x_window_prop_card32_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED,
&val, 1))
return EINA_FALSE;
return val ? EINA_TRUE : EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_preferred_rotation_set(Ecore_X_Window win,
int rot)
{
unsigned int val = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (rot != -1)
{
val = (unsigned int)rot;
ecore_x_window_prop_card32_set(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION,
&val, 1);
}
else
{
ecore_x_window_prop_property_del(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION);
}
}
EAPI Eina_Bool
ecore_x_e_window_rotation_preferred_rotation_get(Ecore_X_Window win,
int *rot)
{
unsigned int val = 0;
int ret = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ret = ecore_x_window_prop_card32_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION,
&val, 1);
if (ret == 1)
{
if (rot) *rot = (int)val;
return EINA_TRUE;
}
return EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_available_rotations_set(Ecore_X_Window win,
const int *rots,
unsigned int count)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!win) return;
if ((rots) && (count > 0))
ecore_x_window_prop_card32_set(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST,
(unsigned int *)rots, count);
else
ecore_x_window_prop_property_del(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST);
}
EAPI Eina_Bool
ecore_x_e_window_rotation_available_rotations_get(Ecore_X_Window win,
int **rots,
unsigned int *count)
{
unsigned char *data = NULL;
int num, i;
int *val = NULL;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if ((!win) || (!rots) || (!count))
return EINA_FALSE;
*rots = NULL;
*count = 0;
if (!ecore_x_window_prop_property_get(win,
ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST,
XA_CARDINAL, 32, &data, &num))
return EINA_FALSE;
*count = num;
if ((num >= 1) && (data))
{
val = calloc(num, sizeof(int));
if (!val)
{
if (data) XFree(data);
return EINA_FALSE;
}
for (i = 0; i < num; i++)
val[i] = ((int *)data)[i];
if (data) XFree(data);
*rots = val;
return EINA_TRUE;
}
if (data) XFree(data);
return EINA_FALSE;
}
EAPI void
ecore_x_e_window_rotation_change_prepare_send(Ecore_X_Window win,
int rot,
Eina_Bool resize,
int w,
int h)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ecore_x_client_message32_send
(win, ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE,
ECORE_X_EVENT_MASK_NONE,
win, rot, resize, w, h);
}
EAPI void
ecore_x_e_window_rotation_change_prepare_done_send(Ecore_X_Window root,
Ecore_X_Window win,
int rot)
{
XEvent xev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!root)
root = DefaultRootWindow(_ecore_x_disp);
xev.xclient.type = ClientMessage;
xev.xclient.display = _ecore_x_disp;
xev.xclient.window = win;
xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE;
xev.xclient.format = 32;
xev.xclient.data.l[0] = win;
xev.xclient.data.l[1] = rot;
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
XSendEvent(_ecore_x_disp, root, False,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev);
}
EAPI void
ecore_x_e_window_rotation_change_request_send(Ecore_X_Window win,
int rot)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ecore_x_client_message32_send
(win, ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST,
ECORE_X_EVENT_MASK_NONE,
win, rot, 0, 0, 0);
}
EAPI void
ecore_x_e_window_rotation_change_done_send(Ecore_X_Window root,
Ecore_X_Window win,
int rot,
int w,
int h)
{
XEvent xev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!root)
root = DefaultRootWindow(_ecore_x_disp);
xev.xclient.type = ClientMessage;
xev.xclient.display = _ecore_x_disp;
xev.xclient.window = win;
xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE;
xev.xclient.format = 32;
xev.xclient.data.l[0] = win;
xev.xclient.data.l[1] = rot;
xev.xclient.data.l[2] = w;
xev.xclient.data.l[3] = h;
xev.xclient.data.l[4] = 0;
XSendEvent(_ecore_x_disp, root, False,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev);
}

View File

@ -473,7 +473,15 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
NULL,
NULL, // screen_dpi_get
NULL,
NULL // msg_send
NULL, // msg_send
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
EAPI Ecore_Evas *

View File

@ -96,7 +96,15 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
NULL, //void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
NULL, //void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi);
NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
NULL //void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
NULL, //void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
EAPI Ecore_Evas *

View File

@ -877,7 +877,12 @@ static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func =
/* 1.8 abstractions */
NULL, // pointer_xy_get
NULL // pointer_warp
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
static Eina_Bool
@ -1997,7 +2002,12 @@ static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func =
/* 1.8 abstractions */
NULL, // pointer_xy_get
NULL // pointer_warp
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
EAPI Ecore_Evas *

View File

@ -564,7 +564,15 @@ static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
NULL, // screen_geometry_get
NULL, // screen_dpi_get
NULL,
NULL // msg_send
NULL, // msg_send
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
EAPI Ecore_Evas *

View File

@ -407,7 +407,15 @@ static Ecore_Evas_Engine_Func _ecore_psl1ght_engine_func =
_ecore_evas_screen_geometry_get, // screen_geometry_get
NULL, // screen_dpi_get
NULL,
NULL //msg_send
NULL, //msg_send
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
EAPI Ecore_Evas *

View File

@ -447,7 +447,15 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
NULL, // screen_geometry_get
NULL, // screen_dpi_get
NULL,
NULL // msg_send
NULL, // msg_send
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
static Ecore_Evas*

View File

@ -79,7 +79,12 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
NULL, // msg_send
_ecore_evas_wl_common_pointer_xy_get,
NULL // pointer warp
NULL, // pointer warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
/* external variables */

View File

@ -79,7 +79,12 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
NULL, // func msg send
_ecore_evas_wl_common_pointer_xy_get,
NULL // pointer_warp
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
/* external variables */

View File

@ -1133,7 +1133,15 @@ static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
NULL, // screen_geometry_get
_ecore_evas_win32_screen_dpi_get,
NULL,
NULL // msg_send
NULL, // msg_send
NULL, // pointer_xy_get
NULL, // pointer_warp
NULL, // wm_rot_preferred_rotation_set
NULL, // wm_rot_available_rotations_set
NULL, // wm_rot_manual_rotation_done_set
NULL // wm_rot_manual_rotation_done
};
#endif /* BUILD_ECORE_EVAS_WIN32 */

View File

@ -88,6 +88,14 @@ struct _Ecore_Evas_Engine_Data_X11 {
unsigned char change : 1; // need to send change event to the WM
unsigned char done : 1; // need to send change done event to the WM
} profile;
struct {
unsigned char supported: 1;
unsigned char prepare : 1;
unsigned char request : 1;
unsigned char done : 1;
unsigned char configure_coming : 1;
Ecore_Job *manual_mode_job;
} wm_rot;
Ecore_X_Window win_shaped_input;
struct
{
@ -107,6 +115,9 @@ static Ecore_Evas_Interface_Software_X11 *_ecore_evas_x_interface_software_x11_n
#ifdef BUILD_ECORE_EVAS_OPENGL_X11
static Ecore_Evas_Interface_Gl_X11 *_ecore_evas_x_interface_gl_x11_new(void);
#endif
static void _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize);
static Eina_Bool _ecore_evas_x_wm_rot_manual_rotation_done_timeout(void *data);
static void _ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(Ecore_Evas *ee);
static void _resize_shape_do(Ecore_Evas *);
static void _shaped_do(Ecore_Evas *, int);
@ -243,6 +254,17 @@ _ecore_evas_x_sync_clear(Ecore_Evas *ee)
edata->sync_counter = 0;
}
static void
_ecore_evas_x_wm_rotation_protocol_set(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if (ecore_x_e_window_rotation_supported_get(edata->win_root))
ee->prop.wm_rot.supported = 1;
else
ee->prop.wm_rot.supported = 0;
}
static void
_ecore_evas_x_window_profile_protocol_set(Ecore_Evas *ee)
{
@ -304,6 +326,21 @@ _ecore_evas_x_window_profile_set(Ecore_Evas *ee)
}
}
static void
_ecore_evas_x_wm_rot_manual_rotation_done_job(void *data)
{
Ecore_Evas *ee = (Ecore_Evas *)data;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
edata->wm_rot.manual_mode_job = NULL;
ee->prop.wm_rot.manual_mode.wait_for_done = EINA_FALSE;
ecore_x_e_window_rotation_change_done_send
(edata->win_root, ee->prop.window, ee->rotation, ee->w, ee->h);
edata->wm_rot.done = 0;
}
# ifdef BUILD_ECORE_EVAS_OPENGL_X11
static Ecore_X_Window
_ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, int w, int h, Eina_Bool override, int argb, const int *opt)
@ -1034,6 +1071,63 @@ _ecore_evas_x_event_client_message(void *data EINA_UNUSED, int type EINA_UNUSED,
e->win, 1,
0, 0, 0);
}
else if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE)
{
ee = ecore_event_window_match(e->data.l[0]);
if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
edata = ee->engine.data;
if (e->data.l[0] != (long)ee->prop.window)
return ECORE_CALLBACK_PASS_ON;
if (ee->prop.wm_rot.supported)
{
if (ee->prop.wm_rot.app_set)
{
ee->prop.wm_rot.angle = (int)e->data.l[1];
ee->prop.wm_rot.win_resize = (int)e->data.l[2];
ee->prop.wm_rot.w = (int)e->data.l[3];
ee->prop.wm_rot.h = (int)e->data.l[4];
if (ee->prop.wm_rot.win_resize)
edata->wm_rot.configure_coming = 1;
edata->wm_rot.prepare = 1;
edata->wm_rot.request = 0;
edata->wm_rot.done = 0;
}
}
}
else if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST)
{
ee = ecore_event_window_match(e->data.l[0]);
if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
edata = ee->engine.data;
if (e->data.l[0] != (long)ee->prop.window)
return ECORE_CALLBACK_PASS_ON;
if (ee->prop.wm_rot.supported)
{
if (ee->prop.wm_rot.app_set)
{
edata->wm_rot.prepare = 0;
edata->wm_rot.request = 1;
edata->wm_rot.done = 0;
if (ee->prop.wm_rot.win_resize)
{
if ((ee->w == ee->prop.wm_rot.w) &&
(ee->h == ee->prop.wm_rot.h))
{
edata->wm_rot.configure_coming = 0;
}
}
if (!edata->wm_rot.configure_coming)
{
if (ee->prop.wm_rot.manual_mode.set)
{
ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE;
_ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(ee);
}
_ecore_evas_x_rotation_set(ee, ee->prop.wm_rot.angle, 1);
}
}
}
}
return ECORE_CALLBACK_PASS_ON;
}
@ -1403,6 +1497,35 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE
ee->expecting_resize.h = 0;
}
if (ee->func.fn_resize) ee->func.fn_resize(ee);
if (ee->prop.wm_rot.supported)
{
if (edata->wm_rot.prepare)
{
if ((ee->prop.wm_rot.w == e->w) &&
(ee->prop.wm_rot.h == e->h))
{
edata->wm_rot.configure_coming = 0;
}
}
else if (edata->wm_rot.request)
{
if ((edata->wm_rot.configure_coming) &&
(ee->prop.wm_rot.w == e->w) &&
(ee->prop.wm_rot.h == e->h))
{
edata->wm_rot.configure_coming = 0;
if (ee->prop.wm_rot.manual_mode.set)
{
ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE;
_ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(ee);
}
_ecore_evas_x_rotation_set(ee,
ee->prop.wm_rot.angle,
EINA_TRUE);
}
}
}
}
return ECORE_CALLBACK_PASS_ON;
}
@ -1714,6 +1837,11 @@ _ecore_evas_x_free(Ecore_Evas *ee)
ecore_x_pixmap_free(edata->pixmap.back);
if (edata->pixmap.front)
ecore_x_pixmap_free(edata->pixmap.front);
if (edata->wm_rot.manual_mode_job)
{
ecore_job_del(edata->wm_rot.manual_mode_job);
edata->wm_rot.manual_mode_job = NULL;
}
_ecore_evas_x_group_leader_unset(ee);
if (edata->sync_counter)
@ -2060,38 +2188,41 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
}
}
#define _USE_WIN_ROT_EFFECT 1
#if _USE_WIN_ROT_EFFECT
static void _ecore_evas_x_flush_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED);
typedef struct _Ecore_Evas_X_Rotation_Effect Ecore_Evas_X_Rotation_Effect;
struct _Ecore_Evas_X_Rotation_Effect
static Eina_Bool
_ecore_evas_x_wm_rotation_check(Ecore_Evas *ee)
{
Eina_Bool wait_for_comp_reply;
};
static Ecore_Evas_X_Rotation_Effect _rot_effect =
{
EINA_FALSE
};
static void
_ecore_evas_x_rotation_effect_setup(void)
{
_rot_effect.wait_for_comp_reply = EINA_TRUE;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if (ee->prop.wm_rot.supported)
{
if (ee->prop.wm_rot.app_set)
{
if (edata->wm_rot.request)
{
if (ee->prop.wm_rot.win_resize)
{
if (!((ee->w == ee->prop.wm_rot.w) &&
(ee->h == ee->prop.wm_rot.h)))
{
return EINA_FALSE;
}
else
edata->wm_rot.configure_coming = 0;
}
}
}
}
return EINA_TRUE;
}
#endif /* end of _USE_WIN_ROT_EFFECT */
static void
_rotation_do(Ecore_Evas *ee, int rotation, int resize)
{
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
#if _USE_WIN_ROT_EFFECT
int angles[2];
angles[0] = rotation;
angles[1] = ee->rotation;
#endif /* end of _USE_WIN_ROT_EFFECT */
if (ee->prop.wm_rot.supported)
{
if (!_ecore_evas_x_wm_rotation_check(ee)) return;
if (!resize) resize = 1;
}
Evas_Engine_Info_Software_X11 *einfo;
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
@ -2100,25 +2231,23 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
einfo->info.rotation = rotation;
_ecore_evas_x_rotation_set_internal(ee, rotation, resize,
(Evas_Engine_Info *)einfo);
# if _USE_WIN_ROT_EFFECT
if (ee->prop.wm_rot.supported)
{
if (ee->prop.wm_rot.app_set)
{
if (edata->wm_rot.request)
{
if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
edata->wm_rot.request = 0;
edata->wm_rot.done = 1;
}
}
}
int angles[2] = { rotation, rotation };
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
if ((ee->visible) &&
((ecore_x_e_comp_sync_supported_get(edata->win_root)) &&
(!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)) &&
(edata->sync_counter) &&
(edata->sync_val > 0))
{
_ecore_evas_x_rotation_effect_setup();
_ecore_evas_x_flush_pre(ee, NULL, NULL);
}
# else
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
# endif
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
}
@ -2127,13 +2256,36 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if (ee->rotation == rotation) return;
if (ee->rotation == rotation)
{
if (ee->prop.wm_rot.supported)
{
if (edata->wm_rot.request)
{
if (ee->prop.wm_rot.manual_mode.set)
{
ee->prop.wm_rot.manual_mode.wait_for_done = EINA_FALSE;
if (ee->prop.wm_rot.manual_mode.timer)
ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
ee->prop.wm_rot.manual_mode.timer = NULL;
}
/* send rotation done message to wm, even if window is already rotated.
* that's why wm must be wait for comming rotation done message
* after sending rotation request.
*/
ecore_x_e_window_rotation_change_done_send
(edata->win_root, ee->prop.window, ee->rotation, ee->w, ee->h);
edata->wm_rot.request = 0;
}
}
return;
}
#if _USE_WIN_ROT_EFFECT
int angles[2];
angles[0] = rotation;
angles[1] = ee->rotation;
#endif /* end of _USE_WIN_ROT_EFFECT */
if (ee->prop.wm_rot.supported)
{
if (!_ecore_evas_x_wm_rotation_check(ee)) return;
if (!resize) resize = 1;
}
if (!strcmp(ee->driver, "opengl_x11"))
{
@ -2145,15 +2297,23 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
einfo->info.rotation = rotation;
_ecore_evas_x_rotation_set_internal(ee, rotation, resize,
(Evas_Engine_Info *)einfo);
# if _USE_WIN_ROT_EFFECT
if (ee->prop.wm_rot.supported)
{
if (ee->prop.wm_rot.app_set)
{
if (edata->wm_rot.request)
{
if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
edata->wm_rot.request = 0;
edata->wm_rot.done = 1;
}
}
}
int angles[2] = { rotation, rotation };
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
# else
ecore_x_window_prop_property_set(ee->prop.window,
ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
# endif
#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
}
else if (!strcmp(ee->driver, "software_x11"))
@ -2168,18 +2328,6 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
_rotation_do(ee, rotation, resize);
return;
}
#if _USE_WIN_ROT_EFFECT
if ((ee->visible) &&
((ecore_x_e_comp_sync_supported_get(edata->win_root)) &&
(!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)) &&
(edata->sync_counter) &&
(edata->sync_val > 0))
{
_ecore_evas_x_rotation_effect_setup();
_ecore_evas_x_flush_pre(ee, NULL, NULL);
}
#endif /* end of _USE_WIN_ROT_EFFECT */
}
static void
@ -2330,6 +2478,7 @@ _alpha_do(Ecore_Evas *ee, int alpha)
ecore_x_window_defaults_set(ee->prop.window);
_ecore_evas_x_protocols_set(ee);
_ecore_evas_x_window_profile_protocol_set(ee);
_ecore_evas_x_wm_rotation_protocol_set(ee);
_ecore_evas_x_sync_set(ee);
_ecore_evas_x_size_pos_hints_update(ee);
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
@ -2481,6 +2630,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
ecore_x_window_defaults_set(ee->prop.window);
_ecore_evas_x_protocols_set(ee);
_ecore_evas_x_window_profile_protocol_set(ee);
_ecore_evas_x_wm_rotation_protocol_set(ee);
_ecore_evas_x_sync_set(ee);
_ecore_evas_x_size_pos_hints_update(ee);
#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
@ -3156,6 +3306,103 @@ _ecore_evas_x_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
return ecore_x_pointer_warp(ee->prop.window, x, y);
}
static void
_ecore_evas_x_wm_rot_preferred_rotation_set(Ecore_Evas *ee, int rot)
{
if (ee->prop.wm_rot.supported)
{
if (!ee->prop.wm_rot.app_set)
{
ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE);
ee->prop.wm_rot.app_set = EINA_TRUE;
}
ecore_x_e_window_rotation_preferred_rotation_set(ee->prop.window, rot);
ee->prop.wm_rot.preferred_rot = rot;
}
}
static void
_ecore_evas_x_wm_rot_available_rotations_set(Ecore_Evas *ee, const int *rots, unsigned int count)
{
if (ee->prop.wm_rot.supported)
{
if (!ee->prop.wm_rot.app_set)
{
ecore_x_e_window_rotation_app_set(ee->prop.window, EINA_TRUE);
ee->prop.wm_rot.app_set = EINA_TRUE;
}
if (ee->prop.wm_rot.available_rots)
{
free(ee->prop.wm_rot.available_rots);
ee->prop.wm_rot.available_rots = NULL;
}
ee->prop.wm_rot.count = 0;
if (count > 0)
{
ee->prop.wm_rot.available_rots = calloc(count, sizeof(int));
if (!ee->prop.wm_rot.available_rots) return;
memcpy(ee->prop.wm_rot.available_rots, rots, sizeof(int) * count);
}
ee->prop.wm_rot.count = count;
ecore_x_e_window_rotation_available_rotations_set(ee->prop.window, rots, count);
}
}
static void
_ecore_evas_x_wm_rot_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set)
{
ee->prop.wm_rot.manual_mode.set = set;
}
static void
_ecore_evas_x_wm_rot_manual_rotation_done(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
if ((ee->prop.wm_rot.supported) &&
(ee->prop.wm_rot.app_set) &&
(ee->prop.wm_rot.manual_mode.set))
{
if (ee->prop.wm_rot.manual_mode.wait_for_done)
{
if (ee->prop.wm_rot.manual_mode.timer)
ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
ee->prop.wm_rot.manual_mode.timer = NULL;
if (edata->wm_rot.manual_mode_job)
ecore_job_del(edata->wm_rot.manual_mode_job);
edata->wm_rot.manual_mode_job = ecore_job_add
(_ecore_evas_x_wm_rot_manual_rotation_done_job, ee);
}
}
}
static Eina_Bool
_ecore_evas_x_wm_rot_manual_rotation_done_timeout(void *data)
{
Ecore_Evas *ee = data;
ee->prop.wm_rot.manual_mode.timer = NULL;
_ecore_evas_x_wm_rot_manual_rotation_done(ee);
return ECORE_CALLBACK_CANCEL;
}
static void
_ecore_evas_x_wm_rot_manual_rotation_done_timeout_update(Ecore_Evas *ee)
{
if (ee->prop.wm_rot.manual_mode.timer)
ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
ee->prop.wm_rot.manual_mode.timer = ecore_timer_add
(4.0f, _ecore_evas_x_wm_rot_manual_rotation_done_timeout, ee);
}
static Ecore_Evas_Engine_Func _ecore_x_engine_func =
{
_ecore_evas_x_free,
@ -3221,7 +3468,12 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func =
NULL, //fn_msg_send
_ecore_evas_x_pointer_xy_get,
_ecore_evas_x_pointer_warp
_ecore_evas_x_pointer_warp,
_ecore_evas_x_wm_rot_preferred_rotation_set,
_ecore_evas_x_wm_rot_available_rotations_set,
_ecore_evas_x_wm_rot_manual_rotation_done_set,
_ecore_evas_x_wm_rot_manual_rotation_done
};
/*
@ -3415,6 +3667,16 @@ _ecore_evas_x_flush_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
}
edata->profile.done = 0;
}
if ((ee->prop.wm_rot.supported) &&
(edata->wm_rot.done))
{
if (!ee->prop.wm_rot.manual_mode.set)
{
ecore_x_e_window_rotation_change_done_send
(edata->win_root, ee->prop.window, ee->rotation, ee->w, ee->h);
edata->wm_rot.done = 0;
}
}
}
#endif
@ -3610,6 +3872,7 @@ ecore_evas_software_x11_new_internal(const char *disp_name, Ecore_X_Window paren
ecore_x_window_defaults_set(ee->prop.window);
_ecore_evas_x_protocols_set(ee);
_ecore_evas_x_window_profile_protocol_set(ee);
_ecore_evas_x_wm_rotation_protocol_set(ee);
_ecore_evas_x_sync_set(ee);
ee->engine.func->fn_render = _ecore_evas_x_render;
@ -4057,6 +4320,7 @@ ecore_evas_gl_x11_options_new_internal(const char *disp_name, Ecore_X_Window par
ecore_x_window_defaults_set(ee->prop.window);
_ecore_evas_x_protocols_set(ee);
_ecore_evas_x_window_profile_protocol_set(ee);
_ecore_evas_x_wm_rotation_protocol_set(ee);
_ecore_evas_x_sync_set(ee);
ee->engine.func->fn_render = _ecore_evas_x_render;