From f5a59c484b91755929435b2854af225cec0fe92b Mon Sep 17 00:00:00 2001 From: Duna Oh Date: Wed, 29 Apr 2015 13:26:55 +0900 Subject: [PATCH] Implementation of 'transient_for' protocol Test Plan: (1) The clients send requests of 'get_tizen_gid' and get their gids. (2) 'set_transient_for' relationship using gids. Change-Id: I3fd264795dab3c84d7ad4c45f22c123f351e8343 --- src/bin/e_pixmap.c | 26 +++++ src/bin/e_pixmap.h | 2 + src/modules/Makefile_wl_desktop_shell.mk | 4 +- src/modules/wl_desktop_shell/e_mod_main.c | 114 +++++++++++++++++++++ .../wl_desktop_shell/e_transient_for_protocol.c | 39 +++++++ .../wl_desktop_shell/e_transient_for_protocol.h | 62 +++++++++++ 6 files changed, 246 insertions(+), 1 deletion(-) create mode 100755 src/modules/wl_desktop_shell/e_transient_for_protocol.c create mode 100755 src/modules/wl_desktop_shell/e_transient_for_protocol.h diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c index 800b910..349c158 100644 --- a/src/bin/e_pixmap.c +++ b/src/bin/e_pixmap.c @@ -8,6 +8,8 @@ #endif static Eina_Hash *pixmaps[2] = {NULL}; +static Eina_Hash *gids = NULL; +static uint32_t gid = 0; struct _E_Pixmap { @@ -18,6 +20,7 @@ struct _E_Pixmap E_Pixmap_Type type; uint64_t win; + uint32_t gid; Ecore_Window parent; int w, h; @@ -262,6 +265,11 @@ e_pixmap_new(E_Pixmap_Type type, ...) cp = _e_pixmap_new(type); cp->win = id; eina_hash_add(pixmaps[type], &id, cp); + if (!gids) + gids = eina_hash_int32_new((Eina_Free_Cb)_e_pixmap_free); + gid++; + cp->gid = gid; + eina_hash_add(gids, &gid, cp); #endif break; } @@ -504,6 +512,24 @@ e_pixmap_find_client(E_Pixmap_Type type, ...) return (!cp) ? NULL : cp->client; } +EAPI E_Client * +e_pixmap_find_client_by_tizen_gid(uint32_t gid) +{ + E_Pixmap *cp; + + if (!gids) return NULL; + cp = eina_hash_find(gids, &gid); + + return (!cp) ? NULL : cp->client; +} + +EAPI uint32_t +e_pixmap_tizen_gid_get(E_Pixmap *cp) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(cp, 0); + return cp->gid; +} + EAPI uint64_t e_pixmap_window_get(E_Pixmap *cp) { diff --git a/src/bin/e_pixmap.h b/src/bin/e_pixmap.h index ff577b0..e47e5ce 100644 --- a/src/bin/e_pixmap.h +++ b/src/bin/e_pixmap.h @@ -36,6 +36,8 @@ EAPI void e_pixmap_client_set(E_Pixmap *cp, E_Client *ec); EAPI E_Client *e_pixmap_client_get(E_Pixmap *cp); EAPI E_Pixmap *e_pixmap_find(E_Pixmap_Type type, ...); EAPI E_Client *e_pixmap_find_client(E_Pixmap_Type type, ...); +EAPI E_Client *e_pixmap_find_client_by_tizen_gid(uint32_t gid); +EAPI uint32_t e_pixmap_tizen_gid_get(E_Pixmap *cp); EAPI uint64_t e_pixmap_window_get(E_Pixmap *cp); EAPI Ecore_Window e_pixmap_parent_window_get(E_Pixmap *cp); EAPI Eina_Bool e_pixmap_native_surface_init(E_Pixmap *cp, Evas_Native_Surface *ns); diff --git a/src/modules/Makefile_wl_desktop_shell.mk b/src/modules/Makefile_wl_desktop_shell.mk index 77f17ec..15f3025 100644 --- a/src/modules/Makefile_wl_desktop_shell.mk +++ b/src/modules/Makefile_wl_desktop_shell.mk @@ -23,7 +23,9 @@ src_modules_wl_desktop_shell_module_la_SOURCES = \ src/modules/wl_desktop_shell/e_scaler.c \ src/modules/wl_desktop_shell/e_scaler.h \ src/modules/wl_desktop_shell/e_scaler_protocol.c \ - src/modules/wl_desktop_shell/e_scaler_protocol.h + src/modules/wl_desktop_shell/e_scaler_protocol.h \ + src/modules/wl_desktop_shell/e_transient_for_protocol.h \ + src/modules/wl_desktop_shell/e_transient_for_protocol.c PHONIES += wl_desktop_shell install-wl_desktop_shell wl_desktop_shell: $(wl_desktop_shellpkg_LTLIBRARIES) $(wl_desktop_shell_DATA) diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index 7194531..bd3b670 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/e_mod_main.c @@ -3,6 +3,7 @@ #include "e.h" #include "e_desktop_shell_protocol.h" #include "e_scaler.h" +#include "e_transient_for_protocol.h" #define XDG_SERVER_VERSION 4 @@ -1347,6 +1348,89 @@ _e_xdg_shell_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *r } } +static void +_e_tizen_gid_cb_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_gid_interface _e_tizen_gid_interface = +{ + _e_tizen_gid_cb_destroy, +}; + +static void +_e_tizen_ext_cb_tizen_gid_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface) +{ + struct wl_resource *res; + E_Pixmap *ep; + uint32_t gid; + + /* get the pixmap from this surface so we can find the client */ + if (!(ep = wl_resource_get_user_data(surface))) + { + wl_resource_post_error(surface, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Pixmap Set On Surface"); + return; + } + + /* make sure it's a wayland pixmap */ + if (e_pixmap_type_get(ep) != E_PIXMAP_TYPE_WL) return; + + /* find the window id for this pixmap */ + gid = e_pixmap_tizen_gid_get(ep); + + DBG("TIZEN_EXT: tizen_gid_get %" PRIu32, gid); + + /* try to create a tizen_gid */ + if (!(res = wl_resource_create(client, &tizen_gid_interface, wl_resource_get_version(resource), id))) + { + wl_resource_post_no_memory(resource); + return; + } + wl_resource_set_implementation(res, &_e_tizen_gid_interface, + ep, NULL); + + tizen_gid_send_notify(res, gid); +} + +static void +_e_tizen_ext_cb_transient_for_set(struct wl_client *client, struct wl_resource *resource, uint32_t surface_gid, uint32_t parent_gid) +{ + E_Client *ec; + E_Client *pc; + struct wl_resource *parent_resource; + + DBG("TIZEN_EXT: surface_gid: %" PRIu32 ", parent_gid : %" PRIu32, surface_gid, parent_gid); + + ec = e_pixmap_find_client_by_tizen_gid(surface_gid); + if (!ec) + { + ERR("No Client for this surface gid"); + return; + } + + /* find the parent client */ + pc = e_pixmap_find_client_by_tizen_gid(parent_gid); + if (!pc) + { + ERR("No Client for this parent gid"); + return; + } + if (pc->comp_data->surface) + { + parent_resource = pc->comp_data->surface; + _e_shell_surface_parent_set(ec, parent_resource); + } +} + +static const struct tizen_ext_interface _e_tizen_ext_interface = +{ + _e_tizen_ext_cb_tizen_gid_get, + _e_tizen_ext_cb_transient_for_set, +}; + static const struct wl_shell_interface _e_shell_interface = { _e_shell_cb_shell_surface_get @@ -1456,6 +1540,28 @@ _e_xdg_shell_cb_bind(struct wl_client *client, void *data, uint32_t version, uin wl_resource_set_dispatcher(res, _e_xdg_shell_cb_dispatch, NULL, cdata, NULL); } +static void +_e_tizen_ext_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + E_Comp_Data *cdata; + struct wl_resource *res; + + if (!(cdata = data)) + { + wl_client_post_no_memory(client); + return; + } + + if (!(res = wl_resource_create(client, &tizen_ext_interface, MIN(version, 1), id))) + { + ERR("Could not create tizen_ext resource: %m"); + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(res, &_e_tizen_ext_interface, cdata, NULL); +} + EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" }; EAPI void * @@ -1491,6 +1597,14 @@ e_modapi_init(E_Module *m) e_scaler_init(); + /* try to add tizen_ext to wayland globals */ + if (!wl_global_create(cdata->wl.disp, &tizen_ext_interface, 1, + cdata, _e_tizen_ext_cb_bind)) + { + ERR("Could not add tizen_ext to wayland globals: %m"); + return NULL; + } + return m; } diff --git a/src/modules/wl_desktop_shell/e_transient_for_protocol.c b/src/modules/wl_desktop_shell/e_transient_for_protocol.c new file mode 100755 index 0000000..a8d9e07 --- /dev/null +++ b/src/modules/wl_desktop_shell/e_transient_for_protocol.c @@ -0,0 +1,39 @@ +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface tizen_gid_interface; +extern const struct wl_interface wl_surface_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + &tizen_gid_interface, + &wl_surface_interface, +}; + +static const struct wl_message tizen_ext_requests[] = { + { "get_tizen_gid", "no", types + 2 }, + { "set_transient_for", "uu", types + 0 }, +}; + +WL_EXPORT const struct wl_interface tizen_ext_interface = { + "tizen_ext", 1, + 2, tizen_ext_requests, + 0, NULL, +}; + +static const struct wl_message tizen_gid_requests[] = { + { "destroy", "", types + 0 }, +}; + +static const struct wl_message tizen_gid_events[] = { + { "notify", "u", types + 0 }, +}; + +WL_EXPORT const struct wl_interface tizen_gid_interface = { + "tizen_gid", 1, + 1, tizen_gid_requests, + 1, tizen_gid_events, +}; + diff --git a/src/modules/wl_desktop_shell/e_transient_for_protocol.h b/src/modules/wl_desktop_shell/e_transient_for_protocol.h new file mode 100755 index 0000000..15c6c4e --- /dev/null +++ b/src/modules/wl_desktop_shell/e_transient_for_protocol.h @@ -0,0 +1,62 @@ +#ifndef TIZEN_EXT_SERVER_PROTOCOL_H +#define TIZEN_EXT_SERVER_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-util.h" + +struct wl_client; +struct wl_resource; + +struct tizen_ext; +struct tizen_gid; + +extern const struct wl_interface tizen_ext_interface; +extern const struct wl_interface tizen_gid_interface; + +struct tizen_ext_interface { + /** + * get_tizen_gid - (none) + * @id: (none) + * @surface: (none) + */ + void (*get_tizen_gid)(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface); + /** + * set_transient_for - (none) + * @surface_gid: (none) + * @parent_gid: (none) + */ + void (*set_transient_for)(struct wl_client *client, + struct wl_resource *resource, + uint32_t surface_gid, + uint32_t parent_gid); +}; + +struct tizen_gid_interface { + /** + * destroy - (none) + */ + void (*destroy)(struct wl_client *client, + struct wl_resource *resource); +}; + +#define TIZEN_GID_NOTIFY 0 + +static inline void +tizen_gid_send_notify(struct wl_resource *resource_, uint32_t gid) +{ + wl_resource_post_event(resource_, TIZEN_GID_NOTIFY, gid); +} + +#ifdef __cplusplus +} +#endif + +#endif -- 2.7.4