summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-09-04 21:18:18 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-09-11 10:37:21 +0200
commit6028952894030de48a199f1633ad83367d33e63e (patch)
tree46c19458c3daef676a648e59fedd98cc5d884cd7
parentf684e85453a5ecc13d8ab8e05ba009366b3ad478 (diff)
evas_callbacks: make the callback protection a little bit safer
the problem here is that we might subscribe to an event before evas_object_callbacks_init has happened. This sounds like something which might not happen. However, with the interfaces project this definitly will start to happen because someone will some day overwrite the evas object and do something before the constructor, which will not raise a error or something but will simply just not work. With this commit we are not listening to the event callbacks via event emission but rather via inheritance. With this there is no "earlier than we listend" point, and the issue in the task is solved by itself. fix T8202 Reviewed-by: Jaehyun Cho <jae_hyun.cho@samsung.com> Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D9841
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c52
-rw-r--r--src/lib/evas/canvas/evas_object_main.c76
-rw-r--r--src/lib/evas/include/evas_private.h6
3 files changed, 102 insertions, 32 deletions
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index 0e9be65..1ef776f 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -800,18 +800,30 @@ _animator_repeater(void *data, const Efl_Event *event)
800 DBG("Emitting animator tick on %p.", obj->object); 800 DBG("Emitting animator tick on %p.", obj->object);
801} 801}
802 802
803static void 803void
804_check_event_catcher_add(void *data, const Efl_Event *event) 804evas_object_callbacks_finalized(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *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
817void
818evas_object_callbacks_event_catcher_add(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, const Efl_Callback_Array_Item *array)
805{ 819{
806 const Efl_Callback_Array_Item_Full *array = event->info;
807 Evas_Object_Protected_Data *obj = data;
808 Evas_Callback_Type type = EVAS_CALLBACK_LAST; 820 Evas_Callback_Type type = EVAS_CALLBACK_LAST;
809 void *gd = NULL; 821 void *gd = NULL;
810 int i; 822 int i;
811 823
812 for (i = 0; array[i].desc != NULL; i++) 824 for (i = 0; array[i].desc != NULL; i++)
813 { 825 {
814 if (obj->layer->evas->gesture_manager) 826 if (obj->layer && obj->layer->evas && obj->layer->evas->gesture_manager)
815 { 827 {
816 if (!gd) gd = _efl_canvas_gesture_manager_private_data_get(obj->layer->evas->gesture_manager); 828 if (!gd) gd = _efl_canvas_gesture_manager_private_data_get(obj->layer->evas->gesture_manager);
817 829
@@ -822,9 +834,12 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
822 { 834 {
823 if (obj->animator_ref++ > 0) break; 835 if (obj->animator_ref++ > 0) break;
824 836
825 efl_event_callback_add(obj->layer->evas->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_repeater, obj); 837 if (efl_finalized_get(eo_obj))
826 DBG("Registering an animator tick on canvas %p for object %p.", 838 {
827 obj->layer->evas->evas, obj->object); 839 efl_event_callback_add(obj->layer->evas->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_repeater, obj);
840 DBG("Registering an animator tick on canvas %p for object %p.",
841 obj->layer->evas->evas, obj->object);
842 }
828 } 843 }
829 else if ((type = _legacy_evas_callback_type(array[i].desc)) != EVAS_CALLBACK_LAST) 844 else if ((type = _legacy_evas_callback_type(array[i].desc)) != EVAS_CALLBACK_LAST)
830 { 845 {
@@ -838,11 +853,9 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
838 } 853 }
839} 854}
840 855
841static void 856void
842_check_event_catcher_del(void *data, const Efl_Event *event) 857evas_object_callbacks_event_catcher_del(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, const Efl_Callback_Array_Item *array)
843{ 858{
844 const Efl_Callback_Array_Item_Full *array = event->info;
845 Evas_Object_Protected_Data *obj = data;
846 void *gd = NULL; 859 void *gd = NULL;
847 int i; 860 int i;
848 861
@@ -870,18 +883,3 @@ _check_event_catcher_del(void *data, const Efl_Event *event)
870 } 883 }
871} 884}
872 885
873EFL_CALLBACKS_ARRAY_DEFINE(event_catcher_watch,
874 { EFL_EVENT_CALLBACK_ADD, _check_event_catcher_add },
875 { EFL_EVENT_CALLBACK_DEL, _check_event_catcher_del });
876
877void
878evas_object_callback_init(Efl_Canvas_Object *eo_obj, Evas_Object_Protected_Data *obj)
879{
880 efl_event_callback_array_add(eo_obj, event_catcher_watch(), obj);
881}
882
883void
884evas_object_callback_shutdown(Efl_Canvas_Object *eo_obj, Evas_Object_Protected_Data *obj)
885{
886 efl_event_callback_array_del(eo_obj, event_catcher_watch(), obj);
887}
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index c5f7b2f..95ee8a2 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -225,7 +225,6 @@ _efl_canvas_object_efl_object_constructor(Eo *eo_obj, Evas_Object_Protected_Data
225 obj->events = eina_cow_alloc(evas_object_events_cow); 225 obj->events = eina_cow_alloc(evas_object_events_cow);
226 226
227 evas_object_inject(eo_obj, obj, evas); 227 evas_object_inject(eo_obj, obj, evas);
228 evas_object_callback_init(eo_obj, obj);
229 228
230 return eo_obj; 229 return eo_obj;
231 230
@@ -255,6 +254,7 @@ _efl_canvas_object_efl_object_finalize(Eo *eo_obj, Evas_Object_Protected_Data *o
255 e->finalize_objects = eina_list_prepend(e->finalize_objects, eo_obj); 254 e->finalize_objects = eina_list_prepend(e->finalize_objects, eo_obj);
256 255
257end: 256end:
257 evas_object_callbacks_finalized(eo_obj, obj);
258 return efl_finalize(efl_super(eo_obj, MY_CLASS)); 258 return efl_finalize(efl_super(eo_obj, MY_CLASS));
259} 259}
260 260
@@ -475,7 +475,6 @@ evas_object_free(Evas_Object_Protected_Data *obj, Eina_Bool clean_layer)
475 if (!obj) return ; 475 if (!obj) return ;
476 eo_obj = obj->object; 476 eo_obj = obj->object;
477 477
478 evas_object_callback_shutdown(eo_obj, obj);
479 if (efl_isa(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS)) 478 if (efl_isa(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
480 _evas_object_image_free(eo_obj); 479 _evas_object_image_free(eo_obj);
481 evas_object_map_set(eo_obj, NULL); 480 evas_object_map_set(eo_obj, NULL);
@@ -2431,6 +2430,73 @@ _efl_canvas_object_coords_inside_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_P
2431 return RECTS_INTERSECT(pos.x, pos.y, 1, 1, c.x, c.y, c.w, c.h); 2430 return RECTS_INTERSECT(pos.x, pos.y, 1, 1, c.x, c.y, c.w, c.h);
2432} 2431}
2433 2432
2433EOLIAN static Eina_Bool
2434_efl_canvas_object_efl_object_event_callback_priority_add(Eo *obj, Evas_Object_Protected_Data *pd,
2435 const Efl_Event_Description *desc,
2436 Efl_Callback_Priority priority,
2437 Efl_Event_Cb func,
2438 const void *user_data)
2439{
2440 Efl_Callback_Array_Item full[2] = {
2441 {desc, func},
2442 {NULL, NULL}
2443 };
2444
2445 if (efl_event_callback_priority_add(efl_super(obj, MY_CLASS), desc, priority, func, user_data))
2446 {
2447 evas_object_callbacks_event_catcher_add(obj, pd, full);
2448 return EINA_TRUE;
2449 }
2450 return EINA_FALSE;
2451}
2452
2453EOLIAN static Eina_Bool
2454_efl_canvas_object_efl_object_event_callback_del(Eo *obj, Evas_Object_Protected_Data *pd,
2455 const Efl_Event_Description *desc,
2456 Efl_Event_Cb func,
2457 const void *user_data)
2458{
2459 Efl_Callback_Array_Item full[2] = {
2460 {desc, func},
2461 {NULL, NULL}
2462 };
2463
2464 if (efl_event_callback_del(efl_super(obj, MY_CLASS), desc, func, user_data))
2465 {
2466 evas_object_callbacks_event_catcher_del(obj, pd, full);
2467 return EINA_TRUE;
2468 }
2469 return EINA_FALSE;
2470}
2471
2472EOLIAN static Eina_Bool
2473_efl_canvas_object_efl_object_event_callback_array_priority_add(Eo *obj, Evas_Object_Protected_Data *pd,
2474 const Efl_Callback_Array_Item *array,
2475 Efl_Callback_Priority priority,
2476 const void *user_data)
2477{
2478
2479 if (efl_event_callback_array_priority_add(efl_super(obj, MY_CLASS), array, priority, user_data))
2480 {
2481 evas_object_callbacks_event_catcher_add(obj, pd, array);
2482 return EINA_TRUE;
2483 }
2484 return EINA_FALSE;
2485}
2486
2487EOLIAN static Eina_Bool
2488_efl_canvas_object_efl_object_event_callback_array_del(Eo *obj, Evas_Object_Protected_Data *pd,
2489 const Efl_Callback_Array_Item *array,
2490 const void *user_data)
2491{
2492 if (efl_event_callback_array_del(efl_super(obj, MY_CLASS), array, user_data))
2493 {
2494 evas_object_callbacks_event_catcher_del(obj, pd, array);
2495 return EINA_TRUE;
2496 }
2497 return EINA_FALSE;
2498}
2499
2434static void 2500static void
2435_is_frame_flag_set(Evas_Object_Protected_Data *obj, Eina_Bool is_frame) 2501_is_frame_flag_set(Evas_Object_Protected_Data *obj, Eina_Bool is_frame)
2436{ 2502{
@@ -2699,7 +2765,11 @@ EOAPI EFL_VOID_FUNC_BODYV(efl_canvas_object_type_set, EFL_FUNC_CALL(type), const
2699 EFL_OBJECT_OP_FUNC(efl_canvas_object_is_frame_object_set, _efl_canvas_object_is_frame_object_set), \ 2765 EFL_OBJECT_OP_FUNC(efl_canvas_object_is_frame_object_set, _efl_canvas_object_is_frame_object_set), \
2700 EFL_OBJECT_OP_FUNC(efl_canvas_object_is_frame_object_get, _efl_canvas_object_is_frame_object_get), \ 2766 EFL_OBJECT_OP_FUNC(efl_canvas_object_is_frame_object_get, _efl_canvas_object_is_frame_object_get), \
2701 EFL_OBJECT_OP_FUNC(efl_canvas_object_legacy_ctor, _efl_canvas_object_legacy_ctor), \ 2767 EFL_OBJECT_OP_FUNC(efl_canvas_object_legacy_ctor, _efl_canvas_object_legacy_ctor), \
2702 EFL_OBJECT_OP_FUNC(efl_canvas_object_type_set, _efl_canvas_object_type_set) 2768 EFL_OBJECT_OP_FUNC(efl_canvas_object_type_set, _efl_canvas_object_type_set), \
2769 EFL_OBJECT_OP_FUNC(efl_event_callback_priority_add, _efl_canvas_object_efl_object_event_callback_priority_add), \
2770 EFL_OBJECT_OP_FUNC(efl_event_callback_array_priority_add, _efl_canvas_object_efl_object_event_callback_array_priority_add), \
2771 EFL_OBJECT_OP_FUNC(efl_event_callback_del, _efl_canvas_object_efl_object_event_callback_del), \
2772 EFL_OBJECT_OP_FUNC(efl_event_callback_array_del, _efl_canvas_object_efl_object_event_callback_array_del)
2703 2773
2704#include "canvas/efl_canvas_object.eo.c" 2774#include "canvas/efl_canvas_object.eo.c"
2705#include "canvas/efl_canvas_object_eo.legacy.c" 2775#include "canvas/efl_canvas_object_eo.legacy.c"
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index a5ea99e..2050a48 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1603,8 +1603,10 @@ void evas_object_clip_across_check(Evas_Object *obj, Evas_Object_Protected_Data
1603void evas_object_clip_across_clippees_check(Evas_Object *obj, Evas_Object_Protected_Data *pd); 1603void evas_object_clip_across_clippees_check(Evas_Object *obj, Evas_Object_Protected_Data *pd);
1604void evas_object_mapped_clip_across_mark(Evas_Object *obj, Evas_Object_Protected_Data *pd); 1604void evas_object_mapped_clip_across_mark(Evas_Object *obj, Evas_Object_Protected_Data *pd);
1605void evas_event_callback_call(Evas *e, Evas_Callback_Type type, void *event_info); 1605void evas_event_callback_call(Evas *e, Evas_Callback_Type type, void *event_info);
1606void evas_object_callback_init(Efl_Canvas_Object *eo_obj, Evas_Object_Protected_Data *obj); 1606void evas_object_callbacks_finalized(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj);
1607void evas_object_callback_shutdown(Efl_Canvas_Object *eo_obj, Evas_Object_Protected_Data *obj); 1607void evas_object_callbacks_event_catcher_add(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, const Efl_Callback_Array_Item *array);
1608void evas_object_callbacks_event_catcher_del(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, const Efl_Callback_Array_Item *array);
1609
1608void evas_object_event_callback_call(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Callback_Type type, void *event_info, int event_id, const Efl_Event_Description *efl_event_desc); 1610void evas_object_event_callback_call(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Callback_Type type, void *event_info, int event_id, const Efl_Event_Description *efl_event_desc);
1609Eina_List *evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y); 1611Eina_List *evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y);
1610void evas_debug_error(void); 1612void evas_debug_error(void);