summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-03-14 15:30:40 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-03-14 15:41:24 +0900
commit0b5b5e44a53c73b4ec64ada2c52e8a7aac3e5033 (patch)
tree3d25c2ec36b22909ed1a0e22490d36edc0eab1bd
parentc15fee9bccabaef9cf25c63c979bcf1c1b581906 (diff)
evas: Fix crash with events on the canvas
Since ecore now uses efl events to feed input events to the canvas, anyone can now listen to any event on the evas. But when using the legacy API the event info needs to be the legacy struct, and not the eo event info otherwise crashes will happen. While this is a new use of events, I consider it valid and it's better to fix it rather than disallowing it. Fixed by wrapping evas events the same way evas object events were handled. Fixes T5266
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c125
1 files changed, 77 insertions, 48 deletions
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index e126d8d7f1..e3d2643bad 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -100,19 +100,14 @@ typedef enum {
100typedef struct 100typedef struct
101{ 101{
102 EINA_INLIST; 102 EINA_INLIST;
103 Evas_Object_Event_Cb func; 103 union {
104 void *data; 104 Evas_Event_Cb evas_cb;
105 Evas_Callback_Type type; 105 Evas_Object_Event_Cb object_cb;
106 Efl_Event_Info_Type efl_event_type; 106 } func;
107} _eo_evas_object_cb_info; 107 void *data;
108 108 Evas_Callback_Type type;
109typedef struct 109 Efl_Event_Info_Type efl_event_type;
110{ 110} Evas_Event_Cb_Wrapper_Info;
111 EINA_INLIST;
112 Evas_Event_Cb func;
113 void *data;
114 Evas_Callback_Type type;
115} _eo_evas_cb_info;
116 111
117static int 112static int
118_evas_event_efl_event_info_type(Evas_Callback_Type type) 113_evas_event_efl_event_info_type(Evas_Callback_Type type)
@@ -162,11 +157,11 @@ _eo_evas_object_cb(void *data, const Efl_Event *event)
162{ 157{
163 Evas_Event_Flags *event_flags = NULL, evflags = EVAS_EVENT_FLAG_NONE; 158 Evas_Event_Flags *event_flags = NULL, evflags = EVAS_EVENT_FLAG_NONE;
164 Efl_Input_Event *efl_event_info = event->info; 159 Efl_Input_Event *efl_event_info = event->info;
165 _eo_evas_object_cb_info *info = data; 160 Evas_Event_Cb_Wrapper_Info *info = data;
166 void *event_info; 161 void *event_info;
167 Evas *evas; 162 Evas *evas;
168 163
169 if (!info->func) return; 164 if (!info->func.object_cb) return;
170 evas = evas_object_evas_get(event->object); 165 evas = evas_object_evas_get(event->object);
171 166
172 event_info = event->info; 167 event_info = event->info;
@@ -185,19 +180,21 @@ _eo_evas_object_cb(void *data, const Efl_Event *event)
185 break; 180 break;
186 181
187 case EFL_EVENT_TYPE_FOCUS: 182 case EFL_EVENT_TYPE_FOCUS:
188 event_info = NULL;
189 // NOTE: fallthrough here is explicitly intended!!!
190 case EFL_EVENT_TYPE_NULL: 183 case EFL_EVENT_TYPE_NULL:
184 info->func.object_cb(info->data, evas, event->object, NULL);
185 return;
186
191 case EFL_EVENT_TYPE_STRUCT: 187 case EFL_EVENT_TYPE_STRUCT:
192 case EFL_EVENT_TYPE_OBJECT: 188 case EFL_EVENT_TYPE_OBJECT:
193 info->func(info->data, evas, event->object, event_info); 189 info->func.object_cb(info->data, evas, event->object, event_info);
194 return; 190 return;
191
195 default: return; 192 default: return;
196 } 193 }
197 194
198 if (!event_info) return; 195 if (!event_info) return;
199 if (event_flags) evflags = *event_flags; 196 if (event_flags) evflags = *event_flags;
200 info->func(info->data, evas, event->object, event_info); 197 info->func.object_cb(info->data, evas, event->object, event_info);
201 if (event_flags && (evflags != *event_flags)) 198 if (event_flags && (evflags != *event_flags))
202 efl_input_event_flags_set(efl_event_info, *event_flags); 199 efl_input_event_flags_set(efl_event_info, *event_flags);
203} 200}
@@ -205,20 +202,47 @@ _eo_evas_object_cb(void *data, const Efl_Event *event)
205static void 202static void
206_eo_evas_cb(void *data, const Efl_Event *event) 203_eo_evas_cb(void *data, const Efl_Event *event)
207{ 204{
205 Evas_Event_Cb_Wrapper_Info *info = data;
206 Efl_Input_Event *efl_event_info = event->info;
207 Evas *evas = event->object;
208 void *event_info; 208 void *event_info;
209 _eo_evas_cb_info *info = data; 209
210 210 if (!info->func.evas_cb) return;
211 //Keep the legacy behaviour for focus events. 211
212 if (event->desc == EFL_CANVAS_EVENT_FOCUS_IN || 212 if (event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_IN ||
213 event->desc == EFL_CANVAS_EVENT_FOCUS_OUT) 213 event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_OUT)
214 event_info = NULL; 214 {
215 else if (event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_IN || 215 event_info = efl_input_focus_object_get(efl_event_info);
216 event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_OUT) 216 goto emit;
217 event_info = efl_input_focus_object_get(event->info); 217 }
218 else 218
219 event_info = event->info; 219 event_info = event->info;
220 220 switch (info->efl_event_type)
221 if (info->func) info->func(info->data, event->object, event_info); 221 {
222 case EFL_EVENT_TYPE_POINTER:
223 event_info = efl_input_pointer_legacy_info_fill(evas, efl_event_info, info->type, NULL);
224 break;
225
226 case EFL_EVENT_TYPE_KEY:
227 event_info = efl_input_key_legacy_info_fill(efl_event_info, NULL);
228 break;
229
230 case EFL_EVENT_TYPE_HOLD:
231 event_info = efl_input_hold_legacy_info_fill(efl_event_info, NULL);
232 break;
233
234 case EFL_EVENT_TYPE_FOCUS:
235 case EFL_EVENT_TYPE_NULL:
236 event_info = NULL;
237 break;
238
239 case EFL_EVENT_TYPE_STRUCT:
240 case EFL_EVENT_TYPE_OBJECT:
241 break;
242 }
243
244emit:
245 info->func.evas_cb(info->data, event->object, event_info);
222} 246}
223 247
224void 248void
@@ -270,7 +294,7 @@ _evas_post_event_callback_free(Evas *eo_e)
270void 294void
271evas_object_event_callback_all_del(Evas_Object *eo_obj) 295evas_object_event_callback_all_del(Evas_Object *eo_obj)
272{ 296{
273 _eo_evas_object_cb_info *info; 297 Evas_Event_Cb_Wrapper_Info *info;
274 Eina_Inlist *itr; 298 Eina_Inlist *itr;
275 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); 299 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
276 300
@@ -295,7 +319,7 @@ evas_object_event_callback_cleanup(Evas_Object *eo_obj)
295void 319void
296evas_event_callback_all_del(Evas *eo_e) 320evas_event_callback_all_del(Evas *eo_e)
297{ 321{
298 _eo_evas_object_cb_info *info; 322 Evas_Event_Cb_Wrapper_Info *info;
299 Eina_Inlist *itr; 323 Eina_Inlist *itr;
300 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); 324 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
301 325
@@ -435,17 +459,19 @@ evas_object_event_callback_priority_add(Evas_Object *eo_obj, Evas_Callback_Type
435 if(!eo_obj) return; 459 if(!eo_obj) return;
436 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS)); 460 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS));
437 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); 461 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
462 Evas_Event_Cb_Wrapper_Info *cb_info;
463 const Efl_Event_Description *desc;
438 464
439 if (!obj) return; 465 if (!obj) return;
440 if (!func) return; 466 if (!func) return;
441 467
442 _eo_evas_object_cb_info *cb_info = calloc(1, sizeof(*cb_info)); 468 cb_info = calloc(1, sizeof(*cb_info));
443 cb_info->func = func; 469 cb_info->func.object_cb = func;
444 cb_info->data = (void *)data; 470 cb_info->data = (void *)data;
445 cb_info->type = type; 471 cb_info->type = type;
446 cb_info->efl_event_type = _evas_event_efl_event_info_type(type); 472 cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
447 473
448 const Efl_Event_Description *desc = _legacy_evas_callback_table(type); 474 desc = _legacy_evas_callback_table(type);
449 efl_event_callback_priority_add(eo_obj, desc, priority, _eo_evas_object_cb, cb_info); 475 efl_event_callback_priority_add(eo_obj, desc, priority, _eo_evas_object_cb, cb_info);
450 476
451 obj->callbacks = 477 obj->callbacks =
@@ -458,7 +484,7 @@ evas_object_event_callback_del(Evas_Object *eo_obj, Evas_Callback_Type type, Eva
458 if(!eo_obj) return NULL; 484 if(!eo_obj) return NULL;
459 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS), NULL); 485 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS), NULL);
460 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); 486 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
461 _eo_evas_object_cb_info *info; 487 Evas_Event_Cb_Wrapper_Info *info;
462 488
463 if (!obj) return NULL; 489 if (!obj) return NULL;
464 if (!func) return NULL; 490 if (!func) return NULL;
@@ -467,7 +493,7 @@ evas_object_event_callback_del(Evas_Object *eo_obj, Evas_Callback_Type type, Eva
467 493
468 EINA_INLIST_REVERSE_FOREACH(obj->callbacks, info) 494 EINA_INLIST_REVERSE_FOREACH(obj->callbacks, info)
469 { 495 {
470 if ((info->func == func) && (info->type == type)) 496 if ((info->func.object_cb == func) && (info->type == type))
471 { 497 {
472 void *tmp = info->data; 498 void *tmp = info->data;
473 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(type), _eo_evas_object_cb, info); 499 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(type), _eo_evas_object_cb, info);
@@ -487,7 +513,7 @@ evas_object_event_callback_del_full(Evas_Object *eo_obj, Evas_Callback_Type type
487 if(!eo_obj) return NULL; 513 if(!eo_obj) return NULL;
488 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS), NULL); 514 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS), NULL);
489 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); 515 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
490 _eo_evas_object_cb_info *info; 516 Evas_Event_Cb_Wrapper_Info *info;
491 517
492 if (!obj) return NULL; 518 if (!obj) return NULL;
493 if (!func) return NULL; 519 if (!func) return NULL;
@@ -496,7 +522,7 @@ evas_object_event_callback_del_full(Evas_Object *eo_obj, Evas_Callback_Type type
496 522
497 EINA_INLIST_FOREACH(obj->callbacks, info) 523 EINA_INLIST_FOREACH(obj->callbacks, info)
498 { 524 {
499 if ((info->func == func) && (info->type == type) && info->data == data) 525 if ((info->func.object_cb == func) && (info->type == type) && info->data == data)
500 { 526 {
501 void *tmp = info->data; 527 void *tmp = info->data;
502 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(type), _eo_evas_object_cb, info); 528 efl_event_callback_del(eo_obj, _legacy_evas_callback_table(type), _eo_evas_object_cb, info);
@@ -523,15 +549,18 @@ evas_event_callback_priority_add(Evas *eo_e, Evas_Callback_Type type, Evas_Callb
523 if(!eo_e) return; 549 if(!eo_e) return;
524 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS)); 550 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
525 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); 551 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
552 Evas_Event_Cb_Wrapper_Info *cb_info;
553 const Efl_Event_Description *desc;
526 554
527 if (!func) return; 555 if (!func) return;
528 556
529 _eo_evas_cb_info *cb_info = calloc(1, sizeof(*cb_info)); 557 cb_info = calloc(1, sizeof(*cb_info));
530 cb_info->func = func; 558 cb_info->func.evas_cb = func;
531 cb_info->data = (void *)data; 559 cb_info->data = (void *)data;
532 cb_info->type = type; 560 cb_info->type = type;
561 cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
533 562
534 const Efl_Event_Description *desc = _legacy_evas_callback_table(type); 563 desc = _legacy_evas_callback_table(type);
535 efl_event_callback_priority_add(eo_e, desc, priority, _eo_evas_cb, cb_info); 564 efl_event_callback_priority_add(eo_e, desc, priority, _eo_evas_cb, cb_info);
536 565
537 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info)); 566 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info));
@@ -543,7 +572,7 @@ evas_event_callback_del(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func)
543 if(!eo_e) return NULL; 572 if(!eo_e) return NULL;
544 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL); 573 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL);
545 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); 574 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
546 _eo_evas_cb_info *info; 575 Evas_Event_Cb_Wrapper_Info *info;
547 576
548 if (!e) return NULL; 577 if (!e) return NULL;
549 if (!func) return NULL; 578 if (!func) return NULL;
@@ -552,7 +581,7 @@ evas_event_callback_del(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func)
552 581
553 EINA_INLIST_REVERSE_FOREACH(e->callbacks, info) 582 EINA_INLIST_REVERSE_FOREACH(e->callbacks, info)
554 { 583 {
555 if ((info->func == func) && (info->type == type)) 584 if ((info->func.evas_cb == func) && (info->type == type))
556 { 585 {
557 void *tmp = info->data; 586 void *tmp = info->data;
558 efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info); 587 efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info);
@@ -572,7 +601,7 @@ evas_event_callback_del_full(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb
572 if(!eo_e) return NULL; 601 if(!eo_e) return NULL;
573 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL); 602 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL);
574 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); 603 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
575 _eo_evas_cb_info *info; 604 Evas_Event_Cb_Wrapper_Info *info;
576 605
577 if (!e) return NULL; 606 if (!e) return NULL;
578 if (!func) return NULL; 607 if (!func) return NULL;
@@ -581,7 +610,7 @@ evas_event_callback_del_full(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb
581 610
582 EINA_INLIST_FOREACH(e->callbacks, info) 611 EINA_INLIST_FOREACH(e->callbacks, info)
583 { 612 {
584 if ((info->func == func) && (info->type == type) && (info->data == data)) 613 if ((info->func.evas_cb == func) && (info->type == type) && (info->data == data))
585 { 614 {
586 void *tmp = info->data; 615 void *tmp = info->data;
587 efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info); 616 efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info);