update for beta release
[framework/uifw/e17.git] / src / bin / e_msg.c
1 #include "e.h"
2
3 typedef struct _E_Msg_Event E_Msg_Event;
4
5 struct _E_Msg_Handler
6 {
7    void (*func) (void *data, const char *name, const char *info, int val, E_Object *obj, void *msgdata);
8    void *data;
9    unsigned char delete_me : 1;
10 };
11
12 struct _E_Msg_Event
13 {
14    char     *name;
15    char     *info;
16    int       val;
17    E_Object *obj;
18    void     *msgdata;
19    void    (*afterfunc) (void *data, E_Object *obj, void *msgdata);
20    void     *afterdata;
21 };
22
23 /* local subsystem functions */
24 static Eina_Bool _e_msg_event_cb(void *data, int ev_type, void *ev);
25 static void _e_msg_event_free(void *data, void *ev);
26
27 /* local subsystem globals */
28 static Eina_List *handlers = NULL;
29 static Eina_List *del_handlers = NULL;
30 static int processing_handlers = 0;
31 static int E_EVENT_MSG = 0;
32 static Ecore_Event_Handler *hand = NULL;
33
34 /* externally accessible functions */
35 EINTERN int
36 e_msg_init(void)
37 {
38    E_EVENT_MSG = ecore_event_type_new();
39    hand = ecore_event_handler_add(E_EVENT_MSG, _e_msg_event_cb, NULL);
40    return 1;
41 }
42
43 EINTERN int
44 e_msg_shutdown(void)
45 {
46    while (handlers) e_msg_handler_del(eina_list_data_get(handlers));
47    E_EVENT_MSG = 0;
48    if (hand) ecore_event_handler_del(hand);
49    hand = NULL;
50    return 1;
51 }
52
53 EAPI void
54 e_msg_send(const char *name, const char *info, int val, E_Object *obj, void *msgdata, void (*afterfunc) (void *data, E_Object *obj, void *msgdata), void *afterdata)
55 {
56    unsigned int size, pos, name_len, info_len;
57    E_Msg_Event *ev;
58    
59    name_len = info_len = 0;
60    size = sizeof(E_Msg_Event);
61    if (name) name_len = strlen(name) + 1;
62    if (info) info_len = strlen(info) + 1;
63    ev = malloc(size + name_len + info_len);
64    if (!ev) return;
65    pos = size;
66    if (name)
67      {
68         ev->name = ((char *)ev) + pos;
69         pos += name_len;
70         strcpy(ev->name, name);
71      }
72    if (info)
73      {
74         ev->info = ((char *)ev) + pos;
75         strcpy(ev->info, info);
76      }
77    ev->val = val;
78    ev->obj = obj;
79    ev->msgdata = msgdata;
80    ev->afterfunc = afterfunc;
81    ev->afterdata = afterdata;
82    if (ev->obj) e_object_ref(ev->obj);
83    ecore_event_add(E_EVENT_MSG, ev, _e_msg_event_free, NULL);
84 }
85
86 EAPI E_Msg_Handler *
87 e_msg_handler_add(void (*func) (void *data, const char *name, const char *info, int val, E_Object *obj, void *msgdata), void *data)
88 {
89    E_Msg_Handler *emsgh;
90    
91    emsgh = calloc(1, sizeof(E_Msg_Handler));
92    if (!emsgh) return NULL;
93    emsgh->func = func;
94    emsgh->data = data;
95    handlers = eina_list_append(handlers, emsgh);
96    return emsgh;
97 }
98
99 EAPI void
100 e_msg_handler_del(E_Msg_Handler *emsgh)
101 {
102    if (processing_handlers > 0)
103      {
104         emsgh->delete_me = 1;
105         del_handlers = eina_list_append(del_handlers, emsgh);
106      }
107    else
108      {
109         handlers = eina_list_remove(handlers, emsgh);
110         free(emsgh);
111      }
112 }
113
114 /* local subsystem functions */
115
116 static Eina_Bool
117 _e_msg_event_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
118 {
119    E_Msg_Event *e;
120    Eina_List *l;
121    E_Msg_Handler *emsgh;
122
123    processing_handlers++;
124    e = ev;
125    EINA_LIST_FOREACH(handlers, l, emsgh)
126      {
127         if (!emsgh->delete_me)
128           emsgh->func(emsgh->data, e->name, e->info, e->val, e->obj, e->msgdata);
129      }
130    if (e->afterfunc) e->afterfunc(e->afterdata, e->obj, e->msgdata);
131    processing_handlers--;
132    if ((processing_handlers == 0) && (del_handlers))
133      {
134         E_FREE_LIST(del_handlers, e_msg_handler_del);
135      }
136    return 1;
137 }
138
139 static void
140 _e_msg_event_free(void *data __UNUSED__, void *ev)
141 {
142    E_Msg_Event *e;
143
144    e = ev;
145    if (e->obj) e_object_unref(e->obj);
146
147    E_FREE(ev);
148 }