From 831efcf101193e0ab890de50916c6fec7218389a Mon Sep 17 00:00:00 2001 From: ChunEon Park Date: Thu, 22 Jan 2015 17:44:09 +0900 Subject: [PATCH] transit: fix crash issue. This fixes the side effect that introduced from 1e06309be42fd2b5d0900b16da0178215c111681 Since transit has supported adding a map effect on the previous map status, transit tried to access object-state map pointer. but theses map pointer won't be valid if the transit keeps the last state because it doesn't back up any object-state data. --- legacy/elementary/src/lib/elm_transit.c | 129 ++++++++++-------------- 1 file changed, 55 insertions(+), 74 deletions(-) diff --git a/legacy/elementary/src/lib/elm_transit.c b/legacy/elementary/src/lib/elm_transit.c index 74e715f429..4d5bf468dd 100644 --- a/legacy/elementary/src/lib/elm_transit.c +++ b/legacy/elementary/src/lib/elm_transit.c @@ -75,29 +75,24 @@ struct _Elm_Transit_Effect_Module Eina_Bool deleted : 1; }; -struct _Elm_Transit_Obj_State -{ - Evas_Coord x, y, w, h; - int r,g,b,a; - Evas_Map *map; - Eina_Bool map_enabled : 1; - Eina_Bool visible : 1; -}; - struct _Elm_Transit_Obj_Data { - struct _Elm_Transit_Obj_State *state; - Eina_Bool freeze_events : 1; + struct { + Evas_Coord x, y, w, h; + int r,g,b,a; + Evas_Map *map; + Eina_Bool map_enabled : 1; + Eina_Bool visible : 1; + Eina_Bool freeze_events : 1; + } state; int ref; }; typedef struct _Elm_Transit_Effect_Module Elm_Transit_Effect_Module; typedef struct _Elm_Transit_Obj_Data Elm_Transit_Obj_Data; -typedef struct _Elm_Transit_Obj_State Elm_Transit_Obj_State; -static void _transit_obj_data_update(Elm_Transit *transit, Evas_Object *obj); +static void _transit_obj_data_save(Evas_Object *obj); static void _transit_obj_data_recover(Elm_Transit *transit, Evas_Object *obj); -static void _transit_obj_states_save(Evas_Object *obj, Elm_Transit_Obj_Data *obj_data); static void _transit_obj_remove_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED); static void _transit_obj_remove(Elm_Transit *transit, Evas_Object *obj); static void _transit_effect_del(Elm_Transit *transit, Elm_Transit_Effect_Module *effect_module); @@ -110,47 +105,36 @@ static Eina_Bool _transit_animate_cb(void *data); static char *_transit_key= "_elm_transit_key"; static void -_transit_obj_data_update(Elm_Transit *transit, Evas_Object *obj) +_transit_obj_data_save(Evas_Object *obj) { Elm_Transit_Obj_Data *obj_data = evas_object_data_get(obj, _transit_key); - if (!obj_data) - obj_data = ELM_NEW(Elm_Transit_Obj_Data); - - obj_data->freeze_events = evas_object_freeze_events_get(obj); - - if (!transit->state_keep && obj_data->state) + if (obj_data) { - if (obj_data->state->map) evas_map_free(obj_data->state->map); - ELM_SAFE_FREE(obj_data->state, free); - } - else - { - _transit_obj_states_save(obj, obj_data); + obj_data->ref++; + return; } + + obj_data = ELM_NEW(Elm_Transit_Obj_Data); + + evas_object_geometry_get(obj, &obj_data->state.x, &obj_data->state.y, + &obj_data->state.w, &obj_data->state.h); + evas_object_color_get(obj, &obj_data->state.r, &obj_data->state.g, + &obj_data->state.b, &obj_data->state.a); + obj_data->state.visible = evas_object_visible_get(obj); + obj_data->state.freeze_events = evas_object_freeze_events_get(obj); + obj_data->state.map_enabled = evas_object_map_enable_get(obj); + + ELM_SAFE_FREE(obj_data->state.map, evas_map_free); + + if (evas_object_map_get(obj)) + obj_data->state.map = evas_map_dup(evas_object_map_get(obj)); + obj_data->ref++; evas_object_data_set(obj, _transit_key, obj_data); } -static void -_transit_obj_states_save(Evas_Object *obj, Elm_Transit_Obj_Data *obj_data) -{ - Elm_Transit_Obj_State *state = obj_data->state; - - if (!state) - state = calloc(1, sizeof(Elm_Transit_Obj_State)); - if (!state) return; - - evas_object_geometry_get(obj, &state->x, &state->y, &state->w, &state->h); - evas_object_color_get(obj, &state->r, &state->g, &state->b, &state->a); - state->visible = evas_object_visible_get(obj); - state->map_enabled = evas_object_map_enable_get(obj); - if (evas_object_map_get(obj)) - state->map = evas_map_dup(evas_object_map_get(obj)); - obj_data->state = state; -} - static void _remove_obj_from_list(Elm_Transit *transit, Evas_Object *obj) { @@ -177,7 +161,6 @@ _transit_obj_remove_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void * obj_data->ref--; if (obj_data->ref == 0) { - free(obj_data->state); free(obj_data); evas_object_data_del(obj, _transit_key); } @@ -190,35 +173,32 @@ static void _transit_obj_data_recover(Elm_Transit *transit, Evas_Object *obj) { Elm_Transit_Obj_Data *obj_data; - Elm_Transit_Obj_State *state; obj_data = evas_object_data_get(obj, _transit_key); if (!obj_data) return; obj_data->ref--; - if (obj_data->ref == 0) - evas_object_data_del(obj, _transit_key); - evas_object_freeze_events_set(obj, obj_data->freeze_events); - state = obj_data->state; - if (state) + //recover the states of the object. + if (!transit->state_keep) { - //recover the states of the object. - if (!transit->state_keep) - { - evas_object_move(obj, state->x, state->y); - evas_object_resize(obj, state->w, state->h); - evas_object_color_set(obj, state->r, state->g, state->b, state->a); - if (state->visible) evas_object_show(obj); - else evas_object_hide(obj); - evas_object_map_enable_set(obj, state->map_enabled); - evas_object_map_set(obj, state->map); - } - if (obj_data->ref == 0) - free(state); + evas_object_move(obj, obj_data->state.x, obj_data->state.y); + evas_object_resize(obj, obj_data->state.w, obj_data->state.h); + evas_object_color_set(obj, obj_data->state.r, obj_data->state.g, + obj_data->state.b, obj_data->state.a); + if (obj_data->state.visible) evas_object_show(obj); + else evas_object_hide(obj); + evas_object_map_enable_set(obj, obj_data->state.map_enabled); + evas_object_map_set(obj, obj_data->state.map); } + if (obj_data->ref == 0) - free(obj_data); + { + ELM_SAFE_FREE(obj_data->state.map, evas_map_free); + free(obj_data); + evas_object_data_del(obj, _transit_key); + evas_object_freeze_events_set(obj, obj_data->state.freeze_events); + } } static void @@ -577,7 +557,7 @@ elm_transit_object_add(Elm_Transit *transit, Evas_Object *obj) { if (!evas_object_data_get(obj, _transit_key)) { - _transit_obj_data_update(transit, obj); + _transit_obj_data_save(obj); evas_object_freeze_events_set(obj, EINA_TRUE); } } @@ -750,7 +730,7 @@ elm_transit_go(Elm_Transit *transit) ELM_SAFE_FREE(transit->animator, ecore_animator_del); EINA_LIST_FOREACH(transit->objs, elist, obj) - _transit_obj_data_update(transit, obj); + _transit_obj_data_save(obj); if (!transit->event_enabled) { @@ -762,6 +742,7 @@ elm_transit_go(Elm_Transit *transit) transit->time.delayed = 0; transit->time.begin = ecore_loop_time_get(); transit->animator = ecore_animator_add(_transit_animate_cb, transit); + _transit_animate_cb(transit); } @@ -1113,9 +1094,9 @@ _transit_effect_zoom_op(Elm_Transit_Effect *effect, Elm_Transit *transit , doubl EINA_LIST_FOREACH(transit->objs, elist, obj) { obj_data = evas_object_data_get(obj, _transit_key); - if (obj_data->state->map_enabled) + if (obj_data->state.map_enabled) { - base_map = obj_data->state->map; + base_map = obj_data->state.map; if (!base_map) return; map = evas_map_dup(base_map); if (!map) return; @@ -1157,8 +1138,8 @@ EAPI Elm_Transit_Effect * elm_transit_effect_zoom_add(Elm_Transit *transit, float from_rate, float to_rate) { ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL); - Elm_Transit_Effect *effect = _transit_effect_zoom_context_new(from_rate, to_rate); - + Elm_Transit_Effect *effect = _transit_effect_zoom_context_new(from_rate, + to_rate); if (!effect) { ERR("Failed to allocate zoom effect! : transit=%p", transit); @@ -2335,9 +2316,9 @@ _transit_effect_rotation_op(Elm_Transit_Effect *effect, Elm_Transit *transit, do EINA_LIST_FOREACH(transit->objs, elist, obj) { obj_data = evas_object_data_get(obj, _transit_key); - if (obj_data->state->map_enabled) + if (obj_data->state.map_enabled) { - base_map = obj_data->state->map; + base_map = obj_data->state.map; if (!base_map) return; map = evas_map_dup(base_map); if (!map) return;