e_xdg_shell_v6: Reimplement xdg_shell_v6 support 44/179144/5 accepted/tizen/unified/20180612.130759 submit/tizen/20180611.112755
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 10 May 2018 23:18:01 +0000 (08:18 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Mon, 11 Jun 2018 02:07:57 +0000 (02:07 +0000)
Change-Id: I8e90b19ae3acffe2e889405e44361a59c0adb0d6

src/bin/Makefile.mk
src/bin/e_comp_wl_shell.c
src/bin/e_comp_wl_shell.h
src/bin/e_includes.h
src/bin/e_xdg_shell_v6.c [new file with mode: 0644]
src/bin/e_xdg_shell_v6.h [new file with mode: 0644]

index 11ae0d1b7d1c05dde7639a0ac23ab1cc8c09f9c1..c104c991a2fa43d742bc47dd5e5513dc2178088d 100644 (file)
@@ -126,7 +126,8 @@ src/bin/e_security.h \
 src/bin/e_keyrouter.h \
 src/bin/e_keyrouter_private.h \
 src/bin/e_gesture.h \
-src/bin/e_input.h
+src/bin/e_input.h \
+src/bin/e_xdg_shell_v6.h
 
 enlightenment_src = \
 src/bin/e_actions.c \
@@ -237,7 +238,8 @@ src/bin/e_input_private.h \
 src/bin/e_input.c \
 src/bin/e_input_inputs.c \
 src/bin/e_input_device.c \
-src/bin/e_input_evdev.c
+src/bin/e_input_evdev.c \
+src/bin/e_xdg_shell_v6.c
 
 src_bin_enlightenment_CPPFLAGS = $(E_CPPFLAGS) -DEFL_BETA_API_SUPPORT -DEFL_EO_API_SUPPORT -DE_LOGGING=1 @WAYLAND_CFLAGS@ $(TTRACE_CFLAGS) $(DLOG_CFLAGS) $(PIXMAN_CFLAGS) $(POLICY_CFLAGS) @TIZEN_REMOTE_SURFACE_CFLAGS@
 if HAVE_LIBGOMP
index 9ea9d459e54fe04ad603f0ef57319604de4ef7f3..60790aa0b9d7e3235b3ce8ca4f41b5d061c23140 100644 (file)
 #define XDG_SERVER_VERSION 5
 
 typedef struct _E_Xdg_Shell E_Xdg_Shell;
-typedef struct _E_Xdg_Pos   E_Xdg_Pos;
 
 struct _E_Xdg_Shell
 {
    struct wl_client   *wc;
    struct wl_resource *res;      /* xdg_shell resource */
    Eina_List          *ping_ecs; /* list of all ec which are waiting for pong response */
-   Eina_List          *positioners; /* list of E_Xdg_Pos */
 };
 
-struct _E_Xdg_Pos
+static Eina_Hash *xdg_sh_hash = NULL;
+
+EINTERN Eina_Bool
+e_shell_e_client_shell_assignable_check(E_Client *ec)
 {
-   E_Xdg_Shell        *sh;
-   struct wl_resource *res;      /* xdg_positioner_v6 resources */
-};
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
 
-static Eina_Hash *xdg_sh_hash = NULL;
+   if (e_object_is_del(E_OBJECT(ec)))
+     {
+        ELOGF("SHELL", "ERR: Could not assign shell: being deleted by compositor",
+              ec->pixmap, ec);
+        return EINA_FALSE;
+     }
+   else if (!ec->comp_data)
+     {
+        ELOGF("SHELL", "ERR: Could not assign shell: No E_Comp_Client_Data",
+              ec->pixmap, ec);
+        return EINA_FALSE;
+     }
+   else if (ec->comp_data->shell.surface)
+     {
+        ELOGF("SHELL", "ERR: Could not assign shell: Already assigned",
+              ec->pixmap, ec);
+        return EINA_FALSE;
+     }
 
-static void
-_e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource)
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_shell_e_client_shsurface_assign(E_Client *ec,
+                                  struct wl_resource *shsurface,
+                                  E_Shell_Surface_Api *api)
+{
+   E_Comp_Client_Data *cdata;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+   EINA_SAFETY_ON_NULL_RETURN(shsurface);
+
+   cdata = ec->comp_data;
+   if (!cdata)
+     {
+        ELOGF("SHELL", "ERR: E_Client must have E_Comp_Client_Data",
+              ec->pixmap, ec);
+        return;
+     }
+
+   cdata->shell.surface = shsurface;
+   if (api)
+     {
+        cdata->shell.configure_send = api->configure_send;
+        cdata->shell.configure = api->configure;
+        cdata->shell.ping = api->ping;
+        cdata->shell.map = api->map;
+        cdata->shell.unmap = api->unmap;
+     }
+
+   ec->netwm.ping = 1;
+   e_object_ref(E_OBJECT(ec));
+}
+
+EINTERN void
+e_shell_e_client_shsurface_api_set(E_Client *ec, E_Shell_Surface_Api *api)
+{
+   E_Comp_Client_Data *cdata;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+   EINA_SAFETY_ON_NULL_RETURN(api);
+
+   cdata = ec->comp_data;
+   if (!cdata)
+     {
+        ELOGF("SHELL", "ERR: E_Client must have E_Comp_Client_Data",
+              ec->pixmap, ec);
+        return;
+     }
+
+   cdata->shell.configure_send = api->configure_send;
+   cdata->shell.configure = api->configure;
+   cdata->shell.ping = api->ping;
+   cdata->shell.map = api->map;
+   cdata->shell.unmap = api->unmap;
+}
+
+EINTERN void
+e_shell_e_client_toplevel_set(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   ELOGF("SHELL", "Set toplevel", ec->pixmap, ec);
+
+   /* set toplevel client properties */
+   ec->icccm.accepts_focus = 1;
+   if (!ec->internal)
+     ec->borderless = 1;
+   ec->lock_border = EINA_TRUE;
+   if ((!ec->internal) || (!ec->borderless))
+     ec->border.changed = ec->changes.border = !ec->borderless;
+   if (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN)
+     ec->netwm.type = E_WINDOW_TYPE_NORMAL;
+   ec->comp_data->set_win_type = EINA_TRUE;
+}
+
+EINTERN void
+e_shell_e_client_popup_set(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   ELOGF("SHELL", "Set popup", ec->pixmap, ec);
+
+   EC_CHANGED(ec);
+   ec->new_client = ec->override = 1;
+   e_client_unignore(ec);
+   e_comp->new_clients++;
+   if (!ec->internal)
+     ec->borderless = !ec->internal_elm_win;
+   ec->lock_border = EINA_TRUE;
+   if (!ec->internal)
+     ec->border.changed = ec->changes.border = !ec->borderless;
+   ec->changes.icon = !!ec->icccm.class;
+   ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU;
+   ec->comp_data->set_win_type = EINA_TRUE;
+   evas_object_layer_set(ec->frame, E_LAYER_CLIENT_POPUP);
+}
+
+EINTERN void
+e_shell_e_client_pong(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
+
+   ELOGF("SHELL", "Pong", ec->pixmap, ec);
+
+   ec->ping_ok = EINA_TRUE;
+   ec->hung = EINA_FALSE;
+}
+
+EINTERN void
+e_shell_e_client_parent_set(E_Client *ec, struct wl_resource *parent_resource)
 {
    E_Client *pc;
    Ecore_Window pwin = 0;
 
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
    if (!parent_resource)
      {
         ec->icccm.fetch.transient_for = EINA_FALSE;
@@ -78,11 +208,44 @@ _e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource)
    ec->icccm.transient_for = pwin;
 }
 
+EINTERN Eina_Bool
+e_shell_e_client_name_title_set(E_Client *ec, const char *name, const char *title)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   if (name)
+     eina_stringshare_replace(&ec->icccm.name, name);
+
+   if (title)
+     {
+        eina_stringshare_replace(&ec->icccm.title, title);
+        if (ec->frame)
+          e_comp_object_frame_title_set(ec->frame, title);
+     }
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_shell_e_client_app_id_set(E_Client *ec, const char *app_id)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   /* set class */
+   eina_stringshare_replace(&ec->icccm.class, app_id);
+   ec->changes.icon = !!ec->icccm.class;
+   EC_CHANGED(ec);
+
+   return EINA_TRUE;
+}
+
 static void
-_e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move, int resize_edges)
+_e_shell_e_client_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move, int resize_edges)
 {
    E_Pointer_Mode resize_mode = E_POINTER_RESIZE_NONE;
 
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
    if (move)
      {
         /* tell E to start moving the client */
@@ -123,51 +286,141 @@ _e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *e
    e_focus_event_mouse_down(ec);
 }
 
-static void
-_e_shell_surface_destroy(struct wl_resource *resource)
+EINTERN Eina_Bool
+e_shell_e_client_interactive_move(E_Client *ec,
+                                  /* TODO Multi seat is not yet supported */
+                                  struct wl_resource *seat EINA_UNUSED)
 {
-   E_Client *ec = NULL;
+   E_Binding_Event_Mouse_Button ev;
 
-   /* get the client for this resource */
-   if ((ec = wl_resource_get_user_data(resource)))
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   if ((ec->maximized) || (ec->fullscreen))
+     return EINA_FALSE;
+
+   TRACE_DS_BEGIN(SHELL:SURFACE MOVE REQUEST CB);
+
+   switch (e_comp_wl->ptr.button)
      {
-        if (e_policy_visibility_client_grab_cancel(ec))
-          {
-             ELOGF("POL_VIS", "CLIENT VIS ON(temp).", ec->pixmap, ec);
-             ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
-             ec->visibility.changed = 1;
-          }
+      case BTN_LEFT:    ev.button = 1; break;
+      case BTN_MIDDLE:  ev.button = 2; break;
+      case BTN_RIGHT:   ev.button = 3; break;
+      default:          ev.button = e_comp_wl->ptr.button; break;
+     }
+
+   e_comp_object_frame_xy_unadjust(ec->frame,
+                                   wl_fixed_to_int(e_comp_wl->ptr.x),
+                                   wl_fixed_to_int(e_comp_wl->ptr.y),
+                                   &ev.canvas.x,
+                                   &ev.canvas.y);
+
+   _e_shell_e_client_mouse_down_helper(ec, &ev, EINA_TRUE, 0);
+
+   TRACE_DS_END();
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_shell_e_client_interactive_resize(E_Client *ec,
+                                    struct wl_resource *resource,
+                                    /* TODO Multi seat is not yet supported */
+                                    struct wl_resource *seat EINA_UNUSED,
+                                    uint32_t edges)
+{
+   E_Binding_Event_Mouse_Button ev;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   if ((edges == 0) || (edges > 15) ||
+       ((edges & 3) == 3) || ((edges & 12) == 12))
+     return EINA_FALSE;
+
+   if ((ec->maximized) || (ec->fullscreen))
+     return EINA_FALSE;
+
+   TRACE_DS_BEGIN(SHELL:SURFACE RESIZE REQUEST CB);
+
+   e_comp_wl->resize.resource = resource;
+   e_comp_wl->resize.edges = edges;
+   e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
+   e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
+
+   switch (e_comp_wl->ptr.button)
+     {
+      case BTN_LEFT:   ev.button = 1; break;
+      case BTN_MIDDLE: ev.button = 2; break;
+      case BTN_RIGHT:  ev.button = 3; break;
+      default:         ev.button = e_comp_wl->ptr.button; break;
+     }
+
+   e_comp_object_frame_xy_unadjust(ec->frame,
+                                   wl_fixed_to_int(e_comp_wl->ptr.x),
+                                   wl_fixed_to_int(e_comp_wl->ptr.y),
+                                   &ev.canvas.x,
+                                   &ev.canvas.y);
+
+   _e_shell_e_client_mouse_down_helper(ec, &ev, EINA_FALSE, edges);
 
-        if ((e_object_unref(E_OBJECT(ec))) &&
-            (!e_object_is_del(E_OBJECT(ec))))
+   TRACE_DS_END();
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_shell_e_client_destroy(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   if (e_policy_visibility_client_grab_cancel(ec))
+     {
+        ELOGF("POL_VIS", "CLIENT VIS ON(temp).", ec->pixmap, ec);
+        ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
+        ec->visibility.changed = 1;
+     }
+
+   if ((e_object_unref(E_OBJECT(ec))) &&
+       (!e_object_is_del(E_OBJECT(ec))))
+     {
+        if (ec->comp_data->mapped)
           {
-             if (ec->comp_data->mapped)
-               {
-                  if ((ec->comp_data->shell.surface) &&
-                      (ec->comp_data->shell.unmap))
-                    {
-                       ELOGF("SHELL", "Call shell.unmap by destory surface", ec->pixmap, ec);
-                       ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
-                    }
-               }
-             if (ec->parent)
+             if ((ec->comp_data->shell.surface) &&
+                 (ec->comp_data->shell.unmap))
                {
-                  ec->parent->transients =
-                     eina_list_remove(ec->parent->transients, ec);
-                  if (ec->parent->modal == ec) ec->parent->modal = NULL;
-                  ec->parent = NULL;
+                  ELOGF("SHELL", "Call shell.unmap by destory surface", ec->pixmap, ec);
+                  ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
                }
-             /* wl_resource_destroy(ec->comp_data->shell.surface); */
           }
-        if (ec->comp_data)
-          ec->comp_data->shell.surface = NULL;
-
-        ELOGF("SHELL", "Destroy shell surface", ec->pixmap, ec);
+        if (ec->parent)
+          {
+             ec->parent->transients =
+                eina_list_remove(ec->parent->transients, ec);
+             if (ec->parent->modal == ec) ec->parent->modal = NULL;
+             ec->parent = NULL;
+          }
+        /* wl_resource_destroy(ec->comp_data->shell.surface); */
      }
 
+   if (ec->comp_data)
+     ec->comp_data->shell.surface = NULL;
+
+   ELOGF("SHELL", "Destroy shell surface", ec->pixmap, ec);
+
    e_policy_client_unmap(ec);
 }
 
+static void
+_e_shell_surface_destroy(struct wl_resource *resource)
+{
+   E_Client *ec = NULL;
+
+   /* get the client for this resource */
+   if (!(ec = wl_resource_get_user_data(resource)))
+     return;
+
+   e_shell_e_client_destroy(ec);
+}
+
 static void
 _e_shell_surface_cb_destroy(struct wl_resource *resource)
 {
@@ -180,17 +433,13 @@ _e_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resourc
    E_Client *ec;
 
    if ((ec = wl_resource_get_user_data(resource)))
-     {
-        ec->ping_ok = EINA_TRUE;
-        ec->hung = EINA_FALSE;
-     }
+     e_shell_e_client_pong(ec);
 }
 
 static void
-_e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED)
+_e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED)
 {
    E_Client *ec;
-   E_Binding_Event_Mouse_Button ev;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -201,29 +450,13 @@ _e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resourc
         return;
      }
 
-   if ((ec->maximized) || (ec->fullscreen)) return;
-
-   switch (e_comp_wl->ptr.button)
-     {
-      case BTN_LEFT:   ev.button = 1; break;
-      case BTN_MIDDLE: ev.button = 2; break;
-      case BTN_RIGHT:  ev.button = 3; break;
-      default: ev.button = e_comp_wl->ptr.button; break;
-     }
-
-   e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
-                                   &ev.canvas.x, &ev.canvas.y);
-
-   _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE, 0);
+   e_shell_e_client_interactive_move(ec, seat_resource);
 }
 
 static void
-_e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges)
+_e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED, uint32_t edges)
 {
    E_Client *ec;
-   E_Binding_Event_Mouse_Button ev;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -234,30 +467,7 @@ _e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resou
         return;
      }
 
-   if ((edges == 0) || (edges > 15) ||
-       ((edges & 3) == 3) || ((edges & 12) == 12)) return;
-
-   if ((ec->maximized) || (ec->fullscreen)) return;
-
-   e_comp_wl->resize.resource = resource;
-   e_comp_wl->resize.edges = edges;
-   e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
-   e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
-
-   switch (e_comp_wl->ptr.button)
-     {
-      case BTN_LEFT:   ev.button = 1; break;
-      case BTN_MIDDLE: ev.button = 2; break;
-      case BTN_RIGHT:  ev.button = 3; break;
-      default: ev.button = e_comp_wl->ptr.button; break;
-     }
-
-   e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
-                                   &ev.canvas.x, &ev.canvas.y);
-
-   _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE, edges);
+   e_shell_e_client_interactive_resize(ec, resource, seat_resource, edges);
 }
 
 static void
@@ -275,15 +485,8 @@ _e_shell_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl
      }
 
    /* set toplevel client properties */
-   ec->icccm.accepts_focus = 1;
-   if (!ec->internal)
-     ec->borderless = !ec->internal;
+   e_shell_e_client_toplevel_set(ec);
 
-   ec->lock_border = EINA_TRUE;
-   if (!ec->internal)
-     ec->border.changed = ec->changes.border = !ec->borderless;
-   ec->netwm.type = E_WINDOW_TYPE_NORMAL;
-   ec->comp_data->set_win_type = EINA_TRUE;
    if ((!ec->lock_user_maximize) && (ec->maximized))
      e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
    if ((!ec->lock_user_fullscreen) && (ec->fullscreen))
@@ -304,7 +507,7 @@ _e_shell_surface_cb_transient_set(struct wl_client *client EINA_UNUSED, struct w
      }
 
    /* set this client as a transient for parent */
-   _e_shell_surface_parent_set(ec, parent_resource);
+   e_shell_e_client_parent_set(ec, parent_resource);
 
    EC_CHANGED(ec);
 }
@@ -355,7 +558,7 @@ _e_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_re
    ec->layer = E_LAYER_CLIENT_POPUP;
 
    /* set this client as a transient for parent */
-   _e_shell_surface_parent_set(ec, parent_resource);
+   e_shell_e_client_parent_set(ec, parent_resource);
 
    EC_CHANGED(ec);
 }
@@ -402,8 +605,7 @@ _e_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_re
      }
 
    /* set title */
-   eina_stringshare_replace(&ec->icccm.title, title);
-   if (ec->frame) e_comp_object_frame_title_set(ec->frame, title);
+   e_shell_e_client_name_title_set(ec, NULL, title);
 }
 
 static void
@@ -640,7 +842,14 @@ static void
 _e_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource)
 {
    E_Client *ec;
-   E_Comp_Client_Data *cdata;
+   struct wl_resource *shsurf_resource;
+   E_Shell_Surface_Api api = {
+      .configure_send = _e_shell_surface_configure_send,
+      .configure = _e_shell_surface_configure,
+      .ping = _e_shell_surface_ping,
+      .map = _e_shell_surface_map,
+      .unmap = _e_shell_surface_unmap,
+   };
 
    /* get the pixmap from this surface so we can find the client */
    if (!(ec = wl_resource_get_user_data(surface_resource)))
@@ -650,47 +859,30 @@ _e_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *reso
                                "No Pixmap Set On Surface");
         return;
      }
-   ec->netwm.ping = 1;
-   /* get the client data */
-   if (!(cdata = ec->comp_data))
-     {
-        wl_resource_post_error(surface_resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Data For Client");
-        return;
-     }
 
-   /* check for existing shell surface */
-   if (cdata->shell.surface)
+   if (!e_shell_e_client_shell_assignable_check(ec))
      {
         wl_resource_post_error(surface_resource,
                                WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has shell surface");
+                               "Could not assign shell surface to wl_surface");
         return;
      }
 
-   /* try to create a shell surface */
-   if (!(cdata->shell.surface =
-         wl_resource_create(client, &wl_shell_surface_interface, 1, id)))
+   shsurf_resource = wl_resource_create(client, &wl_shell_surface_interface, 1, id);
+   if (!shsurf_resource)
      {
-        wl_resource_post_no_memory(surface_resource);
+        wl_client_post_no_memory(client);
         return;
      }
-   ELOGF("SHELL", "Create shell surface", ec->pixmap, ec);
 
-   wl_resource_set_implementation(cdata->shell.surface,
+   wl_resource_set_implementation(shsurf_resource,
                                   &_e_shell_surface_interface,
                                   ec,
                                   _e_shell_surface_cb_destroy);
 
-   e_object_ref(E_OBJECT(ec));
-
-   cdata->shell.configure_send = _e_shell_surface_configure_send;
-   cdata->shell.configure = _e_shell_surface_configure;
-   cdata->shell.ping = _e_shell_surface_ping;
-   cdata->shell.map = _e_shell_surface_map;
-   cdata->shell.unmap = _e_shell_surface_unmap;
+   ELOGF("SHELL", "Create shell surface", ec->pixmap, ec);
 
+   e_shell_e_client_shsurface_assign(ec, shsurf_resource, &api);
    e_comp_wl_shell_surface_ready(ec);
 }
 
@@ -792,7 +984,7 @@ _e_xdg_shell_surface_cb_parent_set(struct wl_client *client EINA_UNUSED, struct
      }
 
    /* set this client as a transient for parent */
-   _e_shell_surface_parent_set(ec, parent_resource);
+   e_shell_e_client_parent_set(ec, parent_resource);
 
    EC_CHANGED(ec);
 }
@@ -812,9 +1004,7 @@ _e_xdg_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct w
      }
 
    /* set title */
-   eina_stringshare_replace(&ec->icccm.title, title);
-   eina_stringshare_replace(&ec->icccm.name, title);
-   if (ec->frame) e_comp_object_frame_title_set(ec->frame, title);
+   e_shell_e_client_name_title_set(ec, title, title);
 }
 
 static void
@@ -834,11 +1024,7 @@ _e_xdg_shell_surface_cb_app_id_set(struct wl_client *client EINA_UNUSED, struct
    /* use the wl_client to get the pid * and set it in the netwm props */
    wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL);
 
-   /* set class */
-   eina_stringshare_replace(&ec->icccm.class, id);
-   /* eina_stringshare_replace(&ec->netwm.name, id); */
-   ec->changes.icon = !!ec->icccm.class;
-   EC_CHANGED(ec);
+   e_shell_e_client_app_id_set(ec, id);
 }
 
 static void
@@ -861,10 +1047,9 @@ _e_xdg_shell_surface_cb_window_menu_show(struct wl_client *client EINA_UNUSED, s
 }
 
 static void
-_e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED)
+_e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED)
 {
    E_Client *ec;
-   E_Binding_Event_Mouse_Button ev;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -875,34 +1060,13 @@ _e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_res
         return;
      }
 
-   if ((ec->maximized) || (ec->fullscreen)) return;
-
-   TRACE_DS_BEGIN(SHELL:SURFACE MOVE REQUEST CB);
-
-   switch (e_comp_wl->ptr.button)
-     {
-      case BTN_LEFT:   ev.button = 1; break;
-      case BTN_MIDDLE: ev.button = 2; break;
-      case BTN_RIGHT:  ev.button = 3; break;
-      default:         ev.button = e_comp_wl->ptr.button; break;
-     }
-
-   e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
-                                   &ev.canvas.x,
-                                   &ev.canvas.y);
-
-   _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE, 0);
-
-   TRACE_DS_END();
-}
+   e_shell_e_client_interactive_move(ec, seat_resource);
+}
 
 static void
-_e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges)
+_e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED, uint32_t edges)
 {
    E_Client *ec;
-   E_Binding_Event_Mouse_Button ev;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -913,38 +1077,7 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r
         return;
      }
 
-   if ((edges == 0) ||
-       (edges > 15) ||
-       ((edges & 3) == 3) ||
-       ((edges & 12) == 12))
-     return;
-
-   if ((ec->maximized) || (ec->fullscreen)) return;
-
-   TRACE_DS_BEGIN(SHELL:SURFACE RESIZE REQUEST CB);
-
-   e_comp_wl->resize.resource = resource;
-   e_comp_wl->resize.edges = edges;
-   e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
-   e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
-
-   switch (e_comp_wl->ptr.button)
-     {
-      case BTN_LEFT:   ev.button = 1; break;
-      case BTN_MIDDLE: ev.button = 2; break;
-      case BTN_RIGHT:  ev.button = 3; break;
-      default:         ev.button = e_comp_wl->ptr.button; break;
-     }
-
-   e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
-                                   &ev.canvas.x,
-                                   &ev.canvas.y);
-
-   _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE, edges);
-
-   TRACE_DS_END();
+   e_shell_e_client_interactive_resize(ec, resource, seat_resource, edges);
 }
 
 static void
@@ -1200,87 +1333,75 @@ _e_xdg_shell_surface_map_cb_timer(void *data)
    return ECORE_CALLBACK_CANCEL;
 }
 
-static void
-_e_xdg_shell_surface_map(struct wl_resource *resource)
+EINTERN void
+e_shell_e_client_map(E_Client *ec)
 {
-   E_Client *ec;
+   int pw = 0;
+   int ph = 0;
+   int cw;
+   int ch;
 
-   if (!resource) return;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   TRACE_DS_BEGIN(SHELL:MAP);
+   if ((ec->comp_data->mapped) || (!e_pixmap_usable_get(ec->pixmap)))
+     return;
 
-   /* get the client for this resource */
-   if (!(ec = wl_resource_get_user_data(resource)))
+   cw = ec->w;
+   ch = ec->h;
+
+   e_pixmap_size_get(ec->pixmap, &pw, &ph);
+   evas_object_geometry_get(ec->frame, NULL, NULL, &cw, &ch);
+   if (cw == 0 && ch == 0)
      {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        TRACE_DS_END();
-        return;
+        cw = ec->w;
+        ch = ec->h;
      }
 
-   if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap)))
+   if (pw != cw || ph != ch)
      {
-        int pw = 0;
-        int ph = 0;
-        int cw = ec->w;
-        int ch = ec->h;
-        e_pixmap_size_get(ec->pixmap, &pw, &ph);
-        evas_object_geometry_get(ec->frame, NULL, NULL, &cw, &ch);
-        if (cw == 0 && ch == 0)
+        if ((ec->changes.need_maximize) ||
+            ((ec->maximized & E_MAXIMIZE_BOTH) == E_MAXIMIZE_BOTH))
           {
-             cw = ec->w;
-             ch = ec->h;
-          }
+             // skip. because the pixmap's size doesnot same to ec's size
+             ELOGF("SHELL",
+                   "Deny Map |win:0x%08x|ec_size:%d,%d|get_size:%d,%d|pix_size:%d,%d",
+                   ec->pixmap, ec,
+                   (unsigned int)e_client_util_win_get(ec),
+                   ec->w, ec->h, cw, ch, pw, ph);
 
-        if (pw != cw || ph != ch)
-          {
-             if ((ec->changes.need_maximize) ||
-                 ((ec->maximized & E_MAXIMIZE_BOTH) == E_MAXIMIZE_BOTH))
-               {
-                  // skip. because the pixmap's size doesnot same to ec's size
-                  ELOGF("SHELL",
-                        "Deny Map |win:0x%08x|ec_size:%d,%d|get_size:%d,%d|pix_size:%d,%d",
-                        ec->pixmap, ec,
-                        (unsigned int)e_client_util_win_get(ec),
-                        ec->w, ec->h, cw, ch, pw, ph);
-
-                  if (!ec->map_timer)
-                    ec->map_timer = ecore_timer_add(3.0, _e_xdg_shell_surface_map_cb_timer, ec);
-
-                  TRACE_DS_END();
-                  return;
-               }
-          }
-        E_FREE_FUNC(ec->map_timer, ecore_timer_del);
+             if (!ec->map_timer)
+               ec->map_timer = ecore_timer_add(3.0, _e_xdg_shell_surface_map_cb_timer, ec);
 
-        ELOGF("SHELL",
-              "Map window  |win:0x%08x|ec_size:%d,%d|pid:%d|title:%s, name:%s",
-              ec->pixmap, ec,
-              (unsigned int)e_client_util_win_get(ec),
-              ec->w, ec->h, ec->netwm.pid, ec->icccm.title, ec->netwm.name);
+             TRACE_DS_END();
+             return;
+          }
+     }
+   E_FREE_FUNC(ec->map_timer, ecore_timer_del);
 
-        ELOGF("SHELL",
-              "spash:%d, first_mapped:%d, iconic:%d(client:%d), raise:%d, lower:%d, ignore:%d, override:%d, input_only:%d",
-              ec->pixmap, ec,
-              ec->use_splash, ec->first_mapped, ec->iconic, ec->exp_iconify.by_client,
-              ec->post_raise, ec->post_lower, ec->ignored, ec->override, ec->input_only);
+   ELOGF("SHELL",
+         "Map window  |win:0x%08x|ec_size:%d,%d|pid:%d|title:%s, name:%s",
+         ec->pixmap, ec,
+         (unsigned int)e_client_util_win_get(ec),
+         ec->w, ec->h, ec->netwm.pid, ec->icccm.title, ec->netwm.name);
 
-        _e_shell_client_map_common_pre(ec);
-        _e_shell_client_map_common_post(ec);
-     }
+   ELOGF("SHELL",
+         "spash:%d, first_mapped:%d, iconic:%d(client:%d), raise:%d, lower:%d, ignore:%d, override:%d, input_only:%d",
+         ec->pixmap, ec,
+         ec->use_splash, ec->first_mapped, ec->iconic, ec->exp_iconify.by_client,
+         ec->post_raise, ec->post_lower, ec->ignored, ec->override, ec->input_only);
 
-   TRACE_DS_END();
+   _e_shell_client_map_common_pre(ec);
+   _e_shell_client_map_common_post(ec);
 }
 
 static void
-_e_xdg_shell_surface_unmap(struct wl_resource *resource)
+_e_xdg_shell_surface_map(struct wl_resource *resource)
 {
    E_Client *ec;
 
    if (!resource) return;
 
-   TRACE_DS_BEGIN(SHELL:UNMAP);
+   TRACE_DS_BEGIN(SHELL:MAP);
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -1292,6 +1413,15 @@ _e_xdg_shell_surface_unmap(struct wl_resource *resource)
         return;
      }
 
+   e_shell_e_client_map(ec);
+
+   TRACE_DS_END();
+}
+
+EINTERN void
+e_shell_e_client_unmap(E_Client *ec)
+{
+
    E_FREE_FUNC(ec->map_timer, ecore_timer_del);
 
    if (ec->comp_data->mapped)
@@ -1309,48 +1439,65 @@ _e_xdg_shell_surface_unmap(struct wl_resource *resource)
               (unsigned int)e_client_util_win_get(ec),
               ec->w, ec->h);
      }
-
-   TRACE_DS_END();
 }
 
 static void
-_e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource)
+_e_xdg_shell_surface_unmap(struct wl_resource *resource)
 {
    E_Client *ec;
-   E_Comp_Client_Data *cdata;
 
-   /* get the pixmap from this surface so we can find the client */
-   if (!(ec = wl_resource_get_user_data(surface_resource)))
+   if (!resource) return;
+
+   TRACE_DS_BEGIN(SHELL:UNMAP);
+
+   /* get the client for this resource */
+   if (!(ec = wl_resource_get_user_data(resource)))
      {
-        wl_resource_post_error(surface_resource,
+        wl_resource_post_error(resource,
                                WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
+                               "No Client For Shell Surface");
+        TRACE_DS_END();
         return;
      }
 
-   ec->netwm.ping = 1;
+   e_shell_e_client_unmap(ec);
+
+   TRACE_DS_END();
+}
+
+static void
+_e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource)
+{
+   E_Client *ec;
+   struct wl_resource *shsurf_resource;
+   E_Shell_Surface_Api api = {
+      .configure_send = _e_xdg_shell_surface_configure_send,
+      .configure = _e_xdg_shell_surface_configure,
+      .ping = _e_xdg_shell_surface_ping,
+      .map = _e_xdg_shell_surface_map,
+      .unmap = _e_xdg_shell_surface_unmap,
+   };
 
-   /* get the client data */
-   if (!(cdata = ec->comp_data))
+   /* get the pixmap from this surface so we can find the client */
+   if (!(ec = wl_resource_get_user_data(surface_resource)))
      {
         wl_resource_post_error(surface_resource,
                                WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Data For Client");
+                               "No Pixmap Set On Surface");
         return;
      }
 
-   /* check for existing shell surface */
-   if (cdata->shell.surface)
+   if (!e_shell_e_client_shell_assignable_check(ec))
      {
         wl_resource_post_error(surface_resource,
                                WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has XDG shell surface");
+                               "Could not assign shell surface to wl_surface");
         return;
      }
 
    /* try to create a shell surface */
-   if (!(cdata->shell.surface =
-         wl_resource_create(client, &xdg_surface_interface, 1, id)))
+   shsurf_resource = wl_resource_create(client, &xdg_surface_interface, 1, id);
+   if (!shsurf_resource)
      {
         ERR("Could not create xdg shell surface");
         wl_resource_post_no_memory(surface_resource);
@@ -1358,29 +1505,13 @@ _e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resour
      }
    ELOGF("SHELL", "Create xdg shell surface", ec->pixmap, ec);
 
-   wl_resource_set_implementation(cdata->shell.surface,
+   wl_resource_set_implementation(shsurf_resource,
                                   &_e_xdg_surface_interface,
                                   ec,
                                   _e_shell_surface_cb_destroy);
 
-   e_object_ref(E_OBJECT(ec));
-
-   cdata->shell.configure_send = _e_xdg_shell_surface_configure_send;
-   cdata->shell.configure = _e_xdg_shell_surface_configure;
-   cdata->shell.ping = _e_xdg_shell_surface_ping;
-   cdata->shell.map = _e_xdg_shell_surface_map;
-   cdata->shell.unmap = _e_xdg_shell_surface_unmap;
-
-   /* set toplevel client properties */
-   ec->icccm.accepts_focus = 1;
-   if (!ec->internal)
-     ec->borderless = 1;
-   ec->lock_border = EINA_TRUE;
-   if ((!ec->internal) || (!ec->borderless))
-     ec->border.changed = ec->changes.border = !ec->borderless;
-   if (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN)
-     ec->netwm.type = E_WINDOW_TYPE_NORMAL;
-   ec->comp_data->set_win_type = EINA_TRUE;
+   e_shell_e_client_shsurface_assign(ec, shsurf_resource, &api);
+   e_shell_e_client_toplevel_set(ec);
 
    e_comp_wl_shell_surface_ready(ec);
 }
@@ -1401,6 +1532,14 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource
 {
    E_Client *ec;
    E_Comp_Client_Data *cdata;
+   struct wl_resource *shsurf_resource;
+   E_Shell_Surface_Api api = {
+        .configure_send = _e_xdg_shell_surface_configure_send,
+        .configure = _e_xdg_shell_surface_configure,
+        .ping = _e_xdg_shell_surface_ping,
+        .map = _e_xdg_shell_surface_map,
+        .unmap = _e_xdg_shell_surface_unmap,
+   };
 
    /* get the pixmap from this surface so we can find the client */
    if (!(ec = wl_resource_get_user_data(surface_resource)))
@@ -1411,21 +1550,11 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource
         return;
      }
 
-   /* get the client data */
-   if (!(cdata = ec->comp_data))
-     {
-        wl_resource_post_error(surface_resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Data For Client");
-        return;
-     }
-
-   /* check for existing shell surface */
-   if (cdata->shell.surface)
+   if (!e_shell_e_client_shell_assignable_check(ec))
      {
         wl_resource_post_error(surface_resource,
                                WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has shell popup surface");
+                               "Could not assign shell surface to wl_surface");
         return;
      }
 
@@ -1439,8 +1568,8 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource
      }
 
    /* try to create a shell surface */
-   if (!(cdata->shell.surface =
-         wl_resource_create(client, &xdg_popup_interface, 1, id)))
+   shsurf_resource = wl_resource_create(client, &xdg_popup_interface, 1, id);
+   if (!shsurf_resource)
      {
         ERR("Could not create xdg shell surface");
         wl_resource_post_no_memory(surface_resource);
@@ -1448,36 +1577,18 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource
      }
    ELOGF("SHELL", "Create xdg shell popup surface", ec->pixmap, ec);
 
-   wl_resource_set_implementation(cdata->shell.surface,
+   wl_resource_set_implementation(shsurf_resource,
                                   &_e_xdg_popup_interface,
                                   ec,
                                   NULL);
 
-   e_object_ref(E_OBJECT(ec));
-
-   cdata->shell.configure_send = _e_xdg_shell_surface_configure_send;
-   cdata->shell.configure = _e_xdg_shell_surface_configure;
-   cdata->shell.ping = _e_xdg_shell_surface_ping;
-   cdata->shell.map = _e_xdg_shell_surface_map;
-   cdata->shell.unmap = _e_xdg_shell_surface_unmap;
-
-   EC_CHANGED(ec);
-   ec->new_client = ec->override = 1;
-   e_client_unignore(ec);
-   e_comp->new_clients++;
-   if (!ec->internal)
-     ec->borderless = !ec->internal_elm_win;
-   ec->lock_border = EINA_TRUE;
-   if (!ec->internal)
-     ec->border.changed = ec->changes.border = !ec->borderless;
-   ec->changes.icon = !!ec->icccm.class;
-   ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU;
-   ec->comp_data->set_win_type = EINA_TRUE;
-   evas_object_layer_set(ec->frame, E_LAYER_CLIENT_POPUP);
+   e_shell_e_client_shsurface_assign(ec, shsurf_resource, &api);
+   e_shell_e_client_popup_set(ec);
 
    /* set this client as a transient for parent */
-   _e_shell_surface_parent_set(ec, parent_resource);
+   e_shell_e_client_parent_set(ec, parent_resource);
 
+   cdata = ec->comp_data;
    if (ec->parent)
      {
         cdata->popup.x = E_CLAMP(x, 0, ec->parent->client.w);
@@ -1502,12 +1613,7 @@ _e_xdg_shell_cb_pong(struct wl_client *client, struct wl_resource *resource, uin
    EINA_SAFETY_ON_FALSE_RETURN(esh->res == resource);
 
    EINA_LIST_FREE(esh->ping_ecs, ec)
-     {
-        if (e_object_is_del(E_OBJECT(ec))) continue;
-
-        ec->ping_ok = EINA_TRUE;
-        ec->hung = EINA_FALSE;
-     }
+      e_shell_e_client_pong(ec);
 }
 
 static void
@@ -1539,10 +1645,8 @@ static void
 _e_xdg_shell_cb_unbind(struct wl_resource *resource)
 {
    E_Xdg_Shell *esh;
-   E_Xdg_Pos *epos;
    E_Client *ec;
    struct wl_client *client;
-   Eina_List *l, *ll;
 
    client = wl_resource_get_client(resource);
    EINA_SAFETY_ON_NULL_RETURN(client);
@@ -1551,16 +1655,7 @@ _e_xdg_shell_cb_unbind(struct wl_resource *resource)
    EINA_SAFETY_ON_NULL_RETURN(esh);
 
    EINA_LIST_FREE(esh->ping_ecs, ec)
-     {
-        if (e_object_is_del(E_OBJECT(ec))) continue;
-        ec->ping_ok = EINA_TRUE;
-        ec->hung = EINA_FALSE;
-     }
-
-   EINA_LIST_FOREACH_SAFE(esh->positioners, l, ll, epos)
-     {
-        E_FREE(epos);
-     }
+      e_shell_e_client_pong(ec);
 
    eina_hash_del_by_key(xdg_sh_hash, &client);
 
@@ -1649,985 +1744,67 @@ err:
    wl_client_post_no_memory(client);
 }
 
-////////////////////////////////////////////////////////////////////////////////
 static void
-_e_xdg_surf_v6_configure_send(struct wl_resource *res_xdg_surf_v6,
-                              uint32_t edges,
-                              int32_t width,
-                              int32_t height)
+_e_tz_surf_cb_tz_res_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface)
 {
+   struct wl_resource *res;
    E_Client *ec;
-   E_Comp_Client_Data *cdata;
-   struct wl_array states;
-   uint32_t serial;
-   struct wl_resource *resource;
-
-   EINA_SAFETY_ON_NULL_RETURN(res_xdg_surf_v6);
+   uint32_t res_id;
 
-   ec = wl_resource_get_user_data(res_xdg_surf_v6);
-   if (!ec)
+   /* get the pixmap from this surface so we can find the client */
+   if (!(ec = wl_resource_get_user_data(surface)))
      {
-        wl_resource_post_error(res_xdg_surf_v6,
+        wl_resource_post_error(surface,
                                WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
+                               "No Pixmap Set On Surface");
         return;
      }
 
-   cdata = ec->comp_data;
-   EINA_SAFETY_ON_NULL_RETURN(cdata);
-   EINA_SAFETY_ON_NULL_RETURN(cdata->sh_v6.res_role);
-
-   resource = cdata->sh_v6.res_role;
-
-   wl_array_init(&states);
-
-   if (ec->fullscreen)
-     {
-        _e_xdg_surface_state_add(resource, &states, ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN);
+   /* find the window id for this pixmap */
+   res_id = e_pixmap_res_id_get(ec->pixmap);
 
-        // send fullscreen size
-        if ((width == 0) && (height == 0))
-          {
-             width = ec->client.w && ec->client.h? ec->client.w : ec->w;
-             height = ec->client.w && ec->client.h? ec->client.h : ec->h;
-          }
-     }
-   else if (ec->maximized)
+   /* try to create a tizen_gid */
+   if (!(res = wl_resource_create(client,
+                                  &tizen_resource_interface,
+                                  wl_resource_get_version(resource),
+                                  id)))
      {
-        _e_xdg_surface_state_add(resource, &states, ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED);
-
-        // send maximized size
-        if ((width == 0) && (height == 0))
-          {
-             width = ec->client.w && ec->client.h? ec->client.w : ec->w;
-             height = ec->client.w && ec->client.h? ec->client.h : ec->h;
-          }
+        wl_resource_post_no_memory(resource);
+        return;
      }
 
-   if (edges != 0)
-     _e_xdg_surface_state_add(resource, &states, ZXDG_TOPLEVEL_V6_STATE_RESIZING);
-
-   if (ec->focused)
-     _e_xdg_surface_state_add(resource, &states, ZXDG_TOPLEVEL_V6_STATE_ACTIVATED);
-
-   zxdg_toplevel_v6_send_configure(cdata->sh_v6.res_role, width, height, &states);
-   serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   zxdg_surface_v6_send_configure(res_xdg_surf_v6, serial);
-
-   wl_array_release(&states);
+   wl_resource_set_implementation(res,
+                                  &_e_tz_res_interface,
+                                  ec,
+                                  NULL);
 
-   ELOGF("SH", "SEND configure v6 %dx%d", ec->pixmap, ec, width, height);
+   tizen_resource_send_resource_id(res, res_id);
 }
 
 static void
-_e_xdg_sh_v6_ping(struct wl_resource *res_xdg_surf_v6)
+_e_tz_surf_cb_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-   E_Client *ec;
-   uint32_t serial;
-   struct wl_client *client;
-   E_Xdg_Shell *esh;
+   wl_resource_destroy(resource);
+}
 
-   if (!res_xdg_surf_v6) return;
+static const struct tizen_surface_interface _e_tz_surf_interface =
+{
+   _e_tz_surf_cb_tz_res_get,
+   _e_tz_surf_cb_destroy
+};
 
-   ec = wl_resource_get_user_data(res_xdg_surf_v6);
-   if (!ec)
+static void
+_e_tz_surf_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+   struct wl_resource *res;
+
+   if (!(res = wl_resource_create(client,
+                                  &tizen_surface_interface,
+                                  version,
+                                  id)))
      {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   client = wl_resource_get_client(res_xdg_surf_v6);
-
-   esh = eina_hash_find(xdg_sh_hash, &client);
-   EINA_SAFETY_ON_NULL_RETURN(esh);
-   EINA_SAFETY_ON_NULL_RETURN(esh->res);
-
-   if (!eina_list_data_find(esh->ping_ecs, ec))
-     esh->ping_ecs = eina_list_append(esh->ping_ecs, ec);
-
-   serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   zxdg_shell_v6_send_ping(esh->res, serial);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-static void
-_e_xdg_toplv_v6_cb_res_destroy(struct wl_resource *res_xdg_toplv_v6)
-{
-   _e_shell_surface_destroy(res_xdg_toplv_v6);
-}
-
-static void
-_e_xdg_toplv_v6_cb_destroy(struct wl_client *client,
-                           struct wl_resource *res_xdg_toplv_v6)
-{
-   wl_resource_destroy(res_xdg_toplv_v6);
-}
-
-static void
-_e_xdg_toplv_v6_cb_parent_set(struct wl_client *client,
-                              struct wl_resource *res_xdg_toplv_v6,
-                              struct wl_resource *res_xdg_toplv_v6_parent)
-{
-   E_Client *ec, *pc;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if (res_xdg_toplv_v6_parent)
-     {
-        pc = wl_resource_get_user_data(res_xdg_toplv_v6_parent);
-        if (!pc)
-          {
-             ERR("Could not get parent resource clinet");
-             return;
-          }
-        if (!pc->comp_data) return;
-        res_xdg_toplv_v6_parent = pc->comp_data->surface;
-     }
-
-   /* set this client as a transient for parent */
-   _e_shell_surface_parent_set(ec, res_xdg_toplv_v6_parent);
-}
-
-static void
-_e_xdg_toplv_v6_cb_title_set(struct wl_client *client,
-                             struct wl_resource *res_xdg_toplv_v6,
-                             const char *title)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   eina_stringshare_replace(&ec->icccm.title, title);
-   eina_stringshare_replace(&ec->icccm.name, title);
-   if (ec->frame) e_comp_object_frame_title_set(ec->frame, title);
-}
-
-static void
-_e_xdg_toplv_v6_cb_app_id_set(struct wl_client *client,
-                              struct wl_resource *res_xdg_toplv_v6,
-                              const char *app_id)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   /* use the wl_client to get the pid * and set it in the netwm props */
-   wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL);
-
-   /* set class */
-   eina_stringshare_replace(&ec->icccm.class, app_id);
-   ec->changes.icon = !!ec->icccm.class;
-   EC_CHANGED(ec);
-}
-
-static void
-_e_xdg_toplv_v6_cb_win_menu_show(struct wl_client *client,
-                                 struct wl_resource *res_xdg_toplv_v6,
-                                 struct wl_resource *res_seat,
-                                 uint32_t serial,
-                                 int32_t x,
-                                 int32_t y)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   /* TODO no op */
-}
-
-static void
-_e_xdg_toplv_v6_cb_move(struct wl_client *client,
-                        struct wl_resource *res_xdg_toplv_v6,
-                        struct wl_resource *res_seat,
-                        uint32_t serial)
-{
-   E_Client *ec;
-   E_Binding_Event_Mouse_Button ev;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if ((ec->maximized) || (ec->fullscreen)) return;
-
-   TRACE_DS_BEGIN(SHELL:SURFACE MOVE REQUEST CB);
-
-   switch (e_comp_wl->ptr.button)
-     {
-      case BTN_LEFT:   ev.button = 1; break;
-      case BTN_MIDDLE: ev.button = 2; break;
-      case BTN_RIGHT:  ev.button = 3; break;
-      default:         ev.button = e_comp_wl->ptr.button; break;
-     }
-
-   e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
-                                   &ev.canvas.x,
-                                   &ev.canvas.y);
-
-   _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE, 0);
-
-   TRACE_DS_END();
-}
-
-static void
-_e_xdg_toplv_v6_cb_resize(struct wl_client *client,
-                          struct wl_resource *res_xdg_toplv_v6,
-                          struct wl_resource *res_seat,
-                          uint32_t serial,
-                          uint32_t edges)
-{
-   E_Client *ec;
-   E_Binding_Event_Mouse_Button ev;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if ((edges == 0) ||
-       (edges > 15) ||
-       ((edges & 3) == 3) ||
-       ((edges & 12) == 12))
-     return;
-
-   if ((ec->maximized) || (ec->fullscreen)) return;
-
-   TRACE_DS_BEGIN(SHELL:SURFACE RESIZE REQUEST CB);
-
-   e_comp_wl->resize.resource = res_xdg_toplv_v6;
-   e_comp_wl->resize.edges = edges;
-   e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
-   e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
-
-   switch (e_comp_wl->ptr.button)
-     {
-      case BTN_LEFT:   ev.button = 1; break;
-      case BTN_MIDDLE: ev.button = 2; break;
-      case BTN_RIGHT:  ev.button = 3; break;
-      default:         ev.button = e_comp_wl->ptr.button; break;
-     }
-
-   e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
-                                   &ev.canvas.x,
-                                   &ev.canvas.y);
-
-   _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE, edges);
-
-   TRACE_DS_END();
-}
-
-static void
-_e_xdg_toplv_v6_cb_max_size_set(struct wl_client *client,
-                                struct wl_resource *res_xdg_toplv_v6,
-                                int32_t w,
-                                int32_t h)
-{
-   /* TODO no op */
-}
-
-static void
-_e_xdg_toplv_v6_cb_min_size_set(struct wl_client *client,
-                                struct wl_resource *res_xdg_toplv_v6,
-                                int32_t w,
-                                int32_t h)
-{
-   /* TODO no op */
-}
-
-static void
-_e_xdg_toplv_v6_cb_maximized_set(struct wl_client *client,
-                                 struct wl_resource *res_xdg_toplv_v6)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if (!ec->lock_user_maximize)
-     {
-        e_client_maximize(ec,
-                          ((e_config->maximize_policy & E_MAXIMIZE_TYPE) | E_MAXIMIZE_BOTH));
-     }
-}
-
-static void
-_e_xdg_toplv_v6_cb_maximized_unset(struct wl_client *client,
-                                   struct wl_resource *res_xdg_toplv_v6)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
-
-   _e_xdg_shell_surface_configure_send(res_xdg_toplv_v6,
-                                       0,
-                                       ec->w,
-                                       ec->h); // TODO
-}
-
-static void
-_e_xdg_toplv_v6_cb_fullscreen_set(struct wl_client *client,
-                                  struct wl_resource *res_xdg_toplv_v6,
-                                  struct wl_resource *res_output)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if (!ec->lock_user_fullscreen)
-     e_client_fullscreen(ec, e_config->fullscreen_policy);
-}
-
-static void
-_e_xdg_toplv_v6_cb_fullscreen_unset(struct wl_client *client,
-                                    struct wl_resource *res_xdg_toplv_v6)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if (!ec->lock_user_fullscreen)
-     e_client_unfullscreen(ec);
-}
-
-static void
-_e_xdg_toplv_v6_cb_minimized_set(struct wl_client *client,
-                                 struct wl_resource *res_xdg_toplv_v6)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_toplv_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_toplv_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-
-   if (!ec->lock_client_iconify)
-     e_client_iconify(ec);
-}
-
-static const struct zxdg_toplevel_v6_interface _e_xdg_toplv_v6_interface =
-{
-   _e_xdg_toplv_v6_cb_destroy,
-   _e_xdg_toplv_v6_cb_parent_set,
-   _e_xdg_toplv_v6_cb_title_set,
-   _e_xdg_toplv_v6_cb_app_id_set,
-   _e_xdg_toplv_v6_cb_win_menu_show,
-   _e_xdg_toplv_v6_cb_move,
-   _e_xdg_toplv_v6_cb_resize,
-   _e_xdg_toplv_v6_cb_max_size_set,
-   _e_xdg_toplv_v6_cb_min_size_set,
-   _e_xdg_toplv_v6_cb_maximized_set,
-   _e_xdg_toplv_v6_cb_maximized_unset,
-   _e_xdg_toplv_v6_cb_fullscreen_set,
-   _e_xdg_toplv_v6_cb_fullscreen_unset,
-   _e_xdg_toplv_v6_cb_minimized_set
-};
-
-////////////////////////////////////////////////////////////////////////////////
-static void
-_e_xdg_popup_v6_cb_res_destroy(struct wl_resource *res_xdg_popup_v6)
-{
-   _e_shell_surface_destroy(res_xdg_popup_v6);
-}
-
-static void
-_e_xdg_popup_v6_cb_destroy(struct wl_client *client,
-                           struct wl_resource *res_xdg_popup_v6)
-{
-   wl_resource_destroy(res_xdg_popup_v6);
-}
-
-static void
-_e_xdg_popup_v6_cb_grab(struct wl_client *client,
-                        struct wl_resource *res_xdg_popup_v6,
-                        struct wl_resource *res_seat,
-                        uint32_t serial)
-{
-   /* TODO no op */
-}
-
-static const struct zxdg_popup_v6_interface _e_xdg_popup_v6_interface =
-{
-   _e_xdg_popup_v6_cb_destroy,
-   _e_xdg_popup_v6_cb_grab
-};
-
-////////////////////////////////////////////////////////////////////////////////
-static void
-_e_xdg_pos_v6_cb_res_destroy(struct wl_resource *res_xdg_pos_v6)
-{
-   E_Xdg_Shell *esh = NULL;
-   E_Xdg_Pos *epos = NULL;
-
-   epos = wl_resource_get_user_data(res_xdg_pos_v6);
-   EINA_SAFETY_ON_NULL_RETURN(epos);
-
-   esh = epos->sh;
-   esh->positioners = eina_list_remove(esh->positioners, epos);
-
-   E_FREE(epos);
-}
-
-static void
-_e_xdg_pos_v6_cb_destroy(struct wl_client *client,
-                         struct wl_resource *res_xdg_pos_v6)
-{
-   wl_resource_destroy(res_xdg_pos_v6);
-}
-
-static void
-_e_xdg_pos_v6_cb_size_set(struct wl_client *client,
-                          struct wl_resource *res_xdg_pos_v6,
-                          int32_t w,
-                          int32_t h)
-{
-   /* TODO: no op */
-}
-
-static void
-_e_xdg_pos_v6_cb_anchor_rect_set(struct wl_client *client,
-                                 struct wl_resource *res_xdg_pos_v6,
-                                 int32_t x,
-                                 int32_t y,
-                                 int32_t w,
-                                 int32_t h)
-{
-   /* TODO: no op */
-}
-
-static void
-_e_xdg_pos_v6_cb_anchor_set(struct wl_client *client,
-                            struct wl_resource *res_xdg_pos_v6,
-                            uint32_t anchor)
-{
-   /* TODO: no op */
-}
-
-static void
-_e_xdg_pos_v6_cb_gravity_set(struct wl_client *client,
-                             struct wl_resource *res_xdg_pos_v6,
-                             uint32_t gravity)
-{
-   /* TODO: no op */
-}
-
-static void
-_e_xdg_pos_v6_cb_constraint_adjustment_set(struct wl_client *client,
-                                           struct wl_resource *res_xdg_pos_v6,
-                                           uint32_t constraint_adjustment)
-{
-   /* TODO: no op */
-}
-
-static void
-_e_xdg_pos_v6_cb_offset_set(struct wl_client *client,
-                            struct wl_resource *res_xdg_pos_v6,
-                            int32_t x,
-                            int32_t y)
-{
-   /* TODO: no op */
-}
-
-static const struct zxdg_positioner_v6_interface _e_xdg_pos_v6_interface =
-{
-   _e_xdg_pos_v6_cb_destroy,
-   _e_xdg_pos_v6_cb_size_set,
-   _e_xdg_pos_v6_cb_anchor_rect_set,
-   _e_xdg_pos_v6_cb_anchor_set,
-   _e_xdg_pos_v6_cb_gravity_set,
-   _e_xdg_pos_v6_cb_constraint_adjustment_set,
-   _e_xdg_pos_v6_cb_offset_set
-};
-
-////////////////////////////////////////////////////////////////////////////////
-static void
-_e_xdg_surf_v6_cb_destroy(struct wl_client *client,
-                          struct wl_resource *res_xdg_surf_v6)
-{
-   wl_resource_destroy(res_xdg_surf_v6);
-}
-
-static void
-_e_xdg_surf_v6_cb_toplevel_get(struct wl_client *client,
-                               struct wl_resource *res_xdg_surf_v6,
-                               uint32_t id)
-{
-   E_Client *ec;
-   E_Comp_Client_Data *cdata;
-
-   ec = wl_resource_get_user_data(res_xdg_surf_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
-        return;
-     }
-
-   cdata = ec->comp_data;
-   if (!cdata)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Data For Client");
-        return;
-     }
-
-   if (cdata->sh_v6.res_role)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has shell toplevel resource");
-        return;
-     }
-
-   cdata->sh_v6.res_role = wl_resource_create(client,
-                                              &zxdg_toplevel_v6_interface,
-                                              1,
-                                              id);
-   if (!cdata->sh_v6.res_role)
-     {
-        ERR("Could not create xdg toplevel resource");
-        wl_resource_post_no_memory(res_xdg_surf_v6);
-        return;
-     }
-
-   wl_resource_set_implementation(cdata->sh_v6.res_role,
-                                  &_e_xdg_toplv_v6_interface,
-                                  ec,
-                                  _e_xdg_toplv_v6_cb_res_destroy); // TODO
-
-   e_object_ref(E_OBJECT(ec));
-
-   cdata->sh_v6.role = E_COMP_WL_SH_SURF_ROLE_TOPLV;
-
-   cdata->shell.configure_send = _e_xdg_surf_v6_configure_send;
-   cdata->shell.configure = _e_xdg_shell_surface_configure;
-   cdata->shell.ping = _e_xdg_sh_v6_ping;
-   cdata->shell.map = _e_xdg_shell_surface_map;
-   cdata->shell.unmap = _e_xdg_shell_surface_unmap;
-
-   /* set toplevel client properties */
-   ec->icccm.accepts_focus = 1;
-   if (!ec->internal)
-     ec->borderless = 1;
-   ec->lock_border = EINA_TRUE;
-   if ((!ec->internal) || (!ec->borderless))
-     ec->border.changed = ec->changes.border = !ec->borderless;
-   if (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN)
-     ec->netwm.type = E_WINDOW_TYPE_NORMAL;
-   ec->comp_data->set_win_type = EINA_TRUE;
-
-   e_comp_wl_shell_surface_ready(ec);
-}
-
-static void
-_e_xdg_surf_v6_cb_popup_get(struct wl_client *client,
-                            struct wl_resource *res_xdg_surf_v6,
-                            uint32_t id,
-                            struct wl_resource *res_xdg_surf_v6_parent,
-                            struct wl_resource *res_xdg_pos_v6)
-{
-   E_Client *ec;
-   E_Comp_Client_Data *cdata;
-
-   ec = wl_resource_get_user_data(res_xdg_surf_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
-        return;
-     }
-
-   cdata = ec->comp_data;
-   if (!cdata)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Data For Client");
-        return;
-     }
-
-   if (cdata->sh_v6.res_role)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has shell popup resource");
-        return;
-     }
-
-   if (!res_xdg_surf_v6_parent)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Popup requires a parent shell surface");
-        return;
-     }
-
-   cdata->sh_v6.res_role = wl_resource_create(client,
-                                              &zxdg_popup_v6_interface,
-                                              1,
-                                              id);
-   if (!cdata->sh_v6.res_role)
-     {
-        ERR("Could not create xdg popup resource");
-        wl_resource_post_no_memory(res_xdg_surf_v6);
-        return;
-     }
-
-   wl_resource_set_implementation(cdata->sh_v6.res_role,
-                                  &_e_xdg_popup_v6_interface,
-                                  ec,
-                                  _e_xdg_popup_v6_cb_res_destroy); // TODO
-
-   e_object_ref(E_OBJECT(ec));
-
-   cdata->sh_v6.role = E_COMP_WL_SH_SURF_ROLE_POPUP;
-
-   cdata->shell.configure_send = _e_xdg_surf_v6_configure_send;
-   cdata->shell.configure = _e_xdg_shell_surface_configure;
-   cdata->shell.ping = _e_xdg_sh_v6_ping;
-   cdata->shell.map = _e_xdg_shell_surface_map;
-   cdata->shell.unmap = _e_xdg_shell_surface_unmap;
-
-   EC_CHANGED(ec);
-   ec->new_client = ec->override = 1;
-   e_client_unignore(ec);
-   e_comp->new_clients++;
-   if (!ec->internal)
-     ec->borderless = !ec->internal_elm_win;
-   ec->lock_border = EINA_TRUE;
-   if (!ec->internal)
-     ec->border.changed = ec->changes.border = !ec->borderless;
-   ec->changes.icon = !!ec->icccm.class;
-   ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU;
-   ec->comp_data->set_win_type = EINA_TRUE;
-   evas_object_layer_set(ec->frame, E_LAYER_CLIENT_POPUP);
-
-   /* set this client as a transient for parent */
-   _e_shell_surface_parent_set(ec, res_xdg_surf_v6_parent);
-}
-
-static void
-_e_xdg_surf_v6_cb_win_geom_set(struct wl_client *client,
-                               struct wl_resource *res_xdg_surf_v6,
-                               int32_t x,
-                               int32_t y,
-                               int32_t w,
-                               int32_t h)
-{
-   E_Client *ec;
-
-   ec = wl_resource_get_user_data(res_xdg_surf_v6);
-   if (!ec)
-     {
-        wl_resource_post_error(res_xdg_surf_v6,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Client For Shell Surface");
-        return;
-     }
-   EINA_RECTANGLE_SET(&ec->comp_data->shell.window, x, y, w, h);
-}
-
-static void
-_e_xdg_surf_v6_cb_configure_ack(struct wl_client *client,
-                                struct wl_resource *res_xdg_surf_v6,
-                                uint32_t serial)
-{
-   /* TODO no op */
-}
-
-static const struct zxdg_surface_v6_interface _e_xdg_surf_v6_interface =
-{
-   _e_xdg_surf_v6_cb_destroy,
-   _e_xdg_surf_v6_cb_toplevel_get,
-   _e_xdg_surf_v6_cb_popup_get,
-   _e_xdg_surf_v6_cb_win_geom_set,
-   _e_xdg_surf_v6_cb_configure_ack
-};
-
-////////////////////////////////////////////////////////////////////////////////
-static void
-_e_xdg_sh_v6_cb_destroy(struct wl_client *client,
-                        struct wl_resource *res_xdg_sh_v6)
-{
-   wl_resource_destroy(res_xdg_sh_v6);
-}
-
-static void
-_e_xdg_sh_v6_cb_pos_create(struct wl_client *client,
-                           struct wl_resource *res_xdg_sh_v6,
-                           uint32_t id)
-{
-   E_Xdg_Shell *esh = NULL;
-   E_Xdg_Pos *epos = NULL;
-   struct wl_resource *res_xdg_pos_v6 = NULL;
-
-   esh = eina_hash_find(xdg_sh_hash, &client);
-   EINA_SAFETY_ON_NULL_GOTO(esh, err);
-   EINA_SAFETY_ON_NULL_GOTO(esh->res, err);
-   EINA_SAFETY_ON_FALSE_GOTO(esh->res == res_xdg_sh_v6, err);
-
-   epos = E_NEW(E_Xdg_Pos, 1);
-   EINA_SAFETY_ON_NULL_GOTO(epos, err);
-
-   res_xdg_pos_v6 = wl_resource_create(client,
-                                       &zxdg_positioner_v6_interface,
-                                       1,
-                                       id);
-   EINA_SAFETY_ON_NULL_GOTO(res_xdg_pos_v6, err);
-
-   wl_resource_set_implementation(res_xdg_pos_v6,
-                                  &_e_xdg_pos_v6_interface,
-                                  epos,
-                                  _e_xdg_pos_v6_cb_res_destroy);
-
-   epos->sh = esh;
-   epos->res = res_xdg_pos_v6;
-
-   esh->positioners = eina_list_append(esh->positioners, epos);
-
-   return;
-
-err:
-   if (epos) E_FREE(epos);
-   wl_resource_post_no_memory(res_xdg_sh_v6);
-}
-
-static void
-_e_xdg_sh_v6_cb_surf_get(struct wl_client *client,
-                         struct wl_resource *res_xdg_sh_v6 EINA_UNUSED,
-                         uint32_t id,
-                         struct wl_resource *res_surf)
-{
-   E_Client *ec = NULL;
-   E_Comp_Client_Data *cdata = NULL;
-
-   ec = wl_resource_get_user_data(res_surf);
-   if (!ec)
-     {
-        wl_resource_post_error(res_surf,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
-        return;
-     }
-
-   cdata = ec->comp_data;
-   if (!cdata)
-     {
-        wl_resource_post_error(res_surf,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Data For Client");
-        return;
-     }
-
-   if (cdata->shell.surface)
-     {
-        wl_resource_post_error(res_surf,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has XDG shell surface");
-        return;
-     }
-
-   cdata->shell.surface = wl_resource_create(client,
-                                             &zxdg_surface_v6_interface,
-                                             1,
-                                             id);
-   if (!cdata->shell.surface)
-     {
-        ERR("Could not create xdg shell surface");
-        wl_resource_post_no_memory(res_surf);
-        return;
-     }
-
-   wl_resource_set_implementation(cdata->shell.surface,
-                                  &_e_xdg_surf_v6_interface,
-                                  ec,
-                                  _e_shell_surface_cb_destroy);
-
-   e_object_ref(E_OBJECT(ec));
-
-   ec->netwm.ping = 1;
-}
-
-static const struct zxdg_shell_v6_interface _e_xdg_sh_v6_interface =
-{
-   _e_xdg_sh_v6_cb_destroy,
-   _e_xdg_sh_v6_cb_pos_create,
-   _e_xdg_sh_v6_cb_surf_get,
-   _e_xdg_shell_cb_pong /* use v5 pong handler */
-};
-
-////////////////////////////////////////////////////////////////////////////////
-static void
-_e_xdg_sh_v6_cb_bind(struct wl_client *client,
-                     void *data,
-                     uint32_t version,
-                     uint32_t id)
-{
-   E_Xdg_Shell *esh;
-   struct wl_resource *res_xdg_sh_v6;
-
-   res_xdg_sh_v6 = wl_resource_create(client,
-                                      &zxdg_shell_v6_interface,
-                                      version,
-                                      id);
-   EINA_SAFETY_ON_NULL_GOTO(res_xdg_sh_v6, err);
-
-   esh = E_NEW(E_Xdg_Shell, 1);
-   EINA_SAFETY_ON_NULL_GOTO(esh, err);
-
-   esh->wc = client;
-   esh->res = res_xdg_sh_v6;
-   eina_hash_add(xdg_sh_hash, &client, esh);
-
-   wl_resource_set_implementation(res_xdg_sh_v6,
-                                  &_e_xdg_sh_v6_interface,
-                                  e_comp->wl_comp_data,
-                                  _e_xdg_shell_cb_unbind);
-   return;
-
-err:
-   wl_client_post_no_memory(client);
-}
-
-static void
-_e_tz_surf_cb_tz_res_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface)
-{
-   struct wl_resource *res;
-   E_Client *ec;
-   uint32_t res_id;
-
-   /* get the pixmap from this surface so we can find the client */
-   if (!(ec = wl_resource_get_user_data(surface)))
-     {
-        wl_resource_post_error(surface,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No Pixmap Set On Surface");
-        return;
-     }
-
-   /* find the window id for this pixmap */
-   res_id = e_pixmap_res_id_get(ec->pixmap);
-
-   /* try to create a tizen_gid */
-   if (!(res = wl_resource_create(client,
-                                  &tizen_resource_interface,
-                                  wl_resource_get_version(resource),
-                                  id)))
-     {
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-
-   wl_resource_set_implementation(res,
-                                  &_e_tz_res_interface,
-                                  ec,
-                                  NULL);
-
-   tizen_resource_send_resource_id(res, res_id);
-}
-
-static void
-_e_tz_surf_cb_destroy(struct wl_client *client, struct wl_resource *resource)
-{
-   wl_resource_destroy(resource);
-}
-
-static const struct tizen_surface_interface _e_tz_surf_interface =
-{
-   _e_tz_surf_cb_tz_res_get,
-   _e_tz_surf_cb_destroy
-};
-
-static void
-_e_tz_surf_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
-{
-   struct wl_resource *res;
-
-   if (!(res = wl_resource_create(client,
-                                  &tizen_surface_interface,
-                                  version,
-                                  id)))
-     {
-        ERR("Could not create tizen_surface resource: %m");
-        wl_client_post_no_memory(client);
+        ERR("Could not create tizen_surface resource: %m");
+        wl_client_post_no_memory(client);
         return;
      }
 
@@ -2660,13 +1837,9 @@ e_comp_wl_shell_init(void)
         return;
      }
 
-   if (!wl_global_create(e_comp_wl->wl.disp,
-                         &zxdg_shell_v6_interface,
-                         1,
-                         e_comp->wl_comp_data,
-                         _e_xdg_sh_v6_cb_bind))
+   if (!e_xdg_shell_v6_init())
      {
-        ERR("Could not create xdg_shell global: %m");
+        ERR("Could not init xdg_shell_v6");
         return;
      }
 
index 35467601a30201064a5fe0982a0bff7e33f32bdb..06fc7dd9a2fcd9aa6532dbf2391226c01d462963 100644 (file)
@@ -3,8 +3,34 @@
 # ifndef E_COMP_WL_SHELL_H
 #  define E_COMP_WL_SHELL_H
 
+typedef struct
+{
+   void (*configure_send)(struct wl_resource *resource, uint32_t edges, int32_t width, int32_t height);
+   void (*configure)(struct wl_resource *resource, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+   void (*ping)(struct wl_resource *resource);
+   void (*map)(struct wl_resource *resource);
+   void (*unmap)(struct wl_resource *resource);
+} E_Shell_Surface_Api;
+
 EINTERN void e_comp_wl_shell_init(void);
 EINTERN void e_comp_wl_shell_shutdown(void);
 
+EINTERN Eina_Bool e_shell_e_client_shell_assignable_check(E_Client *ec);
+EINTERN void      e_shell_e_client_shsurface_assign(E_Client *ec, struct wl_resource *shsurface, E_Shell_Surface_Api *api);
+EINTERN void      e_shell_e_client_shsurface_api_set(E_Client *ec, E_Shell_Surface_Api *api);
+EINTERN void      e_shell_e_client_toplevel_set(E_Client *ec);
+EINTERN void      e_shell_e_client_popup_set(E_Client *ec);
+EINTERN Eina_Bool e_shell_e_client_name_title_set(E_Client *ec, const char *name, const char *title);
+EINTERN Eina_Bool e_shell_e_client_app_id_set(E_Client *ec, const char *app_id);
+EINTERN void      e_shell_e_client_parent_set(E_Client *ec, struct wl_resource *parent_resource);
+EINTERN void      e_shell_e_client_map(E_Client *ec);
+EINTERN void      e_shell_e_client_unmap(E_Client *ec);
+EINTERN Eina_Bool e_shell_e_client_interactive_move(E_Client *ec, struct wl_resource *seat);
+EINTERN Eina_Bool e_shell_e_client_interactive_resize(E_Client *ec, struct wl_resource *resource, struct wl_resource *seat, uint32_t edges);
+EINTERN void      e_shell_e_client_pong(E_Client *ec);
+EINTERN void      e_shell_e_client_destroy(E_Client *ec);
+
+
+
 # endif
 #endif
index b62f4b32ee785ad531eff1e61a155178aff8d338..7d59e074e58cc13f0516251053c6f1d7cc4ba6cd 100644 (file)
@@ -80,3 +80,4 @@
 #include "e_keyrouter.h"
 #include "e_gesture.h"
 #include "e_input.h"
+#include "e_xdg_shell_v6.h"
diff --git a/src/bin/e_xdg_shell_v6.c b/src/bin/e_xdg_shell_v6.c
new file mode 100644 (file)
index 0000000..7af9738
--- /dev/null
@@ -0,0 +1,2007 @@
+#include "e.h"
+#include <xdg-shell-unstable-v6-server-protocol.h>
+
+#ifdef LOG
+#undef LOG
+#endif
+#ifdef ERR
+#undef ERR
+#endif
+
+#define LOG(f, p, e, x...)  ELOGF("XDG6 <LOG>", f, p, e, ##x)
+#define ERR(f, p, e, x...)  ELOGF("XDG6 <ERR>", f, p, e, ##x)
+
+#define e_xdg_surface_role_biggest_struct E_Xdg_Toplevel
+
+typedef enum   _E_Xdg_Surface_Role        E_Xdg_Surface_Role;
+typedef struct _E_Xdg_Size                E_Xdg_Size;
+typedef struct _E_Xdg_Shell               E_Xdg_Shell;
+typedef struct _E_Xdg_Surface             E_Xdg_Surface;
+typedef struct _E_Xdg_Toplevel            E_Xdg_Toplevel;
+typedef struct _E_Xdg_Popup               E_Xdg_Popup;
+typedef struct _E_Xdg_Positioner          E_Xdg_Positioner;
+typedef struct _E_Xdg_Toplevel_State      E_Xdg_Toplevel_State;
+typedef struct _E_Xdg_Surface_Configure   E_Xdg_Surface_Configure;
+
+enum _E_Xdg_Surface_Role
+{
+   E_XDG_SURFACE_ROLE_NONE,
+   E_XDG_SURFACE_ROLE_TOPLEVEL,
+   E_XDG_SURFACE_ROLE_POPUP,
+};
+
+struct _E_Xdg_Size
+{
+   int w, h;
+};
+
+struct _E_Xdg_Shell
+{
+   struct wl_client     *wclient;
+   struct wl_resource   *resource;     /* xdg_shell resource */
+   Eina_List            *surfaces;     /* list of all E_Xdg_Surface belonging to shell */
+   Eina_List            *positioners;  /* list of E_Xdg_Positioner */
+   uint32_t              ping_serial;
+};
+
+struct _E_Xdg_Toplevel_State
+{
+   Eina_Bool maximized;
+   Eina_Bool fullscreen;
+   Eina_Bool resizing;
+   Eina_Bool activated;
+};
+
+struct _E_Xdg_Surface
+{
+   struct wl_resource   *resource;        /* wl_resource for Zxdg_Surface_V6 */
+   E_Client             *ec;              /* E_Client corresponding Xdg_Surface */
+   E_Xdg_Shell          *shell;           /* Xdg_Shell created Xdg_Surface */
+   Eina_List            *configure_list;  /* list of data being appended whenever configure send and remove by ack_configure */
+
+   Ecore_Idle_Enterer   *configure_idle;  /* Idle_Enterer for sending configure */
+   Ecore_Event_Handler  *commit_handler;  /* Handler raised when wl_buffer is committed. */
+
+   E_Xdg_Surface_Role    role;
+   Eina_Rectangle        configured_geometry;   /* configured geometry by compositor */
+   Eina_Rectangle        window_geometry;       /* window geometry set by client */
+
+   Eina_Bool             configured :1;
+   Eina_Bool             has_window_geometry: 1;
+   Eina_Bool             wait_next_commit;
+};
+
+struct _E_Xdg_Toplevel
+{
+   E_Xdg_Surface         base;
+   struct wl_resource   *resource;
+
+   struct
+   {
+      E_Xdg_Toplevel_State state;
+      E_Xdg_Size           size;
+      uint32_t             edges;
+   } pending;
+   struct
+   {
+      E_Xdg_Toplevel_State state;
+      E_Xdg_Size           size;
+      E_Xdg_Size           min_size, max_size;
+   } next;
+   struct
+   {
+      E_Xdg_Toplevel_State state;
+      E_Xdg_Size           min_size, max_size;
+   } current;
+};
+
+struct _E_Xdg_Popup
+{
+   E_Xdg_Surface         base;
+
+   struct wl_resource   *resource;
+   E_Xdg_Surface        *parent;
+
+   Eina_Rectangle        geometry;
+   Eina_Bool             committed;
+};
+
+struct _E_Xdg_Surface_Configure
+{
+   uint32_t serial;
+   E_Xdg_Toplevel_State state;
+   E_Xdg_Size size;
+};
+
+struct _E_Xdg_Positioner
+{
+   E_Xdg_Shell          *shell;
+   struct wl_resource   *resource;     /* xdg_positioner_v6 resources */
+   E_Xdg_Size            size;
+   Eina_Rectangle        anchor_rect;
+   enum zxdg_positioner_v6_anchor                  anchor;
+   enum zxdg_positioner_v6_gravity                 gravity;
+   enum zxdg_positioner_v6_constraint_adjustment   constraint_adjustment;
+   struct
+   {
+      int x, y;
+   } offset;
+};
+
+static struct wl_global *global_resource = NULL;
+
+static void             _e_xdg_shell_surface_add(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf);
+static void             _e_xdg_shell_surface_remove(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf);
+static void             _e_xdg_shell_ping(E_Xdg_Shell *shell);
+static Eina_Bool        _e_xdg_surface_cb_configure_send(void *data);
+static Eina_Rectangle   _e_xdg_positioner_geometry_get(E_Xdg_Positioner *p);
+
+/**********************************************************
+ * Implementation for Utility
+ **********************************************************/
+static Eina_Bool
+_e_client_shsurface_assignable_check(E_Client *ec)
+{
+   if (!e_shell_e_client_shell_assignable_check(ec))
+     {
+        ERR("Could not assign shell", ec->pixmap, ec);
+        wl_resource_post_error(ec->comp_data->surface,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Could not assign shell surface to wl_surface");
+        return EINA_FALSE;
+     }
+
+   if (e_pixmap_usable_get(ec->pixmap))
+     {
+        wl_resource_post_error(ec->comp_data->surface,
+                               ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER,
+                               "buffer attached/committed before configure");
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_client_xdg_shell_v6_assigned_check(E_Client *ec)
+{
+   return !!ec->comp_data->sh_v6.res_role;
+}
+
+static void
+_e_client_xdg_shell_v6_assign(E_Client *ec,
+                              struct wl_resource *resource,
+                              E_Comp_Wl_Sh_Surf_Role role)
+{
+   ec->comp_data->sh_v6.res_role = resource;
+   ec->comp_data->sh_v6.role = role;
+}
+
+static void
+_validate_size(struct wl_resource *resource, int32_t value)
+{
+   if (value <= 0)
+     wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, "Invalid size passed");
+}
+/* End of utility */
+
+/**********************************************************
+ * Implementation for Xdg_popup
+ **********************************************************/
+static void
+_e_xdg_popup_positioner_apply(E_Xdg_Popup *popup, E_Xdg_Positioner *pos)
+{
+   popup->geometry = _e_xdg_positioner_geometry_get(pos);
+
+   /* TODO apply geometry to popup */
+
+}
+
+static void
+_e_xdg_popup_parent_set(E_Xdg_Popup *popup, E_Xdg_Surface *parent)
+{
+   popup->parent = parent;
+   /* set this client as a transient for parent */
+   e_shell_e_client_parent_set(popup->base.ec, parent->ec->comp_data->surface);
+}
+
+static void
+_e_xdg_popup_set(E_Xdg_Popup *popup, struct wl_resource *resource)
+{
+   popup->resource = resource;
+   _e_client_xdg_shell_v6_assign(popup->base.ec, resource, E_COMP_WL_SH_SURF_ROLE_POPUP);
+   e_shell_e_client_popup_set(popup->base.ec);
+}
+
+static void
+_e_xdg_popup_committed(E_Xdg_Popup *popup)
+{
+   if (!popup->committed)
+     {
+        if (!popup->base.configure_idle)
+          {
+             popup->base.configure_idle =
+                ecore_idle_enterer_add(_e_xdg_surface_cb_configure_send, popup);
+          }
+     }
+
+   popup->committed = EINA_TRUE;
+
+   /* TODO: Weston does update the position of popup here */
+}
+
+static void
+_e_xdg_popup_configure_send(E_Xdg_Popup *popup)
+{
+   zxdg_popup_v6_send_configure(popup->resource,
+                                popup->geometry.x,
+                                popup->geometry.y,
+                                popup->geometry.w,
+                                popup->geometry.h);
+}
+
+static void
+_e_xdg_popup_cb_resource_destroy(struct wl_resource *resource)
+{
+   /* Nothing to do here */
+}
+
+static void
+_e_xdg_popup_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_xdg_popup_cb_grab(struct wl_client *client,
+                     struct wl_resource *resource,
+                     struct wl_resource *res_seat,
+                     uint32_t serial)
+{
+   /* TODO no op */
+}
+
+static const struct zxdg_popup_v6_interface _e_xdg_popup_interface =
+{
+   _e_xdg_popup_cb_destroy,
+   _e_xdg_popup_cb_grab
+};
+
+/* End of Xdg_Popup */
+
+/**********************************************************
+ * Implementation for Xdg_toplevel
+ ***********************************************************/
+static void
+_e_xdg_toplevel_set(E_Xdg_Toplevel *toplevel, struct wl_resource *resource)
+{
+   toplevel->resource = resource;
+   _e_client_xdg_shell_v6_assign(toplevel->base.ec, resource, E_COMP_WL_SH_SURF_ROLE_TOPLV);
+   e_shell_e_client_toplevel_set(toplevel->base.ec);
+   e_comp_wl_shell_surface_ready(toplevel->base.ec);
+}
+
+static void
+_e_xdg_toplevel_committed(E_Xdg_Toplevel *toplevel)
+{
+   E_Client *ec;
+   int pw, ph;
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("E_Xdg_Toplevel must have E_Client", NULL, NULL);
+        return;
+     }
+
+   if (!ec->comp_data)
+     {
+        ERR("E_Client must have E_Comp_Client_Data", ec->pixmap, ec);
+        return;
+     }
+
+   if (!e_pixmap_usable_get(ec->pixmap))
+     {
+        ERR("E_Pixmap should be valid here", ec->pixmap, ec);
+        return;
+     }
+
+   e_pixmap_size_get(ec->pixmap, &pw, &ph);
+
+   if ((toplevel->next.state.maximized || toplevel->next.state.fullscreen) &&
+       (toplevel->next.size.w != ec->comp_data->shell.window.w ||
+        toplevel->next.size.h != ec->comp_data->shell.window.h))
+     {
+        ERR("Xdg_surface buffer does not match the configured state\nmaximized: "
+            "%d fullscreen: %d expected size (%d %d) window size (%d %d)",
+            ec->pixmap, ec,
+            toplevel->next.state.maximized,
+            toplevel->next.state.fullscreen,
+            toplevel->next.size.w, toplevel->next.size.h,
+            ec->comp_data->shell.window.w, ec->comp_data->shell.window.h);
+        /* TODO Disable this part for now, but need to consider enabling it later.
+         * To enable this part, we first need to ensure that do not send configure
+         * with argument of size as 0, and make client ensure that set
+         * window geometry correctly so that match its commit buffer size, if
+         * its state is maximize or fullscreen.
+         */
+        /*
+           wl_resource_post_error(toplevel->base.shell->resource,
+           ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
+           "xdg_surface buffer does not match the configured state");
+           return;
+           */
+     }
+   toplevel->current.state = toplevel->next.state;
+   toplevel->current.min_size = toplevel->next.min_size;
+   toplevel->current.max_size = toplevel->next.max_size;
+
+   /* Now we can adjust size of its composite object corresponding client */
+}
+
+static void
+_e_xdg_toplevel_configure_ack(E_Xdg_Toplevel *toplevel,
+                              E_Xdg_Surface_Configure *configure)
+{
+   LOG("Ack configure TOPLEVEL size (%d %d) "
+       "state (f %d m %d r %d a %d)",
+       toplevel->base.ec->pixmap, toplevel->base.ec,
+       configure->size.w, configure->size.h,
+       configure->state.fullscreen, configure->state.maximized,
+       configure->state.resizing, configure->state.activated);
+
+   toplevel->next.state = configure->state;
+   toplevel->next.size = configure->size;
+   toplevel->base.wait_next_commit = EINA_TRUE;
+}
+
+static void
+_e_xdg_toplevel_configure_send(E_Xdg_Toplevel *toplevel,
+                               E_Xdg_Surface_Configure *configure)
+{
+   uint32_t *s;
+   struct wl_array states;
+
+   configure->state = toplevel->pending.state;
+   configure->size = toplevel->pending.size;
+
+   wl_array_init(&states);
+   if (toplevel->pending.state.maximized)
+     {
+        s = wl_array_add(&states, sizeof(uint32_t));
+        *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED;
+     }
+   if (toplevel->pending.state.fullscreen)
+     {
+        s = wl_array_add(&states, sizeof(uint32_t));
+        *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN;
+     }
+   if (toplevel->pending.state.resizing)
+     {
+        s = wl_array_add(&states, sizeof(uint32_t));
+        *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING;
+     }
+   if (toplevel->pending.state.activated)
+     {
+        s = wl_array_add(&states, sizeof(uint32_t));
+        *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
+     }
+
+   LOG("Send configure: Topevel size (%d %d) "
+       "state (f %d m %d r %d a %d)",
+       toplevel->base.ec->pixmap, toplevel->base.ec,
+       toplevel->pending.size.w, toplevel->pending.size.h,
+       toplevel->pending.state.fullscreen, toplevel->pending.state.maximized,
+       toplevel->pending.state.resizing, toplevel->pending.state.activated);
+
+   zxdg_toplevel_v6_send_configure(toplevel->resource,
+                                   toplevel->pending.size.w,
+                                   toplevel->pending.size.h,
+                                   &states);
+
+   wl_array_release(&states);
+}
+
+static void
+_e_xdg_toplevel_configure_pending_set(E_Xdg_Toplevel *toplevel,
+                                      uint32_t edges,
+                                      int32_t width,
+                                      int32_t height)
+{
+   E_Client *ec, *focused;
+
+   ec = toplevel->base.ec;
+
+   toplevel->pending.state.fullscreen = ec->fullscreen;
+   toplevel->pending.state.maximized = !!ec->maximized;
+   toplevel->pending.state.resizing = !!edges;
+   toplevel->pending.edges = edges;
+   toplevel->pending.size.w = width;
+   toplevel->pending.size.h = height;
+
+   if ((toplevel->pending.state.maximized) ||
+       (toplevel->pending.state.fullscreen))
+     {
+        /* NOTE
+         * DO NOT configure maximized or fullscreen surface to (0x0) size.
+         * If the width or height arguments are zero, it means the client should
+         * decide its own window dimension. See xdg-shell-v6.xml
+         */
+        LOG("FORCELY STAY current size (%d %d) of E_Client, requested size "
+            "is (%d %d), the state (maximize %d, fullscreen %d)",
+            ec->pixmap, ec, ec->w, ec->h, width, height,
+            toplevel->pending.state.maximized,
+            toplevel->pending.state.fullscreen);
+        toplevel->pending.size.w = ec->w;
+        toplevel->pending.size.h = ec->h;
+     }
+
+   focused = e_client_focused_get();
+   toplevel->pending.state.activated = (ec == focused);
+
+   LOG("Set pending state: edges %d size (%d %d) "
+       "state (f %d m %d r %d a %d)",
+       ec->pixmap, ec,
+       toplevel->pending.edges,
+       toplevel->pending.size.w, toplevel->pending.size.h,
+       toplevel->pending.state.fullscreen, toplevel->pending.state.maximized,
+       toplevel->pending.state.resizing, toplevel->pending.state.activated);
+}
+
+static Eina_Bool
+_e_xdg_toplevel_pending_state_compare(E_Xdg_Toplevel *toplevel)
+{
+   E_Xdg_Surface_Configure *configure;
+   int pw, ph;
+   int cw, ch;
+
+   struct {
+        E_Xdg_Toplevel_State state;
+        E_Xdg_Size size;
+   } configured;
+
+   /* must send configure at least once */
+   if (!toplevel->base.configured)
+     return EINA_FALSE;
+
+   if (!toplevel->base.configure_list)
+     {
+        /* if configure_list is empty, last configure is actually the current
+         * state */
+        e_pixmap_size_get(toplevel->base.ec->pixmap, &pw, &ph);
+        e_client_geometry_get(toplevel->base.ec, NULL, NULL, &cw, &ch);
+
+        if ((pw != cw) || (ph != ch))
+          {
+             ERR("The size of buffer is different with expected "
+                 "client size. So, here, let it compare with buffer size.",
+                 toplevel->base.ec->pixmap, toplevel->base.ec);
+          }
+
+        configured.state = toplevel->current.state;
+        configured.size.w = pw;
+        configured.size.h = ph;
+     }
+   else
+     {
+        configure = eina_list_last_data_get(toplevel->base.configure_list);
+        configured.state = configure->state;
+        configured.size = configure->size;
+     }
+
+   if (toplevel->pending.state.activated != configured.state.activated)
+     return EINA_FALSE;
+   if (toplevel->pending.state.fullscreen != configured.state.fullscreen)
+     return EINA_FALSE;
+   if (toplevel->pending.state.maximized != configured.state.maximized)
+     return EINA_FALSE;
+   if (toplevel->pending.state.resizing != configured.state.resizing)
+     return EINA_FALSE;
+
+   if ((toplevel->pending.size.w == configured.size.w) &&
+       (toplevel->pending.size.h == configured.size.h))
+     return EINA_TRUE;
+
+   if ((toplevel->pending.size.w == 0) &&
+       (toplevel->pending.size.h == 0))
+     return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
+static void
+_e_xdg_toplevel_cb_resource_destroy(struct wl_resource *resource)
+{
+   /* Nothing to do here */
+}
+
+static void
+_e_xdg_toplevel_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_xdg_toplevel_cb_parent_set(struct wl_client *client,
+                              struct wl_resource *resource,
+                              struct wl_resource *res_parent)
+{
+   E_Xdg_Toplevel *toplevel, *parent;
+   E_Client *pc;
+   struct wl_resource *parent_wsurface = NULL;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   if (res_parent)
+     {
+        parent = wl_resource_get_user_data(res_parent);
+        if (!parent)
+          {
+             ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+             wl_resource_post_error(res_parent,
+                                    WL_DISPLAY_ERROR_INVALID_OBJECT,
+                                    "No E_Xdg_Toplevel data in wl_resource");
+
+             return;
+          }
+
+        pc = parent->base.ec;
+        if (!pc)
+          {
+             ERR("Toplevel must have E_Client", NULL, NULL);
+             wl_resource_post_error(res_parent,
+                                    WL_DISPLAY_ERROR_INVALID_OBJECT,
+                                    "No E_Client data in wl_resource");
+             return;
+          }
+
+        if (!pc->comp_data) return;
+
+        parent_wsurface = pc->comp_data->surface;
+     }
+
+   /* set this client as a transient for parent */
+   e_shell_e_client_parent_set(toplevel->base.ec, parent_wsurface);
+}
+
+static void
+_e_xdg_toplevel_cb_title_set(struct wl_client *client,
+                             struct wl_resource *resource,
+                             const char *title)
+{
+   E_Xdg_Toplevel *toplevel;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   e_shell_e_client_name_title_set(toplevel->base.ec, title, title);
+}
+
+static void
+_e_xdg_toplevel_cb_app_id_set(struct wl_client *client,
+                              struct wl_resource *resource,
+                              const char *app_id)
+{
+   E_Xdg_Toplevel *toplevel;
+   E_Client *ec;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("Toplevel must have E_Client", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Client data in wl_resource");
+        return;
+     }
+
+   /* use the wl_client to get the pid * and set it in the netwm props */
+   wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL);
+
+   e_shell_e_client_app_id_set(ec, app_id);
+}
+
+static void
+_e_xdg_toplevel_cb_win_menu_show(struct wl_client *client,
+                                 struct wl_resource *resource,
+                                 struct wl_resource *res_seat,
+                                 uint32_t serial,
+                                 int32_t x,
+                                 int32_t y)
+{
+   /* TODO no op */
+}
+
+static void
+_e_xdg_toplevel_cb_move(struct wl_client *client,
+                        struct wl_resource *resource,
+                        struct wl_resource *res_seat,
+                        uint32_t serial)
+{
+   E_Xdg_Toplevel *toplevel;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   if (!e_shell_e_client_interactive_move(toplevel->base.ec, res_seat))
+     {
+        ERR("Failed to move this Toplevel", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Can't move this surface");
+        return;
+     }
+}
+
+static void
+_e_xdg_toplevel_cb_resize(struct wl_client *client,
+                          struct wl_resource *resource,
+                          struct wl_resource *res_seat,
+                          uint32_t serial,
+                          uint32_t edges)
+{
+   E_Xdg_Toplevel *toplevel;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   if (!e_shell_e_client_interactive_resize(toplevel->base.ec, resource, res_seat, edges))
+     {
+        ERR("Failed to resize this Toplevel", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Can't resize this surface");
+        return;
+     }
+}
+
+static void
+_e_xdg_toplevel_cb_max_size_set(struct wl_client *client,
+                                struct wl_resource *resource,
+                                int32_t w,
+                                int32_t h)
+{
+   E_Xdg_Toplevel *toplevel;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No data in wl_resource");
+        return;
+     }
+
+   toplevel->next.max_size.w = w;
+   toplevel->next.max_size.h = h;
+}
+
+static void
+_e_xdg_toplevel_cb_min_size_set(struct wl_client *client,
+                                struct wl_resource *resource,
+                                int32_t w,
+                                int32_t h)
+{
+   E_Xdg_Toplevel *toplevel;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No data in wl_resource");
+        return;
+     }
+
+   toplevel->next.min_size.w = w;
+   toplevel->next.min_size.h = h;
+}
+
+static void
+_e_xdg_toplevel_cb_maximized_set(struct wl_client *client, struct wl_resource *resource)
+{
+   E_Xdg_Toplevel *toplevel;
+   E_Client *ec;
+   E_Maximize max;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("Toplevel must have E_Client", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Client data in wl_resource");
+        return;
+     }
+
+   if (!ec->lock_user_maximize)
+     {
+        max = (e_config->maximize_policy & E_MAXIMIZE_TYPE) | E_MAXIMIZE_BOTH;
+        e_client_maximize(ec, max);
+     }
+}
+
+static void
+_e_xdg_toplevel_cb_maximized_unset(struct wl_client *client, struct wl_resource *resource)
+{
+   E_Xdg_Toplevel *toplevel;
+   E_Client *ec;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("Toplevel must have E_Client", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Client data in wl_resource");
+        return;
+     }
+
+   /* it's doubtful */
+   e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
+}
+
+static void
+_e_xdg_toplevel_cb_fullscreen_set(struct wl_client *client,
+                                  struct wl_resource *resource,
+                                  struct wl_resource *res_output)
+{
+   E_Xdg_Toplevel *toplevel;
+   E_Client *ec;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("Toplevel must have E_Client", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Client data in wl_resource");
+        return;
+     }
+
+   if (!ec->lock_user_fullscreen)
+     e_client_fullscreen(ec, e_config->fullscreen_policy);
+}
+
+static void
+_e_xdg_toplevel_cb_fullscreen_unset(struct wl_client *client, struct wl_resource *resource)
+{
+   E_Xdg_Toplevel *toplevel;
+   E_Client *ec;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("Toplevel must have E_Client", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Client data in wl_resource");
+        return;
+     }
+
+   if (!ec->lock_user_fullscreen)
+     e_client_unfullscreen(ec);
+}
+
+static void
+_e_xdg_toplevel_cb_minimized_set(struct wl_client *client, struct wl_resource *resource)
+{
+   E_Xdg_Toplevel *toplevel;
+   E_Client *ec;
+
+   toplevel = wl_resource_get_user_data(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Toplevel data in wl_resource");
+        return;
+     }
+
+   ec = toplevel->base.ec;
+   if (!ec)
+     {
+        ERR("Toplevel must have E_Client", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Client data in wl_resource");
+        return;
+     }
+
+   if (!ec->lock_client_iconify)
+     e_client_iconify(ec);
+}
+
+static const struct zxdg_toplevel_v6_interface _e_xdg_toplevel_interface =
+{
+   _e_xdg_toplevel_cb_destroy,
+   _e_xdg_toplevel_cb_parent_set,
+   _e_xdg_toplevel_cb_title_set,
+   _e_xdg_toplevel_cb_app_id_set,
+   _e_xdg_toplevel_cb_win_menu_show,
+   _e_xdg_toplevel_cb_move,
+   _e_xdg_toplevel_cb_resize,
+   _e_xdg_toplevel_cb_max_size_set,
+   _e_xdg_toplevel_cb_min_size_set,
+   _e_xdg_toplevel_cb_maximized_set,
+   _e_xdg_toplevel_cb_maximized_unset,
+   _e_xdg_toplevel_cb_fullscreen_set,
+   _e_xdg_toplevel_cb_fullscreen_unset,
+   _e_xdg_toplevel_cb_minimized_set
+};
+
+/* End of Xdg_toplevel */
+
+/**********************************************************
+ * Implementation for Xdg_Positioner
+ **********************************************************/
+static Eina_Rectangle
+_e_xdg_positioner_geometry_get(E_Xdg_Positioner *p)
+{
+   Eina_Rectangle geometry = {
+        .x = p->offset.x,
+        .y = p->offset.y,
+        .w = p->size.w,
+        .h = p->size.h,
+   };
+
+   if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP)
+     geometry.y += p->anchor_rect.y;
+   else if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)
+     geometry.y += p->anchor_rect.y + p->anchor_rect.h;
+   else
+     geometry.y += p->anchor_rect.y + p->anchor_rect.h / 2;
+
+   if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT)
+     geometry.x += p->anchor_rect.x;
+   else if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT)
+     geometry.x += p->anchor_rect.x + p->anchor_rect.w;
+   else
+     geometry.x += p->anchor_rect.x + p->anchor_rect.w / 2;
+
+   if (p->gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP)
+     geometry.y -= geometry.h;
+   else if (!(p->gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM))
+     geometry.y = geometry.h / 2;
+
+   if (p->gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT)
+     geometry.x -= geometry.w;
+   else if (!(p->gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT))
+     geometry.x = geometry.w / 2;
+
+   if (p->constraint_adjustment == ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE)
+     return geometry;
+
+   /* TODO: According to weston, add compositor policy configuration and the
+    * code here
+    */
+
+   return geometry;
+}
+
+static Eina_Bool
+_e_xdg_positioner_validation_check(E_Xdg_Positioner *p)
+{
+   return ((p->size.w != 0) && (p->anchor_rect.w != 0));
+}
+
+static void
+_e_xdg_positioner_cb_resource_destroy(struct wl_resource *resource)
+{
+   E_Xdg_Positioner *p;
+
+   p = wl_resource_get_user_data(resource);
+   EINA_SAFETY_ON_NULL_RETURN(p);
+
+   if (!p->shell)
+     goto finish;
+
+   p->shell->positioners = eina_list_remove(p->shell->positioners, p);
+
+finish:
+   free(p);
+}
+
+static void
+_e_xdg_positioner_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_xdg_positioner_cb_size_set(struct wl_client *client,
+                              struct wl_resource *resource,
+                              int32_t w, int32_t h)
+{
+   E_Xdg_Positioner *p;
+
+   _validate_size(resource, w);
+   _validate_size(resource, h);
+
+   p = wl_resource_get_user_data(resource);
+   p->size.w = w;
+   p->size.h = h;
+}
+
+static void
+_e_xdg_positioner_cb_anchor_rect_set(struct wl_client *client,
+                                     struct wl_resource *resource,
+                                     int32_t x, int32_t y, int32_t w, int32_t h)
+{
+   E_Xdg_Positioner *p;
+
+   _validate_size(resource, w);
+   _validate_size(resource, h);
+
+   p = wl_resource_get_user_data(resource);
+   EINA_RECTANGLE_SET(&p->anchor_rect, x, y, w, h);
+}
+
+static void
+_e_xdg_positioner_cb_anchor_set(struct wl_client *client,
+                                struct wl_resource *resource,
+                                enum zxdg_positioner_v6_anchor anchor)
+{
+   E_Xdg_Positioner *p;
+
+   if ((anchor & (ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)) ==
+       (ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM))
+     {
+        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
+                               "Invalid anchor values passed");
+     }
+   else if ((anchor & (ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT)) ==
+            (ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT))
+     {
+        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
+                               "Invalid anchor values passed");
+     }
+   else
+     {
+        p = wl_resource_get_user_data(resource);
+        p->anchor = anchor;
+     }
+}
+
+static void
+_e_xdg_positioner_cb_gravity_set(struct wl_client *client,
+                                 struct wl_resource *resource,
+                                 enum zxdg_positioner_v6_gravity gravity)
+{
+   E_Xdg_Positioner *p;
+
+   if ((gravity & (ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM)) ==
+       (ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM))
+     {
+        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
+                               "Invalid gravity values passed");
+     }
+   else if ((gravity & (ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT)) ==
+            (ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT))
+     {
+        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
+                               "Invalid gravity values passed");
+     }
+   else
+     {
+        p = wl_resource_get_user_data(resource);
+        p->gravity = gravity;
+     }
+}
+
+static void
+_e_xdg_positioner_cb_constraint_adjustment_set(struct wl_client *client,
+                                               struct wl_resource *resource,
+                                               enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment)
+{
+   E_Xdg_Positioner *p;
+
+   p = wl_resource_get_user_data(resource);
+   p->constraint_adjustment = constraint_adjustment;
+}
+
+static void
+_e_xdg_positioner_cb_offset_set(struct wl_client *client,
+                                struct wl_resource *resource,
+                                int32_t x, int32_t y)
+{
+   E_Xdg_Positioner *p;
+
+   p = wl_resource_get_user_data(resource);
+   p->offset.x = x;
+   p->offset.y = y;
+}
+
+static const struct zxdg_positioner_v6_interface _e_xdg_positioner_interface =
+{
+   _e_xdg_positioner_cb_destroy,
+   _e_xdg_positioner_cb_size_set,
+   _e_xdg_positioner_cb_anchor_rect_set,
+   _e_xdg_positioner_cb_anchor_set,
+   _e_xdg_positioner_cb_gravity_set,
+   _e_xdg_positioner_cb_constraint_adjustment_set,
+   _e_xdg_positioner_cb_offset_set,
+};
+
+/* End of Xdg_positioner */
+
+/**********************************************************
+ * Implementation for Xdg_Surface
+ **********************************************************/
+static const char *
+_e_xdg_surface_util_role_string_get(E_Xdg_Surface *exsurf)
+{
+   switch (exsurf->role)
+     {
+      case E_XDG_SURFACE_ROLE_TOPLEVEL:
+         return "TOPLEVEL";
+      case E_XDG_SURFACE_ROLE_POPUP:
+         return "POPUP";
+      default:
+      case E_XDG_SURFACE_ROLE_NONE:
+         return "NONE";
+     }
+}
+
+static Eina_Bool
+_e_xdg_surface_cb_configure_send(void *data)
+{
+   E_Xdg_Surface *exsurf;
+   E_Xdg_Surface_Configure *configure;
+
+   exsurf = data;
+
+   EINA_SAFETY_ON_NULL_GOTO(exsurf, end);
+   EINA_SAFETY_ON_NULL_GOTO(exsurf->ec, end);
+   EINA_SAFETY_ON_NULL_GOTO(exsurf->ec->comp_data, end);
+
+   if (e_object_is_del(E_OBJECT(exsurf->ec)))
+     goto end;
+
+   /* Make configure */
+   configure = E_NEW(E_Xdg_Surface_Configure, 1);
+   if (!configure)
+     {
+        ERR("Failed to allocate memory: E_Xdg_Surface_Configure", NULL, NULL);
+        goto end;
+     }
+
+   exsurf->configure_list = eina_list_append(exsurf->configure_list, configure);
+   configure->serial = wl_display_next_serial(e_comp_wl->wl.disp);
+
+   switch (exsurf->role)
+     {
+      case E_XDG_SURFACE_ROLE_NONE:
+         ERR("Cannot reach here", NULL, NULL);
+         break;
+      case E_XDG_SURFACE_ROLE_POPUP:
+         _e_xdg_popup_configure_send((E_Xdg_Popup *)exsurf);
+         break;
+      case E_XDG_SURFACE_ROLE_TOPLEVEL:
+         _e_xdg_toplevel_configure_send((E_Xdg_Toplevel *)exsurf, configure);
+         break;
+     }
+
+   zxdg_surface_v6_send_configure(exsurf->resource, configure->serial);
+
+   LOG("Send configure: %s serial %d", exsurf->ec->pixmap, exsurf->ec,
+       _e_xdg_surface_util_role_string_get(exsurf), configure->serial);
+
+end:
+   exsurf->configure_idle = NULL;
+   return ECORE_CALLBACK_DONE;
+}
+
+static void
+_e_xdg_surface_configure_send(struct wl_resource *resource,
+                              uint32_t edges,
+                              int32_t width,
+                              int32_t height)
+{
+   E_Xdg_Surface *exsurf;
+   Eina_Bool pending_same = EINA_FALSE;
+
+   EINA_SAFETY_ON_NULL_RETURN(resource);
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        ERR("Invalid wl_resource", NULL, NULL);
+        return;
+     }
+
+   LOG("Scheduling task to send configure %s edges %d w %d h %d",
+       exsurf->ex->pixmap, exsurf->ec,
+       _e_xdg_surface_util_role_string_get(exsurf), edges, width, height);
+
+   switch (exsurf->role)
+     {
+      case E_XDG_SURFACE_ROLE_NONE:
+      default:
+         ERR("Cannot reach here", exsurf->ec->pixmap, exsurf->ec);
+         break;
+      case E_XDG_SURFACE_ROLE_TOPLEVEL:
+         _e_xdg_toplevel_configure_pending_set((E_Xdg_Toplevel *)exsurf,
+                                               edges, width, height);
+
+         pending_same = _e_xdg_toplevel_pending_state_compare((E_Xdg_Toplevel *)exsurf);
+         if (pending_same)
+           {
+              LOG("\tSKIP Configuring state is same with current state",
+                  exsurf->ec->pixmap, exsurf->ec);
+           }
+         break;
+      case E_XDG_SURFACE_ROLE_POPUP:
+         break;
+     }
+
+   if (exsurf->configure_idle)
+     {
+        if (!pending_same)
+          return;
+
+        LOG("\tRemove configure idler", exsurf->ec->pixmap, exsurf->ec);
+
+        E_FREE_FUNC(exsurf->configure_idle, ecore_idle_enterer_del);
+     }
+   else
+     {
+        if (pending_same)
+          return;
+
+        exsurf->configure_idle =
+           ecore_idle_enterer_add(_e_xdg_surface_cb_configure_send, exsurf);
+
+        LOG("\tAdd configure idler %p",
+            exsurf->ec->pixmap, exsurf->ec, exsurf->configure_idle);
+     }
+}
+
+static void
+_e_xdg_surface_configure(struct wl_resource *resource,
+                         Evas_Coord x, Evas_Coord y,
+                         Evas_Coord w, Evas_Coord h)
+{
+   E_Xdg_Surface *exsurf;
+
+   EINA_SAFETY_ON_NULL_RETURN(resource);
+
+   /* get the client for this resource */
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        ERR("No E_Xdg_Surface data in wl_resource", NULL, NULL);
+        return;
+     }
+
+   if ((exsurf->configured_geometry.x == x) &&
+       (exsurf->configured_geometry.y == y) &&
+       (exsurf->configured_geometry.w == w) &&
+       (exsurf->configured_geometry.h == h))
+     {
+        LOG("Configure (SKIP) Trying to resize it the same size "
+            "with previous %s (%d %d %d %d)",
+            exsurf->ec->pixmap, exsurf->ec,
+            _e_xdg_surface_util_role_string_get(exsurf),
+            x, y, w, h);
+
+        return;
+     }
+
+   EINA_RECTANGLE_SET(&exsurf->configured_geometry, x, y, w, h);
+
+   LOG("Configure %s geometry (%d %d %d %d)",
+       exsurf->ec->pixmap, exsurf->ec,
+       _e_xdg_surface_util_role_string_get(exsurf), x, y, w, h);
+
+   e_client_util_move_resize_without_frame(exsurf->ec, x, y, w, h);
+}
+
+static void
+_e_xdg_surface_ping(struct wl_resource *resource)
+{
+   E_Xdg_Surface *exsurf;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        ERR("No E_Xdg_Surface data in wl_resource", NULL, NULL);
+        return;
+     }
+
+   if (e_object_is_del(E_OBJECT(exsurf->ec)))
+     return;
+
+   _e_xdg_shell_ping(exsurf->shell);
+}
+
+static void
+_e_xdg_surface_map(struct wl_resource *resource)
+{
+   E_Xdg_Surface *exsurf;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        ERR("No E_Xdg_Surface in wl_resource", NULL, NULL);
+        return;
+     }
+
+   e_shell_e_client_map(exsurf->ec);
+}
+
+static void
+_e_xdg_surface_unmap(struct wl_resource *resource)
+{
+   E_Xdg_Surface *exsurf;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        ERR("No E_Xdg_Surface in wl_resource", NULL, NULL);
+        return;
+     }
+
+   e_shell_e_client_unmap(exsurf->ec);
+}
+
+static Eina_Bool
+_e_xdg_surface_role_assign(E_Xdg_Surface *exsurf,
+                           struct wl_resource *resource,
+                           E_Xdg_Surface_Role role)
+{
+   E_Shell_Surface_Api api = {
+        .configure_send = _e_xdg_surface_configure_send,
+        .configure = _e_xdg_surface_configure,
+        .ping = _e_xdg_surface_ping,
+        .map = _e_xdg_surface_map,
+        .unmap = _e_xdg_surface_unmap,
+   };
+
+   if (_e_client_xdg_shell_v6_assigned_check(exsurf->ec))
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Client already has shell resource");
+        return EINA_FALSE;
+     }
+
+   exsurf->role = role;
+
+   e_shell_e_client_shsurface_api_set(exsurf->ec, &api);
+
+   switch (role)
+     {
+      case E_XDG_SURFACE_ROLE_NONE:
+      default:
+         ERR("Cannot reach here", exsurf->ec->pixmap, exsurf->ec);
+         return EINA_FALSE;
+
+      case E_XDG_SURFACE_ROLE_TOPLEVEL:
+         _e_xdg_toplevel_set((E_Xdg_Toplevel *)exsurf, resource);
+         break;
+
+      case E_XDG_SURFACE_ROLE_POPUP:
+         _e_xdg_popup_set((E_Xdg_Popup *)exsurf, resource);
+         break;
+     }
+
+   return EINA_TRUE;
+}
+
+static void
+_e_xdg_surface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_xdg_surface_cb_toplevel_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
+{
+   E_Xdg_Surface *exsurf;
+   struct wl_resource *toplevel_resource;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Surface data in wl_resource");
+        return;
+     }
+
+   toplevel_resource = wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id);
+   if (!toplevel_resource)
+     {
+        ERR("Could not create xdg toplevel resource", NULL, NULL);
+        wl_resource_post_no_memory(resource);
+        return;
+     }
+
+   wl_resource_set_implementation(toplevel_resource,
+                                  &_e_xdg_toplevel_interface,
+                                  exsurf,
+                                  _e_xdg_toplevel_cb_resource_destroy);
+
+   if (!_e_xdg_surface_role_assign(exsurf, toplevel_resource, E_XDG_SURFACE_ROLE_TOPLEVEL))
+     {
+        ERR("Failed to assign TOPLEVEL role", exsurf->ec->pixmap, exsurf->ec);
+        wl_resource_destroy(toplevel_resource);
+        return;
+     }
+}
+
+static void
+_e_xdg_surface_cb_popup_get(struct wl_client *client,
+                            struct wl_resource *resource,
+                            uint32_t id,
+                            struct wl_resource *res_parent,
+                            struct wl_resource *res_pos)
+{
+   struct wl_resource *popup_resource;
+   E_Xdg_Surface *exsurf, *parent;
+   E_Xdg_Positioner *p;
+
+   if (!res_parent)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Popup requires a parent shell surface");
+        return;
+     }
+
+   parent = wl_resource_get_user_data(res_parent);
+   if (!parent)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "xdg_popup must have parent");
+        return;
+     }
+
+   p = wl_resource_get_user_data(res_pos);
+   if (!p)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "invalid positioner");
+        return;
+     }
+
+   if (!_e_xdg_positioner_validation_check(p))
+     {
+        wl_resource_post_error(resource,
+                               ZXDG_SHELL_V6_ERROR_INVALID_POSITIONER,
+                               "invalid positioner");
+        return;
+     }
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Popup data in wl_resource");
+        return;
+     }
+
+   popup_resource = wl_resource_create(client, &zxdg_popup_v6_interface, 1, id);
+   if (!popup_resource)
+     {
+        ERR("Could not create xdg popup resource", NULL, NULL);
+        wl_resource_post_no_memory(resource);
+     }
+
+   wl_resource_set_implementation(popup_resource,
+                                  &_e_xdg_popup_interface,
+                                  exsurf,
+                                  _e_xdg_popup_cb_resource_destroy);
+
+
+   if (!_e_xdg_surface_role_assign(exsurf, popup_resource, E_XDG_SURFACE_ROLE_POPUP))
+     {
+        ERR("Failed to assign role to surface", exsurf->ec->pixmap, exsurf->ec);
+        wl_resource_destroy(popup_resource);
+        return;
+     }
+
+   _e_xdg_popup_parent_set((E_Xdg_Popup *)exsurf, parent);
+   _e_xdg_popup_positioner_apply((E_Xdg_Popup *)exsurf, p);
+}
+
+static void
+_e_xdg_surface_cb_win_geometry_set(struct wl_client *client,
+                                   struct wl_resource *resource,
+                                   int32_t x,
+                                   int32_t y,
+                                   int32_t w,
+                                   int32_t h)
+{
+   E_Xdg_Surface *exsurf;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Surface data in wl_resource");
+        return;
+     }
+
+   LOG("Set window geometry: geometry(%d %d %d %d)",
+       exsurf->ec->pixmap, exsurf->ec, x, y, w, h);
+
+   exsurf->has_window_geometry = EINA_TRUE;
+   EINA_RECTANGLE_SET(&exsurf->window_geometry, x, y, w, h);
+
+   exsurf->wait_next_commit = EINA_TRUE;
+}
+
+static void
+_e_xdg_surface_cb_configure_ack(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
+{
+   E_Xdg_Surface *exsurf;
+   E_Xdg_Surface_Configure *configure;
+   Eina_List *l, *ll;
+   Eina_Bool found = EINA_FALSE;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Surface data in wl_surface");
+        return;
+     }
+
+   LOG("Ack configure", exsurf->ec->pixmap, exsurf->ec);
+
+   if ((exsurf->role != E_XDG_SURFACE_ROLE_TOPLEVEL) &&
+       (exsurf->role != E_XDG_SURFACE_ROLE_POPUP))
+     {
+        wl_resource_post_error(resource,
+                               ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
+                               "xdg_surface must have a role");
+        return;
+     }
+
+   EINA_LIST_FOREACH_SAFE(exsurf->configure_list, l, ll, configure)
+     {
+        if (configure->serial < serial)
+          {
+             exsurf->configure_list =
+                eina_list_remove_list(exsurf->configure_list, l);
+             free(configure);
+          }
+        else if (configure->serial == serial)
+          {
+             exsurf->configure_list =
+                eina_list_remove_list(exsurf->configure_list, l);
+             found = EINA_TRUE;
+             break;
+          }
+        else
+          break;
+     }
+
+   LOG("Ack configure %s first %d serial %d found %d",
+       exsurf->ec->pixmap, exsurf->ec,
+       _e_xdg_surface_util_role_string_get(exsurf),
+       !exsurf->configured,
+       serial, found);
+
+   if (!found)
+     {
+        wl_resource_post_error(exsurf->shell->resource,
+                               ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
+                               "Wrong configure serial: %u", serial);
+        return;
+     }
+
+   exsurf->configured = EINA_TRUE;
+
+   switch (exsurf->role)
+     {
+      case E_XDG_SURFACE_ROLE_NONE:
+         ERR("Cannot reach here", exsurf->ec->pixmap, exsurf->ec);
+         break;
+      case E_XDG_SURFACE_ROLE_TOPLEVEL:
+         _e_xdg_toplevel_configure_ack((E_Xdg_Toplevel *)exsurf, configure);
+         break;
+      case E_XDG_SURFACE_ROLE_POPUP:
+         break;
+     }
+
+   E_FREE_FUNC(configure, free);
+}
+
+static const struct zxdg_surface_v6_interface _e_xdg_surface_interface =
+{
+   _e_xdg_surface_cb_destroy,
+   _e_xdg_surface_cb_toplevel_get,
+   _e_xdg_surface_cb_popup_get,
+   _e_xdg_surface_cb_win_geometry_set,
+   _e_xdg_surface_cb_configure_ack
+};
+
+static Eina_Bool
+_e_xdg_surface_cb_commit(void *data, int type, void *event)
+{
+   E_Xdg_Surface *exsurf;
+   E_Event_Client *ev;
+
+   exsurf = (E_Xdg_Surface *)data;
+   ev = (E_Event_Client *)event;
+
+   if (exsurf->ec != ev->ec)
+     goto end;
+
+   if (!exsurf->wait_next_commit)
+     goto end;
+
+   LOG("Wl_Surface Commit, Update Xdg_Surface state %s",
+       exsurf->ec->pixmap, exsurf->ec,
+       _e_xdg_surface_util_role_string_get(exsurf));
+
+   exsurf->wait_next_commit = EINA_FALSE;
+
+   if (exsurf->has_window_geometry)
+     {
+        exsurf->has_window_geometry = EINA_FALSE;
+        EINA_RECTANGLE_SET(&exsurf->ec->comp_data->shell.window,
+                           exsurf->window_geometry.x,
+                           exsurf->window_geometry.y,
+                           exsurf->window_geometry.w,
+                           exsurf->window_geometry.h);
+     }
+
+   switch (exsurf->role)
+     {
+      case E_XDG_SURFACE_ROLE_NONE:
+         wl_resource_post_error(exsurf->resource,
+                                ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
+                                "xdg_surface must have a role");
+         break;
+      case E_XDG_SURFACE_ROLE_TOPLEVEL:
+         _e_xdg_toplevel_committed((E_Xdg_Toplevel *)exsurf);
+         break;
+      case E_XDG_SURFACE_ROLE_POPUP:
+         _e_xdg_popup_committed((E_Xdg_Popup *)exsurf);
+         break;
+     }
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_e_xdg_surface_destroy(E_Xdg_Surface *exsurf)
+{
+   _e_xdg_shell_surface_remove(exsurf->shell, exsurf);
+
+   if (exsurf->configure_list)
+     eina_list_free(exsurf->configure_list);
+   if (exsurf->configure_idle)
+     ecore_idle_enterer_del(exsurf->configure_idle);
+   if (exsurf->commit_handler)
+     ecore_event_handler_del(exsurf->commit_handler);
+
+   free(exsurf);
+}
+
+static void
+_e_xdg_surface_cb_resource_destroy(struct wl_resource *resource)
+{
+   E_Xdg_Surface *exsurf;
+
+   exsurf = wl_resource_get_user_data(resource);
+   if (!exsurf)
+     {
+        ERR("No E_Xdg_Surface data in wl_resource", NULL, NULL);
+        return;
+
+     }
+
+   LOG("Destroy resource of Xdg_Surface %s",
+       exsurf->ec->pixmap, exsurf->ec,
+       _e_xdg_surface_util_role_string_get(exsurf));
+
+   e_shell_e_client_destroy(exsurf->ec);
+   _e_xdg_surface_destroy(exsurf);
+
+}
+
+static E_Xdg_Surface *
+_e_xdg_surface_create(E_Xdg_Shell *shell,
+                      struct wl_resource *wsurface,
+                      uint32_t id)
+{
+   E_Xdg_Surface *exsurf;
+   E_Client *ec;
+
+   ec = wl_resource_get_user_data(wsurface);
+   if (!ec)
+     {
+        ERR("No E_Client data in wl_resource", NULL, NULL);
+        wl_resource_post_error(wsurface,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No data in wl_resource");
+        return NULL;
+     }
+
+   LOG("Create Xdg_Surface", ec->pixmap, ec);
+
+   if (!_e_client_shsurface_assignable_check(ec))
+     {
+        ERR("Cannot get xdg_surface with this wl_surface", ec->pixmap, ec);
+        return NULL;
+     }
+
+   exsurf = (E_Xdg_Surface *)calloc(1, sizeof(e_xdg_surface_role_biggest_struct));
+   if (!exsurf)
+     {
+        wl_client_post_no_memory(shell->wclient);
+        return NULL;
+     }
+
+   exsurf->resource = wl_resource_create(shell->wclient,
+                                         &zxdg_surface_v6_interface,
+                                         1,
+                                         id);
+   if (!exsurf->resource)
+     {
+        ERR("Could not create wl_resource for xdg surface", ec->pixmap, ec);
+        wl_client_post_no_memory(shell->wclient);
+        free(exsurf);
+        return NULL;
+     }
+
+   wl_resource_set_implementation(exsurf->resource,
+                                  &_e_xdg_surface_interface,
+                                  exsurf,
+                                  _e_xdg_surface_cb_resource_destroy);
+
+   e_shell_e_client_shsurface_assign(ec, exsurf->resource, NULL);
+
+   exsurf->shell = shell;
+   exsurf->ec = ec;
+   exsurf->configured = EINA_FALSE;
+   exsurf->commit_handler =
+      ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
+                              _e_xdg_surface_cb_commit,
+                              exsurf);
+
+   _e_xdg_shell_surface_add(shell, exsurf);
+
+   return exsurf;
+}
+/* End of Xdg_surface */
+
+/**********************************************************
+ * Implementation for Xdg_Shell
+ **********************************************************/
+static void
+_e_xdg_shell_surface_add(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf)
+{
+   if (!shell) return;
+   shell->surfaces = eina_list_append(shell->surfaces, exsurf);
+}
+
+static void
+_e_xdg_shell_surface_remove(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf)
+{
+   if (!shell) return;
+   shell->surfaces = eina_list_remove(shell->surfaces, exsurf);
+}
+
+static void
+_e_xdg_shell_ping(E_Xdg_Shell *shell)
+{
+   EINA_SAFETY_ON_NULL_RETURN(shell);
+
+   if (shell->ping_serial != 0)
+     return;
+
+   shell->ping_serial = wl_display_next_serial(e_comp_wl->wl.disp);
+   zxdg_shell_v6_send_ping(shell->resource, shell->ping_serial);
+}
+
+static void
+_e_xdg_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   LOG("Destroy Xdg_Shell", NULL, NULL);
+
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_xdg_shell_cb_positioner_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
+{
+   E_Xdg_Shell *shell;
+   E_Xdg_Positioner *p;
+   struct wl_resource *new_res;
+
+   LOG("Create Positioner", NULL, NULL);
+
+   shell = wl_resource_get_user_data(resource);
+   if (!shell)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No resource for xdg_shell_v6");
+        return;
+     }
+
+   new_res = wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id);
+   if (!new_res)
+     {
+        wl_resource_post_no_memory(resource);
+        return;
+     }
+
+   p = E_NEW(E_Xdg_Positioner, 1);
+   if (!p)
+     {
+        wl_resource_destroy(new_res);
+        wl_resource_post_no_memory(resource);
+        return;
+     }
+   p->shell = shell;
+   p->resource = new_res;
+
+   shell->positioners = eina_list_append(shell->positioners, p);
+
+   wl_resource_set_implementation(new_res,
+                                  &_e_xdg_positioner_interface,
+                                  p,
+                                  _e_xdg_positioner_cb_resource_destroy);
+}
+
+static void
+_e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *wsurface)
+{
+   E_Xdg_Shell *shell;
+   E_Xdg_Surface *exsurf;
+
+   shell = wl_resource_get_user_data(resource);
+   if (!shell)
+     {
+        ERR("No E_Xdg_Shell data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No shell data in wl_resource");
+        return;
+     }
+
+   exsurf = _e_xdg_surface_create(shell, wsurface, id);
+   if (!exsurf)
+     {
+        ERR("Failed to create E_Xdg_Surface", NULL, NULL);
+        return;
+     }
+}
+
+static void
+_e_xdg_shell_cb_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
+{
+   E_Xdg_Shell *shell;
+   E_Xdg_Surface *exsurf;
+   Eina_List *l;
+
+   LOG("Pong", NULL, NULL);
+
+   shell = wl_resource_get_user_data(resource);
+   if (!shell)
+     {
+        ERR("No E_Xdg_Shell data in wl_resource", NULL, NULL);
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No E_Xdg_Shell data in wl_resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(shell->surfaces, l, exsurf)
+      e_shell_e_client_pong(exsurf->ec);
+
+   shell->ping_serial = 0;
+}
+
+static const struct zxdg_shell_v6_interface _e_xdg_shell_interface =
+{
+   _e_xdg_shell_cb_destroy,
+   _e_xdg_shell_cb_positioner_create,
+   _e_xdg_shell_cb_surface_get,
+   _e_xdg_shell_cb_pong
+};
+
+static E_Xdg_Shell *
+_e_xdg_shell_create(struct wl_client *client, struct wl_resource *resource)
+{
+   E_Xdg_Shell *shell;
+
+   shell = E_NEW(E_Xdg_Shell, 1);
+   if (!shell)
+     return NULL;
+
+   shell->wclient = client;
+   shell->resource = resource;
+
+   return shell;
+}
+
+static void
+_e_xdg_shell_destroy(E_Xdg_Shell *shell)
+{
+   E_Xdg_Surface *exsurf;
+   E_Xdg_Positioner *p;
+
+   EINA_LIST_FREE(shell->surfaces, exsurf)
+     {
+        /* Do we need to do it even though shell is just about to be destroyed? */
+        e_shell_e_client_pong(exsurf->ec);
+        exsurf->shell = NULL;
+     }
+
+   EINA_LIST_FREE(shell->positioners, p)
+      p->shell = NULL;
+
+   free(shell);
+}
+
+static void
+_e_xdg_shell_cb_unbind(struct wl_resource *resource)
+{
+   E_Xdg_Shell *shell;
+
+   LOG("Unbind Xdg_Shell", NULL, NULL);
+
+   shell = wl_resource_get_user_data(resource);
+   if (!shell)
+     {
+        ERR("No E_Xdg_Shell in wl_resource", NULL, NULL);
+        return;
+     }
+
+   _e_xdg_shell_destroy(shell);
+}
+
+static void
+_e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
+{
+   E_Xdg_Shell *shell;
+   struct wl_resource *resource;
+
+   LOG("Bind Xdg_Shell", NULL, NULL);
+
+   /* Create resource for zxdg_shell_v6 */
+   resource = wl_resource_create(client,
+                                 &zxdg_shell_v6_interface,
+                                 version,
+                                 id);
+   if (!resource)
+     goto err_res;
+
+
+   shell = _e_xdg_shell_create(client, resource);
+   if (!shell)
+     {
+        ERR("Failed to create E_Xdg_Shell", NULL, NULL);
+        goto err_shell;
+     }
+
+   wl_resource_set_implementation(resource, &_e_xdg_shell_interface,
+                                  shell, _e_xdg_shell_cb_unbind);
+
+   return;
+err_shell:
+   wl_resource_destroy(resource);
+err_res:
+   wl_client_post_no_memory(client);
+}
+
+EINTERN Eina_Bool
+e_xdg_shell_v6_init(void)
+{
+   LOG("Initializing Xdg_Shell_V6", NULL, NULL);
+
+   /* try to create global xdg_shell interface */
+   global_resource = wl_global_create(e_comp_wl->wl.disp,
+                                      &zxdg_shell_v6_interface,
+                                      1,
+                                      e_comp->wl_comp_data,
+                                      _e_xdg_shell_cb_bind);
+   if (!global_resource)
+     {
+        ERR("Could not create zxdg_shell_v6 global: %m", NULL, NULL);
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_xdg_shell_v6_shutdown(void)
+{
+   E_FREE_FUNC(global_resource, wl_global_destroy);
+}
+/* End of Xdg_shell */
diff --git a/src/bin/e_xdg_shell_v6.h b/src/bin/e_xdg_shell_v6.h
new file mode 100644 (file)
index 0000000..c77b23b
--- /dev/null
@@ -0,0 +1,9 @@
+#ifdef E_TYPEDEFS
+#else
+# ifndef E_XDG_SHELL_V6_H
+#  define E_XDG_SHELL_V6_H
+
+EINTERN Eina_Bool e_xdg_shell_v6_init(void);
+
+# endif
+#endif