--- /dev/null
+#include "e.h"
+#include <wtz-shell-server-protocol.h>
+
+#ifdef LOG
+#undef LOG
+#endif
+#ifdef ERR
+#undef ERR
+#endif
+
+#define LOG(f, e, x...) ELOGF("WTZ <LOG>", f, e, ##x)
+#define ERR(f, e, x...) ELOGF("WTZ <ERR>", f, e, ##x)
+
+#define E_WTZ_SURFACE_TYPE (int)0xE0b91100
+
+typedef struct _E_Wtz_Shell E_Wtz_Shell;
+typedef struct _E_Wtz_Surface E_Wtz_Surface;
+
+struct _E_Wtz_Shell
+{
+ struct wl_client *wclient;
+ struct wl_resource *resource; /* wtz_shell resource */
+ Eina_List *shell_surfaces; /* list of all E_Wtz_Surface belonging to shell */
+};
+
+struct _E_Wtz_Surface
+{
+ E_Object e_obj_inherit;
+
+ struct wl_resource *resource; /* wl_resource for Zwtz_Surface_V6 */
+ E_Client *ec; /* E_Client corresponding Wtz_Surface */
+ E_Wtz_Shell *shell; /* Wtz_Shell created Wtz_Surface */
+};
+
+static struct wl_global *global_resource = NULL;
+
+/**********************************************************
+ * Implementation for Wtz_Surface
+ **********************************************************/
+
+static void
+_e_wtz_surface_free(E_Wtz_Surface *shell_surface)
+{
+ free(shell_surface);
+}
+
+static void
+_e_wtz_surface_del(E_Wtz_Surface *shell_surface)
+{
+ E_Wtz_Shell *shell = shell_surface->shell;
+
+ shell->shell_surfaces = eina_list_remove(shell->shell_surfaces, shell_surface);
+}
+
+static void
+_e_wtz_surface_cb_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_wtz_surface_cb_assign_screen(struct wl_client *client,
+ struct wl_resource *resource, struct wl_resource *screen_resource)
+{
+ E_Wtz_Surface *shell_surface;
+ E_Zone *zone;
+
+ shell_surface = wl_resource_get_user_data(resource);
+ EINA_SAFETY_ON_NULL_RETURN(shell_surface);
+
+ zone = wl_resource_get_user_data(screen_resource);
+ EINA_SAFETY_ON_NULL_RETURN(zone);
+
+ // TODO:
+}
+
+static const struct wtz_surface_interface _e_wtz_surface_interface =
+{
+ _e_wtz_surface_cb_destroy,
+ _e_wtz_surface_cb_assign_screen,
+};
+
+static void
+_e_wtz_surface_cb_resource_destroy(struct wl_resource *resource)
+{
+ E_Wtz_Surface *shell_surface;
+
+ shell_surface = wl_resource_get_user_data(resource);
+ EINA_SAFETY_ON_NULL_RETURN(shell_surface);
+
+ /* set null after destroying shell of e_client, ec will be freed */
+ shell_surface->ec = NULL;
+
+ e_object_del(E_OBJECT(shell_surface));
+}
+
+static E_Wtz_Surface *
+_e_wtz_surface_create(E_Wtz_Shell *shell,
+ struct wl_resource *surface,
+ uint32_t id)
+{
+ E_Wtz_Surface *shell_surface;
+ E_Client *ec;
+
+ ec = wl_resource_get_user_data(surface);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(shell, NULL);
+
+ ELOGF("WTZ_SHELL", "Create Wtz_Surface", ec);
+
+ if (ec->comp_data->wtz_surface_assigned)
+ {
+ ERR("wtz_surface is already assigned.", ec);
+ wl_resource_post_error(surface, WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "Could not assign shell surface to wl_surface");
+ return NULL;
+ }
+
+ shell_surface = E_OBJECT_ALLOC(E_Wtz_Surface, E_WTZ_SURFACE_TYPE,
+ _e_wtz_surface_free);
+ if (!shell_surface)
+ {
+ wl_client_post_no_memory(shell->wclient);
+ return NULL;
+ }
+ e_object_del_func_set(E_OBJECT(shell_surface),
+ E_OBJECT_CLEANUP_FUNC(_e_wtz_surface_del));
+
+ shell_surface->resource = wl_resource_create(shell->wclient,
+ &wtz_surface_interface, 1, id);
+ if (!shell_surface->resource)
+ {
+ ERR("Could not create wl_resource for wtz surface", ec);
+ wl_client_post_no_memory(shell->wclient);
+ e_object_del(E_OBJECT(shell_surface));
+ return NULL;
+ }
+
+ wl_resource_set_implementation(shell_surface->resource,
+ &_e_wtz_surface_interface, shell_surface,
+ _e_wtz_surface_cb_resource_destroy);
+
+
+ ec->comp_data->wtz_surface_assigned = EINA_TRUE;
+ shell_surface->shell = shell;
+ shell_surface->ec = ec;
+ shell->shell_surfaces =
+ eina_list_append(shell->shell_surfaces, shell_surface);
+
+ return shell_surface;
+}
+/* End of Wtz_surface */
+
+/**********************************************************
+ * Implementation for Wtz_Shell
+ **********************************************************/
+static void
+_e_wtz_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+ LOG("Destroy Wtz_Shell", NULL);
+
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_wtz_shell_cb_surface_get(struct wl_client *client,
+ struct wl_resource *resource, uint32_t id, struct wl_resource *surface)
+{
+ E_Wtz_Shell *shell;
+ E_Wtz_Surface *shell_surface;
+
+ shell = wl_resource_get_user_data(resource);
+ EINA_SAFETY_ON_NULL_RETURN(shell);
+
+ shell_surface = _e_wtz_surface_create(shell, surface, id);
+ if (!shell_surface)
+ {
+ ERR("Failed to create E_Wtz_Surface", NULL);
+ return;
+ }
+}
+
+static const struct wtz_shell_interface _e_wtz_shell_interface =
+{
+ _e_wtz_shell_cb_destroy,
+ _e_wtz_shell_cb_surface_get,
+};
+
+static E_Wtz_Shell *
+_e_wtz_shell_create(struct wl_client *client, struct wl_resource *resource)
+{
+ E_Wtz_Shell *shell;
+
+ shell = E_NEW(E_Wtz_Shell, 1);
+ if (!shell)
+ return NULL;
+
+ shell->wclient = client;
+ shell->resource = resource;
+
+ return shell;
+}
+
+static void
+_e_wtz_shell_destroy(E_Wtz_Shell *shell)
+{
+ E_Wtz_Surface *shell_surface;
+
+ EINA_LIST_FREE(shell->shell_surfaces, shell_surface)
+ {
+ /* Do we need to do it even though shell is just about to be destroyed? */
+ shell_surface->shell = NULL;
+ }
+
+ free(shell);
+}
+
+static void
+_e_wtz_shell_cb_unbind(struct wl_resource *resource)
+{
+ E_Wtz_Shell *shell;
+
+ LOG("Unbind Wtz_Shell", NULL);
+
+ shell = wl_resource_get_user_data(resource);
+ if (!shell)
+ {
+ ERR("No E_Wtz_Shell in wl_resource", NULL);
+ return;
+ }
+
+ _e_wtz_shell_destroy(shell);
+}
+
+static void
+_e_wtz_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED,
+ uint32_t version, uint32_t id)
+{
+ E_Wtz_Shell *shell;
+ struct wl_resource *resource;
+
+ /* Create resource for wtz_shell */
+ resource = wl_resource_create(client, &wtz_shell_interface, version, id);
+ if (!resource)
+ goto err_res;
+
+
+ shell = _e_wtz_shell_create(client, resource);
+ if (!shell)
+ {
+ ERR("Failed to create E_Wtz_Shell", NULL);
+ goto err_shell;
+ }
+
+ wl_resource_set_implementation(resource, &_e_wtz_shell_interface,
+ shell, _e_wtz_shell_cb_unbind);
+
+ return;
+err_shell:
+ wl_resource_destroy(resource);
+err_res:
+ wl_client_post_no_memory(client);
+}
+/* End of Wtz_shell */
+
+EINTERN Eina_Bool
+e_wtz_shell_init(void)
+{
+ global_resource = wl_global_create(e_comp_wl->wl.disp, &wtz_shell_interface,
+ 1, e_comp->wl_comp_data, _e_wtz_shell_cb_bind);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(global_resource, EINA_FALSE);
+
+ return EINA_TRUE;
+}
+
+EINTERN void
+e_wtz_shell_shutdown(void)
+{
+ E_FREE_FUNC(global_resource, wl_global_destroy);
+}