Split tizen_subsurface_watcher implementation out 36/298236/1 accepted/tizen/unified/20230904.165048
authorSeunghun Lee <shiin.lee@samsung.com>
Fri, 18 Aug 2023 03:08:42 +0000 (12:08 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 4 Sep 2023 05:02:59 +0000 (14:02 +0900)
This patch introduces E_Subsurface_Watcher implementing
tizen_subsurface_watcher protocol. This removes watcher dependency from
the E_Client. Therefore, the E_Client does no longer have to handle a
watcher by itself.

Change-Id: Ifd657f0dbc4288c18151be0e12a024f1bdad61a9

src/bin/Makefile.mk
src/bin/e_comp_wl.h
src/bin/e_compositor.c
src/bin/e_compositor.h
src/bin/e_policy_wl.c
src/bin/e_subsurface_watcher.c [new file with mode: 0644]
src/bin/e_subsurface_watcher.h [new file with mode: 0644]

index 579b8f2..acba64d 100644 (file)
@@ -285,7 +285,8 @@ src/bin/e_single_pixel_buffer.c \
 src/bin/e_comp_wl_buffer.c \
 src/bin/e_compositor.c \
 src/bin/e_blender.c \
-src/bin/e_devicemgr_keyboard_grab.c
+src/bin/e_devicemgr_keyboard_grab.c \
+src/bin/e_subsurface_watcher.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 b15d4b8..72b3cc7 100644 (file)
@@ -418,8 +418,6 @@ struct _E_Comp_Wl_Client_Data
         E_Comp_Wl_Hook *comp_wl_del_hook;
 
         Eina_Bool restacking : 1;
-
-        struct wl_resource *watcher;
      } sub;
 
    /* regular surface resource (wl_compositor_create_surface) */
index 8321646..1d0a38f 100644 (file)
@@ -1,16 +1,12 @@
 #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;
 
@@ -37,6 +33,11 @@ struct _E_Surface
    struct wl_listener destroy;
    struct wl_listener commit;
    struct wl_listener new_subsurface;
+
+   struct
+     {
+        struct wl_signal parent_destroy;
+     } events;
 };
 
 struct _E_Subsurface
@@ -227,6 +228,41 @@ e_comp_wl_subsurface_commit(E_Client *ec)
    return EINA_TRUE;
 }
 
+EINTERN E_Surface *
+e_surface_from_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;
+}
+
+EINTERN void
+e_surface_destroy_listener_add(E_Surface *surface, struct wl_listener *listener)
+{
+   wl_signal_add(&surface->base.destroy_signal, listener);
+}
+
+EINTERN struct wl_listener *
+e_surface_destroy_listener_get(E_Surface *surface, wl_notify_func_t notify)
+{
+   return wl_signal_get(&surface->base.destroy_signal, notify);
+}
+
+EINTERN void
+e_surface_parent_destroy_listener_add(E_Surface *surface, struct wl_listener *listener)
+{
+   wl_signal_add(&surface->events.parent_destroy, listener);
+}
+
 static void
 _e_compositor_cb_display_destroy(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
 {
@@ -435,6 +471,7 @@ _e_surface_create(E_Client *ec)
    e_object_ref(E_OBJECT(ec));
    surface->ec = ec;
 
+   wl_signal_init(&surface->events.parent_destroy);
    wl_signal_init(&surface->base.destroy_signal);
    wl_signal_init(&surface->base.apply_viewport_signal);
    wl_signal_init(&surface->base.state_commit_signal);
@@ -472,9 +509,6 @@ _e_surface_destroy(E_Surface *surface)
         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);
@@ -1261,20 +1295,14 @@ 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);
 
+   wl_signal_emit(&sub->surface->events.parent_destroy, sub->surface);
+
    wl_list_remove(&sub->parent_surface_destroy.link);
    wl_list_init(&sub->parent_surface_destroy.link);
 
    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);
-     }
 }
 
index e099b42..dee1174 100644 (file)
@@ -1,7 +1,14 @@
 #ifndef E_COMPOSITOR_H
 #define E_COMPOSITOR_H
 
+typedef struct _E_Surface E_Surface;
+
 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);
 
+EINTERN E_Surface *e_surface_from_resource(struct wl_resource *surface_resource);
+EINTERN void e_surface_destroy_listener_add(E_Surface *surface, struct wl_listener *listener);
+EINTERN void e_surface_parent_destroy_listener_add(E_Surface *surface, struct wl_listener *listener);
+EINTERN struct wl_listener *e_surface_destroy_listener_get(E_Surface *surface, wl_notify_func_t notify);
+
 #endif
index d3228e9..201822c 100644 (file)
@@ -14,6 +14,7 @@
 #include "e_policy_conformant_internal.h"
 #include "e_policy_visibility.h"
 #include "e_appinfo.h"
+#include "e_subsurface_watcher.h"
 
 #include <device/display.h>
 #include <wayland-server.h>
@@ -2264,13 +2265,8 @@ _tzpol_iface_cb_subsurface_get(struct wl_client *client, struct wl_resource *res
      {
         ELOGF("TZPOL", "SUBSURF   | Invalid parent(%p). "
               "Create with fake implementation", ec, epc);
-        cdata = e_client_cdata_get(ec);
-        if ((cdata) &&
-            (cdata->sub.watcher))
-          {
-             tizen_subsurface_watcher_send_message(cdata->sub.watcher,
-                                                   TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_INVALID);
-          }
+
+        e_subsurface_watcher_invalid_parent_notify(surface);
 
         /* We have to create a subsurface resource here even though it's error case
          * because server will send the fatal error when a client destroy a subsurface object.
@@ -3410,53 +3406,14 @@ _tz_dpy_pol_iface_cb_destroy(struct wl_client *client, struct wl_resource *resou
 }
 
 static void
-_tzpol_iface_cb_subsurf_watcher_destroy(struct wl_resource *resource)
-{
-   E_Client *ec;
-   E_Comp_Wl_Client_Data *cdata;
-
-   if (!(ec = wl_resource_get_user_data(resource))) return;
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return;
-
-   cdata->sub.watcher = NULL;
-}
-
-static void
-_tzpol_subsurf_watcher_iface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
-{
-   wl_resource_destroy(resource);
-}
-
-static const struct tizen_subsurface_watcher_interface _tzpol_subsurf_watcher_iface =
-{
-   _tzpol_subsurf_watcher_iface_cb_destroy,
-};
-
-static void
 _tzpol_iface_cb_subsurf_watcher_get(struct wl_client *client, struct wl_resource *res_tzpol, uint32_t id, struct wl_resource *surface)
 {
    E_Client *ec;
-   E_Comp_Wl_Client_Data *cdata;
-   struct wl_resource *res;
 
    if (!(ec = e_client_from_surface_resource(surface))) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return;
-
-   if (!(res = wl_resource_create(client, &tizen_subsurface_watcher_interface, 1, id)))
-     {
-        wl_resource_post_no_memory(res_tzpol);
-        return;
-     }
-
-   cdata->sub.watcher = res;
 
-   wl_resource_set_implementation(res,
-                                  &_tzpol_subsurf_watcher_iface,
-                                  ec,
-                                  _tzpol_iface_cb_subsurf_watcher_destroy);
+   e_subsurface_watcher_add(client, id, surface);
 }
 
 static void
diff --git a/src/bin/e_subsurface_watcher.c b/src/bin/e_subsurface_watcher.c
new file mode 100644 (file)
index 0000000..1a253f1
--- /dev/null
@@ -0,0 +1,140 @@
+#include "e_subsurface_watcher.h"
+#include "e_compositor.h"
+
+#include <tizen-extension-server-protocol.h>
+
+#define TIZEN_SUBSURFACE_WATCHER_VERSION 1
+
+#ifdef ESWINF
+#undef ESWINF
+#endif
+#define ESWINF(f, w, x...) INF("watcher(%p)|"f, w, ##x)
+
+typedef struct _E_Subsurface_Watcher E_Subsurface_Watcher;
+
+struct _E_Subsurface_Watcher
+{
+   struct wl_resource *resource;
+
+   struct wl_listener surface_destroy;
+   struct wl_listener parent_destroy;
+};
+
+static void
+_e_subsurface_watcher_cb_surface_destroy(struct wl_listener *listener, void *data)
+{
+   E_Subsurface_Watcher *watcher;
+
+   watcher = wl_container_of(listener, watcher, surface_destroy);
+   wl_resource_destroy(watcher->resource);
+}
+
+static E_Subsurface_Watcher *
+_e_subsurface_watcher_from_surface_resource(struct wl_resource *surface_resource)
+{
+   E_Subsurface_Watcher *watcher = NULL;
+   E_Surface *surface;
+   struct wl_listener *listener;
+
+   surface = e_surface_from_resource(surface_resource);
+   if (!surface)
+     return NULL;
+
+   listener = e_surface_destroy_listener_get(surface, _e_subsurface_watcher_cb_surface_destroy);
+   if (listener)
+     watcher = wl_container_of(listener, watcher, surface_destroy);
+
+   return watcher;
+}
+
+static void
+_e_subsurface_watcher_cb_parent_destroy(struct wl_listener *listener, void *data)
+{
+   E_Subsurface_Watcher *watcher;
+
+   watcher = wl_container_of(listener, watcher, parent_destroy);
+
+   ESWINF("Notify destroyed parent", watcher);
+
+   tizen_subsurface_watcher_send_message(watcher->resource,
+                                         TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_DESTROYED);
+}
+
+static void
+_e_subsurface_watcher_cb_resource_destroy(struct wl_resource *resource)
+{
+   E_Subsurface_Watcher *watcher;
+
+   watcher = wl_resource_get_user_data(resource);
+
+   ESWINF("Destroy", watcher);
+
+   wl_list_remove(&watcher->surface_destroy.link);
+   wl_list_remove(&watcher->parent_destroy.link);
+   free(watcher);
+}
+
+static void
+_e_subsurface_watcher_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static const struct tizen_subsurface_watcher_interface _e_subsurface_watcher_impl =
+{
+   .destroy = _e_subsurface_watcher_cb_destroy,
+};
+
+EINTERN void
+e_subsurface_watcher_add(struct wl_client *client, uint32_t id, struct wl_resource *surface_resource)
+{
+   E_Subsurface_Watcher *watcher;
+   E_Surface *surface;
+
+   watcher = E_NEW(E_Subsurface_Watcher, 1);
+   if (!watcher)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   watcher->resource = wl_resource_create(client,
+                                          &tizen_subsurface_watcher_interface,
+                                          TIZEN_SUBSURFACE_WATCHER_VERSION,
+                                          id);
+   if (!watcher->resource)
+     {
+        free(watcher);
+        wl_client_post_no_memory(client);
+        return;
+     }
+   wl_resource_set_implementation(watcher->resource,
+                                  &_e_subsurface_watcher_impl,
+                                  watcher,
+                                  _e_subsurface_watcher_cb_resource_destroy);
+
+   surface = e_surface_from_resource(surface_resource);
+
+   watcher->surface_destroy.notify = _e_subsurface_watcher_cb_surface_destroy;
+   e_surface_destroy_listener_add(surface, &watcher->surface_destroy);
+
+   watcher->parent_destroy.notify = _e_subsurface_watcher_cb_parent_destroy;
+   e_surface_parent_destroy_listener_add(surface, &watcher->parent_destroy);
+
+   ESWINF("Created for surface(%p)", watcher, surface);
+}
+
+EINTERN void
+e_subsurface_watcher_invalid_parent_notify(struct wl_resource *surface_resource)
+{
+   E_Subsurface_Watcher *watcher;
+
+   watcher = _e_subsurface_watcher_from_surface_resource(surface_resource);
+   if (!watcher)
+     return;
+
+   ESWINF("Notify invalid parent", watcher);
+
+   tizen_subsurface_watcher_send_message(watcher->resource,
+                                         TIZEN_SUBSURFACE_WATCHER_MSG_PARENT_ID_INVALID);
+}
diff --git a/src/bin/e_subsurface_watcher.h b/src/bin/e_subsurface_watcher.h
new file mode 100644 (file)
index 0000000..f9288ea
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef E_SUBSURFACE_WATCHER_H
+#define E_SUBSURFACE_WATCHER_H
+
+#include "e.h"
+
+EINTERN void e_subsurface_watcher_add(struct wl_client *client, uint32_t id, struct wl_resource *surface_resource);
+EINTERN void e_subsurface_watcher_invalid_parent_notify(struct wl_resource *surface_resource);
+
+#endif