From 74cdf85ea9a1931e508703ddd1cfb1c9ce68f3c1 Mon Sep 17 00:00:00 2001 From: Gwanglim Lee Date: Wed, 5 Dec 2012 06:48:46 +0000 Subject: [PATCH] From: Gwanglim Lee Subject: Re: Re: Re: [E-devel] [RFC] Virtual desktop window profile I've attached 4th patch. May the 4th be with you. ecore patch has been merged with efl and all files are based on r80123. Thanks & Regards, Gwanglim ------- Original Message ------- Sender : Daniel Juyung Seo Date : 2012-12-04 01:55 (GMT+09:00) Title : Re: Re: [E-devel] [RFC] Virtual desktop window profile It looks ok to me. Sorry but can you re-generate the patch according to the recent ecore merge to efl single tree? Daniel Juyung Seo (SeoZ) On Thu, Nov 29, 2012 at 12:29 AM, Gwanglim Lee wrote: Dear Raster and Daniel Juyung Seo, I've attached 3rd patches and test_config according to your reviews. These are based on r79782. [elementary & ecore] 1. "profile,set" -> "profile,changed" - done 2. spaces after EINA_LIST_FOREACH - done 3. variable type - keep 4. author - done 5. removing deprecated marking in patch - done 6. add elm_win_available_profiles_get to test_config for the debugging purpose - done 7. check whether a given profile is present in an available profiles. otherwise window profile will be one of the item in available profiles. - newly added thing to the elm_win 8. merge with EO - done. :( Any comments would be appreciated. SVN revision: 80214 --- AUTHORS | 1 + ChangeLog | 21 +- NEWS | 34 +++ src/lib/ecore/Ecore.h | 1 + src/lib/ecore_evas/Ecore_Evas.h | 60 +++++ src/lib/ecore_evas/ecore_evas.c | 112 ++++++++ src/lib/ecore_evas/ecore_evas_buffer.c | 19 ++ src/lib/ecore_evas/ecore_evas_cocoa.c | 1 + src/lib/ecore_evas/ecore_evas_directfb.c | 1 + src/lib/ecore_evas/ecore_evas_ews.c | 1 + src/lib/ecore_evas/ecore_evas_extn.c | 161 ++++++++++- src/lib/ecore_evas/ecore_evas_fb.c | 1 + src/lib/ecore_evas/ecore_evas_private.h | 29 +- src/lib/ecore_evas/ecore_evas_psl1ght.c | 1 + src/lib/ecore_evas/ecore_evas_sdl.c | 1 + src/lib/ecore_evas/ecore_evas_wayland_egl.c | 1 + src/lib/ecore_evas/ecore_evas_wayland_shm.c | 1 + src/lib/ecore_evas/ecore_evas_win32.c | 1 + src/lib/ecore_evas/ecore_evas_x.c | 150 ++++++++--- src/lib/ecore_x/Ecore_X.h | 112 ++++++++ src/lib/ecore_x/Ecore_X_Atoms.h | 8 + src/lib/ecore_x/ecore_x_atoms_decl.h | 21 +- src/lib/ecore_x/xcb/ecore_xcb_e.c | 281 +++++++++++++++++++- src/lib/ecore_x/xlib/ecore_x_e.c | 257 +++++++++++++++++- 24 files changed, 1219 insertions(+), 57 deletions(-) diff --git a/AUTHORS b/AUTHORS index 27b13c7435..a4bffc569c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -184,6 +184,7 @@ Eduardo Lima (Etrunko) Alexey Yakovenko Myoungwoon Roy Kim(roy_kim) Robert David +Gwanglim Lee Embryo ------ diff --git a/ChangeLog b/ChangeLog index b4bd2e9982..faeefbcfdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2012-12-04 Gwanglim Lee + + * Add window profile support: + * Add ecore_evas and ecore_x APIs to support the window profile. + * Implement window profile for ecore_evas_x, ecore_evas_extn_socket, + ecore_evas_extn_plug and ecore_evas_buffer. + * Deprecate ECORE_X_ATOM_E_PROFILE and ECORE_X_ATOM_E_PROFILE_LIST. + * Deprecate ecore_x_e_window_profile_list_set. Use + ecore_x_e_window_available_profiles_set instead. + * Deprecate ecore_x_e_window_profile_list_get. Use + ecore_x_e_window_available_profiles_get instead. + * Add ecore_evas_sub_ecore_evas_list_get API. + +2012-12-05 Cedric Bail + + * Fix build of Ecore_Evas_Extn on Solaris 11. + 2012-11-30 Gustavo Sverzut Barbieri (k-s) * Fix evas_object_box.c to properly reset size_hint_min to zero if @@ -109,7 +126,3 @@ * Fix the evas memory leak - eina_rectangles allocated internally. -2012-12-05 Cedric Bail - - * Fix build of Ecore_Evas_Extn on Solaris 11. - diff --git a/NEWS b/NEWS index b0f87aae5c..09a0500dc8 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,40 @@ Additions: * Add eina_thread API * Add eina_list_last_data_get * Add Cserve2 scalecache support + * ecore_x: + - Add window profile support. + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED + ECORE_X_ATOM_E_WINDOW_PROFILE + ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST + ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST + ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE + ecore_x_e_window_profile_supported_set() + ecore_x_e_window_profile_supported_get() + ecore_x_e_window_available_profiles_set() + ecore_x_e_window_available_profiles_get() + ecore_x_e_window_profile_change_send() + ecore_x_e_window_profile_change_request_send() + ecore_x_e_window_profile_change_done_send() + * ecore_evas: + - ecore_evas_window_profile_supported_get() + - ecore_evas_window_profile_set() + - ecore_evas_window_profile_get() + - ecore_evas_window_available_profiles_set() + - ecore_evas_window_available_profiles_get() + - ecore_evas_sub_ecore_evas_list_get() + * ecore_evas_extn: + - Add window profile support. + * ecore_evas_buffer: + - Add window profile support. + +Deprecations: + * ecore_x: + - Old profile stuffs. + ECORE_X_ATOM_E_PROFILE + ECORE_X_ATOM_E_PROFILE_LIST + ecore_x_e_window_profile_list_set() + ecore_x_e_window_profile_list_get() Improvements: * Single EFL tree covering all EFL library components. diff --git a/src/lib/ecore/Ecore.h b/src/lib/ecore/Ecore.h index 5a02211526..f73bcae3fe 100644 --- a/src/lib/ecore/Ecore.h +++ b/src/lib/ecore/Ecore.h @@ -122,6 +122,7 @@ sudo make install @author Haifeng Deng @author Jérémy Zurcher @author Vikram Narayanan + @author Gwanglim Lee Please contact to get in contact with the developers and maintainers. diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h index 3c59c80c84..b701aeec8f 100644 --- a/src/lib/ecore_evas/Ecore_Evas.h +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -661,6 +661,59 @@ EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool on); * @see ecore_evas_maximized_set() */ EAPI Eina_Bool ecore_evas_maximized_get(const Ecore_Evas *ee); +/** + * @brief Query if the underlying windowing system supports the window profile. + * + * @param ee The Ecore_Evas + * @return @c EINA_TRUE if the window profile is supported, @c EINA_FALSE otherwise. + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.8.0 + */ +EAPI Eina_Bool ecore_evas_window_profile_supported_get(const Ecore_Evas *ee); +/** + * @brief Set the window profile + * + * @param ee The Ecore_Evas to set + * @param profile The string value of the window profile + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.8.0 + */ +EAPI void ecore_evas_window_profile_set(Ecore_Evas *ee, const char *profile); +/** + * @brief Get the window profile + * + * @param ee The Ecore_Evas to get the window profile from. + * @return The string value of the window profile, or NULL if none exists + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.8.0 + */ +EAPI const char *ecore_evas_window_profile_get(const Ecore_Evas *ee); +/** + * @brief Set the array of available window profiles + * + * @param ee The Ecore_Evas to set + * @param profiles The string array of available window profiels + * @param count The number of members in profiles + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.8.0 + */ +EAPI void ecore_evas_window_available_profiles_set(Ecore_Evas *ee, const char **profiles, const unsigned int count); +/** + * @brief Get the array of available window profiles + * + * @param ee The Ecore_Evas to get available window profiles from. + * @param profiles Where to return the string array of available window profiles + * @param count Where to return the number of members in profiles + * @return EINA_TRUE if available window profiles exist, EINA_FALSE otherwise + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.8.0 + */ +EAPI Eina_Bool ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsigned int *count); /** * @brief Move an Ecore_Evas. * @@ -1886,6 +1939,13 @@ EAPI unsigned char ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Get * just deleting the list. */ EAPI Eina_List *ecore_evas_ecore_evas_list_get(void); +/** + * @brief Get a list of all the sub ecore_evases. + * + * @param ee Ecore_Evas to get the list from. + * @return A list of sub ecore_evases, or @c NULL if there is no sub ecore_evases. + */ +EAPI Eina_List *ecore_evas_sub_ecore_evas_list_get(const Ecore_Evas *ee); /* specific calls to an x11 environment ecore_evas */ EAPI void ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win); diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 3d841e7db6..9a665fd581 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -1859,6 +1859,77 @@ ecore_evas_maximized_get(const Ecore_Evas *ee) return ee->prop.maximized ? EINA_TRUE : EINA_FALSE; } +EAPI Eina_Bool +ecore_evas_window_profile_supported_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_window_profile_supported_get"); + return EINA_FALSE; + } + return ee->profile_supported ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_window_profile_set(Ecore_Evas *ee, const char *profile) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_window_profile_set"); + return; + } + IFC(ee, fn_profile_set) (ee, profile); + IFE; +} + +EAPI const char * +ecore_evas_window_profile_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_window_profile_get"); + return NULL; + } + return ee->prop.profile.name; +} + +EAPI void +ecore_evas_window_available_profiles_set(Ecore_Evas *ee, const char **profiles, const unsigned int count) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_window_available_profiles_set"); + return; + } + IFC(ee, fn_profiles_set) (ee, profiles, count); + IFE; +} + +EAPI Eina_Bool +ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsigned int *count) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_window_available_profiles_get"); + return EINA_FALSE; + } + + if ((ee->prop.profile.available_list) && + (ee->prop.profile.count >= 1)) + { + if (profiles) *profiles = ee->prop.profile.available_list; + if (count) *count = ee->prop.profile.count; + return EINA_TRUE; + } + else + return EINA_FALSE; +} + EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on) { @@ -2433,6 +2504,10 @@ _ecore_evas_free(Ecore_Evas *ee) ee->prop.name = NULL; if (ee->prop.clas) free(ee->prop.clas); ee->prop.clas = NULL; + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = NULL; + _ecore_evas_window_available_profiles_free(ee); + ee->prop.profile.available_list = 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); @@ -2662,6 +2737,31 @@ _ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device, flags, timestamp, NULL); } +void +_ecore_evas_window_profile_free(Ecore_Evas *ee) +{ + if (ee->prop.profile.name) + eina_stringshare_del(ee->prop.profile.name); +} + +void +_ecore_evas_window_available_profiles_free(Ecore_Evas *ee) +{ + if (ee->prop.profile.available_list) + { + int i; + for (i = 0; i < ee->prop.profile.count; i++) + { + if (ee->prop.profile.available_list[i]) + { + eina_stringshare_del(ee->prop.profile.available_list[i]); + ee->prop.profile.available_list[i] = NULL; + } + } + free(ee->prop.profile.available_list); + } +} + EAPI Eina_List * ecore_evas_ecore_evas_list_get(void) { @@ -2676,6 +2776,18 @@ ecore_evas_ecore_evas_list_get(void) return l; } +EAPI Eina_List * +ecore_evas_sub_ecore_evas_list_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_sub_ecore_evas_list_get"); + return NULL; + } + return ee->sub_ecore_evas; +} + EAPI void ecore_evas_input_event_register(Ecore_Evas *ee) { diff --git a/src/lib/ecore_evas/ecore_evas_buffer.c b/src/lib/ecore_evas/ecore_evas_buffer.c index 26f48ce336..8dcd71442e 100644 --- a/src/lib/ecore_evas/ecore_evas_buffer.c +++ b/src/lib/ecore_evas/ecore_evas_buffer.c @@ -467,6 +467,22 @@ _ecore_evas_buffer_alpha_set(Ecore_Evas *ee, int alpha) } } +static void +_ecore_evas_buffer_profile_set(Ecore_Evas *ee, const char *profile) +{ + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = NULL; + + if (profile) + { + ee->prop.profile.name = (char *)eina_stringshare_add(profile); + + /* just change ee's state.*/ + if (ee->func.fn_state_change) + ee->func.fn_state_change(ee); + } +} + static Ecore_Evas_Engine_Func _ecore_buffer_engine_func = { _ecore_evas_buffer_free, @@ -516,6 +532,7 @@ static Ecore_Evas_Engine_Func _ecore_buffer_engine_func = _ecore_evas_buffer_alpha_set, NULL, //transparent NULL, // profiles_set + _ecore_evas_buffer_profile_set, NULL, NULL, @@ -583,6 +600,7 @@ ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, i ee->h = h; ee->req.w = ee->w; ee->req.h = ee->h; + ee->profile_supported = 1; ee->prop.max.w = 0; ee->prop.max.h = 0; @@ -722,6 +740,7 @@ ecore_evas_object_image_new(Ecore_Evas *ee_target) ee->h = h; ee->req.w = ee->w; ee->req.h = ee->h; + ee->profile_supported = 1; ee->prop.max.w = 0; ee->prop.max.h = 0; diff --git a/src/lib/ecore_evas/ecore_evas_cocoa.c b/src/lib/ecore_evas/ecore_evas_cocoa.c index bf88e5e33f..32acb57ccb 100644 --- a/src/lib/ecore_evas/ecore_evas_cocoa.c +++ b/src/lib/ecore_evas/ecore_evas_cocoa.c @@ -464,6 +464,7 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func = NULL, NULL, //transparent NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_directfb.c b/src/lib/ecore_evas/ecore_evas_directfb.c index f3567341b1..caeed21def 100644 --- a/src/lib/ecore_evas/ecore_evas_directfb.c +++ b/src/lib/ecore_evas/ecore_evas_directfb.c @@ -490,6 +490,7 @@ static Ecore_Evas_Engine_Func _ecore_directfb_engine_func = NULL, /* alpha */ NULL, //transparent NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_ews.c b/src/lib/ecore_evas/ecore_evas_ews.c index ceffd663e6..37f445612b 100644 --- a/src/lib/ecore_evas/ecore_evas_ews.c +++ b/src/lib/ecore_evas/ecore_evas_ews.c @@ -684,6 +684,7 @@ static const Ecore_Evas_Engine_Func _ecore_ews_engine_func = _ecore_evas_ews_alpha_set, _ecore_evas_ews_transparent_set, NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_extn.c b/src/lib/ecore_evas/ecore_evas_extn.c index 61840723c7..41bdb665e3 100644 --- a/src/lib/ecore_evas/ecore_evas_extn.c +++ b/src/lib/ecore_evas/ecore_evas_extn.c @@ -189,6 +189,8 @@ enum // opcodes OP_UPDATE_DONE, OP_LOCK_FILE, OP_SHM_REF, + OP_PROFILE_CHANGE_REQUEST, + OP_PROFILE_CHANGE_DONE, OP_EV_MOUSE_IN, OP_EV_MOUSE_OUT, OP_EV_MOUSE_UP, @@ -218,6 +220,7 @@ enum typedef struct _Ipc_Data_Resize Ipc_Data_Resize; typedef struct _Ipc_Data_Update Ipc_Data_Update; +typedef struct _Ipc_Data_Profile Ipc_Data_Profile; typedef struct _Ipc_Data_Ev_Mouse_In Ipc_Data_Ev_Mouse_In; typedef struct _Ipc_Data_Ev_Mouse_Out Ipc_Data_Ev_Mouse_Out; typedef struct _Ipc_Data_Ev_Mouse_Up Ipc_Data_Ev_Mouse_Up; @@ -241,6 +244,11 @@ struct _Ipc_Data_Update int x, w, y, h; }; +struct _Ipc_Data_Profile +{ + const char *name; +}; + struct _Ipc_Data_Ev_Mouse_In { unsigned int timestamp; @@ -368,6 +376,9 @@ struct _Extn Eina_Bool have_lock : 1; Eina_Bool have_real_lock : 1; } file; + struct { + Eina_Bool done : 1; /* need to send change done event to the client(plug) */ + } profile; }; static Eina_List *extn_ee_list = NULL; @@ -1136,6 +1147,49 @@ _ecore_evas_extn_cb_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_ ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_HIDE, 0, 0, 0, NULL, 0); } +static void +_ecore_evas_extn_plug_profile_set(Ecore_Evas *ee, const char *profile) +{ + Extn *extn; + + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = NULL; + + extn = ee->engine.buffer.data; + if (!extn) return; + + if (profile) + { + ee->prop.profile.name = (char *)eina_stringshare_add(profile); + if (extn->ipc.server) + { + Ipc_Data_Profile *ipc; + char *st, *p; + int len = 0; + + len += sizeof(Ipc_Data_Profile); + len += strlen(ee->prop.profile.name) + 1; + len += 1; + + st = alloca(len); + ipc = (Ipc_Data_Profile *)st; + memset(st, 0, len); + p = st + sizeof(Ipc_Data_Profile); + + strcpy(p, ee->prop.profile.name); + ipc->name = p - (long)st; + p += strlen(p) + 1; + + /* send window profile change request to the server(socket) + * and wait for profile change done from the server + */ + ecore_ipc_server_send(extn->ipc.server, MAJOR, + OP_PROFILE_CHANGE_REQUEST, + 0, 0, 0, ipc, len); + } + } +} + static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = { _ecore_evas_extn_free, @@ -1185,6 +1239,7 @@ static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = NULL, NULL, //transparent NULL, // profiles_set + _ecore_evas_extn_plug_profile_set, NULL, NULL, NULL, @@ -1363,6 +1418,10 @@ _ipc_server_data(void *data, int type EINA_UNUSED, void *event) _ecore_evas_resize(ee, ipc->w, ipc->h); } break; + case OP_PROFILE_CHANGE_DONE: + /* profile change finished being sent - done now. */ + /* do something here */ + break; default: break; } @@ -1414,6 +1473,7 @@ ecore_evas_extn_plug_new(Ecore_Evas *ee_target) ee->h = h; ee->req.w = ee->w; ee->req.h = ee->h; + ee->profile_supported = 1; ee->prop.max.w = 0; ee->prop.max.h = 0; @@ -1657,6 +1717,40 @@ _ecore_evas_socket_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNU _ecore_evas_socket_resize(ee, w, h); } +static void +_ecore_evas_extn_socket_window_profile_change_done_send(Ecore_Evas *ee) +{ + Extn *extn; + Ecore_Ipc_Client *client; + Eina_List *l = NULL; + Ipc_Data_Profile *ipc; + char *st, *p; + int len = 0; + + extn = ee->engine.buffer.data; + if (!extn) return; + + len += sizeof(Ipc_Data_Profile); + len += strlen(ee->prop.profile.name) + 1; + len += 1; + + st = alloca(len); + ipc = (Ipc_Data_Profile *)st; + memset(st, 0, len); + p = st + sizeof(Ipc_Data_Profile); + + strcpy(p, ee->prop.profile.name); + ipc->name = p - (long)st; + p += strlen(p) + 1; + + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + { + ecore_ipc_client_send(client, MAJOR, + OP_PROFILE_CHANGE_DONE, + 0, 0, 0, ipc, len); + } +} + int _ecore_evas_extn_socket_render(Ecore_Evas *ee) { @@ -1702,6 +1796,11 @@ _ecore_evas_extn_socket_render(Ecore_Evas *ee) _ecore_evas_idle_timeout_update(ee); EINA_LIST_FOREACH(extn->ipc.clients, ll, client) ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0); + if (extn->profile.done) + { + _ecore_evas_extn_socket_window_profile_change_done_send(ee); + extn->profile.done = EINA_FALSE; + } } if (ee->func.fn_post_render) ee->func.fn_post_render(ee); @@ -1995,6 +2094,27 @@ _ipc_client_data(void *data, int type EINA_UNUSED, void *event) evas_event_default_flags_set(ee->evas, flags); } break; + case OP_PROFILE_CHANGE_REQUEST: + if (e->size >= (int)sizeof(Ipc_Data_Profile)) + { + if ((e->data) && (e->size > 0) && + (((unsigned char *)e->data)[e->size - 1] == 0)) + { + Ipc_Data_Profile *ipc = e->data; + STRGET(name); + if (ipc->name) + { + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = (char *)eina_stringshare_add(ipc->name); + + if (ee->func.fn_state_change) + ee->func.fn_state_change(ee); + + extn->profile.done = EINA_TRUE; + } + } + } + break; default: break; } @@ -2034,6 +2154,43 @@ _ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha) } } +static void +_ecore_evas_extn_socket_profile_set(Ecore_Evas *ee, const char *profile) +{ + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = NULL; + + if (profile) + { + ee->prop.profile.name = (char *)eina_stringshare_add(profile); + + if (ee->func.fn_state_change) + ee->func.fn_state_change(ee); + } +} + +static void +_ecore_evas_extn_socket_available_profiles_set(Ecore_Evas *ee, const char **plist, int n) +{ + int i; + _ecore_evas_window_available_profiles_free(ee); + ee->prop.profile.available_list = NULL; + + if ((plist) && (n >= 1)) + { + ee->prop.profile.available_list = calloc(n, sizeof(char *)); + if (ee->prop.profile.available_list) + { + for (i = 0; i < n; i++) + ee->prop.profile.available_list[i] = (char *)eina_stringshare_add(plist[i]); + ee->prop.profile.count = n; + + if (ee->func.fn_state_change) + ee->func.fn_state_change(ee); + } + } +} + static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func = { _ecore_evas_extn_free, @@ -2082,7 +2239,8 @@ static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func = NULL, _ecore_evas_extn_socket_alpha_set, NULL, //transparent - NULL, // profiles_set + _ecore_evas_extn_socket_available_profiles_set, + _ecore_evas_extn_socket_profile_set, NULL, NULL, @@ -2123,6 +2281,7 @@ ecore_evas_extn_socket_new(int w, int h) ee->h = h; ee->req.w = ee->w; ee->req.h = ee->h; + ee->profile_supported = 1; /* to accept the profile change request from the client(plug) */ ee->prop.max.w = 0; ee->prop.max.h = 0; diff --git a/src/lib/ecore_evas/ecore_evas_fb.c b/src/lib/ecore_evas/ecore_evas_fb.c index 0f98e62d06..8b36e8b825 100644 --- a/src/lib/ecore_evas/ecore_evas_fb.c +++ b/src/lib/ecore_evas/ecore_evas_fb.c @@ -552,6 +552,7 @@ static Ecore_Evas_Engine_Func _ecore_fb_engine_func = NULL, NULL, //transparent NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index 0c7b03043d..2d9cb016b8 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -163,7 +163,8 @@ struct _Ecore_Evas_Engine_Func void (*fn_ignore_events_set) (Ecore_Evas *ee, int ignore); void (*fn_alpha_set) (Ecore_Evas *ee, int alpha); void (*fn_transparent_set) (Ecore_Evas *ee, int transparent); - void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int num_profiles); + void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int count); + void (*fn_profile_set) (Ecore_Evas *ee, const char *profile); void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group); void (*fn_aspect_set) (Ecore_Evas *ee, double aspect); @@ -218,6 +219,11 @@ struct _Ecore_Evas_Engine unsigned char above : 1; unsigned char below : 1; } state; + struct { + unsigned char available : 1; // need to setup available profiles in a window + 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; Ecore_X_Window win_shaped_input; } x; #endif @@ -310,7 +316,11 @@ struct _Ecore_Evas char *title; char *name; char *clas; - char *profile; + struct { + char *name; + char **available_list; + int count; + } profile; struct { int w, h; } min, @@ -378,6 +388,7 @@ struct _Ecore_Evas unsigned char semi_sync : 1; unsigned char deleted : 1; int gl_sync_draw_done; // added by gl77.lee + unsigned char profile_supported : 1; }; void _ecore_evas_ref(Ecore_Evas *ee); @@ -487,4 +498,18 @@ extern Eina_Bool _ecore_evas_app_comp_sync; void _ecore_evas_extn_init(void); void _ecore_evas_extn_shutdown(void); +/** + * @brief Free the string of the window profile. + * + * This is a helper function to free window profile. + */ +void _ecore_evas_window_profile_free(Ecore_Evas *ee); + +/** + * @brief Free the string array of available window profiles. + * + * This is a helper function to free available window profiles. + */ +void _ecore_evas_window_available_profiles_free(Ecore_Evas *ee); + #endif diff --git a/src/lib/ecore_evas/ecore_evas_psl1ght.c b/src/lib/ecore_evas/ecore_evas_psl1ght.c index 35252a3703..c9f62e4702 100644 --- a/src/lib/ecore_evas/ecore_evas_psl1ght.c +++ b/src/lib/ecore_evas/ecore_evas_psl1ght.c @@ -396,6 +396,7 @@ static Ecore_Evas_Engine_Func _ecore_psl1ght_engine_func = NULL, NULL, //transparent NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_sdl.c b/src/lib/ecore_evas/ecore_evas_sdl.c index 90b348ef2c..e609b1a60f 100644 --- a/src/lib/ecore_evas/ecore_evas_sdl.c +++ b/src/lib/ecore_evas/ecore_evas_sdl.c @@ -438,6 +438,7 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func = NULL, NULL, //transparent NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index ed176e8b6e..61d0f89e35 100644 --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c @@ -85,6 +85,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = _ecore_evas_wl_alpha_set, _ecore_evas_wl_transparent_set, NULL, // func profiles set + NULL, // func profile set NULL, // window group set NULL, // aspect set NULL, // urgent set diff --git a/src/lib/ecore_evas/ecore_evas_wayland_shm.c b/src/lib/ecore_evas/ecore_evas_wayland_shm.c index 24e349534a..470ac6ddda 100644 --- a/src/lib/ecore_evas/ecore_evas_wayland_shm.c +++ b/src/lib/ecore_evas/ecore_evas_wayland_shm.c @@ -101,6 +101,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = _ecore_evas_wl_alpha_set, _ecore_evas_wl_transparent_set, NULL, // func profiles set + NULL, // func profile set NULL, // window group set NULL, // aspect set NULL, // urgent set diff --git a/src/lib/ecore_evas/ecore_evas_win32.c b/src/lib/ecore_evas/ecore_evas_win32.c index 32ecc46de4..4a2eff7f4f 100644 --- a/src/lib/ecore_evas/ecore_evas_win32.c +++ b/src/lib/ecore_evas/ecore_evas_win32.c @@ -1111,6 +1111,7 @@ static Ecore_Evas_Engine_Func _ecore_win32_engine_func = _ecore_evas_win32_alpha_set, NULL, //transparent NULL, // profiles_set + NULL, // profile_set NULL, NULL, diff --git a/src/lib/ecore_evas/ecore_evas_x.c b/src/lib/ecore_evas/ecore_evas_x.c index d94f055319..4608d56860 100644 --- a/src/lib/ecore_evas/ecore_evas_x.c +++ b/src/lib/ecore_evas/ecore_evas_x.c @@ -133,6 +133,63 @@ _ecore_evas_x_sync_clear(Ecore_Evas *ee) ee->engine.x.sync_counter = 0; } +static void +_ecore_evas_x_window_profile_protocol_set(Ecore_Evas *ee) +{ + /* check and set profile protocol hint */ + if (ecore_x_e_window_profile_supported_get(ee->engine.x.win_root)) + { + unsigned int v = 1; + ecore_x_window_prop_card32_set + (ee->prop.window, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + &v, 1); + + ee->profile_supported = 1; + } + else + ee->profile_supported = 0; +} + +static void +_ecore_evas_x_window_profile_set(Ecore_Evas *ee) +{ + if (((ee->should_be_visible) || (ee->visible)) && + (ee->profile_supported)) + { + if (ee->engine.x.profile.available) + { + ecore_x_e_window_available_profiles_set + (ee->prop.window, + (const char **)ee->prop.profile.available_list, + (const int)ee->prop.profile.count); + + ee->engine.x.profile.available = 0; + } + + if (ee->engine.x.profile.change) + { + if (ee->prop.profile.name) + { + /* We need to keep the profile as an x property to let the WM. + * Then the WM reads it when creating the border window. + */ + Ecore_X_Atom a = ecore_x_atom_get(ee->prop.profile.name); + ecore_x_window_prop_atom_set + (ee->prop.window, + ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE, + &a, 1); + + ecore_x_e_window_profile_change_send + (ee->engine.x.win_root, + ee->prop.window, + ee->prop.profile.name); + } + ee->engine.x.profile.change = 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, int override, int argb, const int *opt) @@ -650,34 +707,6 @@ _ecore_evas_x_event_property_change(void *data EINA_UNUSED, int type EINA_UNUSED break; } } - else if (e->atom == ECORE_X_ATOM_E_PROFILE) - { - char *p = ecore_x_e_window_profile_get(e->win); - if ((p) && (ee->prop.profile)) - { - if (strcmp(p, ee->prop.profile) != 0) - { - free(ee->prop.profile); - ee->prop.profile = strdup(p); - state_change = 1; - } - } - else if ((!p) && (ee->prop.profile)) - { - free(ee->prop.profile); - ee->prop.profile = NULL; - state_change = 1; - } - else if ((p) && (!ee->prop.profile)) - { - ee->prop.profile = strdup(p); - state_change = 1; - } - - if (p) - free(p); - } - if (state_change) { if (ee->func.fn_state_change) ee->func.fn_state_change(ee); @@ -757,6 +786,29 @@ _ecore_evas_x_event_client_message(void *data EINA_UNUSED, int type EINA_UNUSED, ee->engine.x.netwm_sync_val_hi = (int)e->data.l[3]; ee->engine.x.netwm_sync_set = 1; } + else if ((e->message_type == ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST)) + { + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (ee->profile_supported) + { + char *p = ecore_x_atom_name_get(e->data.l[1]); + if (p) + { + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = (char *)eina_stringshare_add(p); + + /* window profiles of each sub_ecore_evas will be changed + * in fn_state_change callback. + */ + if (ee->func.fn_state_change) + ee->func.fn_state_change(ee); + + ee->engine.x.profile.done = 1; + free(p); + } + } + } return ECORE_CALLBACK_PASS_ON; } @@ -1879,6 +1931,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) _ecore_evas_x_group_leader_update(ee); 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_sync_set(ee); _ecore_evas_x_size_pos_hints_update(ee); #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ @@ -1999,6 +2052,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) _ecore_evas_x_group_leader_update(ee); 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_sync_set(ee); _ecore_evas_x_size_pos_hints_update(ee); #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */ @@ -2128,6 +2182,7 @@ _ecore_evas_x_show(Ecore_Evas *ee) if (ee->prop.avoid_damage) _ecore_evas_x_render(ee); _ecore_evas_x_sync_set(ee); + _ecore_evas_x_window_profile_set(ee); ecore_x_window_show(ee->prop.window); if (ee->prop.fullscreen) ecore_x_window_focus(ee->prop.window); @@ -2435,11 +2490,37 @@ _ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on) _ecore_evas_x_state_update(ee); } +static void +_ecore_evas_x_profile_set(Ecore_Evas *ee, const char *profile) +{ + _ecore_evas_window_profile_free(ee); + ee->prop.profile.name = NULL; + + if (profile) + ee->prop.profile.name = (char *)eina_stringshare_add(profile); + ee->engine.x.profile.change = 1; + _ecore_evas_x_window_profile_set(ee); +} + static void _ecore_evas_x_profiles_set(Ecore_Evas *ee, const char **plist, int n) { - /* Ecore_Evas's profile will be updated when WM sets the E_PROFILE. */ - ecore_x_e_window_profile_list_set(ee->prop.window, plist, n); + int i; + _ecore_evas_window_available_profiles_free(ee); + ee->prop.profile.available_list = NULL; + + if ((plist) && (n >= 1)) + { + ee->prop.profile.available_list = calloc(n, sizeof(char *)); + if (ee->prop.profile.available_list) + { + for (i = 0; i < n; i++) + ee->prop.profile.available_list[i] = (char *)eina_stringshare_add(plist[i]); + ee->prop.profile.count = n; + } + } + ee->engine.x.profile.available = 1; + _ecore_evas_x_window_profile_set(ee); } static void @@ -2648,6 +2729,7 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func = _ecore_evas_x_alpha_set, _ecore_evas_x_transparent_set, _ecore_evas_x_profiles_set, + _ecore_evas_x_profile_set, _ecore_evas_x_window_group_set, _ecore_evas_x_aspect_set, @@ -2717,6 +2799,12 @@ _ecore_evas_x_flush_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_ ee->engine.x.netwm_sync_val_lo); ee->engine.x.netwm_sync_set = 0; } + if (ee->engine.x.profile.done) + { + ecore_x_e_window_profile_change_done_send + (ee->engine.x.win_root, ee->prop.window,ee->prop.profile.name); + ee->engine.x.profile.done = 0; + } } #endif @@ -2898,6 +2986,7 @@ ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, _ecore_evas_x_group_leader_set(ee); 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_sync_set(ee); ee->engine.func->fn_render = _ecore_evas_x_render; @@ -3147,6 +3236,7 @@ ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, _ecore_evas_x_group_leader_set(ee); 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_sync_set(ee); ee->engine.func->fn_render = _ecore_evas_x_render; diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index b3fc0fabab..a072103cc6 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -1682,10 +1682,122 @@ EAPI void ecore_x_e_comp_dump_send(Ecore_X_Window win EAPI void ecore_x_e_comp_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pixmap); EAPI Ecore_X_Pixmap ecore_x_e_comp_pixmap_get(Ecore_X_Window win); +/** + * @brief Get the window profile + * + * @param win The client x window + * @return The string value of the window profile, or NULL if none exists + */ EAPI char *ecore_x_e_window_profile_get(Ecore_X_Window win); +/** + * @brief Set the window profile + * + * @param win The client x window + * @param profile The string value of the window profile + */ EAPI void ecore_x_e_window_profile_set(Ecore_X_Window win, const char *profile); +/** + * @brief Set the array of window profiles + * + * @param win The client x window + * @param profiles The string array of window profiles + * @param num_profiles The number of window profiles + * + * @deprecated use ecore_x_e_window_available_profiles_set + */ EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, const char **profiles, unsigned int num_profiles); +/** + * @brief Get the array of window profiles + * + * @param win The client x window + * @param profiles Where to return the string array of window profiles + * @param ret_num Where to return the number of window profiles + * @return EINA_TRUE if window profiles exist, EINA_FALSE otherwise + * + * @deprecated use ecore_x_e_window_available_profiles_get + */ EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, const char ***profiles, int *ret_num); +/** + * @brief Set the status for the window profile support + * + * @param root The root window + * @param enabled The enabled value for the window profile support + * + * @since 1.8 + */ +EAPI void ecore_x_e_window_profile_supported_set(Ecore_X_Window root, Eina_Bool enabled); +/** + * @brief Query if the window profile is supported + * + * @param root The root window + * @return EINA_TRUE if it is supported, EINA_FALSE otherwise + * + * @since 1.8 + */ +EAPI Eina_Bool ecore_x_e_window_profile_supported_get(Ecore_X_Window root); +/** + * @brief Set the array of available window profiles + * + * @param win The client x window + * @param profiles The string array of available window profiles + * @param count The number of available window profiles + * + * @since 1.8 + */ +EAPI void ecore_x_e_window_available_profiles_set(Ecore_X_Window win, const char **profiles, unsigned int count); +/** + * @brief Get the array of avaialbe window profiles + * + * @param win The client x window + * @param profiles Where to return the string array of available window profiles + * @param count Where to return the number of members in profiles + * @return EINA_TRUE if available window profiles exist, EINA_FALSE otherwise + * + * @since 1.8 + */ +EAPI Eina_Bool ecore_x_e_window_available_profiles_get(Ecore_X_Window win, const char ***profiles, int *count); +/** + * @brief Send a profile change event to the window manager + * + * This function sends a request to the window manager to change the profile. + * If honored by the window manager, the client will receive a profile change + * request event back. If the client has replied, the window manager will move + * the client window on the virtual desktop associated with changed profile. + * + * @param root The root x window + * @param win The client x window + * @param profile The string value of the window profile + * + * @since 1.8 + */ +EAPI void ecore_x_e_window_profile_change_send(Ecore_X_Window root, Ecore_X_Window win, const char *profile); +/** + * @brief Send a profile change request event to the client + * + * This function sends a request to the client to change the profile. + * If the client has replied, the window manager will move the client window + * on the virtual desktop associated with changed profile. + * + * @param win The client x window + * @param profile The string value of the window profile + * + * @since 1.8 + */ +EAPI void ecore_x_e_window_profile_change_request_send(Ecore_X_Window win, const char *profile); +/** + * @brief Send a profile change done event to the window manager + * + * This function sends a profile change done event to the window manager. + * Upon receiving, the window manager will move the client window + * on the virtual desktop associated with changed profile. + * + * @param root The root x window + * @param win The client x window + * @param profile The string value of the window profile + * + * @since 1.8 + */ +EAPI void ecore_x_e_window_profile_change_done_send(Ecore_X_Window root, Ecore_X_Window win, const char *profile); EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); EAPI Eina_Bool ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); diff --git a/src/lib/ecore_x/Ecore_X_Atoms.h b/src/lib/ecore_x/Ecore_X_Atoms.h index ca6351d839..22a3ff9bd4 100644 --- a/src/lib/ecore_x/Ecore_X_Atoms.h +++ b/src/lib/ecore_x/Ecore_X_Atoms.h @@ -279,8 +279,16 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION; /* currently elementary and E specific extension */ +/* @deprecated use ECORE_X_ATOM_E_WINDOW_PROFILE */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE; +/* @deprecated use ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE; /* for sliding window */ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE; diff --git a/src/lib/ecore_x/ecore_x_atoms_decl.h b/src/lib/ecore_x/ecore_x_atoms_decl.h index 155283efe6..46311e0eb4 100644 --- a/src/lib/ecore_x/ecore_x_atoms_decl.h +++ b/src/lib/ecore_x/ecore_x_atoms_decl.h @@ -315,8 +315,17 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT = 0; /* currently elementary and E specific extension */ -EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST = 0; +/* @deprecated use ECORE_X_ATOM_E_WINDOW_PROFILE */ +EINA_DEPRECATED EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE = 0; +/* @deprecated use ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST */ +EINA_DEPRECATED EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST = 0; + +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE = 0; typedef struct _Atom_Item Atom_Item; @@ -597,6 +606,12 @@ const Atom_Item atom_items[] = { "_E_COMP_DUMP", &ECORE_X_ATOM_E_COMP_DUMP }, { "_E_COMP_PIXMAP", &ECORE_X_ATOM_E_COMP_PIXMAP }, { "_E_VIDEO_PARENT", &ECORE_X_ATOM_E_VIDEO_PARENT }, - { "_E_VIDEO_POSITION", &ECORE_X_ATOM_E_VIDEO_POSITION } + { "_E_VIDEO_POSITION", &ECORE_X_ATOM_E_VIDEO_POSITION }, + { "_E_WINDOW_PROFILE_SUPPORTED", &ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED }, + { "_E_WINDOW_PROFILE", &ECORE_X_ATOM_E_WINDOW_PROFILE }, + { "_E_WINDOW_PROFILE_CHANGE", &ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE }, + { "_E_WINDOW_PROFILE_AVAILABLE_LIST", &ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST }, + { "_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 } }; diff --git a/src/lib/ecore_x/xcb/ecore_xcb_e.c b/src/lib/ecore_x/xcb/ecore_xcb_e.c index 82d94b634f..9862a9d2ad 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_e.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_e.c @@ -125,6 +125,10 @@ ecore_x_e_comp_sync_supported_get(Ecore_X_Window root) return EINA_FALSE; } +/* + * @since 1.3 + * @deprecated use ecore_x_e_window_available_profiles_set + */ EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, const char **profiles, @@ -133,22 +137,28 @@ ecore_x_e_window_profile_list_set(Ecore_X_Window win, Ecore_X_Atom *atoms; LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + if (!win) return; - if (!num_profiles) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST); + if ((!profiles) || (num_profiles <= 0)) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST); else { atoms = alloca(num_profiles * sizeof(Ecore_X_Atom)); ecore_x_atoms_get(profiles, num_profiles, atoms); ecore_x_window_prop_property_set(win, - ECORE_X_ATOM_E_PROFILE_LIST, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, ECORE_X_ATOM_ATOM, 32, (void *)atoms, num_profiles); } } +/* + * @since 1.3 + * @deprecated use ecore_x_e_window_available_profiles_get + */ EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, const char ***profiles, @@ -158,6 +168,9 @@ ecore_x_e_window_profile_list_get(Ecore_X_Window win, Ecore_X_Atom *atoms; int num, i; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + if (ret_num) *ret_num = 0; @@ -167,9 +180,8 @@ ecore_x_e_window_profile_list_get(Ecore_X_Window win, if (!win) return EINA_FALSE; - LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!ecore_x_window_prop_property_get(win, - ECORE_X_ATOM_E_PROFILE_LIST, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, ECORE_X_ATOM_ATOM, 32, &data, &num)) return EINA_FALSE; @@ -208,15 +220,17 @@ ecore_x_e_window_profile_set(Ecore_X_Window win, Ecore_X_Atom atom; LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + if (!win) return; if (!profile) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE); + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_WINDOW_PROFILE); else { atom = ecore_x_atom_get(profile); - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE, + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_WINDOW_PROFILE, ECORE_X_ATOM_ATOM, 32, (void *)&atom, 1); } } @@ -230,7 +244,8 @@ ecore_x_e_window_profile_get(Ecore_X_Window win) int num; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE, + CHECK_XCB_CONN; + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_WINDOW_PROFILE, ECORE_X_ATOM_ATOM, 32, &data, &num)) return NULL; @@ -243,6 +258,256 @@ ecore_x_e_window_profile_get(Ecore_X_Window win) return profile; } +EAPI void +ecore_x_e_window_profile_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_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + } + else + { + int ret = 0; + + ret = ecore_x_window_prop_xid_get(root, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + if ((ret == 1) && (win)) + { + ecore_x_window_prop_property_del(root, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED); + ecore_x_window_free(win); + } + } +} + +EAPI Eina_Bool +ecore_x_e_window_profile_supported_get(Ecore_X_Window root) +{ + Ecore_X_Window win, win2; + int ret = 0; + + 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_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win, 1); + if ((ret == 1) && (win)) + { + ret = + ecore_x_window_prop_xid_get(win, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win2, 1); + if ((ret == 1) && (win2 == win)) + return EINA_TRUE; + } + return EINA_FALSE; +} + +EAPI void +ecore_x_e_window_available_profiles_set(Ecore_X_Window win, + const char **profiles, + unsigned int count) +{ + Ecore_X_Atom *atoms; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) + return; + + if ((!profiles) || (count <= 0)) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST); + else + { + atoms = alloca(count * sizeof(Ecore_X_Atom)); + ecore_x_atoms_get(profiles, count, atoms); + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, + ECORE_X_ATOM_ATOM, 32, (void *)atoms, + count); + } +} + +EAPI Eina_Bool +ecore_x_e_window_available_profiles_get(Ecore_X_Window win, + const char ***profiles, + int *count) +{ + unsigned char *data = NULL; + Ecore_X_Atom *atoms; + int num, i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (count) + *count = 0; + + if (profiles) + *profiles = NULL; + + if (!win) + return EINA_FALSE; + + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, + ECORE_X_ATOM_ATOM, 32, &data, &num)) + return EINA_FALSE; + + if (count) + *count = num; + + if (profiles) + { + (*profiles) = calloc(num, sizeof(char *)); + if (!(*profiles)) + { + if (count) + *count = 0; + + if (data) + free(data); + + return EINA_FALSE; + } + + atoms = (Ecore_X_Atom *)data; + for (i = 0; i < num; i++) + (*profiles)[i] = ecore_x_atom_name_get(atoms[i]); + } + + if (data) + free(data); + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_window_profile_change_send(Ecore_X_Window root, + Ecore_X_Window win, + const char *profile) +{ + xcb_client_message_event_t ev; + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!root) + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (!win) + return; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + atom = ecore_x_atom_get(profile); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE; + ev.data.data32[0] = win; + ev.data.data32[1] = atom; + ev.data.data32[2] = 0; // later + ev.data.data32[3] = 0; // later + ev.data.data32[4] = 0; // later + + 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_profile_change_request_send(Ecore_X_Window win, + const char *profile) +{ + xcb_client_message_event_t ev; + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) + return; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + atom = ecore_x_atom_get(profile); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST; + ev.data.data32[0] = win; + ev.data.data32[1] = atom; + ev.data.data32[2] = 0; // later + ev.data.data32[3] = 0; // later + ev.data.data32[4] = 0; // later + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, + (const char *)&ev); +} + +EAPI void +ecore_x_e_window_profile_change_done_send(Ecore_X_Window root, + Ecore_X_Window win, + const char *profile) +{ + xcb_client_message_event_t ev; + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!root) + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (!win) + return; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + atom = ecore_x_atom_get(profile); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE; + ev.data.data32[0] = win; + ev.data.data32[1] = atom; + ev.data.data32[2] = 0; // later + ev.data.data32[3] = 0; // later + ev.data.data32[4] = 0; // later + + 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_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled) diff --git a/src/lib/ecore_x/xlib/ecore_x_e.c b/src/lib/ecore_x/xlib/ecore_x_e.c index 430b24b117..586a972e08 100644 --- a/src/lib/ecore_x/xlib/ecore_x_e.c +++ b/src/lib/ecore_x/xlib/ecore_x_e.c @@ -1138,7 +1138,7 @@ ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root, /* * @since 1.3 - * + * @deprecated use ecore_x_e_window_available_profiles_set */ EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, @@ -1151,14 +1151,14 @@ ecore_x_e_window_profile_list_set(Ecore_X_Window win, if (!win) return; - if (!num_profiles) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST); + if ((!profiles) || (num_profiles <= 0)) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST); else { atoms = alloca(num_profiles * sizeof(Ecore_X_Atom)); ecore_x_atoms_get(profiles, num_profiles, atoms); ecore_x_window_prop_property_set(win, - ECORE_X_ATOM_E_PROFILE_LIST, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, XA_ATOM, 32, (void *)atoms, num_profiles); } @@ -1166,6 +1166,7 @@ ecore_x_e_window_profile_list_set(Ecore_X_Window win, /* * @since 1.3 + * @deprecated use ecore_x_e_window_available_profiles_get */ EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, @@ -1176,6 +1177,8 @@ ecore_x_e_window_profile_list_get(Ecore_X_Window win, Ecore_X_Atom *atoms; int num, i; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (ret_num) *ret_num = 0; @@ -1185,9 +1188,8 @@ ecore_x_e_window_profile_list_get(Ecore_X_Window win, if (!win) return EINA_FALSE; - LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!ecore_x_window_prop_property_get(win, - ECORE_X_ATOM_E_PROFILE_LIST, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, XA_ATOM, 32, &data, &num)) return EINA_FALSE; @@ -1233,11 +1235,11 @@ ecore_x_e_window_profile_set(Ecore_X_Window win, return; if (!profile) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE); + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_WINDOW_PROFILE); else { atom = ecore_x_atom_get(profile); - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE, + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_WINDOW_PROFILE, XA_ATOM, 32, (void *)&atom, 1); } } @@ -1254,7 +1256,7 @@ ecore_x_e_window_profile_get(Ecore_X_Window win) int num; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE, + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_WINDOW_PROFILE, XA_ATOM, 32, &data, &num)) return NULL; @@ -1267,6 +1269,243 @@ ecore_x_e_window_profile_get(Ecore_X_Window win) return profile; } +EAPI void +ecore_x_e_window_profile_supported_set(Ecore_X_Window root, + Eina_Bool enabled) +{ + Ecore_X_Window win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + if (enabled) + { + win = ecore_x_window_new(root, 1, 2, 3, 4); + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, &win, 1); + } + else + { + int ret; + + ret = + ecore_x_window_prop_xid_get(root, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win, 1); + if ((ret == 1) && (win)) + { + ecore_x_window_prop_property_del( + root, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED); + ecore_x_window_free(win); + } + } +} + +EAPI Eina_Bool +ecore_x_e_window_profile_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_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win, 1); + if ((ret == 1) && (win)) + { + ret = + ecore_x_window_prop_xid_get(win, + ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win2, 1); + if ((ret == 1) && (win2 == win)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EAPI void +ecore_x_e_window_available_profiles_set(Ecore_X_Window win, + const char **profiles, + unsigned int count) +{ + Ecore_X_Atom *atoms; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) + return; + + if ((!profiles) || (count <= 0)) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST); + else + { + atoms = alloca(count * sizeof(Ecore_X_Atom)); + ecore_x_atoms_get(profiles, count, atoms); + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, + XA_ATOM, 32, (void *)atoms, + count); + } +} + +EAPI Eina_Bool +ecore_x_e_window_available_profiles_get(Ecore_X_Window win, + const char ***profiles, + int *count) +{ + unsigned char *data; + Ecore_X_Atom *atoms; + int num, i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (count) + *count = 0; + + if (profiles) + *profiles = NULL; + + if (!win) + return EINA_FALSE; + + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_E_WINDOW_PROFILE_AVAILABLE_LIST, + XA_ATOM, 32, &data, &num)) + return EINA_FALSE; + + if (count) + *count = num; + + if (profiles) + { + (*profiles) = calloc(num, sizeof(char *)); + if (!(*profiles)) + { + if (count) + *count = 0; + + if (data) + free(data); + + return EINA_FALSE; + } + + atoms = (Ecore_X_Atom *)data; + for (i = 0; i < num; i++) + (*profiles)[i] = ecore_x_atom_name_get(atoms[i]); + } + + if (data) + XFree(data); + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_window_profile_change_send(Ecore_X_Window root, + Ecore_X_Window win, + const char *profile) +{ + XEvent xev; + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + if (!win) + return; + + atom = ecore_x_atom_get(profile); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = atom; + xev.xclient.data.l[2] = 0; // later + xev.xclient.data.l[3] = 0; // later + xev.xclient.data.l[4] = 0; // later + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + +EAPI void +ecore_x_e_window_profile_change_request_send(Ecore_X_Window win, + const char *profile) +{ + XEvent xev; + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!win) + return; + + atom = ecore_x_atom_get(profile); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_REQUEST; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = atom; + xev.xclient.data.l[2] = 0; // later + xev.xclient.data.l[3] = 0; // later + xev.xclient.data.l[4] = 0; // later + + XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev); +} + + +EAPI void +ecore_x_e_window_profile_change_done_send(Ecore_X_Window root, + Ecore_X_Window win, + const char *profile) +{ + XEvent xev; + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!root) + root = DefaultRootWindow(_ecore_x_disp); + + atom = ecore_x_atom_get(profile); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_E_WINDOW_PROFILE_CHANGE_DONE; + xev.xclient.format = 32; + xev.xclient.data.l[0] = win; + xev.xclient.data.l[1] = atom; + xev.xclient.data.l[2] = 0; // later + xev.xclient.data.l[3] = 0; // later + xev.xclient.data.l[4] = 0; // later + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + EAPI void ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled)