1
2 #include "evas_common_private.h"
3 #include "evas_private.h"
4
5 EVAS_MEMPOOL(_mp_pc);
6
7 extern Eina_Hash* signals_hash_table;
8
9 /* Legacy events, do not use anywhere */
10 void _evas_object_smart_callback_call_internal(Evas_Object *eo_obj, const Efl_Event_Description *efl_event_desc);
11 static const Efl_Event_Description _EVAS_OBJECT_EVENT_FREE = EFL_EVENT_DESCRIPTION("free");
12 static const Efl_Event_Description _EVAS_OBJECT_EVENT_DEL = EFL_EVENT_DESCRIPTION("del");
13 #define EVAS_OBJECT_EVENT_FREE (&(_EVAS_OBJECT_EVENT_FREE))
14 #define EVAS_OBJECT_EVENT_DEL (&(_EVAS_OBJECT_EVENT_DEL))
15
16 /**
17 * Evas events descriptions for Eo.
18 */
19 #define DEFINE_EVAS_CALLBACKS(FUNC, LAST, ...) \
20 static const Efl_Event_Description *FUNC(unsigned int index) \
21 { \
22 static const Efl_Event_Description *internals[LAST] = { NULL }; \
23 \
24 if (index >= LAST) return NULL; \
25 if (internals[0] == NULL) \
26 { \
27 memcpy(internals, \
28 ((const Efl_Event_Description*[]) { __VA_ARGS__ }), \
29 sizeof ((const Efl_Event_Description *[]) { __VA_ARGS__ })); \
30 } \
31 return internals[index]; \
32 }
33
34 DEFINE_EVAS_CALLBACKS(_legacy_evas_callback_table, EVAS_CALLBACK_LAST,
35 EFL_EVENT_POINTER_IN,
36 EFL_EVENT_POINTER_OUT,
37 EFL_EVENT_POINTER_DOWN,
38 EFL_EVENT_POINTER_UP,
39 EFL_EVENT_POINTER_MOVE,
40 EFL_EVENT_POINTER_WHEEL,
41 EFL_EVENT_FINGER_DOWN,
42 EFL_EVENT_FINGER_UP,
43 EFL_EVENT_FINGER_MOVE,
44 EVAS_OBJECT_EVENT_FREE,
45 EFL_EVENT_KEY_DOWN,
46 EFL_EVENT_KEY_UP,
47 EFL_EVENT_FOCUS_IN,
48 EFL_EVENT_FOCUS_OUT,
49 EFL_GFX_ENTITY_EVENT_SHOW,
50 EFL_GFX_ENTITY_EVENT_HIDE,
51 EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
52 EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
53 EFL_GFX_ENTITY_EVENT_STACKING_CHANGED,
54 EVAS_OBJECT_EVENT_DEL,
55 EFL_EVENT_HOLD,
56 EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
57 EFL_GFX_IMAGE_EVENT_IMAGE_PRELOAD,
58 EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN,
59 EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT,
60 EVAS_CANVAS_EVENT_RENDER_FLUSH_PRE,
61 EVAS_CANVAS_EVENT_RENDER_FLUSH_POST,
62 EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN,
63 EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_OUT,
64 EFL_GFX_IMAGE_EVENT_IMAGE_UNLOAD,
65 EFL_CANVAS_SCENE_EVENT_RENDER_PRE,
66 EFL_CANVAS_SCENE_EVENT_RENDER_POST,
67 EFL_GFX_IMAGE_EVENT_IMAGE_RESIZED,
68 EFL_CANVAS_SCENE_EVENT_DEVICE_CHANGED,
69 EFL_EVENT_POINTER_AXIS,
70 EVAS_CANVAS_EVENT_VIEWPORT_RESIZE );
71
72 static inline Evas_Callback_Type
_legacy_evas_callback_type(const Efl_Event_Description * desc)73 _legacy_evas_callback_type(const Efl_Event_Description *desc)
74 {
75 Evas_Callback_Type type;
76
77 for (type = 0; type < EVAS_CALLBACK_LAST; type++)
78 {
79 if (_legacy_evas_callback_table(type) == desc)
80 return type;
81 }
82
83 return EVAS_CALLBACK_LAST;
84 }
85
86 typedef enum {
87 EFL_EVENT_TYPE_NULL,
88 EFL_EVENT_TYPE_OBJECT,
89 EFL_EVENT_TYPE_STRUCT,
90 EFL_EVENT_TYPE_POINTER,
91 EFL_EVENT_TYPE_KEY,
92 EFL_EVENT_TYPE_HOLD,
93 EFL_EVENT_TYPE_FOCUS
94 } Efl_Event_Info_Type;
95
96 typedef struct
97 {
98 EINA_INLIST;
99 union {
100 Evas_Event_Cb evas_cb;
101 Evas_Object_Event_Cb object_cb;
102 } func;
103 void *data;
104 Evas_Callback_Type type;
105 Efl_Event_Info_Type efl_event_type;
106 Evas_Callback_Priority priority;
107 } Evas_Event_Cb_Wrapper_Info;
108
109 static int
_evas_event_efl_event_info_type(Evas_Callback_Type type)110 _evas_event_efl_event_info_type(Evas_Callback_Type type)
111 {
112 switch (type)
113 {
114 case EVAS_CALLBACK_MOUSE_IN:
115 case EVAS_CALLBACK_MOUSE_OUT:
116 case EVAS_CALLBACK_MOUSE_DOWN:
117 case EVAS_CALLBACK_MOUSE_UP:
118 case EVAS_CALLBACK_MOUSE_MOVE:
119 case EVAS_CALLBACK_MOUSE_WHEEL:
120 case EVAS_CALLBACK_MULTI_DOWN:
121 case EVAS_CALLBACK_MULTI_UP:
122 case EVAS_CALLBACK_MULTI_MOVE:
123 case EVAS_CALLBACK_AXIS_UPDATE:
124 return EFL_EVENT_TYPE_POINTER;
125
126 case EVAS_CALLBACK_KEY_DOWN:
127 case EVAS_CALLBACK_KEY_UP:
128 return EFL_EVENT_TYPE_KEY;
129
130 case EVAS_CALLBACK_HOLD:
131 return EFL_EVENT_TYPE_HOLD;
132
133 case EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN:
134 case EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT: /* Efl.Canvas.Object */
135 return EFL_EVENT_TYPE_OBJECT;
136
137 case EVAS_CALLBACK_RENDER_POST: /* Efl_Gfx_Event_Render_Post */
138 return EFL_EVENT_TYPE_STRUCT;
139
140 case EVAS_CALLBACK_DEVICE_CHANGED: /* Efl.Input.Device */
141 return EFL_EVENT_TYPE_OBJECT;
142
143 case EVAS_CALLBACK_FOCUS_IN:
144 case EVAS_CALLBACK_FOCUS_OUT:
145 return EFL_EVENT_TYPE_FOCUS;
146
147 default:
148 return EFL_EVENT_TYPE_NULL;
149 }
150 }
151
152 static void
_eo_evas_object_cb(void * data,const Efl_Event * event)153 _eo_evas_object_cb(void *data, const Efl_Event *event)
154 {
155 Evas_Event_Flags *event_flags = NULL, evflags = EVAS_EVENT_FLAG_NONE;
156 Efl_Input_Event *efl_event_info = event->info;
157 Evas_Event_Cb_Wrapper_Info *info = data;
158 void *event_info;
159 Evas *evas;
160
161 if (!info->func.object_cb) return;
162 evas = evas_object_evas_get(event->object);
163
164 event_info = event->info;
165 switch (info->efl_event_type)
166 {
167 case EFL_EVENT_TYPE_POINTER:
168 event_info = efl_input_pointer_legacy_info_fill(evas, efl_event_info, info->type, &event_flags);
169 break;
170
171 case EFL_EVENT_TYPE_KEY:
172 event_info = efl_input_key_legacy_info_fill(efl_event_info, &event_flags);
173 break;
174
175 case EFL_EVENT_TYPE_HOLD:
176 event_info = efl_input_hold_legacy_info_fill(efl_event_info, &event_flags);
177 break;
178
179 case EFL_EVENT_TYPE_FOCUS:
180 case EFL_EVENT_TYPE_NULL:
181 info->func.object_cb(info->data, evas, event->object, NULL);
182 return;
183
184 case EFL_EVENT_TYPE_STRUCT:
185 case EFL_EVENT_TYPE_OBJECT:
186 info->func.object_cb(info->data, evas, event->object, event_info);
187 return;
188
189 default: return;
190 }
191
192 if (!event_info) return;
193 if (event_flags) evflags = *event_flags;
194 info->func.object_cb(info->data, evas, event->object, event_info);
195 if (event_flags && (evflags != *event_flags))
196 efl_input_event_flags_set(efl_event_info,
197 (Efl_Input_Flags)*event_flags);
198 }
199
200 static void
_eo_evas_cb(void * data,const Efl_Event * event)201 _eo_evas_cb(void *data, const Efl_Event *event)
202 {
203 Evas_Event_Cb_Wrapper_Info *info = data;
204 Efl_Input_Event *efl_event_info = event->info;
205 Evas *evas = event->object;
206 void *event_info;
207
208 if (!info->func.evas_cb) return;
209
210 if (event->desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_IN ||
211 event->desc == EFL_CANVAS_SCENE_EVENT_OBJECT_FOCUS_OUT)
212 {
213 event_info = efl_input_focus_object_get(efl_event_info);
214 goto emit;
215 }
216
217 event_info = event->info;
218 switch (info->efl_event_type)
219 {
220 case EFL_EVENT_TYPE_POINTER:
221 event_info = efl_input_pointer_legacy_info_fill(evas, efl_event_info, info->type, NULL);
222 break;
223
224 case EFL_EVENT_TYPE_KEY:
225 event_info = efl_input_key_legacy_info_fill(efl_event_info, NULL);
226 break;
227
228 case EFL_EVENT_TYPE_HOLD:
229 event_info = efl_input_hold_legacy_info_fill(efl_event_info, NULL);
230 break;
231
232 case EFL_EVENT_TYPE_FOCUS:
233 case EFL_EVENT_TYPE_NULL:
234 event_info = NULL;
235 break;
236
237 case EFL_EVENT_TYPE_STRUCT:
238 case EFL_EVENT_TYPE_OBJECT:
239 break;
240 }
241
242 emit:
243 info->func.evas_cb(info->data, event->object, event_info);
244 }
245
246 void
_evas_post_event_callback_call_real(Evas * eo_e,Evas_Public_Data * e,int min_event_id)247 _evas_post_event_callback_call_real(Evas *eo_e, Evas_Public_Data *e, int min_event_id)
248 {
249 Evas_Post_Callback *pc;
250 Eina_List *l, *l_next;
251 int skip = 0;
252
253 if (e->delete_me) return;
254
255 _evas_walk(e);
256 e->running_post_events++;
257 EINA_LIST_FOREACH_SAFE(e->post_events, l, l_next, pc)
258 {
259 if ((unsigned int) pc->event_id < (unsigned int) min_event_id) break;
260 e->post_events = eina_list_remove_list(e->post_events, l);
261 if ((!skip) && (!e->delete_me) && (!pc->delete_me))
262 {
263 if (!pc->func((void*)pc->data, eo_e)) skip = 1;
264 }
265 EVAS_MEMPOOL_FREE(_mp_pc, pc);
266 }
267 e->running_post_events--;
268 _evas_unwalk(e);
269
270 if (!e->running_post_events && e->post_events
271 && (e->current_event == EVAS_CALLBACK_LAST))
272 {
273 WRN("Not all post-event callbacks have been processed!");
274 _evas_post_event_callback_call_real(eo_e, e, 0);
275 }
276 }
277
278 void
_evas_post_event_callback_free(Evas * eo_e)279 _evas_post_event_callback_free(Evas *eo_e)
280 {
281 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
282 Evas_Post_Callback *pc;
283
284 if (EINA_LIKELY(!e->post_events)) return;
285
286 EINA_LIST_FREE(e->post_events, pc)
287 {
288 EVAS_MEMPOOL_FREE(_mp_pc, pc);
289 }
290 }
291
292 void
evas_object_event_callback_all_del(Evas_Object * eo_obj)293 evas_object_event_callback_all_del(Evas_Object *eo_obj)
294 {
295 Evas_Event_Cb_Wrapper_Info *info;
296 Eina_Inlist *itr;
297 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
298
299 if (!obj) return;
300 if (!obj->callbacks) return;
301 EINA_INLIST_FOREACH_SAFE(obj->callbacks, itr, info)
302 {
303 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(info->type), _eo_evas_object_cb, info);
304
305 obj->callbacks =
306 eina_inlist_remove(obj->callbacks, EINA_INLIST_GET(info));
307 free(info);
308 }
309 }
310
311 void
evas_object_event_callback_cleanup(Evas_Object * eo_obj)312 evas_object_event_callback_cleanup(Evas_Object *eo_obj)
313 {
314 evas_object_event_callback_all_del(eo_obj);
315 }
316
317 void
evas_event_callback_all_del(Evas * eo_e)318 evas_event_callback_all_del(Evas *eo_e)
319 {
320 Evas_Event_Cb_Wrapper_Info *info;
321 Eina_Inlist *itr;
322 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
323
324 if (!e) return;
325 if (!e->callbacks) return;
326
327 EINA_INLIST_FOREACH_SAFE(e->callbacks, itr, info)
328 {
329 efl_event_callback_del(eo_e, _legacy_evas_callback_table(info->type), _eo_evas_cb, info);
330
331 e->callbacks =
332 eina_inlist_remove(e->callbacks, EINA_INLIST_GET(info));
333 free(info);
334 }
335 }
336
337 void
evas_event_callback_cleanup(Evas * eo_e)338 evas_event_callback_cleanup(Evas *eo_e)
339 {
340 evas_event_callback_all_del(eo_e);
341 }
342
343 void
evas_event_callback_call(Evas * eo_e,Evas_Callback_Type type,void * event_info)344 evas_event_callback_call(Evas *eo_e, Evas_Callback_Type type, void *event_info)
345 {
346 efl_event_callback_legacy_call(eo_e, _legacy_evas_callback_table(type), event_info);
347 }
348
349 static void
_evas_callback_legacy_smart_compatibility_do_it(Evas_Object * eo_obj,const Efl_Event_Description * efl_event_desc,void * event_info)350 _evas_callback_legacy_smart_compatibility_do_it(Evas_Object *eo_obj, const Efl_Event_Description *efl_event_desc, void *event_info)
351 {
352 /* this is inverted: the base call is the legacy compat and this is the new event */
353 if ((efl_event_desc == EFL_GFX_ENTITY_EVENT_SHOW) || (efl_event_desc == EFL_GFX_ENTITY_EVENT_HIDE))
354 efl_event_callback_call(eo_obj, EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, event_info);
355 else if ((efl_event_desc == EFL_GFX_IMAGE_EVENT_IMAGE_PRELOAD) || (efl_event_desc == EFL_GFX_IMAGE_EVENT_IMAGE_UNLOAD))
356 efl_event_callback_call(eo_obj, EFL_GFX_IMAGE_EVENT_IMAGE_PRELOAD_STATE_CHANGED, event_info);
357 }
358
359
360 void
evas_object_event_callback_call(Evas_Object * eo_obj,Evas_Object_Protected_Data * obj,Evas_Callback_Type type,void * event_info,int event_id,const Efl_Event_Description * efl_event_desc)361 evas_object_event_callback_call(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
362 Evas_Callback_Type type, void *event_info, int event_id,
363 const Efl_Event_Description *efl_event_desc)
364 {
365 /* MEM OK */
366 const Evas_Button_Flags CLICK_MASK = EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK;
367 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
368 Evas_Callback_Type prev_type;
369 Evas_Public_Data *e;
370
371 if (!obj) return;
372 if ((obj->delete_me) || (!obj->layer)) return;
373 if ((obj->last_event_id == event_id) &&
374 (obj->last_event_type == type)) return;
375 if (obj->last_event_id > event_id)
376 {
377 if ((obj->last_event_type == EVAS_CALLBACK_MOUSE_OUT) &&
378 ((type >= EVAS_CALLBACK_MOUSE_DOWN) &&
379 (type <= EVAS_CALLBACK_MULTI_MOVE)))
380 {
381 return;
382 }
383 }
384 obj->last_event_id = event_id;
385 obj->last_event_type = type;
386 if (!(e = obj->layer->evas)) return;
387
388 _evas_walk(e);
389
390 // gesture hook
391 if ( type == EVAS_CALLBACK_MOUSE_MOVE ||
392 type == EVAS_CALLBACK_MULTI_MOVE ||
393 type == EVAS_CALLBACK_MOUSE_DOWN ||
394 type == EVAS_CALLBACK_MULTI_DOWN ||
395 type == EVAS_CALLBACK_MOUSE_UP ||
396 type == EVAS_CALLBACK_MULTI_UP)
397 _efl_canvas_gesture_manager_filter_event(e->gmd, eo_obj, event_info);
398
399 if (obj->is_smart)
400 _evas_object_smart_callback_call_internal(eo_obj, efl_event_desc);
401
402 if (!_evas_object_callback_has_by_type(obj, type))
403 goto nothing_here;
404
405 if ((type == EVAS_CALLBACK_MOUSE_DOWN) || (type == EVAS_CALLBACK_MOUSE_UP))
406 {
407 flags = (Evas_Button_Flags)efl_input_pointer_button_flags_get(event_info);
408 if (flags & CLICK_MASK)
409 {
410 if (obj->last_mouse_down_counter < (e->last_mouse_down_counter - 1))
411 efl_input_pointer_button_flags_set(event_info, flags & ~CLICK_MASK);
412 }
413 obj->last_mouse_down_counter = e->last_mouse_down_counter;
414 }
415
416 if (!efl_event_desc)
417 {
418 /* This can happen for DEL and FREE which are defined only in here */
419 efl_event_desc = _legacy_evas_callback_table(type);
420 }
421
422 prev_type = e->current_event;
423 e->current_event = type;
424
425 efl_event_callback_legacy_call(eo_obj, efl_event_desc, event_info);
426 _evas_callback_legacy_smart_compatibility_do_it(eo_obj, efl_event_desc, event_info);
427
428 /* multi events with finger 0 - only for eo callbacks */
429 if (type == EVAS_CALLBACK_MOUSE_DOWN)
430 {
431 if (_evas_object_callback_has_by_type(obj, EVAS_CALLBACK_MULTI_DOWN))
432 {
433 e->current_event = EVAS_CALLBACK_MULTI_DOWN;
434 efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_DOWN, event_info);
435 }
436 efl_input_pointer_button_flags_set(event_info, (Efl_Pointer_Flags) flags);
437 }
438 else if (type == EVAS_CALLBACK_MOUSE_UP)
439 {
440 if (_evas_object_callback_has_by_type(obj, EVAS_CALLBACK_MULTI_UP))
441 {
442 e->current_event = EVAS_CALLBACK_MULTI_UP;
443 efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_UP, event_info);
444 }
445 efl_input_pointer_button_flags_set(event_info, (Efl_Pointer_Flags)flags);
446 }
447 else if (type == EVAS_CALLBACK_MOUSE_MOVE)
448 {
449 if (_evas_object_callback_has_by_type(obj, EVAS_CALLBACK_MULTI_MOVE))
450 {
451 e->current_event = EVAS_CALLBACK_MULTI_MOVE;
452 efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_MOVE, event_info);
453 }
454 }
455
456 e->current_event = prev_type;
457
458 nothing_here:
459 if (!obj->no_propagate)
460 {
461 if ((obj->smart.parent || ((obj->events) && obj->events->parent)) &&
462 (type != EVAS_CALLBACK_FREE) &&
463 (type <= EVAS_CALLBACK_KEY_UP))
464 {
465 Evas_Object_Protected_Data *parent_obj;
466 Eo *parent;
467
468 parent = ((obj->events) && obj->events->parent) ?
469 obj->events->parent: obj->smart.parent;
470 parent_obj = efl_data_scope_get(parent, EFL_CANVAS_OBJECT_CLASS);
471 evas_object_event_callback_call(parent, parent_obj, type, event_info, event_id, efl_event_desc);
472 }
473 }
474 _evas_unwalk(e);
475 }
476
477 EAPI void
evas_object_event_callback_add(Evas_Object * eo_obj,Evas_Callback_Type type,Evas_Object_Event_Cb func,const void * data)478 evas_object_event_callback_add(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
479 {
480 evas_object_event_callback_priority_add(eo_obj, type,
481 EVAS_CALLBACK_PRIORITY_DEFAULT, func, data);
482 }
483
484 EAPI void
evas_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)485 evas_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)
486 {
487 Evas_Object_Protected_Data *obj;
488 Evas_Event_Cb_Wrapper_Info *cb_info;
489 const Efl_Event_Description *desc;
490
491 EINA_SAFETY_ON_NULL_RETURN(eo_obj);
492 EINA_SAFETY_ON_NULL_RETURN(func);
493
494 EINA_SAFETY_ON_TRUE_RETURN(efl_invalidated_get(eo_obj));
495
496 obj = efl_data_scope_safe_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
497 EINA_SAFETY_ON_NULL_RETURN(obj);
498
499 cb_info = calloc(1, sizeof(*cb_info));
500 cb_info->func.object_cb = func;
501 cb_info->data = (void *)data;
502 cb_info->type = type;
503 cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
504
505 desc = _legacy_evas_callback_table(type);
506 efl_event_callback_priority_add(eo_obj, desc, priority, _eo_evas_object_cb, cb_info);
507
508 obj->callbacks =
509 eina_inlist_append(obj->callbacks, EINA_INLIST_GET(cb_info));
510 }
511
512 EAPI void *
evas_object_event_callback_del(Evas_Object * eo_obj,Evas_Callback_Type type,Evas_Object_Event_Cb func)513 evas_object_event_callback_del(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func)
514 {
515 Evas_Object_Protected_Data *obj;
516 Evas_Event_Cb_Wrapper_Info *info;
517
518 if (!eo_obj) return NULL;
519 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
520
521 obj = efl_data_scope_safe_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
522 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
523
524 if (!obj->callbacks) return NULL;
525
526 EINA_INLIST_REVERSE_FOREACH(obj->callbacks, info)
527 {
528 if ((info->func.object_cb == func) && (info->type == type))
529 {
530 void *tmp = info->data;
531 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(type), _eo_evas_object_cb, info);
532
533 obj->callbacks =
534 eina_inlist_remove(obj->callbacks, EINA_INLIST_GET(info));
535 free(info);
536 return tmp;
537 }
538 }
539 return NULL;
540 }
541
542 EAPI void *
evas_object_event_callback_del_full(Evas_Object * eo_obj,Evas_Callback_Type type,Evas_Object_Event_Cb func,const void * data)543 evas_object_event_callback_del_full(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
544 {
545 Evas_Object_Protected_Data *obj;
546 Evas_Event_Cb_Wrapper_Info *info;
547
548 if (!eo_obj) return NULL;
549 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
550
551 obj = efl_data_scope_safe_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
552 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
553
554 if (!obj->callbacks) return NULL;
555
556 EINA_INLIST_FOREACH(obj->callbacks, info)
557 {
558 if ((info->func.object_cb == func) && (info->type == type) && info->data == data)
559 {
560 void *tmp = info->data;
561 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(type), _eo_evas_object_cb, info);
562
563 obj->callbacks =
564 eina_inlist_remove(obj->callbacks, EINA_INLIST_GET(info));
565 free(info);
566 return tmp;
567 }
568 }
569 return NULL;
570 }
571
572 EAPI void
evas_event_callback_add(Evas * eo_e,Evas_Callback_Type type,Evas_Event_Cb func,const void * data)573 evas_event_callback_add(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data)
574 {
575 evas_event_callback_priority_add(eo_e, type, EVAS_CALLBACK_PRIORITY_DEFAULT,
576 func, data);
577 }
578
579 void
_deferred_callbacks_process(Evas * eo_e,Evas_Public_Data * e)580 _deferred_callbacks_process(Evas *eo_e, Evas_Public_Data *e)
581 {
582 Evas_Event_Cb_Wrapper_Info *cb_info;
583 const Efl_Event_Description *desc;
584
585 while (e->deferred_callbacks)
586 {
587 cb_info = EINA_INLIST_CONTAINER_GET(e->deferred_callbacks,
588 Evas_Event_Cb_Wrapper_Info);
589 e->deferred_callbacks = eina_inlist_remove(e->deferred_callbacks,
590 e->deferred_callbacks);
591 desc = _legacy_evas_callback_table(cb_info->type);
592 efl_event_callback_priority_add(eo_e, desc, cb_info->priority, _eo_evas_cb, cb_info);
593 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info));
594 }
595 }
596
597 EAPI void
evas_event_callback_priority_add(Evas * eo_e,Evas_Callback_Type type,Evas_Callback_Priority priority,Evas_Event_Cb func,const void * data)598 evas_event_callback_priority_add(Evas *eo_e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data)
599 {
600 Evas_Public_Data *e;
601 Evas_Event_Cb_Wrapper_Info *cb_info;
602 const Efl_Event_Description *desc;
603
604 EINA_SAFETY_ON_NULL_RETURN(eo_e);
605 EINA_SAFETY_ON_NULL_RETURN(func);
606
607 EINA_SAFETY_ON_TRUE_RETURN(efl_invalidated_get(eo_e));
608
609 e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
610 EINA_SAFETY_ON_NULL_RETURN(e);
611
612 cb_info = calloc(1, sizeof(*cb_info));
613 cb_info->func.evas_cb = func;
614 cb_info->data = (void *)data;
615 cb_info->priority = priority;
616 cb_info->type = type;
617 cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
618
619 if ((e->rendering || e->inside_post_render) && type == EVAS_CALLBACK_RENDER_POST)
620 {
621 e->deferred_callbacks = eina_inlist_append(e->deferred_callbacks,
622 EINA_INLIST_GET(cb_info));
623 }
624 else
625 {
626 desc = _legacy_evas_callback_table(type);
627 efl_event_callback_priority_add(eo_e, desc, priority, _eo_evas_cb, cb_info);
628
629 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info));
630 }
631 }
632
633 EAPI void *
evas_event_callback_del(Evas * eo_e,Evas_Callback_Type type,Evas_Event_Cb func)634 evas_event_callback_del(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func)
635 {
636 Evas_Public_Data *e;
637 Evas_Event_Cb_Wrapper_Info *info;
638
639 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_e, NULL);
640 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
641
642 e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
643 EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
644
645 if (!e->callbacks) return NULL;
646
647 if (type == EVAS_CALLBACK_RENDER_POST)
648 EINA_INLIST_REVERSE_FOREACH(e->deferred_callbacks, info)
649 {
650 if (info->func.evas_cb == func)
651 {
652 void *tmp = info->data;
653
654 e->deferred_callbacks =
655 eina_inlist_remove(e->deferred_callbacks, EINA_INLIST_GET(info));
656 free(info);
657 return tmp;
658 }
659 }
660
661 EINA_INLIST_REVERSE_FOREACH(e->callbacks, info)
662 {
663 if ((info->func.evas_cb == func) && (info->type == type))
664 {
665 void *tmp = info->data;
666 efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info);
667
668 e->callbacks =
669 eina_inlist_remove(e->callbacks, EINA_INLIST_GET(info));
670 free(info);
671 return tmp;
672 }
673 }
674 return NULL;
675 }
676
677 EAPI void *
evas_event_callback_del_full(Evas * eo_e,Evas_Callback_Type type,Evas_Event_Cb func,const void * data)678 evas_event_callback_del_full(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data)
679 {
680 Evas_Public_Data *e;
681 Evas_Event_Cb_Wrapper_Info *info;
682
683 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_e, NULL);
684 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
685
686 e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
687 EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
688
689 if (!e->callbacks) return NULL;
690
691 if (type == EVAS_CALLBACK_RENDER_POST)
692 EINA_INLIST_REVERSE_FOREACH(e->deferred_callbacks, info)
693 {
694 if ((info->func.evas_cb == func) && (info->data == data))
695 {
696 void *tmp = info->data;
697
698 e->deferred_callbacks =
699 eina_inlist_remove(e->deferred_callbacks, EINA_INLIST_GET(info));
700 free(info);
701 return tmp;
702 }
703 }
704
705 EINA_INLIST_FOREACH(e->callbacks, info)
706 {
707 if ((info->func.evas_cb == func) && (info->type == type) && (info->data == data))
708 {
709 void *tmp = info->data;
710 efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info);
711
712 e->callbacks =
713 eina_inlist_remove(e->callbacks, EINA_INLIST_GET(info));
714 free(info);
715 return tmp;
716 }
717 }
718 return NULL;
719 }
720
721 EAPI void
evas_post_event_callback_push(Evas * eo_e,Evas_Object_Event_Post_Cb func,const void * data)722 evas_post_event_callback_push(Evas *eo_e, Evas_Object_Event_Post_Cb func, const void *data)
723 {
724 Evas_Public_Data *e;
725 Evas_Post_Callback *pc;
726
727 EINA_SAFETY_ON_NULL_RETURN(eo_e);
728 EINA_SAFETY_ON_TRUE_RETURN(efl_invalidated_get(eo_e));
729
730 e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
731 EINA_SAFETY_ON_NULL_RETURN(e);
732 if (e->delete_me) return;
733 if (e->current_event == EVAS_CALLBACK_LAST)
734 {
735 ERR("%s() can only be called from an input event callback!", __func__);
736 return;
737 }
738 EVAS_MEMPOOL_INIT(_mp_pc, "evas_post_callback", Evas_Post_Callback, 64, );
739 pc = EVAS_MEMPOOL_ALLOC(_mp_pc, Evas_Post_Callback);
740 if (!pc) return;
741 EVAS_MEMPOOL_PREP(_mp_pc, pc, Evas_Post_Callback);
742
743 pc->func = func;
744 pc->data = data;
745 pc->type = e->current_event;
746 pc->event_id = _evas_event_counter;
747 e->post_events = eina_list_prepend(e->post_events, pc);
748 }
749
750 EAPI void
evas_post_event_callback_remove(Evas * eo_e,Evas_Object_Event_Post_Cb func)751 evas_post_event_callback_remove(Evas *eo_e, Evas_Object_Event_Post_Cb func)
752 {
753 Evas_Public_Data *e;
754 Evas_Post_Callback *pc;
755 Eina_List *l;
756
757 EINA_SAFETY_ON_NULL_RETURN(eo_e);
758
759 e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
760 EINA_SAFETY_ON_NULL_RETURN(e);
761 EINA_LIST_FOREACH(e->post_events, l, pc)
762 {
763 if (pc->func == func)
764 {
765 pc->delete_me = 1;
766 return;
767 }
768 }
769 }
770
771 EAPI void
evas_post_event_callback_remove_full(Evas * eo_e,Evas_Object_Event_Post_Cb func,const void * data)772 evas_post_event_callback_remove_full(Evas *eo_e, Evas_Object_Event_Post_Cb func, const void *data)
773 {
774 Evas_Public_Data *e;
775 Evas_Post_Callback *pc;
776 Eina_List *l;
777
778 EINA_SAFETY_ON_NULL_RETURN(eo_e);
779
780 e = efl_data_scope_safe_get(eo_e, EVAS_CANVAS_CLASS);
781 EINA_SAFETY_ON_NULL_RETURN(e);
782 EINA_LIST_FOREACH(e->post_events, l, pc)
783 {
784 if ((pc->func == func) && (pc->data == data))
785 {
786 pc->delete_me = 1;
787 return;
788 }
789 }
790 }
791
792 static void
_animator_repeater(void * data,const Efl_Event * event)793 _animator_repeater(void *data, const Efl_Event *event)
794 {
795 Evas_Object_Protected_Data *obj = data;
796
797 efl_event_callback_legacy_call(obj->object, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, event->info);
798 DBG("Emitting animator tick on %p.", obj->object);
799 }
800
801 void
evas_object_callbacks_finalized(Eo * eo_obj EINA_UNUSED,Evas_Object_Protected_Data * obj)802 evas_object_callbacks_finalized(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
803 {
804 EINA_SAFETY_ON_NULL_RETURN(obj);
805
806 if (obj->animator_ref > 0)
807 {
808 if (obj->layer && obj->layer->evas)
809 {
810 efl_event_callback_add(obj->layer->evas->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_repeater, obj);
811 DBG("Registering an animator tick on canvas %p for object %p.",
812 obj->layer->evas->evas, obj->object);
813 }
814 }
815 }
816
817 void
evas_object_callbacks_event_catcher_add(Eo * eo_obj EINA_UNUSED,Evas_Object_Protected_Data * obj,const Efl_Callback_Array_Item * array)818 evas_object_callbacks_event_catcher_add(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, const Efl_Callback_Array_Item *array)
819 {
820 Evas_Callback_Type type = EVAS_CALLBACK_LAST;
821 int i;
822
823 for (i = 0; array[i].desc != NULL; i++)
824 {
825 if (obj->layer && obj->layer->evas && obj->layer->evas->gesture_manager)
826 _efl_canvas_gesture_manager_callback_add_hook(obj->layer->evas->gmd, obj->object, array[i].desc);
827
828 if (array[i].desc == EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK)
829 {
830 if (obj->animator_ref++ > 0) break;
831
832 if (efl_finalized_get(eo_obj))
833 {
834 efl_event_callback_add(obj->layer->evas->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_repeater, obj);
835 DBG("Registering an animator tick on canvas %p for object %p.",
836 obj->layer->evas->evas, obj->object);
837 }
838 }
839 else if ((type = _legacy_evas_callback_type(array[i].desc)) != EVAS_CALLBACK_LAST)
840 {
841 obj->callback_mask |= (((uint64_t)1) << type);
842 }
843 else if (array[i].desc == EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED)
844 {
845 obj->callback_mask |= (((uint64_t)1) << EVAS_CALLBACK_SHOW);
846 obj->callback_mask |= (((uint64_t)1) << EVAS_CALLBACK_HIDE);
847 }
848 }
849 }
850
851 void
evas_object_callbacks_event_catcher_del(Eo * eo_obj EINA_UNUSED,Evas_Object_Protected_Data * obj,const Efl_Callback_Array_Item * array)852 evas_object_callbacks_event_catcher_del(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, const Efl_Callback_Array_Item *array)
853 {
854 int i;
855
856 if (!obj->layer ||
857 !obj->layer->evas)
858 return ;
859
860 for (i = 0; array[i].desc != NULL; i++)
861 {
862 if (obj->layer->evas->gesture_manager)
863 _efl_canvas_gesture_manager_callback_del_hook(obj->layer->evas->gmd, obj->object, array[i].desc);
864
865 if (array[i].desc == EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK)
866 {
867 if ((--obj->animator_ref) > 0) break;
868
869 efl_event_callback_del(obj->layer->evas->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_repeater, obj);
870 DBG("Unregistering an animator tick on canvas %p for object %p.",
871 obj->layer->evas->evas, obj->object);
872 }
873 }
874 }
875
876 void
evas_object_callbacks_shutdown(Eo * eo_obj EINA_UNUSED,Evas_Object_Protected_Data * obj)877 evas_object_callbacks_shutdown(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
878 {
879 if (obj->animator_ref > 0)
880 efl_event_callback_del(obj->layer->evas->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_repeater, obj);
881 obj->animator_ref = 0;
882 }
883