summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/evas_callbacks.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/lib/evas/canvas/evas_callbacks.c
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/lib/evas/canvas/evas_callbacks.c')
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c675
1 files changed, 675 insertions, 0 deletions
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
new file mode 100644
index 0000000000..faf84455e6
--- /dev/null
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -0,0 +1,675 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4static void evas_object_event_callback_clear(Evas_Object *eo_obj);
5static void evas_event_callback_clear(Evas *eo_e);
6int _evas_event_counter = 0;
7
8EVAS_MEMPOOL(_mp_fn);
9EVAS_MEMPOOL(_mp_cb);
10EVAS_MEMPOOL(_mp_pc);
11
12extern Eina_Hash* signals_hash_table;
13
14EAPI const Eo_Event_Description _EVAS_EVENT_MOUSE_IN =
15 EO_EVENT_DESCRIPTION("Mouse In", "Mouse In Event");
16EAPI const Eo_Event_Description _EVAS_EVENT_MOUSE_OUT =
17 EO_EVENT_DESCRIPTION("Mouse Out", "Mouse Out Event");
18EAPI const Eo_Event_Description _EVAS_EVENT_MOUSE_DOWN =
19 EO_EVENT_DESCRIPTION("Mouse Down", "Mouse Button Down Event");
20EAPI const Eo_Event_Description _EVAS_EVENT_MOUSE_UP =
21 EO_EVENT_DESCRIPTION("Mouse Up", "Mouse Button Up Event");
22EAPI const Eo_Event_Description _EVAS_EVENT_MOUSE_MOVE =
23 EO_EVENT_DESCRIPTION("Mouse Move", "Mouse Move Event");
24EAPI const Eo_Event_Description _EVAS_EVENT_MOUSE_WHEEL =
25 EO_EVENT_DESCRIPTION("Mouse Wheel", "Mouse Wheel Event");
26EAPI const Eo_Event_Description _EVAS_EVENT_MULTI_DOWN =
27 EO_EVENT_DESCRIPTION("Multi Down", "Mouse-touch Down Event");
28EAPI const Eo_Event_Description _EVAS_EVENT_MULTI_UP =
29 EO_EVENT_DESCRIPTION("Multi Up", "Mouse-touch Up Event");
30EAPI const Eo_Event_Description _EVAS_EVENT_MULTI_MOVE =
31 EO_EVENT_DESCRIPTION("Multi Move", "Multi-touch Move Event");
32EAPI const Eo_Event_Description _EVAS_EVENT_FREE =
33 EO_EVENT_DESCRIPTION("Free", "Object Being Freed (Called after Del)");
34EAPI const Eo_Event_Description _EVAS_EVENT_KEY_DOWN =
35 EO_EVENT_DESCRIPTION("Key Down", "Key Press Event");
36EAPI const Eo_Event_Description _EVAS_EVENT_KEY_UP =
37 EO_EVENT_DESCRIPTION("Key Up", "Key Release Event");
38EAPI const Eo_Event_Description _EVAS_EVENT_FOCUS_IN =
39 EO_EVENT_DESCRIPTION("Focus In", "Focus In Event");
40EAPI const Eo_Event_Description _EVAS_EVENT_FOCUS_OUT =
41 EO_EVENT_DESCRIPTION("Focus Out", "Focus Out Event");
42EAPI const Eo_Event_Description _EVAS_EVENT_SHOW =
43 EO_EVENT_DESCRIPTION("Show", "Show Event");
44EAPI const Eo_Event_Description _EVAS_EVENT_HIDE =
45 EO_EVENT_DESCRIPTION("Hide", "Hide Event");
46EAPI const Eo_Event_Description _EVAS_EVENT_MOVE =
47 EO_EVENT_DESCRIPTION("Move", "Move Event");
48EAPI const Eo_Event_Description _EVAS_EVENT_RESIZE =
49 EO_EVENT_DESCRIPTION("Resize", "Resize Event");
50EAPI const Eo_Event_Description _EVAS_EVENT_RESTACK =
51 EO_EVENT_DESCRIPTION("Restack", "Restack Event");
52EAPI const Eo_Event_Description _EVAS_EVENT_DEL =
53 EO_EVENT_DESCRIPTION("Del", "Object Being Deleted (called before Free)");
54EAPI const Eo_Event_Description _EVAS_EVENT_HOLD =
55 EO_EVENT_DESCRIPTION("Hold", "Events go on/off hold");
56EAPI const Eo_Event_Description _EVAS_EVENT_CHANGED_SIZE_HINTS =
57 EO_EVENT_DESCRIPTION("Changed Size Hints", "Size hints changed event");
58EAPI const Eo_Event_Description _EVAS_EVENT_IMAGE_PRELOADED =
59 EO_EVENT_DESCRIPTION("Image Preloaded", "Image has been preloaded");
60EAPI const Eo_Event_Description _EVAS_EVENT_IMAGE_RESIZE=
61 EO_EVENT_DESCRIPTION("Image Resize", "Image resize");
62EAPI const Eo_Event_Description _EVAS_EVENT_CANVAS_FOCUS_IN =
63 EO_EVENT_DESCRIPTION("Canvas Focus In", "Canvas got focus as a whole");
64EAPI const Eo_Event_Description _EVAS_EVENT_CANVAS_FOCUS_OUT =
65 EO_EVENT_DESCRIPTION("Canvas Focus Out", "Canvas lost focus as a whole");
66EAPI const Eo_Event_Description _EVAS_EVENT_RENDER_FLUSH_PRE =
67 EO_EVENT_DESCRIPTION("Render Flush Pre", "Called just before rendering is updated on the canvas target");
68EAPI const Eo_Event_Description _EVAS_EVENT_RENDER_FLUSH_POST =
69 EO_EVENT_DESCRIPTION("Render Flush Post", "Called just after rendering is updated on the canvas target");
70EAPI const Eo_Event_Description _EVAS_EVENT_CANVAS_OBJECT_FOCUS_IN =
71 EO_EVENT_DESCRIPTION("Canvas Object Focus In", "Canvas object got focus");
72EAPI const Eo_Event_Description _EVAS_EVENT_CANVAS_OBJECT_FOCUS_OUT =
73 EO_EVENT_DESCRIPTION("Canvas Object Focus Out", "Canvas object lost focus");
74EAPI const Eo_Event_Description _EVAS_EVENT_IMAGE_UNLOADED =
75 EO_EVENT_DESCRIPTION("Image Unloaded", "Image data has been unloaded (by some mechanism in Evas that throw out original image data)");
76EAPI const Eo_Event_Description _EVAS_EVENT_RENDER_PRE =
77 EO_EVENT_DESCRIPTION("Render Pre", "Called just before rendering starts on the canvas target @since 1.2");
78EAPI const Eo_Event_Description _EVAS_EVENT_RENDER_POST =
79 EO_EVENT_DESCRIPTION("Render Post", "Called just after rendering stops on the canvas target @since 1.2");
80
81/**
82 * Evas events descriptions for Eo.
83 */
84static const Eo_Event_Description *_legacy_evas_callback_table[EVAS_CALLBACK_LAST] =
85{
86 EVAS_EVENT_MOUSE_IN,
87 EVAS_EVENT_MOUSE_OUT,
88 EVAS_EVENT_MOUSE_DOWN,
89 EVAS_EVENT_MOUSE_UP,
90 EVAS_EVENT_MOUSE_MOVE,
91 EVAS_EVENT_MOUSE_WHEEL,
92 EVAS_EVENT_MULTI_DOWN,
93 EVAS_EVENT_MULTI_UP,
94 EVAS_EVENT_MULTI_MOVE,
95 EVAS_EVENT_FREE,
96 EVAS_EVENT_KEY_DOWN,
97 EVAS_EVENT_KEY_UP,
98 EVAS_EVENT_FOCUS_IN,
99 EVAS_EVENT_FOCUS_OUT,
100 EVAS_EVENT_SHOW,
101 EVAS_EVENT_HIDE,
102 EVAS_EVENT_MOVE,
103 EVAS_EVENT_RESIZE,
104 EVAS_EVENT_RESTACK,
105 EVAS_EVENT_DEL,
106 EVAS_EVENT_HOLD,
107 EVAS_EVENT_CHANGED_SIZE_HINTS,
108 EVAS_EVENT_IMAGE_PRELOADED,
109 EVAS_EVENT_IMAGE_RESIZE,
110 EVAS_EVENT_CANVAS_FOCUS_IN,
111 EVAS_EVENT_CANVAS_FOCUS_OUT,
112 EVAS_EVENT_RENDER_FLUSH_PRE,
113 EVAS_EVENT_RENDER_FLUSH_POST,
114 EVAS_EVENT_CANVAS_OBJECT_FOCUS_IN,
115 EVAS_EVENT_CANVAS_OBJECT_FOCUS_OUT,
116 EVAS_EVENT_IMAGE_UNLOADED,
117 EVAS_EVENT_RENDER_PRE,
118 EVAS_EVENT_RENDER_POST
119};
120
121void
122_evas_post_event_callback_call(Evas *eo_e, Evas_Public_Data *e)
123{
124 Evas_Post_Callback *pc;
125 int skip = 0;
126
127 if (e->delete_me) return;
128 _evas_walk(e);
129 EINA_LIST_FREE(e->post_events, pc)
130 {
131 if ((!skip) && (!e->delete_me) && (!pc->delete_me))
132 {
133 if (!pc->func((void*)pc->data, eo_e)) skip = 1;
134 }
135 EVAS_MEMPOOL_FREE(_mp_pc, pc);
136 }
137 _evas_unwalk(e);
138}
139
140void
141_evas_post_event_callback_free(Evas *eo_e)
142{
143 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
144 Evas_Post_Callback *pc;
145
146 EINA_LIST_FREE(e->post_events, pc)
147 {
148 EVAS_MEMPOOL_FREE(_mp_pc, pc);
149 }
150}
151
152void
153evas_event_callback_list_post_free(Eina_Inlist **list)
154{
155 Eina_Inlist *l;
156
157 /* MEM OK */
158 for (l = *list; l;)
159 {
160 Evas_Func_Node *fn;
161
162 fn = (Evas_Func_Node *)l;
163 l = l->next;
164 if (fn->delete_me)
165 {
166 *list = eina_inlist_remove(*list, EINA_INLIST_GET(fn));
167 EVAS_MEMPOOL_FREE(_mp_fn, fn);
168 }
169 }
170}
171
172static void
173evas_object_event_callback_clear(Evas_Object *eo_obj)
174{
175 Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
176 if (!obj->callbacks) return;
177 if (!obj->callbacks->deletions_waiting) return;
178 obj->callbacks->deletions_waiting = 0;
179 evas_event_callback_list_post_free(&obj->callbacks->callbacks);
180 if (!obj->callbacks->callbacks)
181 {
182 EVAS_MEMPOOL_FREE(_mp_cb, obj->callbacks);
183 obj->callbacks = NULL;
184 }
185}
186
187static void
188evas_event_callback_clear(Evas *eo_e)
189{
190 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
191 if (!e->callbacks) return;
192 if (!e->callbacks->deletions_waiting) return;
193 e->callbacks->deletions_waiting = 0;
194 evas_event_callback_list_post_free(&e->callbacks->callbacks);
195 if (!e->callbacks->callbacks)
196 {
197 EVAS_MEMPOOL_FREE(_mp_cb, e->callbacks);
198 e->callbacks = NULL;
199 }
200}
201
202void
203evas_object_event_callback_all_del(Evas_Object *eo_obj)
204{
205 Evas_Func_Node *fn;
206 Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
207
208 if (!obj->callbacks) return;
209 EINA_INLIST_FOREACH(obj->callbacks->callbacks, fn)
210 fn->delete_me = 1;
211}
212
213void
214evas_object_event_callback_cleanup(Evas_Object *eo_obj)
215{
216 /* MEM OK */
217 Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
218 if (!obj->callbacks) return;
219 evas_event_callback_list_post_free(&obj->callbacks->callbacks);
220 EVAS_MEMPOOL_FREE(_mp_cb, obj->callbacks);
221 obj->callbacks = NULL;
222}
223
224void
225evas_event_callback_all_del(Evas *eo_e)
226{
227 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
228 Evas_Func_Node *fn;
229
230 if (!e->callbacks) return;
231 EINA_INLIST_FOREACH(e->callbacks->callbacks, fn)
232 fn->delete_me = 1;
233}
234
235void
236evas_event_callback_cleanup(Evas *eo_e)
237{
238 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
239 /* MEM OK */
240 if (!e->callbacks) return;
241 evas_event_callback_list_post_free(&e->callbacks->callbacks);
242 EVAS_MEMPOOL_FREE(_mp_cb, e->callbacks);
243 e->callbacks = NULL;
244}
245
246void
247evas_event_callback_call(Evas *eo_e, Evas_Callback_Type type, void *event_info)
248{
249 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
250 Eina_Inlist **l_mod = NULL, *l;
251
252 _evas_walk(e);
253 if (e->callbacks)
254 {
255 l_mod = &e->callbacks->callbacks;
256 e->callbacks->walking_list++;
257 for (l = *l_mod; l; l = l->next)
258 {
259 Evas_Func_Node *fn;
260
261 fn = (Evas_Func_Node *)l;
262 if ((fn->type == type) && (!fn->delete_me))
263 {
264 Evas_Event_Cb func = fn->func;
265 if (func)
266 func(fn->data, eo_e, event_info);
267 }
268 if (e->delete_me) break;
269 }
270 e->callbacks->walking_list--;
271 if (!e->callbacks->walking_list)
272 {
273 evas_event_callback_clear(eo_e);
274 l_mod = NULL;
275 }
276 }
277 _evas_unwalk(e);
278}
279
280void
281evas_object_event_callback_call(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Callback_Type type, void *event_info, int event_id)
282{
283 /* MEM OK */
284 Eina_Inlist **l_mod = NULL, *l;
285 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
286 Evas_Public_Data *e;
287
288 if ((obj->delete_me) || (!obj->layer)) return;
289 if ((obj->last_event == event_id) &&
290 (obj->last_event_type == type)) return;
291 if (obj->last_event > event_id)
292 {
293 if ((obj->last_event_type == EVAS_CALLBACK_MOUSE_OUT) &&
294 ((type >= EVAS_CALLBACK_MOUSE_DOWN) &&
295 (type <= EVAS_CALLBACK_MULTI_MOVE)))
296 {
297 return;
298 }
299 }
300 obj->last_event = event_id;
301 obj->last_event_type = type;
302 if (!(e = obj->layer->evas)) return;
303
304 _evas_walk(e);
305 if (obj->callbacks)
306 {
307 l_mod = &obj->callbacks->callbacks;
308 switch (type)
309 {
310 case EVAS_CALLBACK_MOUSE_DOWN:
311 {
312 Evas_Event_Mouse_Down *ev = event_info;
313
314 flags = ev->flags;
315 if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
316 {
317 if (obj->last_mouse_down_counter < (e->last_mouse_down_counter - 1))
318 ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
319 }
320 obj->last_mouse_down_counter = e->last_mouse_down_counter;
321 break;
322 }
323 case EVAS_CALLBACK_MOUSE_UP:
324 {
325 Evas_Event_Mouse_Up *ev = event_info;
326
327 flags = ev->flags;
328 if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
329 {
330 if (obj->last_mouse_up_counter < (e->last_mouse_up_counter - 1))
331 ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
332 }
333 obj->last_mouse_up_counter = e->last_mouse_up_counter;
334 break;
335 }
336 default:
337 break;
338 }
339 obj->callbacks->walking_list++;
340 for (l = *l_mod; l; l = l->next)
341 {
342 Evas_Func_Node *fn;
343
344 fn = (Evas_Func_Node *)l;
345 if ((fn->type == type) && (!fn->delete_me))
346 {
347 Evas_Object_Event_Cb func = fn->func;
348 if (func)
349 func(fn->data, obj->layer->evas->evas, eo_obj, event_info);
350 }
351 if (obj->delete_me) break;
352 }
353 obj->callbacks->walking_list--;
354 if (!obj->callbacks->walking_list)
355 {
356 evas_object_event_callback_clear(eo_obj);
357 l_mod = NULL;
358 }
359
360 const Eo_Event_Description *event_desc = eina_hash_find(signals_hash_table, _legacy_evas_callback_table[type]->name);
361 if (event_desc)
362 eo_do(eo_obj, eo_event_callback_call(_legacy_evas_callback_table[type], event_info, NULL));
363
364 if (type == EVAS_CALLBACK_MOUSE_DOWN)
365 {
366 Evas_Event_Mouse_Down *ev = event_info;
367 ev->flags = flags;
368 }
369 else if (type == EVAS_CALLBACK_MOUSE_UP)
370 {
371 Evas_Event_Mouse_Up *ev = event_info;
372 ev->flags = flags;
373 }
374 }
375
376 if (!((obj->no_propagate) && (l_mod) && (*l_mod)))
377 {
378 if (!obj->no_propagate)
379 {
380 if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
381 (type <= EVAS_CALLBACK_KEY_UP))
382 {
383 Evas_Object_Protected_Data *smart_parent = eo_data_get(obj->smart.parent, EVAS_OBJ_CLASS);
384 evas_object_event_callback_call(obj->smart.parent, smart_parent, type, event_info, event_id);
385 }
386 }
387 }
388 _evas_unwalk(e);
389}
390
391static int
392_callback_priority_cmp(const void *_a, const void *_b)
393{
394 const Evas_Func_Node *a, *b;
395 a = EINA_INLIST_CONTAINER_GET(_a, Evas_Func_Node);
396 b = EINA_INLIST_CONTAINER_GET(_b, Evas_Func_Node);
397 if (a->priority < b->priority)
398 return -1;
399 else
400 return 1;
401}
402
403EAPI void
404evas_object_event_callback_add(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
405{
406 evas_object_event_callback_priority_add(eo_obj, type,
407 EVAS_CALLBACK_PRIORITY_DEFAULT, func, data);
408}
409
410EAPI void
411evas_object_event_callback_priority_add(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Object_Event_Cb func, const void *data)
412{
413 Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
414 /* MEM OK */
415 Evas_Func_Node *fn;
416
417 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
418 return;
419 MAGIC_CHECK_END();
420
421 if (!func) return;
422
423 if (!obj->callbacks)
424 {
425 EVAS_MEMPOOL_INIT(_mp_cb, "evas_callbacks", Evas_Callbacks, 64, );
426 obj->callbacks = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Callbacks);
427 if (!obj->callbacks) return;
428 EVAS_MEMPOOL_PREP(_mp_cb, obj->callbacks, Evas_Callbacks);
429 }
430
431 EVAS_MEMPOOL_INIT(_mp_fn, "evas_func_node", Evas_Func_Node, 128, );
432 fn = EVAS_MEMPOOL_ALLOC(_mp_fn, Evas_Func_Node);
433 if (!fn) return;
434 EVAS_MEMPOOL_PREP(_mp_fn, fn, Evas_Func_Node);
435 fn->func = func;
436 fn->data = (void *)data;
437 fn->type = type;
438 fn->priority = priority;
439
440 obj->callbacks->callbacks =
441 eina_inlist_sorted_insert(obj->callbacks->callbacks, EINA_INLIST_GET(fn),
442 _callback_priority_cmp);
443}
444
445EAPI void *
446evas_object_event_callback_del(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func)
447{
448 /* MEM OK */
449 Evas_Func_Node *fn;
450
451 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
452 return NULL;
453 MAGIC_CHECK_END();
454 Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
455
456 if (!func) return NULL;
457
458 if (!obj->callbacks) return NULL;
459
460 EINA_INLIST_FOREACH(obj->callbacks->callbacks, fn)
461 {
462 if ((fn->func == func) && (fn->type == type) && (!fn->delete_me))
463 {
464 void *tmp;
465
466 tmp = fn->data;
467 fn->delete_me = 1;
468 obj->callbacks->deletions_waiting = 1;
469 if (!obj->callbacks->walking_list)
470 evas_object_event_callback_clear(eo_obj);
471 return tmp;
472 }
473 }
474 return NULL;
475}
476
477EAPI void *
478evas_object_event_callback_del_full(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
479{
480 /* MEM OK */
481 Evas_Func_Node *fn;
482
483 MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
484 return NULL;
485 MAGIC_CHECK_END();
486 Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
487
488 if (!func) return NULL;
489
490 if (!obj->callbacks) return NULL;
491
492 EINA_INLIST_FOREACH(obj->callbacks->callbacks, fn)
493 {
494 if ((fn->func == func) && (fn->type == type) && (fn->data == data) && (!fn->delete_me))
495 {
496 void *tmp;
497
498 tmp = fn->data;
499 fn->delete_me = 1;
500 obj->callbacks->deletions_waiting = 1;
501 if (!obj->callbacks->walking_list)
502 evas_object_event_callback_clear(eo_obj);
503 return tmp;
504 }
505 }
506 return NULL;
507}
508
509EAPI void
510evas_event_callback_add(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data)
511{
512 evas_event_callback_priority_add(eo_e, type, EVAS_CALLBACK_PRIORITY_DEFAULT,
513 func, data);
514}
515
516EAPI void
517evas_event_callback_priority_add(Evas *eo_e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data)
518{
519 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
520 /* MEM OK */
521 Evas_Func_Node *fn;
522
523 MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
524 return;
525 MAGIC_CHECK_END();
526
527 if (!func) return;
528
529 if (!e->callbacks)
530 {
531 EVAS_MEMPOOL_INIT(_mp_cb, "evas_callbacks", Evas_Callbacks, 64, );
532 e->callbacks = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Callbacks);
533 if (!e->callbacks) return;
534 EVAS_MEMPOOL_PREP(_mp_cb, e->callbacks, Evas_Callbacks);
535 }
536
537 EVAS_MEMPOOL_INIT(_mp_fn, "evas_func_node", Evas_Func_Node, 128, );
538 fn = EVAS_MEMPOOL_ALLOC(_mp_fn, Evas_Func_Node);
539 if (!fn) return;
540 EVAS_MEMPOOL_PREP(_mp_fn, fn, Evas_Func_Node);
541 fn->func = func;
542 fn->data = (void *)data;
543 fn->type = type;
544 fn->priority = priority;
545
546 e->callbacks->callbacks = eina_inlist_sorted_insert(e->callbacks->callbacks,
547 EINA_INLIST_GET(fn), _callback_priority_cmp);
548}
549
550EAPI void *
551evas_event_callback_del(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func)
552{
553 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
554 /* MEM OK */
555 Evas_Func_Node *fn;
556
557 MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
558 return NULL;
559 MAGIC_CHECK_END();
560
561 if (!func) return NULL;
562
563 if (!e->callbacks) return NULL;
564
565 EINA_INLIST_FOREACH(e->callbacks->callbacks, fn)
566 {
567 if ((fn->func == func) && (fn->type == type) && (!fn->delete_me))
568 {
569 void *data;
570
571 data = fn->data;
572 fn->delete_me = 1;
573 e->callbacks->deletions_waiting = 1;
574 if (!e->callbacks->walking_list)
575 evas_event_callback_clear(eo_e);
576 return data;
577 }
578 }
579 return NULL;
580}
581
582EAPI void *
583evas_event_callback_del_full(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data)
584{
585 /* MEM OK */
586 Evas_Func_Node *fn;
587
588 MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
589 return NULL;
590 MAGIC_CHECK_END();
591 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
592
593 if (!func) return NULL;
594
595 if (!e->callbacks) return NULL;
596
597 EINA_INLIST_FOREACH(e->callbacks->callbacks, fn)
598 {
599 if ((fn->func == func) && (fn->type == type) && (fn->data == data) && (!fn->delete_me))
600 {
601 void *tmp;
602
603 tmp = fn->data;
604 fn->delete_me = 1;
605 e->callbacks->deletions_waiting = 1;
606 if (!e->callbacks->walking_list)
607 evas_event_callback_clear(eo_e);
608 return tmp;
609 }
610 }
611 return NULL;
612}
613
614EAPI void
615evas_post_event_callback_push(Evas *eo_e, Evas_Object_Event_Post_Cb func, const void *data)
616{
617 Evas_Post_Callback *pc;
618
619 MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
620 return;
621 MAGIC_CHECK_END();
622
623 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
624 EVAS_MEMPOOL_INIT(_mp_pc, "evas_post_callback", Evas_Post_Callback, 64, );
625 pc = EVAS_MEMPOOL_ALLOC(_mp_pc, Evas_Post_Callback);
626 if (!pc) return;
627 EVAS_MEMPOOL_PREP(_mp_pc, pc, Evas_Post_Callback);
628 if (e->delete_me) return;
629
630 pc->func = func;
631 pc->data = data;
632 e->post_events = eina_list_prepend(e->post_events, pc);
633}
634
635EAPI void
636evas_post_event_callback_remove(Evas *eo_e, Evas_Object_Event_Post_Cb func)
637{
638 Evas_Post_Callback *pc;
639 Eina_List *l;
640
641 MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
642 return;
643 MAGIC_CHECK_END();
644
645 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
646 EINA_LIST_FOREACH(e->post_events, l, pc)
647 {
648 if (pc->func == func)
649 {
650 pc->delete_me = 1;
651 return;
652 }
653 }
654}
655
656EAPI void
657evas_post_event_callback_remove_full(Evas *eo_e, Evas_Object_Event_Post_Cb func, const void *data)
658{
659 Evas_Post_Callback *pc;
660 Eina_List *l;
661
662 MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
663 return;
664 MAGIC_CHECK_END();
665
666 Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
667 EINA_LIST_FOREACH(e->post_events, l, pc)
668 {
669 if ((pc->func == func) && (pc->data == data))
670 {
671 pc->delete_me = 1;
672 return;
673 }
674 }
675}