From 2c12f4b0a7e49ff59d8d3fc4f09811f4a3261c88 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Mon, 3 Oct 2011 12:30:32 +0000 Subject: [PATCH] Edje signals: Add the ability to provide extra data for signals. SVN revision: 63771 --- legacy/edje/ChangeLog | 5 +++ legacy/edje/src/lib/Edje.h | 13 +++++++ legacy/edje/src/lib/edje_message_queue.c | 16 +++++++- legacy/edje/src/lib/edje_private.h | 12 +++++- legacy/edje/src/lib/edje_program.c | 47 ++++++++++++++++++++++-- 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/legacy/edje/ChangeLog b/legacy/edje/ChangeLog index 4d543a957e..816810b775 100644 --- a/legacy/edje/ChangeLog +++ b/legacy/edje/ChangeLog @@ -158,6 +158,11 @@ * 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. diff --git a/legacy/edje/src/lib/Edje.h b/legacy/edje/src/lib/Edje.h index f0b08ecce4..84c1427c72 100644 --- a/legacy/edje/src/lib/Edje.h +++ b/legacy/edje/src/lib/Edje.h @@ -1928,6 +1928,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. * diff --git a/legacy/edje/src/lib/edje_message_queue.c b/legacy/edje/src/lib/edje_message_queue.c index d00d125fec..f8fce6cd27 100644 --- a/legacy/edje/src/lib/edje_message_queue.c +++ b/legacy/edje/src/lib/edje_message_queue.c @@ -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 */ diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 0eec3cdc11..0793c55fcb 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -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); diff --git a/legacy/edje/src/lib/edje_program.c b/legacy/edje/src/lib/edje_program.c index be50463f4d..26160c87a1 100644 --- a/legacy/edje/src/lib/edje_program.c +++ b/legacy/edje/src/lib/edje_program.c @@ -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); @@ -801,6 +801,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; @@ -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)