enlightenment/src/bin/e_msg.c

137 lines
3.0 KiB
C

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
typedef struct _E_Msg_Event E_Msg_Event;
struct _E_Msg_Handler
{
void (*func) (void *data, const char *name, const char *info, int val, E_Object *obj);
void *data;
unsigned char delete_me : 1;
};
struct _E_Msg_Event
{
const char *name;
const char *info;
int val;
E_Object *obj;
};
/* local subsystem functions */
static int _e_msg_event_cb(void *data, int ev_type, void *ev);
static void _e_msg_event_free(void *data, void *ev);
/* local subsystem globals */
static Evas_List *handlers = NULL;
static Evas_List *del_handlers = NULL;
static int processing_handlers = 0;
static int E_EVENT_MSG = 0;
static Ecore_Event_Handler *hand = NULL;
/* externally accessible functions */
EAPI int
e_msg_init(void)
{
E_EVENT_MSG = ecore_event_type_new();
hand = ecore_event_handler_add(E_EVENT_MSG, _e_msg_event_cb, NULL);
return 1;
}
EAPI int
e_msg_shutdown(void)
{
while (handlers) e_msg_handler_del(handlers->data);
E_EVENT_MSG = 0;
if (hand) ecore_event_handler_del(hand);
hand = NULL;
return 1;
}
EAPI void
e_msg_send(const char *name, const char *info, int val, E_Object *obj)
{
E_Msg_Event *ev;
ev = calloc(1, sizeof(E_Msg_Event));
/* FIXME: probably better todup the strings but merge with a single
* malloc for the event struct */
if (name) ev->name = evas_stringshare_add(name);
if (info) ev->info = evas_stringshare_add(info);
ev->val = val;
ev->obj = obj;
if (ev->obj) e_object_ref(ev->obj);
ecore_event_add(E_EVENT_MSG, ev, _e_msg_event_free, NULL);
}
EAPI E_Msg_Handler *
e_msg_handler_add(void (*func) (void *data, const char *name, const char *info, int val, E_Object *obj), void *data)
{
E_Msg_Handler *emsgh;
emsgh = calloc(1, sizeof(E_Msg_Handler));
if (!emsgh) return NULL;
emsgh->func = func;
emsgh->data = data;
handlers = evas_list_append(handlers, emsgh);
return emsgh;
}
EAPI void
e_msg_handler_del(E_Msg_Handler *emsgh)
{
if (processing_handlers > 0)
{
emsgh->delete_me = 1;
del_handlers = evas_list_append(del_handlers, emsgh);
}
else
{
handlers = evas_list_remove(handlers, emsgh);
free(emsgh);
}
}
/* local subsystem functions */
static int
_e_msg_event_cb(void *data, int ev_type, void *ev)
{
E_Msg_Event *e;
Evas_List *l;
processing_handlers++;
e = ev;
for (l = handlers; l; l = l->next)
{
E_Msg_Handler *emsgh;
emsgh = l->data;
if (!emsgh->delete_me)
emsgh->func(emsgh->data, e->name, e->info, e->val, e->obj);
}
processing_handlers--;
if ((processing_handlers == 0) && (del_handlers))
{
while (del_handlers)
{
e_msg_handler_del(del_handlers->data);
del_handlers = evas_list_remove_list(del_handlers, del_handlers);
}
}
return 1;
}
static void
_e_msg_event_free(void *data, void *ev)
{
E_Msg_Event *e;
e = ev;
if (e->name) evas_stringshare_del(e->name);
if (e->info) evas_stringshare_del(e->info);
if (e->obj) e_object_unref(e->obj);
}