e_pixmap: added the E_Pixmap hook feature. 91/44391/1
authorGwanglim Lee <gl77.lee@samsung.com>
Tue, 21 Jul 2015 10:11:57 +0000 (19:11 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Tue, 21 Jul 2015 10:11:57 +0000 (19:11 +0900)
This allows e's sub-module to know when wl_surface is destroyed.

Change-Id: I8c90733f1b00562de74d578d7fd0d555fa2cce5e

src/bin/e_pixmap.c
src/bin/e_pixmap.h

index ad1653f9ddc5b6f27d59e13b476ffe9a5097674c..7b1b519e5f67ba92f9650e9b4c4897658a22d999 100644 (file)
@@ -50,6 +50,48 @@ struct _E_Pixmap
    Eina_Bool image_argb : 1;
 };
 
+static int _e_pixmap_hooks_delete = 0;
+static int _e_pixmap_hooks_walking = 0;
+
+static Eina_Inlist *_e_pixmap_hooks[] =
+{
+   [E_PIXMAP_HOOK_NEW] = NULL,
+   [E_PIXMAP_HOOK_DEL] = NULL,
+};
+
+static void
+_e_pixmap_hooks_clean(void)
+{
+   Eina_Inlist *l;
+   E_Pixmap_Hook *ph;
+   unsigned int x;
+
+   for (x = 0; x < E_PIXMAP_HOOK_LAST; x++)
+     EINA_INLIST_FOREACH_SAFE(_e_pixmap_hooks[x], l, ph)
+       {
+          if (!ph->delete_me) continue;
+          _e_pixmap_hooks[x] = eina_inlist_remove(_e_pixmap_hooks[x],
+                                                  EINA_INLIST_GET(ph));
+          free(ph);
+       }
+}
+
+static void
+_e_pixmap_hook_call(E_Pixmap_Hook_Point hookpoint, E_Pixmap *cp)
+{
+   E_Pixmap_Hook *ph;
+
+   _e_pixmap_hooks_walking++;
+   EINA_INLIST_FOREACH(_e_pixmap_hooks[hookpoint], ph)
+     {
+        if (ph->delete_me) continue;
+        ph->func(ph->data, cp);
+     }
+   _e_pixmap_hooks_walking--;
+   if ((_e_pixmap_hooks_walking == 0) && (_e_pixmap_hooks_delete > 0))
+     _e_pixmap_hooks_clean();
+}
+
 #if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
 static void 
 _e_pixmap_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
@@ -196,6 +238,7 @@ e_pixmap_free(E_Pixmap *cp)
 {
    if (!cp) return 0;
    if (--cp->refcount) return cp->refcount;
+   _e_pixmap_hook_call(E_PIXMAP_HOOK_DEL, cp);
    e_pixmap_image_clear(cp, EINA_FALSE);
    if (cp->parent) eina_hash_set(pixmaps[cp->type], &cp->parent, NULL);
    eina_hash_del_by_key(pixmaps[cp->type], &cp->win);
@@ -271,6 +314,7 @@ e_pixmap_new(E_Pixmap_Type type, ...)
         break;
      }
    va_end(l);
+   _e_pixmap_hook_call(E_PIXMAP_HOOK_NEW, cp);
    return cp;
 }
 
@@ -1052,3 +1096,33 @@ e_pixmap_cdata_set(E_Pixmap *cp, E_Comp_Client_Data *cdata)
    cp->cdata = cd;
 #endif
 }
+
+EAPI E_Pixmap_Hook *
+e_pixmap_hook_add(E_Pixmap_Hook_Point hookpoint, E_Pixmap_Hook_Cb func, const void *data)
+{
+   E_Pixmap_Hook *ph;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_PIXMAP_HOOK_LAST, NULL);
+   ph = E_NEW(E_Pixmap_Hook, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ph, NULL);
+   ph->hookpoint = hookpoint;
+   ph->func = func;
+   ph->data = (void*)data;
+   _e_pixmap_hooks[hookpoint] = eina_inlist_append(_e_pixmap_hooks[hookpoint],
+                                                   EINA_INLIST_GET(ph));
+   return ph;
+}
+
+EAPI void
+e_pixmap_hook_del(E_Pixmap_Hook *ph)
+{
+   ph->delete_me = 1;
+   if (_e_pixmap_hooks_walking == 0)
+     {
+        _e_pixmap_hooks[ph->hookpoint] = eina_inlist_remove(_e_pixmap_hooks[ph->hookpoint],
+                                                            EINA_INLIST_GET(ph));
+        free(ph);
+     }
+   else
+     _e_pixmap_hooks_delete++;
+}
index 4110e2ec63e38451dc4cf0f94db4e02a4313c351..4011f56d5b7c1d0705861fc2138ed4c4ef9662c4 100644 (file)
@@ -12,6 +12,26 @@ typedef enum
 # ifndef E_PIXMAP_H
 # define E_PIXMAP_H
 
+typedef struct _E_Pixmap_Hook E_Pixmap_Hook;
+
+typedef enum _E_Pixmap_Hook_Point
+{
+   E_PIXMAP_HOOK_NEW,
+   E_PIXMAP_HOOK_DEL,
+   E_PIXMAP_HOOK_LAST
+} E_Pixmap_Hook_Point;
+
+typedef void (*E_Pixmap_Hook_Cb)(void *data, E_Pixmap *cp);
+
+struct _E_Pixmap_Hook
+{
+   EINA_INLIST;
+   E_Pixmap_Hook_Point hookpoint;
+   E_Pixmap_Hook_Cb    func;
+   void               *data;
+   unsigned char       delete_me : 1;
+};
+
 EAPI int e_pixmap_free(E_Pixmap *cp);
 EAPI E_Pixmap *e_pixmap_ref(E_Pixmap *cp);
 EAPI E_Pixmap *e_pixmap_new(E_Pixmap_Type type, ...);
@@ -52,6 +72,8 @@ EAPI Eina_Bool e_pixmap_validate_check(const E_Pixmap *cp);
 
 EAPI void e_pixmap_image_opaque_set(E_Pixmap *cp, int x, int y, int w, int h);
 EAPI void e_pixmap_image_opaque_get(E_Pixmap *cp, int *x, int *y, int *w, int *h);
+EAPI E_Pixmap_Hook *e_pixmap_hook_add(E_Pixmap_Hook_Point hookpoint, E_Pixmap_Hook_Cb func, const void *data);
+EAPI void e_pixmap_hook_del(E_Pixmap_Hook *ph);
 
 static inline Eina_Bool
 e_pixmap_is_x(const E_Pixmap *cp)