Use libds for implementation of wayland core protocols 82/295982/1
authorSeunghun Lee <shiin.lee@samsung.com>
Tue, 21 Feb 2023 06:42:37 +0000 (15:42 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 18 Jul 2023 04:40:27 +0000 (13:40 +0900)
This patch replaces following implementations of wayland protocols with
libds:

  wl_tbm, wl_buffer, wl_compositor, wl_region, wl_surface, wl_subsurface

Change-Id: Idf985dbfe585c75313b06d3ec328f657034c6961

16 files changed:
configure.ac
src/bin/Makefile.mk
src/bin/e_client.c
src/bin/e_comp.h
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_comp_wl_buffer.c
src/bin/e_comp_wl_buffer.h
src/bin/e_comp_wl_private.h
src/bin/e_comp_wl_subsurface.c
src/bin/e_comp_wl_subsurface.h
src/bin/e_comp_wl_tbm.c
src/bin/e_comp_wl_tbm.h
src/bin/e_compositor.c [new file with mode: 0644]
src/bin/e_compositor.h [new file with mode: 0644]
src/bin/e_policy_wl.c

index 4cf30ed..6f27486 100755 (executable)
@@ -288,6 +288,8 @@ e_requires="\
   libtdm >= "1.0.0" \
   glib-2.0 \
   gobject-2.0 \
+  libds \
+  libds-tizen-tbm-server \
   "
 
 PKG_CHECK_MODULES(E_INFO, [
index 8e1194b..2448908 100644 (file)
@@ -275,7 +275,8 @@ src/bin/e_wtz_shell.c \
 src/bin/e_device.c \
 src/bin/e_input_event.c \
 src/bin/e_single_pixel_buffer.c \
-src/bin/e_comp_wl_buffer.c
+src/bin/e_comp_wl_buffer.c \
+src/bin/e_compositor.c
 
 src_bin_enlightenment_CPPFLAGS = $(E_CPPFLAGS) -DEFL_BETA_API_SUPPORT -DEFL_EO_API_SUPPORT -DE_LOGGING=2 @WAYLAND_CFLAGS@ $(TTRACE_CFLAGS) $(DLOG_CFLAGS) $(PIXMAN_CFLAGS) $(POLICY_CFLAGS) $(EGL_CFLAGS)
 if HAVE_LIBGOMP
index 9726041..acd59ac 100644 (file)
@@ -8718,7 +8718,9 @@ e_client_is_layout_apply(E_Client *ec)
 E_API E_Client *
 e_client_from_surface_resource(struct wl_resource *surface_resource)
 {
-   return wl_resource_get_user_data(surface_resource);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(surface_resource, NULL);
+
+   return e_comp_wl_util_client_from_surface_resource(surface_resource);
 }
 
 EINTERN void
index 41eef38..fc87169 100644 (file)
@@ -200,6 +200,7 @@ struct _E_Comp_Connected_Client_Info
    int pid;
    int uid;
    int gid;
+   struct wl_listener destroy;
 };
 
 EINTERN Eina_Bool     e_comp_init(void);
index d44ffc1..0c8c281 100644 (file)
@@ -14,8 +14,6 @@
 #define __STDC_FORMAT_MACROS
 #include <inttypes.h>
 
-#define COMPOSITOR_VERSION 4
-
 #define E_COM_WL_PREPARE_GAP_LOG_TIME 2000
 
 /* Resource Data Mapping: (wl_resource_get_user_data)
  *
  */
 
+typedef struct _E_Comp_Data E_Comp_Data;
+
+struct _E_Comp_Data
+{
+   E_Comp_Wl_Data base;
+   struct wl_listener client_created;
+};
+
 static void _e_comp_wl_move_resize_init(void);
 
-static E_Client * _e_comp_wl_client_usable_get(pid_t pid, E_Pixmap *ep);
 static Eina_Bool _e_comp_wl_cursor_timer_control(Evas_Callback_Type type, E_Client *ec);
 
 /* local variables */
@@ -216,12 +221,6 @@ _e_comp_wl_configure_send(E_Client *ec, Eina_Bool edges, Eina_Bool send_size)
 }
 
 static void
-_e_comp_wl_focus_down_set(E_Client *ec EINA_UNUSED)
-{
-   // do nothing
-}
-
-static void
 _e_comp_wl_focus_check(void)
 {
    E_Client *ec;
@@ -3116,1040 +3115,212 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
 }
 
 static void
-_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+_e_comp_wl_surface_render_stop(E_Client *ec)
 {
-   DBG("Surface Cb Destroy: %d", wl_resource_get_id(resource));
-   wl_resource_destroy(resource);
+   /* FIXME: this may be fine after e_pixmap can create textures for wl clients? */
+   //if ((!ec->internal) && (!e_comp_gl_get()))
+     ec->dead = 1;
+
+   /* check if internal animation is running */
+   if (e_comp_object_is_animating(ec->frame)) return;
+   /* check if external animation is running */
+   if (evas_object_data_get(ec->frame, "effect_running")) return;
+
+   evas_object_hide(ec->frame);
 }
 
-static void
-_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
+EINTERN void
+e_comp_wl_client_surface_finish(E_Client *ec)
 {
-   E_Client *ec;
-   E_Comp_Wl_Buffer *buffer = NULL;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
+   struct wl_resource *res;
+   struct wl_client *surface_client = NULL;
+   Eina_List *l, *ll;
 
-   if (buffer_resource)
+   if (ec == e_client_focused_get())
      {
-        if (!(buffer = e_comp_wl_buffer_get(buffer_resource, ec)))
-          {
-             ERR("Could not get buffer from resource");
-             wl_client_post_no_memory(client);
-             return;
-          }
-     }
+        struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
+        surface_client = wl_resource_get_client(surface);
 
-   if (!ec->comp_data->mapped)
-     {
-        if (ec->comp_data->shell.surface &&
-            !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
+        g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
+        EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
           {
-             ELOGF("COMP", "Current unmapped. ATTACH buffer:%p", ec, buffer);
-          }
-     }
+             if (wl_resource_get_client(res) ==
+                 surface_client)
+               e_comp_wl->kbd.focused =
+                  eina_list_remove_list(e_comp_wl->kbd.focused, l);
 
-   if (!buffer)
-     {
-        if (ec->comp_data->mapped)
-          {
-             /* will be unmapped. so run capture */
-             e_comp_wl_remote_surface_image_save(ec);
           }
+
+        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
      }
 
-   _e_comp_wl_surface_state_buffer_set(&ec->comp_data->pending, buffer);
+   e_comp_wl_client_surface_set(ec, NULL);
 
-   ec->comp_data->pending.sx = sx;
-   ec->comp_data->pending.sy = sy;
-   ec->comp_data->pending.new_attach = EINA_TRUE;
+   ec->comp_data->wl_surface = NULL;
+   e_pixmap_win_id_del(ec->pixmap);
 
-   e_client_fps_update(ec);
+   _e_comp_wl_surface_render_stop(ec);
+   e_object_del(E_OBJECT(ec));
 }
 
 static void
-_e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
+_e_comp_wl_pname_get(pid_t pid, char *name, int size)
 {
-   E_Client *ec;
-   Eina_Rectangle *dmg = NULL;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   if (!(dmg = eina_rectangle_new(x, y, w, h))) return;
+   if (!name) return;
 
-   ec->comp_data->pending.damages =
-     eina_list_append(ec->comp_data->pending.damages, dmg);
-}
+   FILE *h;
+   char proc[512], pname[512];
+   size_t len;
 
-static void
-_e_comp_wl_frame_cb_destroy(struct wl_resource *resource)
-{
-   E_Client *ec;
-   E_Comp_Wl_Subsurf_Data *sdata;
+   snprintf(proc, 512,"/proc/%d/cmdline", pid);
 
-   if (!(ec = wl_resource_get_user_data(resource))) return;
-   if (!ec->comp_data) return;
+   h = fopen(proc, "r");
+   if (!h) return;
 
-   if (ec->comp_data->frames)
-     {
-        ec->comp_data->frames =
-          eina_list_remove(ec->comp_data->frames, resource);
-     }
+   len = fread(pname, sizeof(char), 512, h);
+   if (len > 0)
+     pname[len - 1] = '\0';
+   else
+     strncpy(pname, "NO NAME", sizeof(pname));
 
-   if (ec->comp_data->pending.frames)
-     {
-        ec->comp_data->pending.frames =
-          eina_list_remove(ec->comp_data->pending.frames, resource);
-     }
+   fclose(h);
 
-   sdata = ec->comp_data->sub.data;
-   if ((sdata) && (sdata->cached.frames))
-     {
-        sdata->cached.frames =
-           eina_list_remove(sdata->cached.frames, resource);
-     }
+   strncpy(name, pname, size);
 }
 
 static void
-_e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback)
+_e_comp_wl_pname_print(pid_t pid)
 {
-   E_Client *ec;
-   struct wl_resource *res;
+   FILE *h;
+   char proc[512], pname[512];
+   size_t len;
 
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
+   snprintf(proc, 512,"/proc/%d/cmdline", pid);
 
-   /* create frame callback */
-   if (!(res =
-         wl_resource_create(client, &wl_callback_interface, 1, callback)))
-     {
-        wl_resource_post_no_memory(resource);
-        return;
-     }
+   h = fopen(proc, "r");
+   if (!h) return;
+
+   len = fread(pname, sizeof(char), 512, h);
+   if (len > 0)
+     pname[len - 1] = '\0';
+   else
+     strncpy(pname, "NO NAME", sizeof(pname));
 
-   wl_resource_set_implementation(res, NULL, ec, _e_comp_wl_frame_cb_destroy);
+   fclose(h);
 
-   ec->comp_data->pending.frames =
-     eina_list_prepend(ec->comp_data->pending.frames, res);
+   ELOGF("COMP", "         |%s", NULL, pname);
 }
 
+
 static void
-_e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource)
+_e_comp_wl_connected_client_cb_destroy(struct wl_listener *listener, void *data)
 {
-   E_Client *ec;
+   struct wl_client *client = data;
+   E_Comp_Connected_Client_Info *cinfo;
+   E_Appinfo *eai;
 
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
+   cinfo = wl_container_of(listener, cinfo, destroy);
 
-   if (ec->comp_data->pending.opaque)
-     eina_tiler_clear(ec->comp_data->pending.opaque);
-   if (region_resource)
-     {
-        Eina_Tiler *tmp;
+   ELOGF("WL_CLIENT", "DESTROY  |client:%8p|%d|%d|%d",
+         NULL, client, cinfo->pid, cinfo->uid, cinfo->gid);
 
-        if (!(tmp = wl_resource_get_user_data(region_resource)))
-          return;
+   eai = e_appinfo_find_with_pid(cinfo->pid);
+   if (e_appinfo_owner_get(eai) == E_APPINFO_OWNER_SERVER)
+     e_appinfo_del(eai);
 
-        eina_tiler_union(ec->comp_data->pending.opaque, tmp);
+   e_comp->connected_clients = eina_list_remove(e_comp->connected_clients, cinfo);
 
-        if (!eina_tiler_empty(ec->comp_data->pending.opaque))
-          {
-             if (ec->argb)
-               {
-                  ec->argb = EINA_FALSE;
-                  ELOGF("COMP", "Set argb:%d", ec, ec->argb);
-                  EC_CHANGED(ec);
-                  _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, ec);
-                  e_comp_object_alpha_set(ec->frame, EINA_FALSE);
-               }
-          }
-     }
-   else
-     {
-        if (!ec->argb)
-          {
-             ec->argb = EINA_TRUE;
-             ELOGF("COMP", "Set argb:%d", ec, ec->argb);
-             EC_CHANGED(ec);
-             _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, ec);
-             e_comp_object_alpha_set(ec->frame, EINA_TRUE);
-          }
-     }
+   wl_list_remove(&cinfo->destroy.link);
+   eina_stringshare_del(cinfo->name);
+   free(cinfo);
 }
 
 static void
-_e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource)
+_e_comp_wl_connected_client_create(struct wl_client *client, char *name, pid_t pid, uid_t uid, gid_t gid)
 {
-   E_Client *ec;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
+   E_Comp_Connected_Client_Info *cinfo;
 
-   if (ec->comp_data->pending.input)
-     eina_tiler_clear(ec->comp_data->pending.input);
-   if (region_resource)
-     {
-        Eina_Tiler *tmp;
+   cinfo = E_NEW(E_Comp_Connected_Client_Info, 1);
+   EINA_SAFETY_ON_NULL_RETURN(cinfo);
 
-        if (!(tmp = wl_resource_get_user_data(region_resource)))
-          return;
+   cinfo->name = eina_stringshare_add(name);
+   cinfo->pid = pid;
+   cinfo->uid = uid;
+   cinfo->gid = gid;
+   cinfo->destroy.notify = _e_comp_wl_connected_client_cb_destroy;
+   wl_client_add_destroy_listener(client, &cinfo->destroy);
+   e_comp->connected_clients = eina_list_append(e_comp->connected_clients, cinfo);
 
-        if (eina_tiler_empty(tmp))
-          {
-             ELOGF("COMP", "         |unset input rect", NULL);
-             e_comp_object_input_objs_del(ec->frame);
-             e_comp_object_input_area_set(ec->frame, -1, -1, 1, 1);
-          }
-        else
-          eina_tiler_union(ec->comp_data->pending.input, tmp);
-     }
-   else
-     {
-        eina_tiler_rect_add(ec->comp_data->pending.input,
-                            &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
-     }
+   _e_comp_wl_pid_hook_call(E_COMP_WL_PID_HOOK_CONNECTED_CLIENT_CREATE, pid);
 }
 
 static void
-_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+_e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
 {
-   E_Client *ec, *subc;
-   Eina_List *l;
-   E_Comp_Config *comp_conf = NULL;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   if (!ec->comp_data->first_commit)
-     ec->comp_data->first_commit = EINA_TRUE;
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 
-   if (!ec->comp_data->mapped)
+   /* send configure */
+   if (ec->comp_data->shell.configure_send)
      {
-        if (ec->comp_data->shell.surface && ec->comp_data->pending.new_attach &&
-            !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
-          {
-             ELOGF("COMP", "Current unmapped. COMMIT. pixmap_usable:%d", ec, e_pixmap_usable_get(ec->pixmap));
-
-             // no canvas update before client's commit request, begin rendering after 1st commit
-             comp_conf = e_comp_config_get();
-             if (comp_conf && comp_conf->canvas_render_delay_after_boot && e_comp->canvas_render_delayed)
-               {
-                  ELOGF("COMP", "Begin canvas update for the first time after boot", ec);
-                  e_comp->canvas_render_delayed = EINA_FALSE;
-               }
-          }
+        if (ec->comp_data->shell.surface)
+          _e_comp_wl_configure_send(ec, 0, 0);
      }
 
-   _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_BEFORE_SURFACE_COMMIT, ec);
-
-   if (e_comp_wl_remote_surface_commit(ec)) return;
-   if (e_comp_wl_subsurface_commit(ec)) return;
+   e_comp_wl->kbd.focus = ec->comp_data->surface;
+}
 
-   e_comp_wl_surface_commit(ec);
+static void
+_e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
+{
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 
-   EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
+   /* send configure */
+   if (ec->comp_data->shell.configure_send)
      {
-        if (ec != subc)
-          e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+        if (ec->comp_data->shell.surface)
+          _e_comp_wl_configure_send(ec, 0, 0);
      }
 
-   EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
-     {
-        if (ec != subc)
-          e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
-     }
+   _e_comp_wl_focus_check();
 
-   _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT, ec);
+   if (e_comp_wl->kbd.focus == ec->comp_data->surface)
+     e_comp_wl->kbd.focus = NULL;
 }
 
 static void
-_e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t transform)
+_e_comp_wl_client_cb_resize_begin(void *data EINA_UNUSED, E_Client *ec)
 {
-   E_Client *ec;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   if (transform < 0 || transform > WL_OUTPUT_TRANSFORM_FLIPPED_270)
-     {
-        wl_resource_post_error(resource,
-                               WL_SURFACE_ERROR_INVALID_TRANSFORM,
-                               "buffer transform must be a valid transform "
-                               "('%d' specified)", transform);
-        return;
-     }
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
+   if (ec->keyboard_resizing) return;
 
-   ec->comp_data->pending.buffer_viewport.buffer.transform = transform;
-   ec->comp_data->pending.buffer_viewport.changed = 1;
+   /* do nothing currently */
+   ;
 }
 
 static void
-_e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t scale)
+_e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
 {
-   E_Client *ec;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
+
+   e_comp_wl->resize.edges = 0;
+   e_comp_wl->resize.resource = NULL;
 
-   if (scale < 1)
+   if (ec->pending_resize)
      {
-        wl_resource_post_error(resource,
-                               WL_SURFACE_ERROR_INVALID_SCALE,
-                               "buffer scale must be at least one "
-                               "('%d' specified)", scale);
-        return;
+        ec->changes.pos = EINA_TRUE;
+        ec->changes.size = EINA_TRUE;
+        EC_CHANGED(ec);
      }
 
-   ec->comp_data->pending.buffer_viewport.buffer.scale = scale;
-   ec->comp_data->pending.buffer_viewport.changed = 1;
+   E_FREE_LIST(ec->pending_resize, free);
 }
 
 static void
-_e_comp_wl_surface_cb_damage_buffer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
+_e_comp_wl_client_cb_move_end(void *data EINA_UNUSED, E_Client *ec)
 {
-   E_Client *ec;
-   Eina_Rectangle *dmg = NULL;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
-
-   if (!(dmg = eina_rectangle_new(x, y, w, h))) return;
-
-   ec->comp_data->pending.buffer_damages =
-     eina_list_append(ec->comp_data->pending.buffer_damages, dmg);
-}
-
-static const struct wl_surface_interface _e_surface_interface =
-{
-   _e_comp_wl_surface_cb_destroy,
-   _e_comp_wl_surface_cb_attach,
-   _e_comp_wl_surface_cb_damage,
-   _e_comp_wl_surface_cb_frame,
-   _e_comp_wl_surface_cb_opaque_region_set,
-   _e_comp_wl_surface_cb_input_region_set,
-   _e_comp_wl_surface_cb_commit,
-   _e_comp_wl_surface_cb_buffer_transform_set,
-   _e_comp_wl_surface_cb_buffer_scale_set,
-   _e_comp_wl_surface_cb_damage_buffer,
-};
-
-static void
-_e_comp_wl_surface_render_stop(E_Client *ec)
-{
-   /* FIXME: this may be fine after e_pixmap can create textures for wl clients? */
-   //if ((!ec->internal) && (!e_comp_gl_get()))
-     ec->dead = 1;
-
-   /* check if internal animation is running */
-   if (e_comp_object_is_animating(ec->frame)) return;
-   /* check if external animation is running */
-   if (evas_object_data_get(ec->frame, "effect_running")) return;
-
-   evas_object_hide(ec->frame);
-}
-
-static void
-_e_comp_wl_surface_destroy(struct wl_resource *resource)
-{
-   E_Client *ec;
-   struct wl_resource *res;
-   struct wl_client *surface_client = NULL;
-   Eina_List *l, *ll;
-
-   if (!(ec = e_client_from_surface_resource(resource))) return;
-
-   if (ec == e_client_focused_get())
-     {
-        struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
-        surface_client = wl_resource_get_client(surface);
-
-        g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-        EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
-          {
-             if (wl_resource_get_client(res) ==
-                 surface_client)
-               e_comp_wl->kbd.focused =
-                  eina_list_remove_list(e_comp_wl->kbd.focused, l);
-          }
-
-        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
-     }
-
-   e_comp_wl_client_surface_set(ec, NULL);
-
-   ec->comp_data->wl_surface = NULL;
-   e_pixmap_win_id_del(ec->pixmap);
-
-   _e_comp_wl_surface_render_stop(ec);
-   e_object_del(E_OBJECT(ec));
-}
-
-static void
-_e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
-{
-   struct wl_resource *res;
-   E_Pixmap *ep = NULL;
-   E_Client *ec = NULL;
-   pid_t pid;
-   int internal = 0;
-
-   DBG("Compositor Cb Surface Create: %d", id);
-
-   TRACE_DS_BEGIN(COMP_WL:SURFACE CREATE CB);
-
-   /* try to create an internal surface */
-   if (!(res = wl_resource_create(client, &wl_surface_interface,
-                                  wl_resource_get_version(resource), id)))
-     {
-        ERR("Could not create compositor surface");
-        wl_client_post_no_memory(client);
-        TRACE_DS_END();
-        return;
-     }
-
-   DBG("\tCreated Resource: %d", wl_resource_get_id(res));
-
-   /* set implementation on resource */
-   wl_resource_set_implementation(res, &_e_surface_interface, NULL,
-                                  _e_comp_wl_surface_destroy);
-
-   wl_client_get_credentials(client, &pid, NULL, NULL);
-   if (pid == getpid())
-     {
-        /* pixmap of internal win was supposed to be created at trap show */
-        internal = 1;
-        ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, (uintptr_t)id);
-     }
-   else
-     {
-        if ((ep = e_pixmap_find(E_PIXMAP_TYPE_WL, (uintptr_t)res)))
-          {
-             ERR("There is e_pixmap already, Delete old e_pixmap %p", ep);
-             e_pixmap_win_id_del(ep);
-             ep = NULL;
-          }
-     }
-
-   if (!ec)
-     {
-        /* try to create new pixmap */
-        if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, res)))
-          {
-             ERR("Could not create new pixmap");
-             wl_resource_destroy(res);
-             wl_client_post_no_memory(client);
-             TRACE_DS_END();
-             return;
-          }
-
-        E_Comp_Wl_Client_Data *cdata = e_pixmap_cdata_get(ep);
-        if (cdata)
-          cdata->wl_surface = res;
-
-        DBG("\tUsing Pixmap: %p", ep);
-
-        if (!(ec = _e_comp_wl_client_usable_get(pid, ep)))
-          {
-             ec = e_client_new(ep, 0, internal);
-          }
-     }
-   if (ec)
-     {
-        if (!ec->netwm.pid)
-          ec->netwm.pid = pid;
-        if (ec->new_client)
-          e_comp->new_clients--;
-        ec->new_client = 0;
-        if ((!ec->client.w) && (ec->client.h))
-          ec->client.w = ec->client.h = 1;
-
-        e_comp_wl_client_surface_set(ec, res);
-
-        ec->icccm.accepts_focus = 1;
-        wl_list_init(&ec->comp_data->pointer_constraints);
-     }
-
-   /* set reference to pixmap so we can fetch it later */
-   DBG("\tUsing Client: %p", ec);
-   wl_resource_set_user_data(res, ec);
-
-   TRACE_DS_END();
-}
-
-static void
-_e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
-   DBG("Region Destroy: %d", wl_resource_get_id(resource));
-   wl_resource_destroy(resource);
-}
-
-static void
-_e_comp_wl_region_area_check(struct wl_client *client, Eina_Tiler *tiler, int32_t x, int32_t y, int32_t w, int32_t h)
-{
-   Eina_Bool need_set = EINA_FALSE;
-   int area_w = 0;
-   int area_h = 0;
-
-   eina_tiler_area_size_get(tiler, &area_w, &area_h);
-   if (x + w > area_w)
-     {
-        area_w = x + w;
-        need_set = EINA_TRUE;
-     }
-
-   if (y + h > area_h)
-     {
-        area_h = y + h;
-        need_set = EINA_TRUE;
-     }
-
-   if (need_set)
-     {
-        INF("change region area. client:%8p(%dx%d)", client, area_w, area_h);
-        eina_tiler_area_size_set(tiler, area_w, area_h);
-     }
-}
-
-static void
-_e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
-{
-   Eina_Tiler *tiler;
-
-   DBG("Region Add: %d", wl_resource_get_id(resource));
-   DBG("\tGeom: %d %d %d %d", x, y, w, h);
-
-   /* get the tiler from the resource */
-   if ((tiler = wl_resource_get_user_data(resource)))
-     {
-        _e_comp_wl_region_area_check(client, tiler, x, y ,w, h);
-        eina_tiler_rect_add(tiler, &(Eina_Rectangle){x, y, w, h});
-     }
-}
-
-static void
-_e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
-{
-   Eina_Tiler *tiler;
-
-   DBG("Region Subtract: %d", wl_resource_get_id(resource));
-   DBG("\tGeom: %d %d %d %d", x, y, w, h);
-
-   /* get the tiler from the resource */
-   if ((tiler = wl_resource_get_user_data(resource)))
-     eina_tiler_rect_del(tiler, &(Eina_Rectangle){x, y, w, h});
-}
-
-static const struct wl_region_interface _e_region_interface =
-{
-   _e_comp_wl_region_cb_destroy,
-   _e_comp_wl_region_cb_add,
-   _e_comp_wl_region_cb_subtract
-};
-
-static void
-_e_comp_wl_compositor_cb_region_destroy(struct wl_resource *resource)
-{
-   Eina_Tiler *tiler;
-
-   DBG("Compositor Region Destroy: %d", wl_resource_get_id(resource));
-
-   /* try to get the tiler from the region resource */
-   if ((tiler = wl_resource_get_user_data(resource)))
-     eina_tiler_free(tiler);
-}
-
-static void
-_e_comp_wl_compositor_cb_region_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
-{
-   Eina_Tiler *tiler;
-   struct wl_resource *res;
-
-   DBG("Region Create: %d", wl_resource_get_id(resource));
-
-   /* try to create new tiler */
-   if (!(tiler = eina_tiler_new(e_comp->w, e_comp->h)))
-     {
-        ERR("Could not create Eina_Tiler");
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-
-   /* set tiler size */
-   eina_tiler_tile_size_set(tiler, 1, 1);
-
-   if (!(res = wl_resource_create(client, &wl_region_interface, 1, id)))
-     {
-        ERR("\tFailed to create region resource");
-               eina_tiler_free(tiler);
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-
-   wl_resource_set_implementation(res, &_e_region_interface, tiler,
-                                  _e_comp_wl_compositor_cb_region_destroy);
-}
-
-static const struct wl_compositor_interface _e_comp_interface =
-{
-   _e_comp_wl_compositor_cb_surface_create,
-   _e_comp_wl_compositor_cb_region_create
-};
-
-static void
-_e_comp_wl_pname_get(pid_t pid, char *name, int size)
-{
-   if (!name) return;
-
-   FILE *h;
-   char proc[512], pname[512];
-   size_t len;
-
-   snprintf(proc, 512,"/proc/%d/cmdline", pid);
-
-   h = fopen(proc, "r");
-   if (!h) return;
-
-   len = fread(pname, sizeof(char), 512, h);
-   if (len > 0)
-     pname[len - 1] = '\0';
-   else
-     strncpy(pname, "NO NAME", sizeof(pname));
-
-   fclose(h);
-
-   strncpy(name, pname, size);
-}
-
-static void
-_e_comp_wl_pname_print(pid_t pid)
-{
-   FILE *h;
-   char proc[512], pname[512];
-   size_t len;
-
-   snprintf(proc, 512,"/proc/%d/cmdline", pid);
-
-   h = fopen(proc, "r");
-   if (!h) return;
-
-   len = fread(pname, sizeof(char), 512, h);
-   if (len > 0)
-     pname[len - 1] = '\0';
-   else
-     strncpy(pname, "NO NAME", sizeof(pname));
-
-   fclose(h);
-
-   ELOGF("COMP", "         |%s", NULL, pname);
-}
-
-
-static void
-_e_comp_wl_compositor_cb_unbind(struct wl_resource *res_comp)
-{
-   E_Appinfo *eai = NULL;
-   struct wl_client *client;
-   pid_t pid = 0;
-   uid_t uid = 0;
-   gid_t gid = 0;
-
-   client = wl_resource_get_client(res_comp);
-   if (client)
-     wl_client_get_credentials(client,
-                               &pid,
-                               &uid,
-                               &gid);
-
-   ELOGF("COMP",
-         "UNBIND   |res_comp:%8p|client:%8p|%d|%d|%d",
-         NULL,
-         res_comp,
-         client,
-         pid, uid, gid);
-
-   E_Comp *comp;
-   if ((comp = wl_resource_get_user_data(res_comp)))
-     {
-        Eina_List *l;
-        E_Comp_Connected_Client_Info *cinfo;
-        EINA_LIST_FOREACH(comp->connected_clients, l, cinfo)
-          {
-             if (cinfo->pid == pid)
-               break;
-             cinfo = NULL;
-          }
-        if (cinfo)
-          {
-             if (cinfo->name)
-               eina_stringshare_del(cinfo->name);
-             comp->connected_clients = eina_list_remove(comp->connected_clients, cinfo);
-             E_FREE(cinfo);
-          }
-     }
-
-   eai = e_appinfo_find_with_pid(pid);
-   if (e_appinfo_owner_get(eai) == E_APPINFO_OWNER_SERVER)
-     {
-        e_appinfo_del(eai);
-     }
-}
-
-static void
-_e_comp_wl_connected_client_create(char *name, pid_t pid, uid_t uid, gid_t gid)
-{
-   E_Comp_Connected_Client_Info *cinfo;
-
-   cinfo = E_NEW(E_Comp_Connected_Client_Info, 1);
-   EINA_SAFETY_ON_NULL_RETURN(cinfo);
-
-   cinfo->name = eina_stringshare_add(name);
-   cinfo->pid = pid;
-   cinfo->uid = uid;
-   cinfo->gid = gid;
-   e_comp->connected_clients = eina_list_append(e_comp->connected_clients, cinfo);
-
-   _e_comp_wl_pid_hook_call(E_COMP_WL_PID_HOOK_CONNECTED_CLIENT_CREATE, pid);
-}
-
-
-static void
-_e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
-{
-   struct wl_resource *res;
-   pid_t pid = 0;
-   uid_t uid = 0;
-   gid_t gid = 0;
-
-   if (!(res =
-         wl_resource_create(client, &wl_compositor_interface,
-                            version, id)))
-     {
-        ERR("Could not create compositor resource: %m");
-        wl_client_post_no_memory(client);
-        return;
-     }
-
-   wl_resource_set_implementation(res, &_e_comp_interface, e_comp, _e_comp_wl_compositor_cb_unbind);
-
-   wl_client_get_credentials(client, &pid, &uid, &gid);
-
-   ELOGF("COMP",
-         "BIND     |res_comp:%8p|client:%8p|%d|%d|%d",
-         NULL,
-         res,
-         client,
-         pid, uid, gid);
-
-   _e_comp_wl_pname_print(pid);
-
-   char name[512];
-   _e_comp_wl_pname_get(pid, name, sizeof(name));
-
-   _e_comp_wl_connected_client_create(name, pid, uid, gid);
-}
-
-static void
-_e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec)
-{
-   Ecore_Window win;
-
-   /* make sure this is a wayland client */
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
-   TRACE_DS_BEGIN(COMP_WL:CLIENT NEW HOOK);
-
-   /* get window id from pixmap */
-   win = e_pixmap_window_get(ec->pixmap);
-
-   /* ignore fake root windows */
-   if ((ec->override) && ((ec->x == -77) && (ec->y == -77)))
-     {
-        e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, win);
-        e_object_del(E_OBJECT(ec));
-        TRACE_DS_END();
-        return;
-     }
-
-   if (!(ec->comp_data = E_NEW(E_Comp_Wl_Client_Data, 1)))
-     {
-        ERR("Could not allocate new client data structure");
-        TRACE_DS_END();
-        return;
-     }
-
-   wl_signal_init(&ec->comp_data->destroy_signal);
-   wl_signal_init(&ec->comp_data->apply_viewport_signal);
-
-   _e_comp_wl_surface_state_init(&ec->comp_data->pending, ec->w, ec->h);
-
-   /* set initial client properties */
-   ec->argb = EINA_FALSE;
-   ELOGF("COMP", "Set argb:%d", ec, ec->argb);
-   ec->no_shape_cut = EINA_TRUE;
-   ec->redirected = ec->ignored = 1;
-   ec->border_size = 0;
-
-   /* NB: could not find a better place to do this, BUT for internal windows,
-    * we need to set delete_request else the close buttons on the frames do
-    * basically nothing */
-   if (ec->internal)
-     ec->icccm.delete_request = EINA_TRUE;
-
-   /* set initial client data properties */
-   ec->comp_data->mapped = EINA_FALSE;
-   ec->comp_data->first_damage = ec->internal;
-
-   ec->comp_data->need_reparent = !ec->internal;
-
-   /* set initial value of scaler */
-   ec->comp_data->scaler.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
-   ec->comp_data->scaler.buffer_viewport.buffer.scale = 1;
-   ec->comp_data->scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
-   ec->comp_data->scaler.buffer_viewport.surface.width = -1;
-
-   e_presentation_time_container_init(&ec->comp_data->presentation_container);
-
-   E_Comp_Wl_Client_Data *p_cdata = e_pixmap_cdata_get(ec->pixmap);
-   EINA_SAFETY_ON_NULL_GOTO(p_cdata, end);
-
-   e_pixmap_cdata_set(ec->pixmap, ec->comp_data);
-
-   g_mutex_init(&ec->comp_data->last_device_kbd_mutex);
-   g_mutex_init(&ec->comp_data->surface_mutex);
-
-end:
-   TRACE_DS_END();
-}
-
-static void
-_e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
-{
-   /* Eina_Rectangle *dmg; */
-   struct wl_resource *cb;
-
-   /* make sure this is a wayland client */
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
-   TRACE_DS_BEGIN(COMP_WL:CLIENT DEL CB);
-
-   g_mutex_clear(&ec->comp_data->last_device_kbd_mutex);
-   g_mutex_clear(&ec->comp_data->surface_mutex);
-
-   _e_comp_wl_hook_call(E_COMP_WL_HOOK_DEL, ec);
-
-   if ((!ec->already_unparented) && (ec->comp_data->reparented))
-     _e_comp_wl_focus_down_set(ec);
-
-   ec->already_unparented = EINA_TRUE;
-   if (ec->comp_data->reparented)
-     {
-        /* reset pixmap parent window */
-        e_pixmap_parent_window_set(ec->pixmap, 0);
-     }
-
-   if (ec->comp_data->sub.watcher)
-     wl_resource_destroy(ec->comp_data->sub.watcher);
-
-   wl_signal_emit(&ec->comp_data->destroy_signal, &ec->comp_data->surface);
-
-   _e_comp_wl_surface_state_finish(&ec->comp_data->pending);
-
-   e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, NULL);
-
-   EINA_LIST_FREE(ec->comp_data->frames, cb)
-     wl_resource_destroy(cb);
-
-   EINA_LIST_FREE(ec->comp_data->pending.frames, cb)
-     wl_resource_destroy(cb);
-
-   if (ec->comp_data->surface)
-     wl_resource_set_user_data(ec->comp_data->surface, NULL);
-
-   _e_comp_wl_focus_check();
-
-   if (ec->comp_data->aux_hint.hints)
-     {
-        E_Comp_Wl_Aux_Hint *hint;
-        EINA_LIST_FREE(ec->comp_data->aux_hint.hints, hint)
-          {
-             eina_stringshare_del(hint->hint);
-             eina_stringshare_del(hint->val);
-             E_FREE(hint);
-          }
-     }
-
-   if (cursor_timer_ec == ec)
-     {
-        E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
-        cursor_timer_ec = NULL;
-     }
-
-   if (e_comp_wl->ptr.ec == ec)
-     e_comp_wl->ptr.ec = NULL;
-
-   if (e_comp_wl->touch.faked_ec == ec)
-     e_comp_wl->touch.faked_ec = NULL;
-
-   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
-
-   if (e_comp_wl->selection.cbhm == surface)
-     e_comp_wl->selection.cbhm = NULL;
-
-   if (e_comp_wl->selection.target == ec)
-     e_comp_wl->selection.target = NULL;
-
-   if (ec->comp_data->viewport_transform)
-     {
-        e_client_transform_core_remove(ec, ec->comp_data->viewport_transform);
-        e_util_transform_del(ec->comp_data->viewport_transform);
-        ec->comp_data->viewport_transform = NULL;
-     }
-
-   e_presentation_time_container_finish(&ec->comp_data->presentation_container);
-
-   _e_comp_wl_client_evas_deinit(ec);
-
-   e_pixmap_cdata_set(ec->pixmap, NULL);
-
-   E_FREE_FUNC(ec->comp_data->on_focus_timer, ecore_timer_del);
-
-   E_FREE(ec->comp_data);
-
-   _e_comp_wl_focus_check();
-
-   TRACE_DS_END();
-}
-
-static void
-_e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
-{
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
-   /* send configure */
-   if (ec->comp_data->shell.configure_send)
-     {
-        if (ec->comp_data->shell.surface)
-          _e_comp_wl_configure_send(ec, 0, 0);
-     }
-
-   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
-   e_comp_wl->kbd.focus = surface;
-}
-
-static void
-_e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
-{
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
-   /* send configure */
-   if (ec->comp_data->shell.configure_send)
-     {
-        if (ec->comp_data->shell.surface)
-          _e_comp_wl_configure_send(ec, 0, 0);
-     }
-
-   _e_comp_wl_focus_check();
-
-   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
-
-   if (e_comp_wl->kbd.focus == surface)
-     e_comp_wl->kbd.focus = NULL;
-}
-
-static void
-_e_comp_wl_client_cb_resize_begin(void *data EINA_UNUSED, E_Client *ec)
-{
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-   if (ec->keyboard_resizing) return;
-
-   /* do nothing currently */
-   ;
-}
-
-static void
-_e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
-{
-   if (e_object_is_del(E_OBJECT(ec))) return;
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
-   e_comp_wl->resize.edges = 0;
-   e_comp_wl->resize.resource = NULL;
-
-   if (ec->pending_resize)
-     {
-        ec->changes.pos = EINA_TRUE;
-        ec->changes.size = EINA_TRUE;
-        EC_CHANGED(ec);
-     }
-
-   E_FREE_LIST(ec->pending_resize, free);
-}
-
-static void
-_e_comp_wl_client_cb_move_end(void *data EINA_UNUSED, E_Client *ec)
-{
-   if (e_object_is_del(E_OBJECT(ec))) return;
-   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-}
-
-static E_Client *
-_e_comp_wl_client_usable_get(pid_t pid, E_Pixmap *ep)
-{
-   /* NOTE: this will return usable E_Client for a surface of specified process
-    * by pid. it doesn't care whatever this surfaces is for but care only what
-    * is owner process of the surface.
-    */
-
-   E_Client *ec = NULL, *_ec = NULL;
-   Eina_List *l;
-
-   /* find launchscreen client list */
-   if (e_comp->launchscrns)
-     {
-        EINA_LIST_FOREACH(e_comp->launchscrns, l, _ec)
-          {
-             if (_ec->netwm.pid == pid)
-               {
-                  ec = _ec;
-                  break;
-               }
-          }
-        if (ec)
-          {
-             E_Pixmap *oldep = NULL;
-
-             if (ec->comp_data)
-               {
-                  /* do NOT replace with the client having comp data */
-                  return NULL;
-               }
-
-             e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, ec);
-
-             oldep = e_client_pixmap_change(ec, ep);
-             if (oldep)
-               {
-                  e_pixmap_win_id_del(oldep);
-                  e_pixmap_free(oldep);
-               }
-
-             if (ec->internal)
-               ec->internal = 0;
-
-             /* to set-up comp data */
-             _e_comp_wl_client_cb_new(NULL, ec);
-             ec->ignored = 0;
-             if (!ec->comp_data) return NULL;
-             _e_comp_wl_client_evas_init(ec);
-
-             ELOGF("COMP", "Reusable ec. new_pixmap:%p", ec, ec->pixmap);
-             _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_REUSE, ec);
-          }
-     }
-
-   return ec;
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 }
 
 static void
@@ -4412,20 +3583,40 @@ _e_comp_wl_gl_idle(void *data)
    return ECORE_CALLBACK_CANCEL;
 }
 
+static void
+_e_comp_wl_cb_client_created(struct wl_listener *listener, void *data)
+{
+   struct wl_client *client = data;
+   pid_t pid = 0;
+   uid_t uid = 0;
+   gid_t gid = 0;
+   char name[512];
+
+   wl_client_get_credentials(client, &pid, &uid, &gid);
+
+   ELOGF("COMP", "WL_CLIENT|client:%8p|%d|%d|%d", NULL, client, pid, uid, gid);
+
+   _e_comp_wl_pname_print(pid);
+   _e_comp_wl_pname_get(pid, name, sizeof(name));
+   _e_comp_wl_connected_client_create(client, name, pid, uid, gid);
+}
+
 static Eina_Bool
-_e_comp_wl_compositor_create(void)
+_e_comp_wl_display_create(void)
 {
+   E_Comp_Data *comp;
    E_Comp_Wl_Data *wl_cdata;
    const char *name;
    int fd = 0;
    Eina_Bool res;
 
    /* create new compositor data */
-   if (!(wl_cdata = E_NEW(E_Comp_Wl_Data, 1)))
+   if (!(comp = E_NEW(E_Comp_Data, 1)))
      {
-       ERR("Could not create compositor data: %m");
-       return EINA_FALSE;
+        ERR("Could not create compositor data: %m");
+        return EINA_FALSE;
      }
+   wl_cdata = &comp->base;
 
    /* set compositor wayland data */
    e_comp_wl = e_comp->wl_comp_data = wl_cdata;
@@ -4455,19 +3646,19 @@ _e_comp_wl_compositor_create(void)
    /* wl_cdata->output.transform = WL_OUTPUT_TRANSFORM_NORMAL; */
    /* wl_cdata->output.scale = e_scale; */
 
-   /* try to add compositor to wayland globals */
-   if (!wl_global_create(wl_cdata->wl.disp, &wl_compositor_interface,
-                         COMPOSITOR_VERSION, e_comp,
-                         _e_comp_wl_compositor_cb_bind))
+   if (!e_compositor_init(wl_cdata->wl.disp))
      {
-        ERR("Could not add compositor to wayland globals: %m");
-        goto comp_global_err;
+        ERR("Failed to initialize compositor");
+        goto comp_err;
      }
 
-   if (!e_comp_wl_subsurfaces_init(wl_cdata))
+   comp->client_created.notify = _e_comp_wl_cb_client_created;
+   wl_display_add_client_created_listener(comp->base.wl.disp, &comp->client_created);
+
+   if (!e_comp_wl_subsurfaces_init())
      {
-        ERR("Failed to init subsurfaces");
-        goto comp_global_err;
+        ERR("Failed to init_subsurfaces");
+        goto subsurfaces_err;
      }
 
    /* initialize shm mechanism */
@@ -4510,12 +3701,15 @@ _e_comp_wl_compositor_create(void)
 input_err:
    e_comp_wl_data_manager_shutdown();
 data_err:
-comp_global_err:
+   e_comp_wl_subsurfaces_shutdown();
+subsurfaces_err:
+   wl_list_remove(&comp->client_created.link);
+comp_err:
    e_env_unset("WAYLAND_DISPLAY");
 sock_err:
    wl_display_destroy(wl_cdata->wl.disp);
 disp_err:
-   free(wl_cdata);
+   free(comp);
    return EINA_FALSE;
 }
 
@@ -4580,7 +3774,7 @@ e_comp_wl_init(void)
    TRACE_DS_BEGIN(COMP_WL:INIT);
 
    /* try to create a wayland compositor */
-   if (!_e_comp_wl_compositor_create())
+   if (!_e_comp_wl_display_create())
      {
         e_error_message_show(_("Enlightenment cannot create a Wayland Compositor!\n"));
         TRACE_DS_END();
@@ -4626,8 +3820,6 @@ e_comp_wl_init(void)
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_END, _e_comp_wl_cb_client_rot_change_end, NULL);
 
    /* add hooks to catch e_client events */
-   E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_NEW_CLIENT,   _e_comp_wl_client_cb_new,          NULL);
-   E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_DEL,          _e_comp_wl_client_cb_del,          NULL);
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_FOCUS_SET,    _e_comp_wl_client_cb_focus_set,    NULL);
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_FOCUS_UNSET,  _e_comp_wl_client_cb_focus_unset,  NULL);
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_RESIZE_BEGIN, _e_comp_wl_client_cb_resize_begin, NULL);
@@ -4650,6 +3842,8 @@ e_comp_wl_deferred_job(void)
 EINTERN void
 e_comp_wl_shutdown(void)
 {
+   E_Comp_Data *comp = (E_Comp_Data *)e_comp_wl;
+
    ecore_idle_exiter_del(e_comp_wl->idle_exiter);
 
    e_comp_wl_subsurfaces_shutdown();
@@ -4666,9 +3860,6 @@ e_comp_wl_shutdown(void)
    e_comp_wl_video_shutdown();
    e_comp_wl_screenshooter_shutdown();
 
-#ifdef HAVE_WAYLAND_TBM
-   e_comp_wl_tbm_shutdown();
-#endif
    e_comp_wl_remote_surface_shutdown();
 
    e_pixmap_shutdown();
@@ -4677,6 +3868,11 @@ e_comp_wl_shutdown(void)
    e_comp_wl_shell_shutdown();
    e_comp_wl_input_shutdown();
 
+   wl_list_remove(&comp->client_created.link);
+
+   e_comp_wl = NULL;
+   e_comp->wl_comp_data = NULL;
+   free(comp);
    // TODO: yigl
 #if 0
    E_Comp_Wl_Output *output;
@@ -6673,3 +5869,298 @@ EINTERN void e_comp_wl_client_surface_set(E_Client *ec, struct wl_resource *surf
    ec->comp_data->surface = surface;
    g_mutex_unlock(&ec->comp_data->surface_mutex);
 }
+
+EINTERN E_Client *
+e_comp_wl_util_client_from_surface_resource(struct wl_resource *surface_resource)
+{
+   return e_compositor_util_client_from_surface_resource(surface_resource);
+}
+
+EINTERN void
+e_comp_wl_client_surface_pending_buffer_set(E_Client *ec, E_Comp_Wl_Buffer *buffer, int32_t sx, int32_t sy)
+{
+   if (!ec->comp_data->mapped)
+     {
+        if (ec->comp_data->shell.surface &&
+            !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
+          {
+             ELOGF("COMP", "Current unmapped. ATTACH buffer:%p", ec, buffer);
+          }
+     }
+
+   if (!buffer)
+     {
+        if (ec->comp_data->mapped)
+          {
+             /* will be unmapped. so run capture */
+             e_comp_wl_remote_surface_image_save(ec);
+          }
+     }
+
+   _e_comp_wl_surface_state_buffer_set(&ec->comp_data->pending, buffer);
+
+   ec->comp_data->pending.sx = sx;
+   ec->comp_data->pending.sy = sy;
+   ec->comp_data->pending.new_attach = EINA_TRUE;
+
+   e_client_fps_update(ec);
+}
+
+EINTERN void
+e_comp_wl_client_surface_pending_opaque_region_set(E_Client *ec, Eina_Tiler *region)
+{
+   if (ec->comp_data->pending.opaque)
+     eina_tiler_clear(ec->comp_data->pending.opaque);
+
+   if (region)
+     {
+        eina_tiler_union(ec->comp_data->pending.opaque, region);
+
+        if (!eina_tiler_empty(ec->comp_data->pending.opaque))
+          {
+             if (ec->argb)
+               {
+                  ec->argb = EINA_FALSE;
+                  ELOGF("COMP", "Set argb:%d", ec, ec->argb);
+                  EC_CHANGED(ec);
+                  _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, ec);
+                  e_comp_object_alpha_set(ec->frame, EINA_FALSE);
+               }
+          }
+     }
+   else
+     {
+        if (!ec->argb)
+          {
+             ec->argb = EINA_TRUE;
+             ELOGF("COMP", "Set argb:%d", ec, ec->argb);
+             EC_CHANGED(ec);
+             _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, ec);
+             e_comp_object_alpha_set(ec->frame, EINA_TRUE);
+          }
+     }
+}
+
+EINTERN void
+e_comp_wl_client_surface_pending_input_region_set(E_Client *ec, Eina_Tiler *region)
+{
+   if (ec->comp_data->pending.input)
+     eina_tiler_clear(ec->comp_data->pending.input);
+
+   if (region)
+     {
+        if (eina_tiler_empty(region))
+          {
+             ELOGF("COMP", "         |unset input rect", NULL);
+             e_comp_object_input_objs_del(ec->frame);
+             e_comp_object_input_area_set(ec->frame, -1, -1, 1, 1);
+          }
+        else
+          eina_tiler_union(ec->comp_data->pending.input, region);
+     }
+   else
+     {
+        eina_tiler_rect_add(ec->comp_data->pending.input,
+                            &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
+     }
+}
+
+EINTERN void
+e_comp_wl_client_surface_pending_frame_callback_add(E_Client *ec, struct wl_resource *callback_resource)
+{
+   ec->comp_data->pending.frames = eina_list_prepend(ec->comp_data->pending.frames, callback_resource);
+}
+
+EINTERN void
+e_comp_wl_client_surface_frame_callback_remove(E_Client *ec, struct wl_resource *callback_resource)
+{
+   E_Comp_Wl_Subsurf_Data *sdata;
+
+   if (!ec->comp_data)
+     return;
+
+   if (ec->comp_data->frames)
+     {
+        ec->comp_data->frames =
+           eina_list_remove(ec->comp_data->frames, callback_resource);
+     }
+
+   if (ec->comp_data->pending.frames)
+     {
+        ec->comp_data->pending.frames =
+           eina_list_remove(ec->comp_data->pending.frames, callback_resource);
+     }
+
+   sdata = ec->comp_data->sub.data;
+   if ((sdata) && (sdata->cached.frames))
+     {
+        sdata->cached.frames =
+           eina_list_remove(sdata->cached.frames, callback_resource);
+     }
+}
+
+EINTERN void
+e_comp_wl_client_surface_pending_commit(E_Client *ec)
+{
+   if (e_object_is_del(E_OBJECT(ec))) return;
+
+   if (e_comp_wl_remote_surface_commit(ec)) return;
+
+   e_comp_wl_surface_commit(ec);
+
+   _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT, ec);
+}
+
+static void
+_e_comp_wl_client_subsurface_set(E_Client *ec, E_Comp_Wl_Subsurf_Data *sub)
+{
+   ec->comp_data->surface = ec->comp_data->wl_surface;
+   ec->comp_data->sub.data = sub;
+
+   /* set subsurface client properties */
+   ec->borderless = EINA_TRUE;
+   ec->argb = EINA_TRUE;
+   ELOGF("SUBSURFACE", "Set argb:%d", ec, ec->argb);
+   ec->lock_border = EINA_TRUE;
+   ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
+   ec->netwm.state.skip_taskbar = EINA_TRUE;
+   ec->netwm.state.skip_pager = EINA_TRUE;
+   ec->no_shape_cut = EINA_TRUE;
+   ec->border_size = 0;
+   ec->lock_user_location = 0;
+   ec->lock_client_location = 0;
+   ec->lock_user_size = 0;
+   ec->lock_client_size = 0;
+   ec->lock_client_stacking = 0;
+   ec->lock_user_shade = 0;
+   ec->lock_client_shade = 0;
+   ec->lock_user_maximize = 0;
+   ec->lock_client_maximize = 0;
+   ec->changes.need_maximize = 0;
+   ec->maximized = E_MAXIMIZE_NONE;
+   EC_CHANGED(ec);
+
+   ec->new_client = ec->netwm.ping = EINA_TRUE;
+   e_comp->new_clients++;
+   e_client_unignore(ec);
+
+   /* Delete 'below_obj' if it was created before 'E_Client' becomes subsurface.
+    * It's not for subsurface. */
+   E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del);
+}
+
+static void
+_e_comp_wl_client_subsurface_parent_set(E_Client *ec, E_Client *parent)
+{
+   E_Comp_Wl_Subsurf_Data *sub = ec->comp_data->sub.data;
+   E_Layer layer;
+
+   ELOGF("COMP", "         |subsurface_parent:%p", ec, parent);
+
+   sub->parent = parent;
+
+   if (parent->frame)
+     {
+        layer = e_client_layer_get(parent);
+        if (layer > E_LAYER_BOTTOM)
+          e_client_layer_set(ec, layer);
+     }
+
+   if (parent->comp_data)
+     {
+        /* append this client to the parents subsurface list */
+        parent->comp_data->sub.list_pending =
+           eina_list_append(parent->comp_data->sub.list_pending, ec);
+        parent->comp_data->sub.list_changed = EINA_TRUE;
+     }
+}
+
+EINTERN void
+e_comp_wl_client_subsurface_parent_unset(E_Client *ec)
+{
+   E_Comp_Wl_Subsurf_Data *sub = ec->comp_data->sub.data;
+   E_Client *parent = sub->parent;
+
+   parent->comp_data->sub.list =
+      eina_list_remove(parent->comp_data->sub.list, ec);
+   parent->comp_data->sub.list_pending =
+      eina_list_remove(parent->comp_data->sub.list_pending, ec);
+   parent->comp_data->sub.below_list =
+      eina_list_remove(parent->comp_data->sub.below_list, ec);
+   parent->comp_data->sub.below_list_pending =
+      eina_list_remove(parent->comp_data->sub.below_list_pending, ec);
+
+   sub->parent = NULL;
+}
+
+EINTERN void
+e_comp_wl_client_subsurface_init(E_Client *ec, struct wl_resource *subsurface_resource, E_Comp_Wl_Subsurf_Data *sub, E_Client *parent, E_Client *offscreen_parent)
+{
+   sub->resource = subsurface_resource;
+   sub->cached_buffer_ref.buffer = NULL;
+   sub->synchronized = EINA_TRUE;
+   sub->parent = parent;
+   sub->remote_surface.offscreen_parent = offscreen_parent;
+   if (offscreen_parent)
+     ELOGF("SUBSURFACE", "         |offscreen_parent:%p", ec, offscreen_parent);
+
+   _e_comp_wl_surface_state_init(&sub->cached, ec->w, ec->h);
+
+   _e_comp_wl_client_subsurface_set(ec, sub);
+   _e_comp_wl_client_subsurface_parent_set(ec, parent);
+
+   e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_CREATE, ec);
+}
+
+EINTERN void
+e_comp_wl_client_subsurface_finish(E_Client *ec)
+{
+   E_Comp_Wl_Subsurf_Data *sub = ec->comp_data->sub.data;
+
+   if (sub->parent)
+     e_comp_wl_client_subsurface_parent_unset(ec);
+
+   e_comp_wl_surface_state_finish(&sub->cached);
+   e_comp_wl_buffer_reference(&sub->cached_buffer_ref, NULL);
+
+   ec->comp_data->sub.data = NULL;
+}
+
+EINTERN void
+e_comp_wl_client_evas_init(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   _e_comp_wl_client_evas_init(ec);
+}
+
+EINTERN void
+e_comp_wl_client_evas_deinit(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   _e_comp_wl_client_evas_deinit(ec);
+}
+
+EINTERN void
+e_comp_wl_focus_check(void)
+{
+   _e_comp_wl_focus_check();
+}
+
+EINTERN Eina_Bool
+e_comp_wl_client_subsurface_cyclic_reference_check(E_Client *ec, E_Client *parent)
+{
+   while (parent)
+     {
+        if (ec == parent)
+          return EINA_TRUE;
+
+        if ((parent->comp_data) && (parent->comp_data->sub.data))
+          parent = parent->comp_data->sub.data->parent;
+        else
+          break;
+     }
+
+   return EINA_FALSE;
+}
index 98328ca..eca86cc 100644 (file)
@@ -595,7 +595,6 @@ EINTERN void e_comp_wl_surface_destroy(struct wl_resource *resource);
 EINTERN void e_comp_wl_surface_attach(E_Client *ec, E_Comp_Wl_Buffer *buffer);
 EINTERN Eina_Bool e_comp_wl_surface_commit(E_Client *ec);
 E_API void e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer);
-EINTERN E_Comp_Wl_Buffer *e_comp_wl_buffer_get(struct wl_resource *resource, E_Client *ec);
 
 EINTERN Eina_Bool e_comp_wl_output_init(const char *id, const char *make, const char *model, int x, int y, int w, int h, int pw, int ph, unsigned int refresh, unsigned int subpixel, unsigned int transform);
 EINTERN void e_comp_wl_output_remove(const char *id);
@@ -676,5 +675,8 @@ EINTERN struct wl_resource *e_comp_wl_client_surface_get(E_Client *ec);
 EINTERN void e_comp_wl_client_surface_set(E_Client *ec, struct wl_resource *surface);
 
 EINTERN void    e_comp_wl_display_flush();
+
+EINTERN E_Client *e_comp_wl_util_client_from_surface_resource(struct wl_resource *surface_resource);
+
 # endif
 #endif
index 2e1ab86..2f13888 100644 (file)
@@ -1,11 +1,20 @@
 #include "e_comp_wl_private.h"
 
+typedef struct _E_Buffer E_Buffer;
+
+struct _E_Buffer
+{
+   E_Comp_Wl_Buffer base;
+   struct ds_buffer *ds_buffer;
+};
+
 static void _e_comp_wl_buffer_ref(E_Comp_Wl_Buffer *buffer);
 static void _e_comp_wl_buffer_unref(E_Comp_Wl_Buffer *buffer);
 static void _e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data);
-static void _e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data);
-static Eina_Bool _e_comp_wl_buffer_native_type_get(E_Comp_Wl_Buffer *buffer, struct wl_resource *resource, E_Client *ec);
-static Eina_Bool _e_comp_wl_buffer_tbm_type_get(E_Comp_Wl_Buffer *buffer, struct wl_resource *resource, E_Client *ec);
+
+static E_Buffer *_e_buffer_create(struct ds_buffer *ds_buffer, E_Client *ec);
+static E_Buffer *_e_buffer_from_base(E_Comp_Wl_Buffer *base);
+static void _e_buffer_cb_resource_destroy(struct wl_listener *listener, void *data);
 
 E_API void
 e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
@@ -31,143 +40,90 @@ e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
 }
 
 /**
- * Get the buffer for a given resource.
+ * Get the buffer for a given ds_buffer.
  *
- * Retrieves the Wayland SHM buffer for the resource and
+ * Retrieves the Wayland SHM buffer for the ds_buffer and
  * uses it to create a new E_Comp_Wl_Buffer object. This
  * buffer will be freed when the resource is destroyed.
  *
- * @param resource that owns the desired buffer
+ * @param ds_buffer that owns the desired buffer
  * @returns a new E_Comp_Wl_Buffer object
  */
 EINTERN E_Comp_Wl_Buffer *
-e_comp_wl_buffer_get(struct wl_resource *resource, E_Client *ec)
+e_comp_wl_buffer_get(struct ds_buffer *ds_buffer, E_Client *ec)
 {
-   E_Comp_Wl_Buffer *buffer = NULL;
+   E_Buffer *buffer;
    struct wl_listener *listener;
-   struct wl_shm_buffer *shmbuff;
-   E_Single_Pixel_Buffer *single_pixel_buffer;
-   Eina_Bool res;
+   struct wl_resource *buffer_resource;
 
-   listener =
-     wl_resource_get_destroy_listener(resource, _e_comp_wl_buffer_cb_destroy);
+   buffer_resource = ds_buffer_get_resource(ds_buffer);
+   listener = wl_resource_get_destroy_listener(buffer_resource, _e_buffer_cb_resource_destroy);
    if (listener)
      {
-        buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
-        goto update;
+        buffer = wl_container_of(listener, buffer, base.destroy_listener);
+        goto done;
      }
 
-   if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL;
-
-   shmbuff = wl_shm_buffer_get(resource);
-   if (shmbuff)
+   buffer = _e_buffer_create(ds_buffer, ec);
+   if (!buffer)
      {
-        buffer->type = E_COMP_WL_BUFFER_TYPE_SHM;
-        buffer->w = wl_shm_buffer_get_width(shmbuff);
-        buffer->h = wl_shm_buffer_get_height(shmbuff);
-        buffer->format = wl_shm_buffer_get_format(shmbuff);
-        buffer->shm_buffer = shmbuff;
+        ERR("Failed to create E_Comp_Wl_Buffer");
+        return NULL;
      }
 
-   if (!buffer->type)
-     {
-        single_pixel_buffer = e_single_pixel_buffer_manager_buffer_get(resource);
-        if (single_pixel_buffer)
-          {
-             buffer->type = E_COMP_WL_BUFFER_TYPE_SINGLE_PIXEL;
-             buffer->w = 1;
-             buffer->h = 1;
-             buffer->format = WL_SHM_FORMAT_ARGB8888;
-             buffer->single_pixel_buffer = single_pixel_buffer;
-          }
-     }
+done:
+   if (buffer->base.tbm_surface)
+     buffer->base.transform = wayland_tbm_server_buffer_get_buffer_transform(NULL, buffer->base.resource);
 
-   if (!buffer->type)
-     {
-        /* TODO: This option is temporarily. It will be removed later. */
-        /* prefer to use native buffer(wl_buffer) */
-        if (e_comp->use_native_type_buffer)
-          {
-             if (e_comp->gl)
-               {
-                  res = _e_comp_wl_buffer_native_type_get(buffer, resource, ec);
-                  EINA_SAFETY_ON_FALSE_GOTO(res, err);
-               }
-             else
-               {
-                  res = _e_comp_wl_buffer_tbm_type_get(buffer, resource, ec);
-                  EINA_SAFETY_ON_FALSE_GOTO(res, err);
-               }
-          }
-        else
-          {
-             res = _e_comp_wl_buffer_tbm_type_get(buffer, resource, ec);
-             if (!res && e_comp->gl)
-               res = _e_comp_wl_buffer_native_type_get(buffer,resource, ec);
-
-             EINA_SAFETY_ON_FALSE_GOTO(res, err);
-          }
-     }
+   return &buffer->base;
+}
 
-   buffer->resource = resource;
-   wl_signal_init(&buffer->destroy_signal);
-   buffer->destroy_listener.notify = _e_comp_wl_buffer_cb_destroy;
-   wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
+static void
+_e_comp_wl_buffer_ref(E_Comp_Wl_Buffer *base)
+{
+   E_Buffer *buffer;
 
-   if (ec)
+   base->busy++;
+   if (base->busy == 1)
      {
-        buffer->debug_info.owner_ptr = (void *)ec;
-        buffer->debug_info.owner_name = eina_stringshare_add(ec->icccm.name?:"");
+        buffer = _e_buffer_from_base(base);
+        if (buffer)
+          ds_buffer_lock(buffer->ds_buffer);
      }
-
-   DBG("Wl Buffer Create: b %p owner '%s'(%p)",
-       buffer, buffer->debug_info.owner_name, buffer->debug_info.owner_ptr);
-
-update:
-   if (buffer->tbm_surface)
-     buffer->transform = wayland_tbm_server_buffer_get_buffer_transform(NULL, resource);
-
-   return buffer;
-
-err:
-   ERR("Invalid resource:%u", wl_resource_get_id(resource));
-   E_FREE(buffer);
-   return NULL;
 }
 
 static void
-_e_comp_wl_buffer_ref(E_Comp_Wl_Buffer *buffer)
+_e_comp_wl_buffer_unref(E_Comp_Wl_Buffer *base)
 {
-   buffer->busy++;
-}
+   E_Buffer *buffer;
 
-static void
-_e_comp_wl_buffer_unref(E_Comp_Wl_Buffer *buffer)
-{
-   buffer->busy--;
-   if (buffer->busy != 0)
+   base->busy--;
+   if (base->busy != 0)
      return;
 
-   if (buffer->buffer_release)
+   if (base->buffer_release)
      {
-        e_explicit_sync_buffer_release_destroy(buffer->buffer_release);
-        buffer->buffer_release = NULL;
+        e_explicit_sync_buffer_release_destroy(base->buffer_release);
+        base->buffer_release = NULL;
      }
 
-   if (buffer->resource)
+   if (base->resource)
      {
-        if (!wl_resource_get_client(buffer->resource)) return;
+        buffer = _e_buffer_from_base(base);
+        if (buffer)
+          ds_buffer_unlock(buffer->ds_buffer);
+        else
+          wl_buffer_send_release(base->resource);
 
-        wl_buffer_send_release(buffer->resource);
 #ifdef HAVE_WAYLAND_TBM
         wayland_tbm_server_increase_buffer_sync_timeline(e_comp_wl->tbm.server,
-                                                         buffer->resource, 1);
+                                                         base->resource, 1);
 #endif
      }
    else
      {
-        if (buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)
-          e_comp_wl_tbm_buffer_destroy(buffer);
+        if (base->type == E_COMP_WL_BUFFER_TYPE_TBM)
+          e_comp_wl_tbm_buffer_destroy(base);
      }
 }
 
@@ -175,77 +131,57 @@ static void
 _e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data)
 {
    E_Comp_Wl_Buffer_Ref *ref;
+   E_Buffer *buffer;
 
    ref = container_of(listener, E_Comp_Wl_Buffer_Ref, destroy_listener);
-   wl_list_remove(&ref->destroy_listener.link);
-   ref->buffer = NULL;
-}
-
-static void
-_e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
-{
-   E_Comp_Wl_Buffer *buffer;
-
-   buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
-
-   DBG("Wl Buffer Destroy: b %p owner '%s'(%p)",
-       buffer, buffer->debug_info.owner_name, buffer->debug_info.owner_ptr);
-
-   /* remove debug info */
-   eina_stringshare_del(buffer->debug_info.owner_name);
-
-   if (buffer->tbm_surface) tbm_surface_internal_unref(buffer->tbm_surface);
-
-   if (buffer->buffer_release)
-     e_explicit_sync_buffer_release_destroy(buffer->buffer_release);
 
-   wl_signal_emit(&buffer->destroy_signal, buffer);
-
-   if (buffer->destroy_listener.notify)
+   if (--ref->buffer->busy == 0)
      {
-        wl_list_remove(&buffer->destroy_listener.link);
-        buffer->destroy_listener.notify = NULL;
+        buffer = _e_buffer_from_base(ref->buffer);
+        if (buffer)
+          ds_buffer_unlock(buffer->ds_buffer);
      }
 
-   free(buffer);
+   wl_list_remove(&ref->destroy_listener.link);
+   ref->buffer = NULL;
 }
 
 static Eina_Bool
-_e_comp_wl_buffer_native_type_get(E_Comp_Wl_Buffer *buffer, struct wl_resource *resource,
+_e_comp_wl_buffer_native_type_get(E_Comp_Wl_Buffer *base, struct wl_resource *resource,
                                   E_Client *ec)
 {
    Eina_Bool res;
 
-   if (!buffer || !resource || !ec) return EINA_FALSE;
+   if (!base || !resource || !ec) return EINA_FALSE;
 
-   buffer->type = E_COMP_WL_BUFFER_TYPE_NATIVE;
+   base->type = E_COMP_WL_BUFFER_TYPE_NATIVE;
    res = e_comp_wl->evas_gl->glapi->evasglQueryWaylandBuffer(e_comp_wl->evas_gl->gl,
                                                              resource,
                                                              EVAS_GL_WIDTH,
-                                                             &buffer->w);
+                                                             &base->w);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, EINA_FALSE);
    res = e_comp_wl->evas_gl->glapi->evasglQueryWaylandBuffer(e_comp_wl->evas_gl->gl,
                                                              resource,
                                                              EVAS_GL_HEIGHT,
-                                                             &buffer->h);
+                                                             &base->h);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, EINA_FALSE);
    res = e_comp_wl->evas_gl->glapi->evasglQueryWaylandBuffer(e_comp_wl->evas_gl->gl,
                                                              resource,
                                                              EVAS_GL_TEXTURE_FORMAT,
-                                                             &buffer->format);
+                                                             &base->format);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, EINA_FALSE);
 
    return EINA_TRUE;
 }
 
 static Eina_Bool
-_e_comp_wl_buffer_tbm_type_get(E_Comp_Wl_Buffer *buffer, struct wl_resource *resource,
+_e_comp_wl_buffer_tbm_type_get(E_Comp_Wl_Buffer *base, struct wl_resource *resource,
                                E_Client *ec)
 {
    tbm_surface_h tsurface;
    struct gbm_bo *gbo;
 
-   if (!buffer || !resource || !ec) return EINA_FALSE;
+   if (!base || !resource || !ec) return EINA_FALSE;
 
    tsurface = wayland_tbm_server_get_surface(e_comp_wl->tbm.server, resource);
    if (tsurface)
@@ -277,27 +213,164 @@ _e_comp_wl_buffer_tbm_type_get(E_Comp_Wl_Buffer *buffer, struct wl_resource *res
 
    if ((ec) && (ec->comp_data->video_client))
      {
-        buffer->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
-        buffer->w = buffer->h = 1;
-        buffer->format = 0;
+        base->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
+        base->w = base->h = 1;
+        base->format = 0;
      }
    else if ((ec) && (e_client_video_hw_composition_check(ec)))
      {
-        buffer->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
-        buffer->w = tbm_surface_get_width(tsurface);
-        buffer->h = tbm_surface_get_height(tsurface);
-        buffer->format = tbm_surface_get_format(tsurface);
+        base->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
+        base->w = tbm_surface_get_width(tsurface);
+        base->h = tbm_surface_get_height(tsurface);
+        base->format = tbm_surface_get_format(tsurface);
      }
    else
      {
-        buffer->type = E_COMP_WL_BUFFER_TYPE_TBM;
-        buffer->w = tbm_surface_get_width(tsurface);
-        buffer->h = tbm_surface_get_height(tsurface);
-        buffer->format = tbm_surface_get_format(tsurface);
+        base->type = E_COMP_WL_BUFFER_TYPE_TBM;
+        base->w = tbm_surface_get_width(tsurface);
+        base->h = tbm_surface_get_height(tsurface);
+        base->format = tbm_surface_get_format(tsurface);
      }
 
-   buffer->tbm_surface = tsurface;
+   base->tbm_surface = tsurface;
 
    return EINA_TRUE;
 }
 
+static Eina_Bool
+_e_comp_wl_buffer_init(E_Comp_Wl_Buffer *base, struct wl_resource *resource, E_Client *ec)
+{
+   struct wl_shm_buffer *shmbuff;
+   E_Single_Pixel_Buffer *single_pixel_buffer;
+   Eina_Bool res;
+
+   shmbuff = wl_shm_buffer_get(resource);
+   if (shmbuff)
+     {
+        base->type = E_COMP_WL_BUFFER_TYPE_SHM;
+        base->w = wl_shm_buffer_get_width(shmbuff);
+        base->h = wl_shm_buffer_get_height(shmbuff);
+        base->format = wl_shm_buffer_get_format(shmbuff);
+        base->shm_buffer = shmbuff;
+     }
+
+   if (!base->type)
+     {
+        single_pixel_buffer = e_single_pixel_buffer_manager_buffer_get(resource);
+        if (single_pixel_buffer)
+          {
+             base->type = E_COMP_WL_BUFFER_TYPE_SINGLE_PIXEL;
+             base->w = 1;
+             base->h = 1;
+             base->format = WL_SHM_FORMAT_ARGB8888;
+             base->single_pixel_buffer = single_pixel_buffer;
+          }
+     }
+
+   if (!base->type)
+     {
+        /* TODO: This option is temporarily. It will be removed later. */
+        /* prefer to use native base(wl_buffer) */
+        if (e_comp->use_native_type_buffer)
+          {
+             if (e_comp->gl)
+               {
+                  res = _e_comp_wl_buffer_native_type_get(base, resource, ec);
+                  EINA_SAFETY_ON_FALSE_GOTO(res, err);
+               }
+             else
+               {
+                  res = _e_comp_wl_buffer_tbm_type_get(base, resource, ec);
+                  EINA_SAFETY_ON_FALSE_GOTO(res, err);
+               }
+          }
+        else
+          {
+             res = _e_comp_wl_buffer_tbm_type_get(base, resource, ec);
+             if (!res && e_comp->gl)
+               res = _e_comp_wl_buffer_native_type_get(base,resource, ec);
+
+             EINA_SAFETY_ON_FALSE_GOTO(res, err);
+          }
+     }
+
+   base->resource = resource;
+   wl_signal_init(&base->destroy_signal);
+
+   if (ec)
+     {
+        base->debug_info.owner_ptr = (void *)ec;
+        base->debug_info.owner_name = eina_stringshare_add(ec->icccm.name?:"");
+     }
+
+   DBG("Wl Buffer Create: b %p owner '%s'(%p)",
+       base, base->debug_info.owner_name, base->debug_info.owner_ptr);
+
+   return EINA_TRUE;
+
+err:
+   ERR("Invalid resource:%u", wl_resource_get_id(resource));
+   return EINA_FALSE;
+}
+
+static void
+_e_comp_wl_buffer_finish(E_Comp_Wl_Buffer *base)
+{
+   DBG("Wl Buffer Destroy: b %p owner '%s'(%p)",
+       base, base->debug_info.owner_name, base->debug_info.owner_ptr);
+
+   /* remove debug info */
+   eina_stringshare_del(base->debug_info.owner_name);
+
+   if (base->tbm_surface) tbm_surface_internal_unref(base->tbm_surface);
+
+   if (base->buffer_release)
+     e_explicit_sync_buffer_release_destroy(base->buffer_release);
+
+   wl_signal_emit(&base->destroy_signal, base);
+}
+
+static E_Buffer *
+_e_buffer_create(struct ds_buffer *ds_buffer, E_Client *ec)
+{
+   E_Buffer *buffer;
+   struct wl_resource *buffer_resource;
+
+   buffer = E_NEW(E_Buffer, 1);
+   if (!buffer)
+     return NULL;
+
+   buffer->ds_buffer = ds_buffer;
+
+   buffer_resource = ds_buffer_get_resource(ds_buffer);
+   if (!_e_comp_wl_buffer_init(&buffer->base, buffer_resource, ec))
+     {
+        free(buffer);
+        return NULL;
+     }
+
+   buffer->base.destroy_listener.notify = _e_buffer_cb_resource_destroy;
+   wl_resource_add_destroy_listener(buffer_resource, &buffer->base.destroy_listener);
+
+   return buffer;
+}
+
+static E_Buffer *
+_e_buffer_from_base(E_Comp_Wl_Buffer *base)
+{
+   if (base->destroy_listener.notify == _e_buffer_cb_resource_destroy)
+     return (E_Buffer *)base;
+   return NULL;
+}
+
+static void
+_e_buffer_cb_resource_destroy(struct wl_listener *listener, void *data)
+{
+   E_Buffer *buffer;
+
+   buffer = wl_container_of(listener, buffer, base.destroy_listener);
+
+   _e_comp_wl_buffer_finish(&buffer->base);
+   wl_list_remove(&buffer->base.destroy_listener.link);
+   free(buffer);
+}
index 2b5724f..fda47a9 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef E_COMP_WL_BUFFER_H
 #define E_COMP_WL_BUFFER_H
 
-EINTERN E_Comp_Wl_Buffer *e_comp_wl_buffer_get(struct wl_resource *resource, E_Client *ec);
+#include <libds/types/ds_buffer.h>
+
+EINTERN E_Comp_Wl_Buffer *e_comp_wl_buffer_get(struct ds_buffer *ds_buffer, E_Client *ec);
 
 #endif
index f2bdf58..cd8c693 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "e.h"
 #include "e_comp_wl_buffer.h"
+#include "e_compositor.h"
 
 struct _E_Comp_Wl_Evas_Gl
 {
@@ -16,4 +17,25 @@ struct _E_Comp_Wl_Evas_Gl
    Evas_GL_API *glapi;
 };
 
+EINTERN void e_comp_wl_focus_check(void);
+
+EINTERN void e_comp_wl_client_evas_init(E_Client *ec);
+EINTERN void e_comp_wl_client_evas_deinit(E_Client *ec);
+
+EINTERN void e_comp_wl_client_surface_init(E_Client *ec);
+EINTERN void e_comp_wl_client_surface_finish(E_Client *ec);
+EINTERN void e_comp_wl_client_surface_pending_buffer_set(E_Client *ec, E_Comp_Wl_Buffer *buffer, int32_t sx, int32_t sy);
+EINTERN void e_comp_wl_client_surface_pending_opaque_region_set(E_Client *ec, Eina_Tiler *region);
+EINTERN void e_comp_wl_client_surface_pending_input_region_set(E_Client *ec, Eina_Tiler *region);
+EINTERN void e_comp_wl_client_surface_pending_frame_callback_add(E_Client *ec, struct wl_resource *callback_resource);
+EINTERN void e_comp_wl_client_surface_frame_callback_remove(E_Client *ec, struct wl_resource *callback_resource);
+EINTERN void e_comp_wl_client_surface_pending_commit(E_Client *ec);
+
+EINTERN void e_comp_wl_client_subsurface_init(E_Client *ec, struct wl_resource *subsurface_resource, E_Comp_Wl_Subsurf_Data *sub, E_Client *parent, E_Client *offscreen_parent);
+EINTERN void e_comp_wl_client_subsurface_finish(E_Client *ec);
+EINTERN void e_comp_wl_client_subsurface_parent_unset(E_Client *ec);
+EINTERN Eina_Bool e_comp_wl_client_subsurface_cyclic_reference_check(E_Client *ec, E_Client *parent);
+EINTERN void e_comp_wl_client_subsurface_commit_to_cache(E_Client *ec);
+EINTERN void e_comp_wl_client_subsurface_commit_from_cache(E_Client *ec);
+
 #endif
index 166f68c..b37f8ab 100644 (file)
@@ -2,49 +2,27 @@
 
 #include <tizen-extension-server-protocol.h>
 
-typedef struct _E_Subsurface     E_Subsurface;
-
-struct _E_Subsurface
-{
-   /* NOTE
-    * DO NOT move 'base' from first field.
-    * The address of it is assigned to ec->comp_data->sub.data and be used
-    * to access not only E_Comp_Wl_Subsurf_Data, but also E_Subsurface. */
-   E_Comp_Wl_Subsurf_Data base;
-
-   E_Client *ec;
-
-   struct
-     {
-        E_Comp_Wl_Hook *ec_del;
-        E_Comp_Wl_Hook *parent_del;
-     } comp_hook;
-};
-
-static struct wl_global *global = NULL;
 static Eina_List *hooks = NULL;
 static Eina_List *handlers = NULL;
 
-static const char *e_comp_wl_subsurface_role_name = "wl_subsurface";
-
 static E_Comp_Wl_Subsurf_Data *_e_comp_wl_subsurface_data_get(E_Client *ec);
 
-static Eina_Bool  _e_comp_wl_subsurface_circular_reference_check(E_Client *ec, E_Client *parent);
-static void       _e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized);
-static Eina_Bool  _e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata);
-static void       _e_comp_wl_subsurface_synchronized_commit(E_Client *ec);
-static void       _e_comp_wl_subsurface_remove_from_parent(E_Client *parent, E_Client *subc);
-static void       _e_comp_wl_subsurface_child_remove(E_Comp_Wl_Client_Data *parent_cdata, E_Client *child);
-static void       _e_comp_wl_subsurface_place_above(E_Client *parent, E_Client *subc, E_Client *above);
-static void       _e_comp_wl_subsurface_place_below(E_Client *parent, E_Client *subc, E_Client *below);
+static void       _e_comp_wl_subsurface_commit_to_cache(E_Client *ec);
+static void       _e_comp_wl_subsurface_commit_from_cache(E_Client *ec);
 static void       _e_comp_wl_subsurface_stack_update(E_Client *ec);
 static void       _e_comp_wl_subsurface_below_obj_destroy(E_Client *ec);
 
-static E_Subsurface  *_e_comp_wl_subsurface_create(struct wl_resource *resource, E_Client *ec, E_Client *epc, E_Client *offscreen_parent);
-static void           _e_comp_wl_subsurface_destroy(E_Subsurface *sub);
-static void           _e_comp_wl_subsurface_ec_link(E_Subsurface *sub, E_Client *ec);
-static void           _e_comp_wl_subsurface_parent_link(E_Subsurface *sub, E_Client *parent);
-static void           _e_comp_wl_subsurface_parent_unlink(E_Subsurface *sub);
+EINTERN void
+e_comp_wl_client_subsurface_commit_to_cache(E_Client *ec)
+{
+   _e_comp_wl_subsurface_commit_to_cache(ec);
+}
+
+EINTERN void
+e_comp_wl_client_subsurface_commit_from_cache(E_Client *ec)
+{
+   _e_comp_wl_subsurface_commit_from_cache(ec);
+}
 
 static void
 _e_comp_wl_subsurface_restack_bg_rectangle(E_Client *ec)
@@ -570,12 +548,6 @@ _e_comp_wl_subsurface_commit_to_cache(E_Client *ec)
                               l);
      }
 
-   e_presentation_time_container_feedback_discard(&sdata->cached.presentation_container);
-   e_presentation_time_container_feedback_merge(&sdata->cached.presentation_container,
-                                                &cdata->pending.presentation_container);
-
-   e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_COMMIT_TO_CACHE, ec);
-
    sdata->cached.has_data = EINA_TRUE;
 }
 
@@ -611,257 +583,6 @@ _e_comp_wl_subsurface_commit_from_cache(E_Client *ec)
 }
 
 static void
-_e_comp_wl_subsurface_synchronized_commit(E_Client *ec)
-{
-   E_Comp_Wl_Subsurf_Data *sdata;
-   E_Client *subc;
-   Eina_List *l;
-
-   sdata = _e_comp_wl_subsurface_data_get(ec);
-   EINA_SAFETY_ON_NULL_RETURN(sdata);
-
-   if (sdata->cached.has_data)
-     _e_comp_wl_subsurface_commit_from_cache(ec);
-
-   e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT, ec);
-
-   EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
-     {
-        if (ec != subc)
-          _e_comp_wl_subsurface_parent_commit(subc, EINA_TRUE);
-     }
-   EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
-     {
-        if (ec != subc)
-          _e_comp_wl_subsurface_parent_commit(subc, EINA_TRUE);
-     }
-}
-
-static void
-_e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized)
-{
-   E_Client *parent;
-   E_Comp_Wl_Subsurf_Data *sdata;
-
-   if (!ec || e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return;
-
-   sdata = _e_comp_wl_subsurface_data_get(ec);
-   EINA_SAFETY_ON_NULL_RETURN(sdata);
-
-   if (!(parent = sdata->parent)) return;
-
-   if (sdata->position.set)
-     {
-        evas_object_move(ec->frame, parent->x + sdata->position.x,
-                         parent->y + sdata->position.y);
-        sdata->position.set = EINA_FALSE;
-     }
-
-   if ((parent_synchronized) || (sdata->synchronized))
-     _e_comp_wl_subsurface_synchronized_commit(ec);
-}
-
-static void
-_e_comp_wl_subsurface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
-   wl_resource_destroy(resource);
-}
-
-static void
-_e_comp_wl_subsurface_cb_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y)
-{
-   E_Subsurface *sub;
-
-   DBG("Subsurface Cb Position Set: %d", wl_resource_get_id(resource));
-
-   sub = wl_resource_get_user_data(resource);
-   if (!sub)
-     return;
-
-   sub->base.position.x = x;
-   sub->base.position.y = y;
-   sub->base.position.set = EINA_TRUE;
-}
-
-static Eina_Bool
-_subsurface_sibling_check(E_Client *ec1, E_Client *ec2)
-{
-   E_Client *parent, *sibling;
-   Eina_List *l;
-
-   parent = ec1->comp_data->sub.data->parent;
-
-   if (parent == ec2)
-     return EINA_TRUE;
-
-   EINA_LIST_FOREACH(parent->comp_data->sub.list_pending, l, sibling)
-     {
-        if ((sibling != ec1) && (sibling == ec2))
-          return EINA_TRUE;
-     }
-
-   EINA_LIST_FOREACH(parent->comp_data->sub.below_list_pending, l, sibling)
-     {
-        if ((sibling != ec1) && (sibling == ec2))
-          return EINA_TRUE;
-     }
-
-   return EINA_FALSE;
-}
-
-static void
-_e_comp_wl_subsurface_cb_place_above(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *sibling_resource)
-{
-   E_Subsurface *sub;
-   E_Client *ecs;
-   E_Client *parent;
-
-   DBG("Subsurface Cb Place Above: %d", wl_resource_get_id(resource));
-
-   sub = wl_resource_get_user_data(resource);
-   if (!sub)
-     return;
-
-   if (!(parent = sub->base.parent)) return;
-   if (e_object_is_del(E_OBJECT(parent)) || !parent->comp_data) return;
-
-   /* try to get the client from the sibling resource */
-   if (!(ecs = e_client_from_surface_resource(sibling_resource))) return;
-
-   if (!_subsurface_sibling_check(sub->ec, ecs))
-     {
-        struct wl_resource *surface = e_comp_wl_client_surface_get(ecs);
-        wl_resource_post_error(sub->base.resource,
-                               WL_SUBSURFACE_ERROR_BAD_SURFACE,
-                               "%s: wl_surface@%d is not a parent or sibling",
-                               "place_above", wl_resource_get_id(surface));
-        return;
-     }
-
-   _e_comp_wl_subsurface_place_above(parent, sub->ec, ecs);
-}
-
-static void
-_e_comp_wl_subsurface_cb_place_below(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *sibling_resource)
-{
-   E_Subsurface *sub;
-   E_Client *ecs;
-   E_Client *parent;
-
-   DBG("Subsurface Cb Place Below: %d", wl_resource_get_id(resource));
-
-   sub = wl_resource_get_user_data(resource);
-   if (!sub)
-     return;
-
-   if (!(parent = sub->base.parent)) return;
-   if (e_object_is_del(E_OBJECT(parent)) || !parent->comp_data) return;
-
-   /* try to get the client from the sibling resource */
-   if (!(ecs = e_client_from_surface_resource(sibling_resource))) return;
-
-   if (!_subsurface_sibling_check(sub->ec, ecs))
-     {
-        struct wl_resource *surface = e_comp_wl_client_surface_get(ecs);
-        wl_resource_post_error(sub->base.resource,
-                               WL_SUBSURFACE_ERROR_BAD_SURFACE,
-                               "%s: wl_surface@%d is not a parent or sibling",
-                               "place_below", wl_resource_get_id(surface));
-        return;
-     }
-
-   _e_comp_wl_subsurface_place_below(parent, sub->ec, ecs);
-}
-
-static void
-_e_comp_wl_subsurface_cb_sync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
-   E_Subsurface *sub;
-
-   DBG("Subsurface Cb Sync Set: %d", wl_resource_get_id(resource));
-
-   sub = wl_resource_get_user_data(resource);
-   if (!sub)
-     return;
-
-   sub->base.synchronized = EINA_TRUE;
-}
-
-static void
-_e_comp_wl_subsurface_cb_desync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
-   E_Subsurface *sub;
-
-   DBG("Subsurface Cb Desync Set: %d", wl_resource_get_id(resource));
-
-   sub = wl_resource_get_user_data(resource);
-   if (!sub)
-     return;
-
-   if (sub->base.synchronized)
-     {
-        sub->base.synchronized = EINA_FALSE;
-
-        if (!_e_comp_wl_subsurface_synchronized_get(&sub->base))
-          _e_comp_wl_subsurface_synchronized_commit(sub->ec);
-     }
-}
-
-static const struct wl_subsurface_interface _e_subsurface_interface =
-{
-   _e_comp_wl_subsurface_cb_destroy,
-   _e_comp_wl_subsurface_cb_position_set,
-   _e_comp_wl_subsurface_cb_place_above,
-   _e_comp_wl_subsurface_cb_place_below,
-   _e_comp_wl_subsurface_cb_sync_set,
-   _e_comp_wl_subsurface_cb_desync_set
-};
-
-static void
-_e_comp_wl_subcompositor_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
-   wl_resource_destroy(resource);
-}
-
-static void
-_e_comp_wl_subcompositor_cb_subsurface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface, struct wl_resource *parent_surface)
-{
-   Eina_Bool res;
-
-   res = e_comp_wl_subsurface_add(client, resource, id,
-                                  surface, parent_surface);
-   if (!res)
-     {
-        ERR("Failed to add subsurface for surface %d",
-            wl_resource_get_id(surface));
-     }
-}
-
-static const struct wl_subcompositor_interface _e_subcomp_interface =
-{
-   _e_comp_wl_subcompositor_cb_destroy,
-   _e_comp_wl_subcompositor_cb_subsurface_get
-};
-
-static void
-_e_comp_wl_subcompositor_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
-{
-   struct wl_resource *res;
-
-   res = wl_resource_create(client, &wl_subcompositor_interface, version, id);
-   if (!res)
-     {
-        ERR("Could not create subcompositor resource: %m");
-        wl_client_post_no_memory(client);
-        return;
-     }
-
-   wl_resource_set_implementation(res, &_e_subcomp_interface, NULL, NULL);
-
-   /* TODO: add handlers for client iconify/uniconify */
-}
-
-static void
 _e_comp_wl_subsurface_cb_ec_iconify(void *data EINA_UNUSED, E_Client *ec)
 {
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -881,52 +602,6 @@ _e_comp_wl_subsurface_cb_ec_uniconify(void *data EINA_UNUSED, E_Client *ec)
 }
 
 static void
-_e_comp_wl_subsurface_cb_resource_destroy(struct wl_resource *resource)
-{
-   E_Subsurface *sub;
-
-   sub = wl_resource_get_user_data(resource);
-   if (!sub)
-     return;
-
-   _e_comp_wl_subsurface_destroy(sub);
-}
-
-static Eina_Bool
-_e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata)
-{
-   while (sdata)
-     {
-        if (sdata->synchronized) return EINA_TRUE;
-        if (!sdata->parent) return EINA_FALSE;
-
-        if (!sdata->parent->comp_data) return EINA_FALSE;
-        if (e_object_is_del(E_OBJECT(sdata->parent))) return EINA_FALSE;
-
-        sdata = _e_comp_wl_subsurface_data_get(sdata->parent);
-     }
-
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_comp_wl_subsurface_circular_reference_check(E_Client *ec, E_Client *parent)
-{
-   while (parent)
-     {
-        if (ec == parent)
-          return EINA_TRUE;
-
-        if ((parent->comp_data) && (parent->comp_data->sub.data))
-          parent = parent->comp_data->sub.data->parent;
-        else
-          break;
-     }
-
-   return EINA_FALSE;
-}
-
-static void
 _e_comp_wl_subsurface_cb_comp_object_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
    E_Client *ec, *above, *below;
@@ -982,21 +657,8 @@ end:
 }
 
 EINTERN Eina_Bool
-e_comp_wl_subsurfaces_init(E_Comp_Wl_Data *wl_comp)
+e_comp_wl_subsurfaces_init(void)
 {
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wl_comp, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wl_comp->wl.disp, EINA_FALSE);
-
-   global = wl_global_create(wl_comp->wl.disp,
-                             &wl_subcompositor_interface,
-                             1, NULL,
-                             _e_comp_wl_subcompositor_cb_bind);
-   if (!global)
-     {
-        ERR("Could not add subcompositor to wayland globals: %m");
-        return EINA_FALSE;
-     }
-
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_ICONIFY,   _e_comp_wl_subsurface_cb_ec_iconify,     NULL);
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_UNICONIFY, _e_comp_wl_subsurface_cb_ec_uniconify,   NULL);
 
@@ -1008,101 +670,11 @@ e_comp_wl_subsurfaces_init(E_Comp_Wl_Data *wl_comp)
 EINTERN void
 e_comp_wl_subsurfaces_shutdown(void)
 {
-   E_FREE_FUNC(global, wl_global_destroy);
    E_FREE_LIST(hooks, e_client_hook_del);
    E_FREE_LIST(handlers, ecore_event_handler_del);
 }
 
 EINTERN Eina_Bool
-e_comp_wl_subsurface_add(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface, struct wl_resource *parent_surface)
-{
-   E_Subsurface *sub;
-   E_Client *ec, *epc;
-   E_Client *offscreen_parent = NULL;
-   struct wl_resource *subsurf_res;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(client, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(resource, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(parent_surface, EINA_FALSE);
-
-   ec = e_client_from_surface_resource(surface);
-   epc = e_client_from_surface_resource(parent_surface);
-
-   if (ec == epc)
-     {
-        wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
-                               "%d: wl_surface@%d cannot be its own parent",
-                               id, wl_resource_get_id(surface));
-        return EINA_FALSE;
-     }
-
-   if (e_comp_wl_subsurface_check(ec))
-     {
-        wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
-                               "%d: wl_surface@%d is already a sub-surface",
-                               id, wl_resource_get_id(surface));
-        return EINA_FALSE;
-     }
-
-   // reparent remote surface provider's subsurfaces
-   if ((epc->comp_data) &&
-       (epc->comp_data->remote_surface.onscreen_parent))
-     {
-        offscreen_parent = epc;
-        epc = epc->comp_data->remote_surface.onscreen_parent;
-     }
-
-   if (_e_comp_wl_subsurface_circular_reference_check(ec, epc))
-     {
-        ERR("Subsurface parent relationship is a cycle : "
-            "[child win : %zx, %s], [parent win : %zx, %s]",
-            e_client_util_win_get(ec), e_client_util_name_get(ec),
-            e_client_util_win_get(epc), e_client_util_name_get(epc));
-        wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
-                               "%d: wl_surface@%d is an ancestor of parent",
-                               id, wl_resource_get_id(surface));
-        return EINA_FALSE;
-     }
-
-   if (!e_comp_wl_surface_role_set(ec, e_comp_wl_subsurface_role_name,
-                                   resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE))
-     {
-        return EINA_FALSE;
-     }
-
-   subsurf_res = wl_resource_create(client, &wl_subsurface_interface, 1, id);
-   if (!subsurf_res)
-     {
-        wl_resource_post_no_memory(resource);
-        return EINA_FALSE;
-     }
-
-   sub = _e_comp_wl_subsurface_create(subsurf_res, ec, epc, offscreen_parent);
-   if (!sub)
-     {
-        wl_resource_destroy(subsurf_res);
-        wl_resource_post_no_memory(resource);
-        return EINA_FALSE;
-     }
-
-   wl_resource_set_implementation(subsurf_res, &_e_subsurface_interface, sub,
-                                  _e_comp_wl_subsurface_cb_resource_destroy);
-
-   ELOGF("SUBSURFACE", "Create with parent(%p)", ec, epc);
-
-   return EINA_TRUE;
-}
-
-EINTERN void
-e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized)
-{
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-
-   _e_comp_wl_subsurface_parent_commit(ec, parent_synchronized);
-}
-
-EINTERN Eina_Bool
 e_comp_wl_subsurface_order_commit(E_Client *ec)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
@@ -1111,60 +683,6 @@ e_comp_wl_subsurface_order_commit(E_Client *ec)
 }
 
 EINTERN Eina_Bool
-e_comp_wl_subsurface_commit(E_Client *ec)
-{
-   E_Comp_Wl_Subsurf_Data *sdata;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
-
-   /* check for valid subcompositor data */
-   if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return EINA_FALSE;
-
-   sdata = _e_comp_wl_subsurface_data_get(ec);
-   if (!sdata) return EINA_FALSE;
-
-   if (_e_comp_wl_subsurface_synchronized_get(sdata))
-     _e_comp_wl_subsurface_commit_to_cache(ec);
-   else
-     {
-        E_Client *subc;
-        Eina_List *l;
-
-        if (sdata->position.set)
-          {
-             E_Client *parent = sdata->parent;
-             if (parent)
-               {
-                  evas_object_move(ec->frame, parent->x + sdata->position.x,
-                                   parent->y + sdata->position.y);
-                  sdata->position.set = EINA_FALSE;
-               }
-          }
-
-        if (sdata->cached.has_data)
-          {
-             _e_comp_wl_subsurface_commit_to_cache(ec);
-             _e_comp_wl_subsurface_commit_from_cache(ec);
-          }
-        else
-          e_comp_wl_surface_commit(ec);
-
-        EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
-          {
-             if (ec != subc)
-               _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
-          }
-        EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
-          {
-             if (ec != subc)
-               _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
-          }
-     }
-
-   return EINA_TRUE;
-}
-
-EINTERN Eina_Bool
 e_comp_wl_subsurface_can_show(E_Client *ec)
 {
    E_Comp_Wl_Subsurf_Data *sdata;
@@ -1306,22 +824,6 @@ e_comp_wl_subsurface_parent_get(E_Client *ec)
    return ec->comp_data->sub.data ? ec->comp_data->sub.data->parent : NULL;
 }
 
-EINTERN void
-e_comp_wl_subsurface_resource_stand_alone_mode_set(struct wl_resource *subsurface_resource)
-{
-   E_Subsurface *sub;
-
-   EINA_SAFETY_ON_FALSE_RETURN(wl_resource_instance_of(subsurface_resource,
-                                                       &wl_subsurface_interface,
-                                                       &_e_subsurface_interface));
-
-   sub = wl_resource_get_user_data(subsurface_resource);
-   EINA_SAFETY_ON_NULL_RETURN(sub);
-
-   ELOGF("SUBSURFACE", "SUBSURF|STAND_ALONE", sub->ec);
-   sub->base.stand_alone = EINA_TRUE;
-}
-
 EINTERN Eina_Bool
 e_comp_wl_subsurface_stand_alone_mode_get(E_Client *ec)
 {
@@ -1333,34 +835,6 @@ e_comp_wl_subsurface_stand_alone_mode_get(E_Client *ec)
       ec->comp_data->sub.data->stand_alone : EINA_FALSE;
 }
 
-EINTERN void
-e_comp_wl_subsurface_resource_place_below_parent(struct wl_resource *subsurface_resource)
-{
-   E_Subsurface *sub;
-   E_Comp_Wl_Client_Data *epc_cdata;
-
-   EINA_SAFETY_ON_FALSE_RETURN(wl_resource_instance_of(subsurface_resource,
-                                                       &wl_subsurface_interface,
-                                                       &_e_subsurface_interface));
-
-   sub = wl_resource_get_user_data(subsurface_resource);
-   EINA_SAFETY_ON_NULL_RETURN(sub);
-
-   EINA_SAFETY_ON_NULL_RETURN(sub->base.parent);
-   epc_cdata = e_client_cdata_get(sub->base.parent);
-   EINA_SAFETY_ON_NULL_RETURN(epc_cdata);
-
-   ELOGF("SUBSURFACE", "SUBSURF|BELOW_PARENT", sub->ec);
-   epc_cdata->sub.list = eina_list_remove(epc_cdata->sub.list, sub->ec);
-   epc_cdata->sub.list_pending = eina_list_remove(epc_cdata->sub.list_pending, sub->ec);
-   epc_cdata->sub.below_list = eina_list_remove(epc_cdata->sub.below_list, sub->ec);
-   epc_cdata->sub.below_list_pending = eina_list_remove(epc_cdata->sub.below_list_pending, sub->ec);
-
-   epc_cdata->sub.below_list_pending = eina_list_append(epc_cdata->sub.below_list_pending, sub->ec);
-   epc_cdata->sub.below_list = eina_list_append(epc_cdata->sub.below_list, sub->ec);
-   epc_cdata->sub.list_changed = EINA_TRUE;
-}
-
 EINTERN Eina_Bool
 e_comp_wl_subsurface_position_get(E_Client *ec, int *x, int *y)
 {
@@ -1399,19 +873,6 @@ e_comp_wl_subsurface_global_coord_get(E_Client *ec, int *x, int *y)
    return EINA_TRUE;
 }
 
-static void
-_e_comp_wl_subsurface_remove_from_parent(E_Client *parent, E_Client *subc)
-{
-   parent->comp_data->sub.list =
-      eina_list_remove(parent->comp_data->sub.list, subc);
-   parent->comp_data->sub.list_pending =
-      eina_list_remove(parent->comp_data->sub.list_pending, subc);
-   parent->comp_data->sub.below_list =
-      eina_list_remove(parent->comp_data->sub.below_list, subc);
-   parent->comp_data->sub.below_list_pending =
-      eina_list_remove(parent->comp_data->sub.below_list_pending, subc);
-}
-
 static E_Comp_Wl_Subsurf_Data *
 _e_comp_wl_subsurface_data_get(E_Client *ec)
 {
@@ -1419,76 +880,6 @@ _e_comp_wl_subsurface_data_get(E_Client *ec)
 }
 
 static void
-_e_comp_wl_subsurface_child_remove(E_Comp_Wl_Client_Data *parent_cdata, E_Client *child)
-{
-   if (parent_cdata->sub.list_pending)
-     {
-        parent_cdata->sub.list_pending =
-           eina_list_remove(parent_cdata->sub.list_pending, child);
-     }
-   if (parent_cdata->sub.below_list_pending)
-     {
-        parent_cdata->sub.below_list_pending =
-           eina_list_remove(parent_cdata->sub.below_list_pending, child);
-     }
-}
-
-static void
-_e_comp_wl_subsurface_place_above(E_Client *parent, E_Client *subc, E_Client *above)
-{
-   E_Comp_Wl_Client_Data *pc;
-
-   pc = parent->comp_data;
-
-   _e_comp_wl_subsurface_child_remove(pc, subc);
-
-   if (parent == above)
-     {
-        pc->sub.list_pending = eina_list_prepend(pc->sub.list_pending, subc);
-     }
-   else if (eina_list_data_find(pc->sub.list_pending, above))
-     {
-        pc->sub.list_pending =
-           eina_list_append_relative(pc->sub.list_pending, subc, above);
-     }
-   else
-     {
-        pc->sub.below_list_pending =
-           eina_list_append_relative(pc->sub.below_list_pending, subc, above);
-     }
-
-   pc->sub.list_changed = EINA_TRUE;
-}
-
-static void
-_e_comp_wl_subsurface_place_below(E_Client *parent, E_Client *subc, E_Client *below)
-{
-   E_Comp_Wl_Client_Data *pc;
-
-   pc = parent->comp_data;
-
-   _e_comp_wl_subsurface_child_remove(pc, subc);
-
-   if (parent == below)
-     {
-        pc->sub.below_list_pending =
-           eina_list_append(pc->sub.below_list_pending, subc);
-     }
-   else if (eina_list_data_find(pc->sub.list_pending, below))
-     {
-        pc->sub.list_pending =
-           eina_list_prepend_relative(pc->sub.list_pending, subc, below);
-     }
-   else
-     {
-        pc->sub.below_list_pending =
-           eina_list_prepend_relative(pc->sub.below_list_pending, subc, below);
-     }
-
-   pc->sub.list_changed = EINA_TRUE;
-}
-
-static void
 _e_comp_wl_subsurface_stack_update(E_Client *ec)
 {
    E_Client *topmost;
@@ -1535,166 +926,3 @@ _e_comp_wl_subsurface_stack_update(E_Client *ec)
           }
      }
 }
-
-static E_Subsurface *
-_e_comp_wl_subsurface_create(struct wl_resource *resource, E_Client *ec, E_Client *epc, E_Client *offscreen_parent)
-{
-   E_Subsurface *sub;
-
-   sub = E_NEW(E_Subsurface, 1);
-   if (!sub)
-     return NULL;
-
-   sub->base.resource = resource;
-   sub->base.cached_buffer_ref.buffer = NULL;
-   sub->base.synchronized = EINA_TRUE;
-   sub->base.remote_surface.offscreen_parent = offscreen_parent;
-   if (offscreen_parent)
-     ELOGF("SUBSURFACE", "         |offscreen_parent:%p", ec, offscreen_parent);
-
-   _e_comp_wl_subsurface_ec_link(sub, ec);
-   _e_comp_wl_subsurface_parent_link(sub, epc);
-
-   e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_CREATE, ec);
-
-   return sub;
-}
-
-static void
-_e_comp_wl_subsurface_destroy(E_Subsurface *sub)
-{
-   sub->ec->comp_data->sub.data = NULL;
-
-   if (sub->base.parent)
-     _e_comp_wl_subsurface_parent_unlink(sub);
-
-   E_FREE_FUNC(sub->comp_hook.ec_del, e_comp_wl_hook_del);
-
-   e_comp_wl_surface_state_finish(&sub->base.cached);
-   e_comp_wl_buffer_reference(&sub->base.cached_buffer_ref, NULL);
-   free(sub);
-}
-
-static void
-_e_comp_wl_subsurface_cb_comp_data_del(void *data, E_Client *ec)
-{
-   E_Subsurface *sub;
-
-   sub = data;
-   if (sub->ec != ec)
-     return;
-
-   ELOGF("SUBSURFACE", "The comp_data of E_Client is deleted", ec);
-
-   wl_resource_set_user_data(sub->base.resource, NULL);
-
-   _e_comp_wl_subsurface_destroy(sub);
-}
-
-static void
-_e_comp_wl_subsurface_ec_link(E_Subsurface *sub, E_Client *ec)
-{
-   sub->ec = ec;
-   sub->comp_hook.ec_del =
-      e_comp_wl_hook_add(E_COMP_WL_HOOK_DEL,
-                         _e_comp_wl_subsurface_cb_comp_data_del,
-                         sub);
-
-   e_comp_wl_client_surface_set(ec, ec->comp_data->wl_surface);
-
-   ec->comp_data->sub.data = &sub->base;
-
-   e_comp_wl_surface_state_init(&sub->base.cached, ec->w, ec->h);
-
-   /* set subsurface client properties */
-   ec->borderless = EINA_TRUE;
-   ec->argb = EINA_TRUE;
-   ELOGF("COMP", "Set argb:%d", ec, ec->argb);
-   ec->lock_border = EINA_TRUE;
-   ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
-   ec->netwm.state.skip_taskbar = EINA_TRUE;
-   ec->netwm.state.skip_pager = EINA_TRUE;
-   ec->no_shape_cut = EINA_TRUE;
-   ec->border_size = 0;
-
-   /* TODO: add callbacks ?? */
-
-   ec->lock_user_location = 0;
-   ec->lock_client_location = 0;
-   ec->lock_user_size = 0;
-   ec->lock_client_size = 0;
-   ec->lock_client_stacking = 0;
-   ec->lock_user_shade = 0;
-   ec->lock_client_shade = 0;
-   ec->lock_user_maximize = 0;
-   ec->lock_client_maximize = 0;
-   ec->changes.need_maximize = 0;
-   ec->maximized = E_MAXIMIZE_NONE;
-   EC_CHANGED(ec);
-
-   ec->new_client = ec->netwm.ping = EINA_TRUE;
-   e_comp->new_clients++;
-   e_client_unignore(ec);
-
-   /* Delete 'below_obj' if it was created before 'E_Client' becomes subsurface.
-    * It's not for subsurface. */
-   E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del);
-}
-
-static void
-_e_comp_wl_subsurface_cb_parent_comp_data_del(void *data, E_Client *ec)
-{
-   E_Subsurface *sub;
-
-   sub = data;
-   if (sub->base.parent != ec)
-     return;
-
-   ELOGF("SUBSURFACE", "The comp_data of parent(%p) is deleted",
-         sub->ec, sub->base.parent);
-
-   if ((sub->ec) &&
-       (sub->ec->comp_data->sub.watcher))
-     tizen_subsurface_watcher_send_message(sub->ec->comp_data->sub.watcher,
-                                           TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_DESTROYED);
-
-   _e_comp_wl_subsurface_parent_unlink(sub);
-}
-
-static void
-_e_comp_wl_subsurface_parent_link(E_Subsurface *sub, E_Client *parent)
-{
-   E_Layer layer;
-
-   ELOGF("COMP", "         |subsurface_parent:%p", sub->ec, parent);
-
-   /* set subsurface data properties */
-   sub->base.parent = parent;
-   sub->comp_hook.parent_del =
-      e_comp_wl_hook_add(E_COMP_WL_HOOK_DEL,
-                         _e_comp_wl_subsurface_cb_parent_comp_data_del,
-                         sub);
-
-   if (parent->frame)
-     {
-        layer = e_client_layer_get(parent);
-        if (layer > E_LAYER_BOTTOM)
-          e_client_layer_set(sub->ec, layer);
-     }
-
-   if (parent->comp_data)
-     {
-        /* append this client to the parents subsurface list */
-        parent->comp_data->sub.list_pending =
-           eina_list_append(parent->comp_data->sub.list_pending, sub->ec);
-        parent->comp_data->sub.list_changed = EINA_TRUE;
-     }
-}
-
-static void
-_e_comp_wl_subsurface_parent_unlink(E_Subsurface *sub)
-{
-   _e_comp_wl_subsurface_remove_from_parent(sub->base.parent, sub->ec);
-   E_FREE_FUNC(sub->comp_hook.parent_del, e_comp_wl_hook_del);
-   sub->base.parent = NULL;
-}
index 95b972c..95367e6 100644 (file)
 EINTERN void          e_comp_wl_subsurface_resource_stand_alone_mode_set(struct wl_resource *subsurface_resource);
 EINTERN void          e_comp_wl_subsurface_resource_place_below_parent(struct wl_resource *subsurface_resource);
 
-EINTERN Eina_Bool     e_comp_wl_subsurfaces_init(E_Comp_Wl_Data *wl_comp);
+EINTERN Eina_Bool     e_comp_wl_subsurfaces_init(void);
 EINTERN void          e_comp_wl_subsurfaces_shutdown(void);
 
-EINTERN Eina_Bool     e_comp_wl_subsurface_add(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface, struct wl_resource *parent_surface);
-EINTERN void          e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized);
+EINTERN Eina_Bool     e_comp_wl_subsurface_add(struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource);
 EINTERN Eina_Bool     e_comp_wl_subsurface_order_commit(E_Client *ec);
 EINTERN Eina_Bool     e_comp_wl_subsurface_commit(E_Client *ec);
 EINTERN Eina_Bool     e_comp_wl_subsurface_can_show(E_Client *ec);
index 8c3a236..08546af 100644 (file)
@@ -3,6 +3,8 @@
 #include <tbm_bufmgr.h>
 #include <tbm_surface_internal.h>
 #include <gbm.h>
+#include <libds-tizen/types/tbm_server.h>
+#include <libds-tizen/tbm_server.h>
 
 static uint64_t e_comp_wl_tbm_gbm_bo_key;
 #define E_COMP_WL_TBM_GBM_BO_KEY  (unsigned long)(&e_comp_wl_tbm_gbm_bo_key)
@@ -91,23 +93,6 @@ _convert_to_tbm_format_from_gbm_format (int gbm_format)
    return 0;
 }
 
-static int
-_e_comp_wl_tbm_bind_wl_display(struct wayland_tbm_server *tbm_server, struct wl_display *display)
-{
-   tbm_bufmgr bufmgr = NULL;
-
-   bufmgr = wayland_tbm_server_get_bufmgr(tbm_server);
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(bufmgr, EINA_FALSE);
-
-   if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display))
-     {
-        e_error_message_show(_("Enlightenment cannot bind native Display TBM!\n"));
-        return EINA_FALSE;
-     }
-
-   return EINA_TRUE;
-}
-
 E_API Eina_Bool
 e_comp_wl_tbm_module_func_set(const char *module_name, E_Comp_Wl_Tbm_Funcs *fn)
 {
@@ -170,10 +155,17 @@ e_comp_wl_tbm_egl_image_buffer_get(int width, int height, tbm_format format)
    return NULL;
 }
 
+static void
+_e_comp_wl_tbm_cb_display_destroy(struct wl_listener *listener, void *data)
+{
+   e_comp->wl_comp_data->tbm.server = NULL;
+}
+
 EINTERN Eina_Bool
 e_comp_wl_tbm_init(void)
 {
-   struct wayland_tbm_server *tbm_server = NULL;
+   static struct wl_listener display_destroy;
+   struct ds_tbm_server *ds_tbm_server;
 
    if (!e_comp)
      {
@@ -186,16 +178,16 @@ e_comp_wl_tbm_init(void)
    if (e_comp->wl_comp_data->tbm.server)
       return EINA_TRUE;
 
-   tbm_server = wayland_tbm_server_init(e_comp->wl_comp_data->wl.disp, NULL, -1, 0);
-   if (!tbm_server)
+   ds_tbm_server = ds_tbm_server_create(e_comp->wl_comp_data->wl.disp);
+   if (!ds_tbm_server)
      {
-        e_error_message_show(_("Enlightenment cannot initialize a Wayland TBM!\n"));
+        e_error_message_show(_("Enlightenment cannot initialize ds_tbm_server!\n"));
         return EINA_FALSE;
      }
 
-   e_comp->wl_comp_data->tbm.server = (void *)tbm_server;
-
-   _e_comp_wl_tbm_bind_wl_display(tbm_server, e_comp->wl_comp_data->wl.disp);
+   e_comp->wl_comp_data->tbm.server = (void *)ds_tbm_server->wl_tbm;
+   display_destroy.notify = _e_comp_wl_tbm_cb_display_destroy;
+   ds_tbm_server_add_destroy_listener(ds_tbm_server, &display_destroy);
 
    if (e_comp_socket_init("tbm-drm-auth"))
      PRCTL("[Winsys] change permission and create sym link for %s", "tbm-drm-auth");
@@ -204,23 +196,6 @@ e_comp_wl_tbm_init(void)
 }
 
 EINTERN void
-e_comp_wl_tbm_shutdown(void)
-{
-   if (!e_comp)
-      return;
-
-   if (!e_comp->wl_comp_data)
-      return;
-
-   if (!e_comp->wl_comp_data->tbm.server)
-      return;
-
-   wayland_tbm_server_deinit((struct wayland_tbm_server *)e_comp->wl_comp_data->tbm.server);
-
-   e_comp->wl_comp_data->tbm.server = NULL;
-}
-
-EINTERN void
 e_comp_wl_tbm_buffer_destroy(E_Comp_Wl_Buffer *buffer)
 {
    if (!buffer) return;
index 0ba3820..f9c8b19 100644 (file)
@@ -19,7 +19,6 @@ struct _E_Comp_Wl_Tbm_Funcs
 };
 
 EINTERN Eina_Bool e_comp_wl_tbm_init(void);
-EINTERN void e_comp_wl_tbm_shutdown(void);
 
 EINTERN E_Comp_Wl_Buffer *e_comp_wl_tbm_buffer_get(tbm_surface_h tsurface);
 EINTERN void e_comp_wl_tbm_buffer_destroy(E_Comp_Wl_Buffer *buffer);
diff --git a/src/bin/e_compositor.c b/src/bin/e_compositor.c
new file mode 100644 (file)
index 0000000..6ae74fd
--- /dev/null
@@ -0,0 +1,1254 @@
+#include "e.h"
+#include "e_comp_wl_private.h"
+
+// for tizen_subsurface_watcher_send_message()
+#include <tizen-extension-server-protocol.h>
+
+#include <libds/compositor.h>
+#include <libds/subcompositor.h>
+#include <libds/types/ds_surface.h>
+#include <libds/types/ds_subsurface.h>
+
+typedef struct _E_Compositor E_Compositor;
+typedef struct _E_Surface E_Surface;
+typedef struct _E_Subsurface E_Subsurface;
+typedef struct _E_Frame_Callback E_Frame_Callback;
+
+struct _E_Compositor
+{
+   struct ds_compositor *ds_compositor;
+   struct ds_subcompositor *ds_subcompositor;
+
+   E_Client_Hook *new_client_hook;
+
+   struct wl_listener new_surface;
+   struct wl_listener display_destroy;
+};
+
+struct _E_Surface
+{
+   E_Comp_Wl_Client_Data base;
+
+   E_Client *ec;
+   struct ds_surface *ds_surface;
+
+   E_Client_Hook *client_del_hook;
+
+   struct wl_listener destroy;
+   struct wl_listener commit;
+   struct wl_listener new_subsurface;
+};
+
+struct _E_Subsurface
+{
+   E_Comp_Wl_Subsurf_Data base;
+
+   E_Surface *surface;
+   struct ds_subsurface *ds_subsurface;
+
+   struct wl_listener destroy;
+   struct wl_listener surface_destroy;
+   struct wl_listener parent_surface_destroy;
+   struct wl_listener cached;
+   struct wl_listener request_move;
+};
+
+struct _E_Frame_Callback
+{
+   E_Client *ec;
+   struct wl_listener destroy;
+};
+
+static void _e_compositor_cb_display_destroy(struct wl_listener *listener, void *data);
+static void _e_compositor_cb_new_surface(struct wl_listener *listener, void *data);
+static void _e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec);
+
+static E_Surface *_e_surface_create(E_Client *ec);
+static E_Surface *_e_surface_from_ds_surface(struct ds_surface *ds_surface);
+static E_Surface *_e_surface_from_comp_data(E_Comp_Wl_Client_Data *comp_data);
+static void _e_surface_destroy(E_Surface *surface);
+static void _e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface);
+static void _e_surface_cb_client_del(void *data, E_Client *ec);
+static void _e_surface_cb_destroy(struct wl_listener *listener, void *data);
+static void _e_surface_cb_commit(struct wl_listener *listener, void *data);
+static void _e_surface_cb_new_subsurface(struct wl_listener *listener, void *data);
+
+static E_Subsurface *_e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surface);
+static E_Subsurface *_e_subsurface_from_surface(E_Surface *surface);
+static E_Subsurface *_e_subsurface_from_resource(struct wl_resource *resource);
+static E_Subsurface *_e_subsurface_from_ds_subsurface(struct ds_subsurface *ds_subsurface);
+static void _e_subsurface_destroy(E_Subsurface *sub);
+static void _e_subsurface_commit(E_Subsurface *sub);
+static void _e_subsurface_place_below_parent(E_Subsurface *sub);
+static void _e_subsurface_cb_destroy(struct wl_listener *listener, void *data);
+static void _e_subsurface_cb_cached(struct wl_listener *listener, void *data);
+static void _e_subsurface_cb_request_move(struct wl_listener *listener, void *data);
+static void _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data);
+static void _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data);
+
+static const char *e_comp_wl_subsurface_role_name = "ds_subsurface";
+static E_Compositor *_compositor;
+
+EINTERN Eina_Bool
+e_compositor_init(struct wl_display *display)
+{
+   E_Compositor *comp;
+
+   if (_compositor)
+     return EINA_TRUE;
+
+   comp = E_NEW(E_Compositor, 1);
+   if (!comp)
+     return EINA_FALSE;
+
+   comp->ds_compositor = ds_compositor_create(display);
+   if (!comp->ds_compositor)
+     {
+        ELOGF("COMPOSITOR", "Could not create ds_compositor", NULL);
+        free(comp);
+        return EINA_FALSE;
+     }
+
+   comp->ds_subcompositor = ds_subcompositor_create(display);
+   if (!comp->ds_subcompositor)
+     {
+        ELOGF("COMPOSITOR", "Could not create ds_subcompositor", NULL);
+        free(comp);
+        return EINA_FALSE;
+     }
+
+   comp->new_surface.notify = _e_compositor_cb_new_surface;
+   ds_compositor_add_new_surface_listener(comp->ds_compositor,
+                                          &comp->new_surface);
+
+   comp->new_client_hook = e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT,
+                                             _e_compositor_cb_new_client,
+                                             NULL);
+
+   comp->display_destroy.notify = _e_compositor_cb_display_destroy;
+   wl_display_add_destroy_listener(display, &comp->display_destroy);
+
+   _compositor = comp;
+
+   return EINA_TRUE;
+}
+
+EINTERN E_Client *
+e_compositor_util_client_from_surface_resource(struct wl_resource *surface_resource)
+{
+   E_Surface *surface;
+   struct ds_surface *ds_surface;
+
+   ds_surface = ds_surface_from_resource(surface_resource);
+   if (!ds_surface)
+     return NULL;
+
+   surface = _e_surface_from_ds_surface(ds_surface);
+   if (!surface)
+     return NULL;
+
+   return surface->ec;
+}
+
+EINTERN Eina_Bool
+e_comp_wl_subsurface_add(struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
+{
+   return !!ds_subsurface_create(resource,
+                                 ds_surface_from_resource(surface_resource),
+                                 ds_surface_from_resource(parent_resource),
+                                 id);
+}
+
+EINTERN void
+e_comp_wl_subsurface_resource_stand_alone_mode_set(struct wl_resource *subsurface_resource)
+{
+   E_Subsurface *sub;
+
+   sub = _e_subsurface_from_resource(subsurface_resource);
+   EINA_SAFETY_ON_NULL_RETURN(sub);
+
+   ELOGF("SUBSURFACE", "SUBSURF|STAND_ALONE", sub->surface->ec);
+
+   sub->base.stand_alone = EINA_TRUE;
+}
+
+EINTERN void
+e_comp_wl_subsurface_resource_place_below_parent(struct wl_resource *subsurface_resource)
+{
+   E_Subsurface *sub;
+   E_Comp_Wl_Client_Data *epc_cdata;
+
+   sub = _e_subsurface_from_resource(subsurface_resource);
+   EINA_SAFETY_ON_NULL_RETURN(sub);
+
+   EINA_SAFETY_ON_NULL_RETURN(sub->base.parent);
+   epc_cdata = e_client_cdata_get(sub->base.parent);
+   EINA_SAFETY_ON_NULL_RETURN(epc_cdata);
+
+   ELOGF("SUBSURFACE", "SUBSURF|BELOW_PARENT", sub->surface->ec);
+
+   _e_subsurface_place_below_parent(sub);
+
+   epc_cdata->sub.list = eina_list_remove(epc_cdata->sub.list, sub->surface->ec);
+   epc_cdata->sub.list_pending = eina_list_remove(epc_cdata->sub.list_pending, sub->surface->ec);
+   epc_cdata->sub.below_list = eina_list_remove(epc_cdata->sub.below_list, sub->surface->ec);
+   epc_cdata->sub.below_list_pending = eina_list_remove(epc_cdata->sub.below_list_pending, sub->surface->ec);
+
+   epc_cdata->sub.below_list_pending = eina_list_append(epc_cdata->sub.below_list_pending, sub->surface->ec);
+   epc_cdata->sub.below_list = eina_list_append(epc_cdata->sub.below_list, sub->surface->ec);
+   epc_cdata->sub.list_changed = EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_comp_wl_subsurface_commit(E_Client *ec)
+{
+   E_Surface *surface;
+   E_Subsurface *sub;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return EINA_FALSE;
+
+   surface = _e_surface_from_comp_data(ec->comp_data);
+   sub = _e_subsurface_from_surface(surface);
+   if (!sub)
+     return EINA_FALSE;
+
+   _e_subsurface_commit(sub);
+
+   return EINA_TRUE;
+}
+
+static void
+_e_compositor_cb_display_destroy(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
+{
+   wl_list_remove(&_compositor->display_destroy.link);
+   wl_list_remove(&_compositor->new_surface.link);
+   e_client_hook_del(_compositor->new_client_hook);
+   E_FREE(_compositor);
+}
+
+static E_Client *
+_e_comp_wl_client_usable_get(pid_t pid, E_Pixmap *ep)
+{
+   /* NOTE: this will return usable E_Client for a surface of specified process
+    * by pid. it doesn't care whatever this surfaces is for but care only what
+    * is owner process of the surface.
+    */
+
+   E_Client *ec = NULL, *_ec = NULL;
+   Eina_List *l;
+
+   /* find launchscreen client list */
+   if (e_comp->launchscrns)
+     {
+        EINA_LIST_FOREACH(e_comp->launchscrns, l, _ec)
+          {
+             if (_ec->netwm.pid == pid)
+               {
+                  ec = _ec;
+                  break;
+               }
+          }
+        if (ec)
+          {
+             E_Pixmap *oldep = NULL;
+
+             if (ec->comp_data)
+               {
+                  /* do NOT replace with the client having comp data */
+                  return NULL;
+               }
+
+             e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, ec);
+
+             oldep = e_client_pixmap_change(ec, ep);
+             if (oldep)
+               {
+                  e_pixmap_win_id_del(oldep);
+                  e_pixmap_free(oldep);
+               }
+
+             if (ec->internal)
+               ec->internal = 0;
+
+             /* to set-up comp data */
+             _e_compositor_cb_new_client(NULL, ec);
+             ec->ignored = 0;
+             if (!ec->comp_data) return NULL;
+             e_comp_wl_client_evas_init(ec);
+
+             ELOGF("COMP", "Reusable ec. new_pixmap:%p", ec, ec->pixmap);
+             e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_REUSE, ec);
+          }
+     }
+
+   return ec;
+}
+
+static void
+_e_compositor_cb_new_surface(struct wl_listener *listener, void *data)
+{
+   struct ds_surface *ds_surface = data;
+   E_Client *ec = NULL;
+   E_Pixmap *ep;
+   struct wl_resource *surface_resource;
+   pid_t pid;
+   int internal = 0;
+
+   DBG("New ds_surface %p", ds_surface);
+
+   TRACE_DS_BEGIN(COMP_WL:NEW SURFACE CB);
+
+   surface_resource = ds_surface_get_wl_resource(ds_surface);
+   wl_client_get_credentials(wl_resource_get_client(surface_resource), &pid, NULL, NULL);
+   if (pid == getpid())
+     {
+        internal = 1;
+        ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, (uintptr_t)wl_resource_get_id(surface_resource));
+     }
+   else if ((ep = e_pixmap_find(E_PIXMAP_TYPE_WL, (uintptr_t)surface_resource)))
+     {
+        ERR("There is e_pixmap already, Delete old e_pixmap %p", ep);
+        e_pixmap_win_id_del(ep);
+     }
+
+   if (!ec)
+     {
+        /* try to create new pixmap */
+        if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, surface_resource)))
+          {
+             ERR("Could not create new pixmap");
+             TRACE_DS_END();
+             return;
+          }
+
+        E_Comp_Wl_Client_Data *cdata = e_pixmap_cdata_get(ep);
+        if (cdata)
+          cdata->wl_surface = surface_resource;
+
+        DBG("\tUsing Pixmap: %p", ep);
+
+        if (!(ec = _e_comp_wl_client_usable_get(pid, ep)))
+          {
+             ec = e_client_new(ep, 0, internal);
+          }
+     }
+   if (ec)
+     {
+        if (!ec->netwm.pid)
+          ec->netwm.pid = pid;
+        if (ec->new_client)
+          e_comp->new_clients--;
+        ec->new_client = 0;
+        if ((!ec->client.w) && (ec->client.h))
+          ec->client.w = ec->client.h = 1;
+        ec->comp_data->surface = surface_resource;
+        ec->icccm.accepts_focus = 1;
+
+        _e_surface_ds_surface_set(_e_surface_from_comp_data(ec->comp_data),
+                                  ds_surface);
+     }
+
+   DBG("\tUsing Client: %p", ec);
+
+   TRACE_DS_END();
+}
+
+static void
+_e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec)
+{
+   E_Surface *surface;
+   Ecore_Window win;
+
+   /* make sure this is a wayland client */
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
+
+   TRACE_DS_BEGIN(COMP_WL:CLIENT NEW HOOK);
+
+   /* get window id from pixmap */
+   win = e_pixmap_window_get(ec->pixmap);
+
+   /* ignore fake root windows */
+   if ((ec->override) && ((ec->x == -77) && (ec->y == -77)))
+     {
+        e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, win);
+        e_object_del(E_OBJECT(ec));
+        TRACE_DS_END();
+        return;
+     }
+
+   surface = _e_surface_create(ec);
+   if (!surface)
+     {
+        ERR("Could not create E_Surface");
+        TRACE_DS_END();
+        return;
+     }
+
+   ec->comp_data = &surface->base;
+
+   /* set initial client properties */
+   ec->argb = EINA_FALSE;
+   ELOGF("COMP", "Set argb:%d", ec, ec->argb);
+   ec->no_shape_cut = EINA_TRUE;
+   ec->redirected = ec->ignored = 1;
+   ec->border_size = 0;
+
+   /* NB: could not find a better place to do this, BUT for internal windows,
+    * we need to set delete_request else the close buttons on the frames do
+    * basically nothing */
+   if (ec->internal)
+     ec->icccm.delete_request = EINA_TRUE;
+
+   E_Comp_Wl_Client_Data *p_cdata = e_pixmap_cdata_get(ec->pixmap);
+   EINA_SAFETY_ON_NULL_GOTO(p_cdata, end);
+
+   e_pixmap_cdata_set(ec->pixmap, &surface->base);
+
+   g_mutex_init(&ec->comp_data->last_device_kbd_mutex);
+   g_mutex_init(&ec->comp_data->surface_mutex);
+
+end:
+   TRACE_DS_END();
+}
+
+static E_Surface *
+_e_surface_create(E_Client *ec)
+{
+   E_Surface *surface;
+
+   surface = E_NEW(E_Surface, 1);
+   if (!surface)
+     return NULL;
+
+   e_object_ref(E_OBJECT(ec));
+   surface->ec = ec;
+
+   wl_signal_init(&surface->base.destroy_signal);
+   wl_signal_init(&surface->base.apply_viewport_signal);
+
+   e_comp_wl_surface_state_init(&surface->base.pending, ec->w, ec->h);
+
+   /* set initial client data properties */
+   surface->base.mapped = EINA_FALSE;
+   surface->base.first_damage = ec->internal;
+   surface->base.need_reparent = !ec->internal;
+
+   /* set initial value of scaler */
+   surface->base.scaler.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
+   surface->base.scaler.buffer_viewport.buffer.scale = 1;
+   surface->base.scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
+   surface->base.scaler.buffer_viewport.surface.width = -1;
+
+   e_presentation_time_container_init(&surface->base.presentation_container);
+
+   surface->client_del_hook = e_client_hook_add(E_CLIENT_HOOK_DEL,
+                                                _e_surface_cb_client_del,
+                                                surface);
+
+   return surface;
+}
+
+static void
+_e_surface_destroy(E_Surface *surface)
+{
+   struct wl_resource *cb;
+
+   if (surface->base.reparented)
+     {
+        /* reset pixmap parent window */
+        e_pixmap_parent_window_set(surface->ec->pixmap, 0);
+     }
+
+   if (surface->base.sub.watcher)
+     wl_resource_destroy(surface->base.sub.watcher);
+
+   wl_signal_emit(&surface->base.destroy_signal, &surface->base.surface);
+
+   e_comp_wl_surface_state_finish(&surface->base.pending);
+
+   e_comp_wl_buffer_reference(&surface->base.buffer_ref, NULL);
+
+   EINA_LIST_FREE(surface->base.frames, cb)
+     wl_resource_destroy(cb);
+
+   EINA_LIST_FREE(surface->base.pending.frames, cb)
+     wl_resource_destroy(cb);
+
+   if (surface->base.aux_hint.hints)
+     {
+        E_Comp_Wl_Aux_Hint *hint;
+        EINA_LIST_FREE(surface->base.aux_hint.hints, hint)
+          {
+             eina_stringshare_del(hint->hint);
+             eina_stringshare_del(hint->val);
+             E_FREE(hint);
+          }
+     }
+
+   if (e_comp_wl->selection.cbhm == surface->base.surface)
+     e_comp_wl->selection.cbhm = NULL;
+
+   if (surface->base.viewport_transform)
+     {
+        e_client_transform_core_remove(surface->ec, surface->base.viewport_transform);
+        e_util_transform_del(surface->base.viewport_transform);
+        surface->base.viewport_transform = NULL;
+     }
+
+   e_presentation_time_container_finish(&surface->base.presentation_container);
+
+   E_FREE_FUNC(surface->base.on_focus_timer, ecore_timer_del);
+
+   e_client_hook_del(surface->client_del_hook);
+
+   surface->ec->comp_data = NULL;
+   e_object_unref(E_OBJECT(surface->ec));
+   free(surface);
+}
+
+static void
+_e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface)
+{
+   surface->ds_surface = ds_surface;
+
+   surface->destroy.notify = _e_surface_cb_destroy;
+   ds_surface_add_destroy_listener(ds_surface, &surface->destroy);
+
+   surface->commit.notify = _e_surface_cb_commit;
+   ds_surface_add_commit_listener(ds_surface, &surface->commit);
+
+   surface->new_subsurface.notify = _e_surface_cb_new_subsurface;
+   ds_surface_add_new_subsurface_listener(ds_surface, &surface->new_subsurface);
+}
+
+static E_Surface *
+_e_surface_from_ds_surface(struct ds_surface *ds_surface)
+{
+   E_Surface *surface = NULL;
+   struct wl_listener *listener;
+
+   listener = wl_signal_get(&ds_surface->events.destroy,
+                            _e_surface_cb_destroy);
+   if (listener)
+     surface = wl_container_of(listener, surface, destroy);
+
+   return surface;
+}
+
+static E_Surface *
+_e_surface_from_comp_data(E_Comp_Wl_Client_Data *comp_data)
+{
+   E_Surface *surface;
+   return wl_container_of(comp_data, surface, base);
+}
+
+static E_Surface *
+_e_surface_root_surface_get(E_Surface *surface)
+{
+   E_Surface *iter = surface;
+   E_Subsurface *sub;
+
+   while ((sub = _e_subsurface_from_surface(iter)))
+     iter = _e_surface_from_ds_surface(sub->ds_subsurface->parent);
+
+   return iter;
+}
+
+static void
+_e_surface_pending_buffer_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   E_Client *ec = surface->ec;
+   E_Comp_Wl_Buffer *buffer = NULL;
+
+   if (ds_surface->buffer)
+     buffer = e_comp_wl_buffer_get(ds_surface->buffer, ec);
+
+   e_comp_wl_client_surface_pending_buffer_set(ec, buffer,
+                                               ds_surface->current.dx,
+                                               ds_surface->current.dy);
+}
+
+static void
+_e_surface_pending_surface_damage_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   pixman_box32_t *rects;
+   int32_t x, y, w, h;
+   int nrects, i;
+   Eina_Rectangle *dmg;
+
+   rects = pixman_region32_rectangles(&ds_surface->current.surface_damage, &nrects);
+   for (i = 0; i < nrects; i++)
+     {
+        x = rects[i].x1;
+        y = rects[i].y1;
+        w = rects[i].x2 - x;
+        h = rects[i].y2 - y;
+
+        dmg = eina_rectangle_new(x, y, w, h);
+        if (dmg)
+          {
+             surface->base.pending.damages =
+                eina_list_append(surface->base.pending.damages, dmg);
+          }
+     }
+}
+
+static void
+_e_surface_pending_buffer_damage_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   pixman_box32_t *rects;
+   int32_t x, y, w, h;
+   int nrects, i;
+   Eina_Rectangle *dmg;
+
+   rects = pixman_region32_rectangles(&ds_surface->current.buffer_damage, &nrects);
+   for (i = 0; i < nrects; i++)
+     {
+        x = rects[i].x1;
+        y = rects[i].y1;
+        w = rects[i].x2 - x;
+        h = rects[i].y2 - y;
+
+        dmg = eina_rectangle_new(x, y, w, h);
+        if (dmg)
+          {
+             surface->base.pending.buffer_damages =
+                eina_list_append(surface->base.pending.buffer_damages, dmg);
+          }
+     }
+}
+
+static void
+_region_area_check(Eina_Tiler *tiler, int32_t x, int32_t y, int32_t w, int32_t h)
+{
+   Eina_Bool need_set = EINA_FALSE;
+   int area_w = 0;
+   int area_h = 0;
+
+   eina_tiler_area_size_get(tiler, &area_w, &area_h);
+   if (x + w > area_w)
+     {
+        area_w = x + w;
+        need_set = EINA_TRUE;
+     }
+
+   if (y + h > area_h)
+     {
+        area_h = y + h;
+        need_set = EINA_TRUE;
+     }
+
+   if (need_set)
+     {
+        INF("change region area. (%dx%d)", area_w, area_h);
+        eina_tiler_area_size_set(tiler, area_w, area_h);
+     }
+}
+
+static Eina_Tiler *
+_tiler_new_from_pixman_region(pixman_region32_t *pixman_region)
+{
+   Eina_Tiler *tiler;
+   pixman_box32_t *rects;
+   int32_t x, y, w, h;
+   int nrects, i;
+
+   tiler = eina_tiler_new(e_comp->w, e_comp->h);
+   if (!tiler)
+     return NULL;
+
+   eina_tiler_tile_size_set(tiler, 1, 1);
+
+   rects = pixman_region32_rectangles(pixman_region, &nrects);
+   for (i = 0; i < nrects; i++)
+     {
+        x = rects[i].x1;
+        y = rects[i].y1;
+        w = rects[i].x2 - x;
+        h = rects[i].y2 - y;
+        _region_area_check(tiler, x, y, w, h);
+        eina_tiler_rect_add(tiler, &(Eina_Rectangle){x, y, w, h});
+     }
+
+   return tiler;
+}
+
+static void
+_e_surface_pending_opaque_region_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   E_Client *ec = surface->ec;
+   Eina_Tiler *region;
+
+   if (pixman_region32_not_empty(&ds_surface->current.opaque))
+     {
+        region = _tiler_new_from_pixman_region(&ds_surface->current.opaque);
+        if (!region)
+          return;
+
+        e_comp_wl_client_surface_pending_opaque_region_set(ec, region);
+
+        eina_tiler_free(region);
+     }
+   else
+     {
+        e_comp_wl_client_surface_pending_opaque_region_set(ec, NULL);
+     }
+}
+
+static void
+_e_surface_pending_input_region_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   E_Client *ec = surface->ec;
+   Eina_Tiler *region;
+
+   if (pixman_region32_not_empty(&ds_surface->current.input))
+     {
+        region = _tiler_new_from_pixman_region(&ds_surface->current.input);
+        if (!region)
+          return;
+
+        e_comp_wl_client_surface_pending_input_region_set(ec, region);
+
+        eina_tiler_free(region);
+     }
+   else
+     {
+        e_comp_wl_client_surface_pending_input_region_set(ec, NULL);
+     }
+}
+
+static void
+_e_surface_pending_buffer_transform_update(E_Surface *surface)
+{
+   int32_t transform = surface->ds_surface->current.transform;
+
+   surface->base.pending.buffer_viewport.buffer.transform = transform;
+   surface->base.pending.buffer_viewport.changed = 1;
+}
+
+static void
+_e_surface_pending_buffer_scale_update(E_Surface *surface)
+{
+   int32_t scale = surface->ds_surface->current.scale;
+
+   surface->base.pending.buffer_viewport.buffer.scale = scale;
+   surface->base.pending.buffer_viewport.changed = 1;
+}
+
+static void
+_frame_callback_cb_destroy(struct wl_listener *listener, void *data)
+{
+   struct wl_resource *resource = data;
+   E_Frame_Callback *frame_callback;
+
+   frame_callback = wl_container_of(listener, frame_callback, destroy);
+   e_comp_wl_client_surface_frame_callback_remove(frame_callback->ec, resource);
+   e_object_unref(E_OBJECT(frame_callback->ec));
+   free(frame_callback);
+}
+
+static void
+_e_surface_pending_frame_callback_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   E_Client *ec = surface->ec;
+   E_Frame_Callback *frame_callback;
+   struct wl_resource *resource;
+
+   wl_resource_for_each(resource, &ds_surface->current.frame_callback_list)
+     {
+        frame_callback = E_NEW(E_Frame_Callback, 1);
+        if (!frame_callback)
+          continue;
+
+        e_object_ref(E_OBJECT(ec));
+        frame_callback->ec = ec;
+
+        frame_callback->destroy.notify = _frame_callback_cb_destroy;
+        wl_resource_add_destroy_listener(resource, &frame_callback->destroy);
+
+        e_comp_wl_client_surface_pending_frame_callback_add(ec, resource);
+     }
+
+   wl_list_init(&ds_surface->current.frame_callback_list);
+}
+
+static void
+_e_surface_pending_viewport_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   struct ds_surface_state *state = &ds_surface->current;
+   E_Comp_Wl_Buffer_Viewport *vp = &surface->base.pending.buffer_viewport;
+
+   if (state->viewport.has_src)
+     {
+        vp->buffer.src_x = wl_fixed_from_double(state->viewport.src.x);
+        vp->buffer.src_y = wl_fixed_from_double(state->viewport.src.y);
+        vp->buffer.src_width = wl_fixed_from_double(state->viewport.src.width);
+        vp->buffer.src_height = wl_fixed_from_double(state->viewport.src.height);
+        vp->changed = EINA_TRUE;
+     }
+   else
+     {
+        vp->buffer.src_width = wl_fixed_from_int(-1);
+        vp->changed = EINA_TRUE;
+     }
+
+   if (state->viewport.has_dst)
+     {
+        vp->surface.width = state->viewport.dst_width;
+        vp->surface.height = state->viewport.dst_height;
+        vp->changed = EINA_TRUE;
+     }
+   else
+     {
+        vp->surface.width = -1;
+        vp->changed = EINA_TRUE;
+     }
+}
+
+static void
+_e_surface_pending_subsurface_order_update(E_Surface *surface)
+{
+   struct ds_surface *ds_surface = surface->ds_surface;
+   struct ds_subsurface *ds_subsurface;
+   E_Subsurface *sub;
+   Eina_Bool reordered = EINA_FALSE;
+
+   E_FREE_FUNC(surface->base.sub.list_pending, eina_list_free);
+   E_FREE_FUNC(surface->base.sub.below_list_pending, eina_list_free);
+
+   wl_list_for_each(ds_subsurface,
+                    &ds_surface->pending.subsurfaces_above,
+                    pending.link)
+     {
+        sub = _e_subsurface_from_ds_subsurface(ds_subsurface);
+        surface->base.sub.list_pending =
+           eina_list_append(surface->base.sub.list_pending, sub->surface->ec);
+
+        reordered |= ds_subsurface->reordered;
+
+        _e_surface_pending_subsurface_order_update(sub->surface);
+     }
+
+   wl_list_for_each(ds_subsurface,
+                    &ds_surface->pending.subsurfaces_below,
+                    pending.link)
+     {
+        sub = _e_subsurface_from_ds_subsurface(ds_subsurface);
+        surface->base.sub.below_list_pending =
+           eina_list_append(surface->base.sub.below_list_pending, sub->surface->ec);
+
+        reordered |= ds_subsurface->reordered;
+
+        _e_surface_pending_subsurface_order_update(sub->surface);
+     }
+
+   surface->base.sub.list_changed |= reordered;
+}
+
+static void
+_e_surface_pending_update(E_Surface *surface)
+{
+   E_Surface *root_surface;
+   struct ds_surface *ds_surface = surface->ds_surface;
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER)
+     _e_surface_pending_buffer_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_SURFACE_DAMAGE)
+     _e_surface_pending_surface_damage_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER_DAMAGE)
+     _e_surface_pending_buffer_damage_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_OPAQUE_REGION)
+     _e_surface_pending_opaque_region_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_INPUT_REGION)
+     _e_surface_pending_input_region_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_TRANSFORM)
+     _e_surface_pending_buffer_transform_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_SCALE)
+     _e_surface_pending_buffer_scale_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_FRAME_CALLBACK_LIST)
+     _e_surface_pending_frame_callback_update(surface);
+
+   if (ds_surface->current.committed & DS_SURFACE_STATE_VIEWPORT)
+     _e_surface_pending_viewport_update(surface);
+
+   // FIXME
+   // It's not supposed to update subsurface order for entire surface tree.
+   // This is for backward compatibility
+   root_surface = _e_surface_root_surface_get(surface);
+   _e_surface_pending_subsurface_order_update(root_surface);
+}
+
+static void
+_e_surface_commit_pre(E_Surface *surface)
+{
+   E_Client *ec = surface->ec;
+   E_Comp_Config *comp_conf = NULL;
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
+
+   if (!surface->base.first_commit)
+     surface->base.first_commit = EINA_TRUE;
+
+   if (!surface->base.mapped)
+     {
+        if (surface->base.shell.surface && surface->base.pending.new_attach &&
+            !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
+          {
+             ELOGF("COMP", "Current unmapped. COMMIT. pixmap_usable:%d", ec, e_pixmap_usable_get(ec->pixmap));
+
+             // no canvas update before client's commit request, begin rendering after 1st commit
+             comp_conf = e_comp_config_get();
+             if (comp_conf && comp_conf->canvas_render_delay_after_boot && e_comp->canvas_render_delayed)
+               {
+                  ELOGF("COMP", "Begin canvas update for the first time after boot", ec);
+                  e_comp->canvas_render_delayed = EINA_FALSE;
+               }
+          }
+     }
+
+   e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_BEFORE_SURFACE_COMMIT, ec);
+}
+
+static void
+_e_surface_commit(E_Surface *surface)
+{
+   e_comp_wl_client_surface_pending_commit(surface->ec);
+}
+
+static void
+_e_surface_cb_client_del(void *data, E_Client *ec)
+{
+   E_Surface *surface = data;
+
+   if (surface->ec != ec)
+     return;
+
+   /* make sure this is a wayland client */
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
+
+   TRACE_DS_BEGIN(COMP_WL:CLIENT DEL CB);
+
+   g_mutex_clear(&ec->comp_data->last_device_kbd_mutex);
+   g_mutex_clear(&ec->comp_data->surface_mutex);
+
+   e_comp_wl_hook_call(E_COMP_WL_HOOK_DEL, ec);
+
+   ec->already_unparented = EINA_TRUE;
+
+   e_comp_wl_client_evas_deinit(ec);
+
+   e_pixmap_cdata_set(ec->pixmap, NULL);
+
+   _e_surface_destroy(surface);
+
+   TRACE_DS_END();
+}
+
+static void
+_e_surface_cb_destroy(struct wl_listener *listener, void *data)
+{
+   E_Surface *surface;
+
+   surface = wl_container_of(listener, surface, destroy);
+
+   wl_list_remove(&surface->destroy.link);
+   wl_list_remove(&surface->commit.link);
+   wl_list_remove(&surface->new_subsurface.link);
+   surface->ds_surface = NULL;
+
+   e_comp_wl_client_surface_finish(surface->ec);
+}
+
+static void
+_e_surface_cb_commit(struct wl_listener *listener, void *data)
+{
+   E_Surface *surface;
+   E_Subsurface *sub;
+
+   surface = wl_container_of(listener, surface, commit);
+
+   _e_surface_pending_update(surface);
+   _e_surface_commit_pre(surface);
+
+   if (e_comp_wl_remote_surface_commit(surface->ec)) return;
+
+   sub = _e_subsurface_from_surface(surface);
+   if (sub)
+     _e_subsurface_commit(sub);
+   else
+     _e_surface_commit(surface);
+}
+
+static void
+_e_surface_cb_new_subsurface(struct wl_listener *listener, void *data)
+{
+   struct ds_subsurface *ds_subsurface = data;
+   E_Surface *surface;
+
+   surface = wl_container_of(listener, surface, new_subsurface);
+
+   if (!_e_subsurface_create(ds_subsurface, surface))
+     {
+        ELOGF("COMPOSITOR", "Could not create E_Subsurface", surface->ec);
+        return;
+     }
+}
+
+static E_Subsurface *
+_e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surface)
+{
+   E_Subsurface *sub;
+   E_Surface *surface;
+   E_Client *offscreen_parent = NULL, *epc = parent_surface->ec;
+
+   sub = E_NEW(E_Subsurface, 1);
+   if (!sub)
+     return NULL;
+
+   surface = _e_surface_from_ds_surface(ds_subsurface->surface);
+
+   if (parent_surface->base.remote_surface.onscreen_parent)
+     {
+        offscreen_parent = epc;
+        epc = parent_surface->base.remote_surface.onscreen_parent;
+     }
+
+   if (e_comp_wl_client_subsurface_cyclic_reference_check(surface->ec, epc))
+     {
+        ERR("Subsurface parent relationship is a cycle : "
+            "[child win : %zx, %s], [parent win : %zx, %s]",
+            e_client_util_win_get(surface->ec),
+            e_client_util_name_get(surface->ec),
+            e_client_util_win_get(epc),
+            e_client_util_name_get(epc));
+        free(sub);
+        return NULL;
+     }
+
+   if (!e_comp_wl_surface_role_set(surface->ec, e_comp_wl_subsurface_role_name,
+                                   NULL, 0))
+     {
+        free(sub);
+        return NULL;
+     }
+
+   sub->ds_subsurface = ds_subsurface;
+   sub->destroy.notify = _e_subsurface_cb_destroy;
+   wl_signal_add(&ds_subsurface->events.destroy, &sub->destroy);
+
+   sub->cached.notify = _e_subsurface_cb_cached;
+   wl_signal_add(&ds_subsurface->events.cached, &sub->cached);
+
+   sub->request_move.notify = _e_subsurface_cb_request_move;
+   wl_signal_add(&ds_subsurface->events.request_move, &sub->request_move);
+
+   sub->surface = surface;
+   sub->surface_destroy.notify = _e_subsurface_cb_surface_destroy;
+   wl_signal_add(&surface->base.destroy_signal, &sub->surface_destroy);
+
+   sub->parent_surface_destroy.notify = _e_subsurface_cb_parent_surface_destroy;
+   wl_signal_add(&parent_surface->base.destroy_signal, &sub->parent_surface_destroy);
+
+   e_comp_wl_client_subsurface_init(surface->ec,
+                                    ds_subsurface->resource,
+                                    &sub->base,
+                                    epc,
+                                    offscreen_parent);
+
+   ELOGF("SUBSURFACE", "Create: parent(%p)", surface->ec, epc);
+
+   return sub;
+}
+
+static void
+_e_subsurface_destroy(E_Subsurface *sub)
+{
+   ELOGF("SUBSURFACE", "Destroy", sub->surface->ec);
+   e_comp_wl_client_subsurface_finish(sub->surface->ec);
+   wl_list_remove(&sub->parent_surface_destroy.link);
+   wl_list_remove(&sub->cached.link);
+   wl_list_remove(&sub->surface_destroy.link);
+   wl_list_remove(&sub->destroy.link);
+   free(sub);
+}
+
+static E_Subsurface *
+_e_subsurface_from_ds_subsurface(struct ds_subsurface *ds_subsurface)
+{
+   struct wl_listener *listener;
+   E_Subsurface *sub = NULL;
+
+   listener = wl_signal_get(&ds_subsurface->events.destroy,
+                            _e_subsurface_cb_destroy);
+   if (listener)
+     sub = wl_container_of(listener, sub, destroy);
+
+   return sub;
+}
+
+static E_Subsurface *
+_e_subsurface_from_surface(E_Surface *surface)
+{
+   if (!ds_surface_is_subsurface(surface->ds_surface))
+     return NULL;
+
+   return _e_subsurface_from_ds_subsurface(
+      ds_subsurface_from_surface(surface->ds_surface));
+}
+
+static E_Subsurface *
+_e_subsurface_from_resource(struct wl_resource *resource)
+{
+   return _e_subsurface_from_ds_subsurface(
+      ds_subsurface_from_resource(resource));
+}
+
+static Eina_Bool
+_e_subsurface_synchronized_check(E_Subsurface *sub)
+{
+   struct ds_subsurface *ds_subsurface = sub->ds_subsurface;
+
+   do
+     {
+        if (ds_subsurface->synchronized)
+          return EINA_TRUE;
+     }
+   while ((ds_subsurface = ds_subsurface_from_surface(ds_subsurface->parent)));
+
+   return EINA_FALSE;
+}
+
+static void
+_e_subsurface_commit(E_Subsurface *sub)
+{
+   if (sub->base.cached.has_data)
+     {
+        e_comp_wl_client_subsurface_commit_to_cache(sub->surface->ec);
+        e_comp_wl_client_subsurface_commit_from_cache(sub->surface->ec);
+     }
+   else
+     {
+        e_comp_wl_surface_commit(sub->surface->ec);
+     }
+
+   if (_e_subsurface_synchronized_check(sub))
+     {
+        e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT,
+                            sub->surface->ec);
+     }
+}
+
+static void
+_e_subsurface_position_update(E_Subsurface *sub)
+{
+   E_Client *ec = sub->surface->ec;
+   int x, y;
+
+   x = sub->base.parent->x + sub->base.position.x;
+   y = sub->base.parent->y + sub->base.position.y;
+   evas_object_move(ec->frame, x, y);
+}
+
+static void
+_e_subsurface_place_below_parent(E_Subsurface *sub)
+{
+   struct ds_subsurface *ds_subsurface = sub->ds_subsurface;
+
+   wl_list_remove(&ds_subsurface->pending.link);
+   wl_list_insert(ds_subsurface->parent->pending.subsurfaces_below.prev,
+                  &ds_subsurface->pending.link);
+
+   // FIXME
+   wl_list_remove(&ds_subsurface->current.link);
+   wl_list_insert(ds_subsurface->parent->current.subsurfaces_below.prev,
+                  &ds_subsurface->current.link);
+
+   ds_subsurface->reordered = true;
+}
+
+static void
+_e_subsurface_cb_destroy(struct wl_listener *listener, void *data)
+{
+   E_Subsurface *sub;
+
+   sub = wl_container_of(listener, sub, destroy);
+   _e_subsurface_destroy(sub);
+}
+
+static void
+_e_subsurface_cb_cached(struct wl_listener *listener, void *data)
+{
+   E_Subsurface *sub;
+
+   sub = wl_container_of(listener, sub, cached);
+
+   e_presentation_time_container_feedback_discard(&sub->base.cached.presentation_container);
+   e_presentation_time_container_feedback_merge(&sub->base.cached.presentation_container,
+                                                &sub->surface->base.pending.presentation_container);
+
+   sub->base.cached.has_data = EINA_TRUE;
+
+   e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_COMMIT_TO_CACHE, sub->surface->ec);
+}
+
+static void
+_e_subsurface_cb_request_move(struct wl_listener *listener, void *data)
+{
+   E_Subsurface *sub;
+   struct ds_subsurface *ds_subsurface;
+
+   sub = wl_container_of(listener, sub, request_move);
+   ds_subsurface = sub->ds_subsurface;
+
+   if ((sub->base.position.x == ds_subsurface->current.x) &&
+       (sub->base.position.y == ds_subsurface->current.y))
+     return;
+
+   sub->base.position.x = ds_subsurface->current.x;
+   sub->base.position.y = ds_subsurface->current.y;
+
+   _e_subsurface_position_update(sub);
+}
+
+static void
+_e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data)
+{
+   E_Subsurface *sub;
+
+   sub = wl_container_of(listener, sub, surface_destroy);
+   _e_subsurface_destroy(sub);
+}
+
+static void
+_e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data)
+{
+   E_Subsurface *sub;
+   E_Client *ec;
+
+   sub = wl_container_of(listener, sub, parent_surface_destroy);
+   e_comp_wl_client_subsurface_parent_unset(sub->surface->ec);
+
+   ec = sub->surface->ec;
+   if (ec->comp_data->sub.watcher)
+     {
+        tizen_subsurface_watcher_send_message(ec->comp_data->sub.watcher,
+                                              TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_DESTROYED);
+     }
+}
+
diff --git a/src/bin/e_compositor.h b/src/bin/e_compositor.h
new file mode 100644 (file)
index 0000000..e099b42
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef E_COMPOSITOR_H
+#define E_COMPOSITOR_H
+
+EINTERN Eina_Bool e_compositor_init(struct wl_display *display);
+EINTERN E_Client *e_compositor_util_client_from_surface_resource(struct wl_resource *surface_resource);
+
+#endif
index 2e2e6e5..b7331ae 100644 (file)
@@ -2274,7 +2274,7 @@ _tzpol_iface_cb_subsurface_get(struct wl_client *client, struct wl_resource *res
         return;
      }
 
-   res = e_comp_wl_subsurface_add(client, resource, id, surface,
+   res = e_comp_wl_subsurface_add(resource, id, surface,
                                   epc->comp_data->wl_surface);
    if (!res)
      {
@@ -3390,7 +3390,6 @@ _tzpol_iface_cb_subsurf_watcher_destroy(struct wl_resource *resource)
    E_Comp_Wl_Client_Data *cdata;
 
    if (!(ec = wl_resource_get_user_data(resource))) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
    cdata = e_client_cdata_get(ec);
    if (!cdata) return;