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)
downloadefl-0b5b5e44a53c73b4ec64ada2c52e8a7aac3e5033.tar.gz
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 {
typedef struct
{
EINA_INLIST;
- Evas_Object_Event_Cb func;
- void *data;
- Evas_Callback_Type type;
- Efl_Event_Info_Type efl_event_type;
-} _eo_evas_object_cb_info;
-
-typedef struct
-{
- EINA_INLIST;
- Evas_Event_Cb func;
- void *data;
- Evas_Callback_Type type;
-} _eo_evas_cb_info;
+ union {
+ Evas_Event_Cb evas_cb;
+ Evas_Object_Event_Cb object_cb;
+ } func;
+ void *data;
+ Evas_Callback_Type type;
+ Efl_Event_Info_Type efl_event_type;
+} Evas_Event_Cb_Wrapper_Info;
static int
_evas_event_efl_event_info_type(Evas_Callback_Type type)
@@ -162,11 +157,11 @@ _eo_evas_object_cb(void *data, const Efl_Event *event)
{
Evas_Event_Flags *event_flags = NULL, evflags = EVAS_EVENT_FLAG_NONE;
Efl_Input_Event *efl_event_info = event->info;
- _eo_evas_object_cb_info *info = data;
+ Evas_Event_Cb_Wrapper_Info *info = data;
void *event_info;
Evas *evas;
- if (!info->func) return;
+ if (!info->func.object_cb) return;
evas = evas_object_evas_get(event->object);
event_info = event->info;
@@ -185,19 +180,21 @@ _eo_evas_object_cb(void *data, const Efl_Event *event)
break;
case EFL_EVENT_TYPE_FOCUS:
- event_info = NULL;
- // NOTE: fallthrough here is explicitly intended!!!
case EFL_EVENT_TYPE_NULL:
+ info->func.object_cb(info->data, evas, event->object, NULL);
+ return;
+
case EFL_EVENT_TYPE_STRUCT:
case EFL_EVENT_TYPE_OBJECT:
- info->func(info->data, evas, event->object, event_info);
+ info->func.object_cb(info->data, evas, event->object, event_info);
return;
+
default: return;
}
if (!event_info) return;
if (event_flags) evflags = *event_flags;
- info->func(info->data, evas, event->object, event_info);
+ info->func.object_cb(info->data, evas, event->object, event_info);
if (event_flags && (evflags != *event_flags))
efl_input_event_flags_set(efl_event_info, *event_flags);
}
@@ -205,20 +202,47 @@ _eo_evas_object_cb(void *data, const Efl_Event *event)
static void
_eo_evas_cb(void *data, const Efl_Event *event)
{
+ Evas_Event_Cb_Wrapper_Info *info = data;
+ Efl_Input_Event *efl_event_info = event->info;
+ Evas *evas = event->object;
void *event_info;
- _eo_evas_cb_info *info = data;
-
- //Keep the legacy behaviour for focus events.
- if (event->desc == EFL_CANVAS_EVENT_FOCUS_IN ||
- event->desc == EFL_CANVAS_EVENT_FOCUS_OUT)
- event_info = NULL;
- else if (event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_IN ||
- event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_OUT)
- event_info = efl_input_focus_object_get(event->info);
- else
- event_info = event->info;
-
- if (info->func) info->func(info->data, event->object, event_info);
+
+ if (!info->func.evas_cb) return;
+
+ if (event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_IN ||
+ event->desc == EFL_CANVAS_EVENT_OBJECT_FOCUS_OUT)
+ {
+ event_info = efl_input_focus_object_get(efl_event_info);
+ goto emit;
+ }
+
+ event_info = event->info;
+ switch (info->efl_event_type)
+ {
+ case EFL_EVENT_TYPE_POINTER:
+ event_info = efl_input_pointer_legacy_info_fill(evas, efl_event_info, info->type, NULL);
+ break;
+
+ case EFL_EVENT_TYPE_KEY:
+ event_info = efl_input_key_legacy_info_fill(efl_event_info, NULL);
+ break;
+
+ case EFL_EVENT_TYPE_HOLD:
+ event_info = efl_input_hold_legacy_info_fill(efl_event_info, NULL);
+ break;
+
+ case EFL_EVENT_TYPE_FOCUS:
+ case EFL_EVENT_TYPE_NULL:
+ event_info = NULL;
+ break;
+
+ case EFL_EVENT_TYPE_STRUCT:
+ case EFL_EVENT_TYPE_OBJECT:
+ break;
+ }
+
+emit:
+ info->func.evas_cb(info->data, event->object, event_info);
}
void
@@ -270,7 +294,7 @@ _evas_post_event_callback_free(Evas *eo_e)
void
evas_object_event_callback_all_del(Evas_Object *eo_obj)
{
- _eo_evas_object_cb_info *info;
+ Evas_Event_Cb_Wrapper_Info *info;
Eina_Inlist *itr;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
@@ -295,7 +319,7 @@ evas_object_event_callback_cleanup(Evas_Object *eo_obj)
void
evas_event_callback_all_del(Evas *eo_e)
{
- _eo_evas_object_cb_info *info;
+ Evas_Event_Cb_Wrapper_Info *info;
Eina_Inlist *itr;
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
@@ -435,17 +459,19 @@ evas_object_event_callback_priority_add(Evas_Object *eo_obj, Evas_Callback_Type
if(!eo_obj) return;
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS));
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+ Evas_Event_Cb_Wrapper_Info *cb_info;
+ const Efl_Event_Description *desc;
if (!obj) return;
if (!func) return;
- _eo_evas_object_cb_info *cb_info = calloc(1, sizeof(*cb_info));
- cb_info->func = func;
+ cb_info = calloc(1, sizeof(*cb_info));
+ cb_info->func.object_cb = func;
cb_info->data = (void *)data;
cb_info->type = type;
cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
- const Efl_Event_Description *desc = _legacy_evas_callback_table(type);
+ desc = _legacy_evas_callback_table(type);
efl_event_callback_priority_add(eo_obj, desc, priority, _eo_evas_object_cb, cb_info);
obj->callbacks =
@@ -458,7 +484,7 @@ evas_object_event_callback_del(Evas_Object *eo_obj, Evas_Callback_Type type, Eva
if(!eo_obj) return NULL;
EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS), NULL);
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
- _eo_evas_object_cb_info *info;
+ Evas_Event_Cb_Wrapper_Info *info;
if (!obj) return NULL;
if (!func) return NULL;
@@ -467,7 +493,7 @@ evas_object_event_callback_del(Evas_Object *eo_obj, Evas_Callback_Type type, Eva
EINA_INLIST_REVERSE_FOREACH(obj->callbacks, info)
{
- if ((info->func == func) && (info->type == type))
+ if ((info->func.object_cb == func) && (info->type == type))
{
void *tmp = info->data;
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
if(!eo_obj) return NULL;
EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_obj, EFL_CANVAS_OBJECT_CLASS), NULL);
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
- _eo_evas_object_cb_info *info;
+ Evas_Event_Cb_Wrapper_Info *info;
if (!obj) return NULL;
if (!func) return NULL;
@@ -496,7 +522,7 @@ evas_object_event_callback_del_full(Evas_Object *eo_obj, Evas_Callback_Type type
EINA_INLIST_FOREACH(obj->callbacks, info)
{
- if ((info->func == func) && (info->type == type) && info->data == data)
+ if ((info->func.object_cb == func) && (info->type == type) && info->data == data)
{
void *tmp = info->data;
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
if(!eo_e) return;
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+ Evas_Event_Cb_Wrapper_Info *cb_info;
+ const Efl_Event_Description *desc;
if (!func) return;
- _eo_evas_cb_info *cb_info = calloc(1, sizeof(*cb_info));
- cb_info->func = func;
+ cb_info = calloc(1, sizeof(*cb_info));
+ cb_info->func.evas_cb = func;
cb_info->data = (void *)data;
cb_info->type = type;
+ cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
- const Efl_Event_Description *desc = _legacy_evas_callback_table(type);
+ desc = _legacy_evas_callback_table(type);
efl_event_callback_priority_add(eo_e, desc, priority, _eo_evas_cb, cb_info);
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)
if(!eo_e) return NULL;
EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL);
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
- _eo_evas_cb_info *info;
+ Evas_Event_Cb_Wrapper_Info *info;
if (!e) return NULL;
if (!func) return NULL;
@@ -552,7 +581,7 @@ evas_event_callback_del(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func)
EINA_INLIST_REVERSE_FOREACH(e->callbacks, info)
{
- if ((info->func == func) && (info->type == type))
+ if ((info->func.evas_cb == func) && (info->type == type))
{
void *tmp = info->data;
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
if(!eo_e) return NULL;
EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL);
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
- _eo_evas_cb_info *info;
+ Evas_Event_Cb_Wrapper_Info *info;
if (!e) return NULL;
if (!func) return NULL;
@@ -581,7 +610,7 @@ evas_event_callback_del_full(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb
EINA_INLIST_FOREACH(e->callbacks, info)
{
- if ((info->func == func) && (info->type == type) && (info->data == data))
+ if ((info->func.evas_cb == func) && (info->type == type) && (info->data == data))
{
void *tmp = info->data;
efl_event_callback_del(eo_e, _legacy_evas_callback_table(type), _eo_evas_cb, info);