Edje signals: Add the ability to provide extra data for signals.
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 3 Oct 2011 12:30:32 +0000 (12:30 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 3 Oct 2011 12:30:32 +0000 (12:30 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/edje@63771 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/lib/Edje.h
src/lib/edje_message_queue.c
src/lib/edje_private.h
src/lib/edje_program.c

index 4d543a9..816810b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
        * Add entry input panel layout setting api's
 
+2011-08-10  Tom Hacohen (TAsn)
+
+       * Signals: Added the ability to pass extra data with edje signals.
+       Added edje_object_signal_callback_extra_data_get to support that.
+
 2011-08-29  Jaehwan Kim
 
        * Add group's inheritance.
index f0b08ec..84c1427 100644 (file)
@@ -1929,6 +1929,19 @@ EAPI void        *edje_object_signal_callback_del_full(Evas_Object *obj, const c
 EAPI void         edje_object_signal_emit         (Evas_Object *obj, const char *emission, const char *source);
 
 /**
+ * @brief Get extra data passed to callbacks.
+ *
+ * @return the extra data for that callback.
+ *
+ * Some callbacks pass extra information. This function gives access to that
+ * extra information. It's somehow like event_info in smart callbacks.
+ *
+ * @see edje_object_signal_callback_add() for more on Edje signals.
+ * @since 1.1.0
+ */
+EAPI void *       edje_object_signal_callback_extra_data_get(void);
+
+/**
  * @brief Set the Edje object to playing or paused states.
  *
  * @param obj A handle to an Edje object.
index d00d125..f8fce6c 100644 (file)
@@ -353,6 +353,14 @@ _edje_message_free(Edje_Message *em)
                  emsg = (Edje_Message_Signal *)em->msg;
                  if (emsg->sig) eina_stringshare_del(emsg->sig);
                  if (emsg->src) eina_stringshare_del(emsg->src);
+                  if (emsg->data && (--(emsg->data->ref) == 0))
+                    {
+                       if (emsg->data->free_func)
+                         {
+                            emsg->data->free_func(emsg->data->data);
+                         }
+                       free(emsg->data);
+                    }
                  free(emsg);
               }
             break;
@@ -417,6 +425,11 @@ _edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, v
             emsg3 = calloc(1, sizeof(Edje_Message_Signal));
             if (emsg2->sig) emsg3->sig = eina_stringshare_add(emsg2->sig);
             if (emsg2->src) emsg3->src = eina_stringshare_add(emsg2->src);
+            if (emsg2->data)
+               {
+                  emsg3->data = emsg2->data;
+                  emsg3->data->ref++;
+               }
             msg = (unsigned char *)emsg3;
          }
        break;
@@ -670,7 +683,8 @@ _edje_message_process(Edje_Message *em)
      {
        _edje_emit_handle(em->edje,
                          ((Edje_Message_Signal *)em->msg)->sig,
-                         ((Edje_Message_Signal *)em->msg)->src);
+                         ((Edje_Message_Signal *)em->msg)->src,
+                         ((Edje_Message_Signal *)em->msg)->data);
        return;
      }
    /* if this has been queued up for the app then just call the callback */
index 0eec3cd..0793c55 100644 (file)
@@ -1370,10 +1370,19 @@ typedef enum _Edje_Queue
 typedef struct _Edje_Message_Signal Edje_Message_Signal;
 typedef struct _Edje_Message        Edje_Message;
 
+typedef struct _Edje_Message_Signal_Data Edje_Message_Signal_Data;
+struct _Edje_Message_Signal_Data
+{
+   int ref;
+   void *data;
+   void (*free_func)(void *);
+};
+
 struct _Edje_Message_Signal
 {
    const char *sig;
    const char *src;
+   Edje_Message_Signal_Data *data;
 };
 
 struct _Edje_Message
@@ -1540,7 +1549,8 @@ void  _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char
 void _edje_programs_patterns_clean(Edje *ed);
 void _edje_programs_patterns_init(Edje *ed);
 void  _edje_emit(Edje *ed, const char *sig, const char *src);
-void  _edje_emit_handle(Edje *ed, const char *sig, const char *src);
+void _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *));
+void _edje_emit_handle(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data);
 void  _edje_signals_sources_patterns_clean(Edje_Signals_Sources_Patterns *ssp);
 void  _edje_callbacks_patterns_clean(Edje *ed);
 
index be50463..26160c8 100644 (file)
@@ -1,6 +1,6 @@
 #include "edje_private.h"
 
-static void _edje_emit_cb(Edje *ed, const char *sig, const char *src);
+static void _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data);
 static void _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param);
 static void _edje_param_set(Edje_Real_Part *part, const char *param, const char *value);
 
@@ -802,6 +802,14 @@ _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig,
 void
 _edje_emit(Edje *ed, const char *sig, const char *src)
 {
+   _edje_emit_full(ed, sig, src, NULL, NULL);
+}
+
+/* data should either be NULL or a malloc allocated data */
+void
+_edje_emit_full(Edje *ed, const char *sig, const char *src, void *data,
+      void (*free_func)(void *))
+{
    Edje_Message_Signal emsg;
    Eina_List *l;
    Evas_Object *obj;
@@ -933,6 +941,17 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
  end:
    emsg.sig = sig;
    emsg.src = src;
+   if (data)
+     {
+        emsg.data = calloc(1, sizeof(*(emsg.data)));
+        emsg.data->ref = 1;
+        emsg.data->data = data;
+        emsg.data->free_func = free_func;
+     }
+   else
+     {
+        emsg.data = NULL;
+     }
    _edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
    EINA_LIST_FOREACH(ed->subobjs, l, obj)
      {
@@ -943,6 +962,15 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
         if (ed2->delete_me) continue;
         _edje_message_send(ed2, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
      }
+
+   if (emsg.data && (--(emsg.data->ref) == 0))
+     {
+        if (emsg.data->free_func)
+          {
+             emsg.data->free_func(emsg.data->data);
+          }
+        free(emsg.data);
+     }
 }
 
 struct _Edje_Program_Data
@@ -1024,7 +1052,8 @@ _edje_callbacks_patterns_init(Edje *ed)
 
 /* FIXME: what if we delete the evas object??? */
 void
-_edje_emit_handle(Edje *ed, const char *sig, const char *src)
+_edje_emit_handle(Edje *ed, const char *sig, const char *src,
+      Edje_Message_Signal_Data *sdata)
 {
    if (ed->delete_me) return;
    if (!sig) sig = "";
@@ -1132,7 +1161,7 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
               }
 #endif
          }
-       _edje_emit_cb(ed, sig, src);
+       _edje_emit_cb(ed, sig, src, sdata);
        if (_edje_block_break(ed))
          {
             goto break_prog;
@@ -1144,9 +1173,18 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
    _edje_unblock(ed);
 }
 
+/* Extra data for callbacks */
+static void *callback_extra_data = NULL;
+
+EAPI void *
+edje_object_signal_callback_extra_data_get(void)
+{
+   return callback_extra_data;
+}
+
 /* FIXME: what if we delete the evas object??? */
 static void
-_edje_emit_cb(Edje *ed, const char *sig, const char *src)
+_edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data)
 {
    Eina_List            *l;
 
@@ -1166,6 +1204,7 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src)
        const Eina_List *match;
        const Eina_List *l2;
         int r = 1;
+        callback_extra_data = (data) ? data->data : NULL;
 
        _edje_callbacks_patterns_init(ed);
        if (ed->patterns.callbacks.u.callbacks.globing)