From 5e691081caebbb4cfa5547a1dec5544d3a39a1cd Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 30 Apr 2007 04:22:42 +0000 Subject: [PATCH] extensive delete me handling for evas free's and list walks SVN revision: 29776 --- legacy/evas/src/lib/canvas/evas_callbacks.c | 278 +------------------- legacy/evas/src/lib/canvas/evas_events.c | 31 ++- legacy/evas/src/lib/canvas/evas_main.c | 26 +- legacy/evas/src/lib/include/evas_private.h | 8 +- 4 files changed, 68 insertions(+), 275 deletions(-) diff --git a/legacy/evas/src/lib/canvas/evas_callbacks.c b/legacy/evas/src/lib/canvas/evas_callbacks.c index 691e2cd699..50945d86ac 100644 --- a/legacy/evas/src/lib/canvas/evas_callbacks.c +++ b/legacy/evas/src/lib/canvas/evas_callbacks.c @@ -30,44 +30,6 @@ evas_object_event_callback_clear(Evas_Object *obj) if (!obj->callbacks) return; if (!obj->callbacks->deletions_waiting) return; obj->callbacks->deletions_waiting = 0; -/* - evas_object_event_callback_list_post_free(&(obj->callbacks->in)); - evas_object_event_callback_list_post_free(&(obj->callbacks->out)); - evas_object_event_callback_list_post_free(&(obj->callbacks->down)); - evas_object_event_callback_list_post_free(&(obj->callbacks->up)); - evas_object_event_callback_list_post_free(&(obj->callbacks->move)); - evas_object_event_callback_list_post_free(&(obj->callbacks->wheel)); - evas_object_event_callback_list_post_free(&(obj->callbacks->free)); - evas_object_event_callback_list_post_free(&(obj->callbacks->key_down)); - evas_object_event_callback_list_post_free(&(obj->callbacks->key_up)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_focus_in)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_focus_out)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_show)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_hide)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_move)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_resize)); - evas_object_event_callback_list_post_free(&(obj->callbacks->obj_restack)); - if ((!obj->callbacks->in) && - (!obj->callbacks->out) && - (!obj->callbacks->down) && - (!obj->callbacks->up) && - (!obj->callbacks->move) && - (!obj->callbacks->wheel) && - (!obj->callbacks->free) && - (!obj->callbacks->key_down) && - (!obj->callbacks->key_up) && - (!obj->callbacks->obj_focus_in) && - (!obj->callbacks->obj_focus_out) && - (!obj->callbacks->obj_show) && - (!obj->callbacks->obj_hide) && - (!obj->callbacks->obj_move) && - (!obj->callbacks->obj_resize) && - (!obj->callbacks->obj_restack)) - { - free(obj->callbacks); - obj->callbacks = NULL; - } - */ evas_object_event_callback_list_post_free(&obj->callbacks->callbacks); if (!obj->callbacks->callbacks) { @@ -96,26 +58,6 @@ evas_object_event_callback_cleanup(Evas_Object *obj) { /* MEM OK */ if (!obj->callbacks) return; - /* - evas_object_event_callback_list_free(&(obj->callbacks->in)); - evas_object_event_callback_list_free(&(obj->callbacks->out)); - evas_object_event_callback_list_free(&(obj->callbacks->down)); - evas_object_event_callback_list_free(&(obj->callbacks->up)); - evas_object_event_callback_list_free(&(obj->callbacks->move)); - evas_object_event_callback_list_free(&(obj->callbacks->wheel)); - evas_object_event_callback_list_free(&(obj->callbacks->free)); - evas_object_event_callback_list_free(&(obj->callbacks->key_down)); - evas_object_event_callback_list_free(&(obj->callbacks->key_up)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_focus_in)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_focus_out)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_show)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_hide)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_move)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_resize)); - evas_object_event_callback_list_free(&(obj->callbacks->obj_restack)); - free(obj->callbacks); - obj->callbacks = NULL; - */ evas_object_event_callback_list_post_free(&obj->callbacks->callbacks); free(obj->callbacks); obj->callbacks = NULL; @@ -132,85 +74,9 @@ evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void if (obj->delete_me) return; e = evas_object_evas_get(obj); + _evas_walk(e); if (obj->callbacks) { - /* - switch (type) - { - case EVAS_CALLBACK_MOUSE_IN: - l_mod = &(obj->callbacks->in); - break; - case EVAS_CALLBACK_MOUSE_OUT: - l_mod = &(obj->callbacks->out); - break; - case EVAS_CALLBACK_MOUSE_DOWN: - { - Evas_Event_Mouse_Down *ev = event_info; - - flags = ev->flags; - if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK)) - { - if (obj->last_mouse_down_counter < (e->last_mouse_down_counter - 1)) - ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK); - } - l_mod = &(obj->callbacks->down); - obj->last_mouse_down_counter = e->last_mouse_down_counter; - break; - } - case EVAS_CALLBACK_MOUSE_UP: - { - Evas_Event_Mouse_Up *ev = event_info; - - flags = ev->flags; - if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK)) - { - if (obj->last_mouse_up_counter < (e->last_mouse_up_counter - 1)) - ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK); - } - l_mod = &(obj->callbacks->up); - obj->last_mouse_up_counter = e->last_mouse_up_counter; - break; - } - case EVAS_CALLBACK_MOUSE_MOVE: - l_mod = &(obj->callbacks->move); - break; - case EVAS_CALLBACK_MOUSE_WHEEL: - l_mod = &(obj->callbacks->wheel); - break; - case EVAS_CALLBACK_FREE: - l_mod = &(obj->callbacks->free); - break; - case EVAS_CALLBACK_KEY_DOWN: - l_mod = &(obj->callbacks->key_down); - break; - case EVAS_CALLBACK_KEY_UP: - l_mod = &(obj->callbacks->key_up); - break; - case EVAS_CALLBACK_FOCUS_IN: - l_mod = &(obj->callbacks->obj_focus_in); - case EVAS_CALLBACK_FOCUS_OUT: - l_mod = &(obj->callbacks->obj_focus_out); - break; - case EVAS_CALLBACK_SHOW: - l_mod = &(obj->callbacks->obj_show); - break; - case EVAS_CALLBACK_HIDE: - l_mod = &(obj->callbacks->obj_hide); - break; - case EVAS_CALLBACK_MOVE: - l_mod = &(obj->callbacks->obj_move); - break; - case EVAS_CALLBACK_RESIZE: - l_mod = &(obj->callbacks->obj_resize); - break; - case EVAS_CALLBACK_RESTACK: - l_mod = &(obj->callbacks->obj_restack); - break; - default: - return; - break; - } - */ l_mod = &obj->callbacks->callbacks; switch (type) { @@ -272,10 +138,13 @@ evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void } } - if ((obj->no_propagate) && (l_mod) && (*l_mod)) return; - if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) && - (type <= EVAS_CALLBACK_KEY_UP)) - evas_object_event_callback_call(obj->smart.parent, type, event_info); + if (!((obj->no_propagate) && (l_mod) && (*l_mod))) + { + if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) && + (type <= EVAS_CALLBACK_KEY_UP)) + evas_object_event_callback_call(obj->smart.parent, type, event_info); + } + _evas_unwalk(e); } /** @@ -471,64 +340,6 @@ evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, void ( free(fn); return; } - /* - switch (type) - { - case EVAS_CALLBACK_MOUSE_IN: - l_mod = &(obj->callbacks->in); - break; - case EVAS_CALLBACK_MOUSE_OUT: - l_mod = &(obj->callbacks->out); - break; - case EVAS_CALLBACK_MOUSE_DOWN: - l_mod = &(obj->callbacks->down); - break; - case EVAS_CALLBACK_MOUSE_UP: - l_mod = &(obj->callbacks->up); - break; - case EVAS_CALLBACK_MOUSE_MOVE: - l_mod = &(obj->callbacks->move); - break; - case EVAS_CALLBACK_MOUSE_WHEEL: - l_mod = &(obj->callbacks->wheel); - break; - case EVAS_CALLBACK_FREE: - l_mod = &(obj->callbacks->free); - break; - case EVAS_CALLBACK_KEY_DOWN: - l_mod = &(obj->callbacks->key_down); - break; - case EVAS_CALLBACK_KEY_UP: - l_mod = &(obj->callbacks->key_up); - break; - case EVAS_CALLBACK_FOCUS_IN: - l_mod = &(obj->callbacks->obj_focus_in); - break; - case EVAS_CALLBACK_FOCUS_OUT: - l_mod = &(obj->callbacks->obj_focus_out); - break; - case EVAS_CALLBACK_SHOW: - l_mod = &(obj->callbacks->obj_show); - break; - case EVAS_CALLBACK_HIDE: - l_mod = &(obj->callbacks->obj_hide); - break; - case EVAS_CALLBACK_MOVE: - l_mod = &(obj->callbacks->obj_move); - break; - case EVAS_CALLBACK_RESIZE: - l_mod = &(obj->callbacks->obj_resize); - break; - case EVAS_CALLBACK_RESTACK: - l_mod = &(obj->callbacks->obj_restack); - break; - default: - free(fn); - return; - break; - } - *l_mod = evas_object_list_append(*l_mod, fn); - */ obj->callbacks->callbacks = evas_object_list_append(obj->callbacks->callbacks, fn); } @@ -571,79 +382,6 @@ evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Type type, void ( if (!obj->callbacks) return NULL; - /* - switch (type) - { - case EVAS_CALLBACK_MOUSE_IN: - l_mod = &(obj->callbacks->in); - break; - case EVAS_CALLBACK_MOUSE_OUT: - l_mod = &(obj->callbacks->out); - break; - case EVAS_CALLBACK_MOUSE_DOWN: - l_mod = &(obj->callbacks->down); - break; - case EVAS_CALLBACK_MOUSE_UP: - l_mod = &(obj->callbacks->up); - break; - case EVAS_CALLBACK_MOUSE_MOVE: - l_mod = &(obj->callbacks->move); - break; - case EVAS_CALLBACK_MOUSE_WHEEL: - l_mod = &(obj->callbacks->wheel); - break; - case EVAS_CALLBACK_FREE: - l_mod = &(obj->callbacks->free); - break; - case EVAS_CALLBACK_KEY_DOWN: - l_mod = &(obj->callbacks->key_down); - break; - case EVAS_CALLBACK_KEY_UP: - l_mod = &(obj->callbacks->key_up); - break; - case EVAS_CALLBACK_FOCUS_IN: - l_mod = &(obj->callbacks->obj_focus_in); - break; - case EVAS_CALLBACK_FOCUS_OUT: - l_mod = &(obj->callbacks->obj_focus_out); - break; - case EVAS_CALLBACK_SHOW: - l_mod = &(obj->callbacks->obj_show); - break; - case EVAS_CALLBACK_HIDE: - l_mod = &(obj->callbacks->obj_hide); - break; - case EVAS_CALLBACK_MOVE: - l_mod = &(obj->callbacks->obj_move); - break; - case EVAS_CALLBACK_RESIZE: - l_mod = &(obj->callbacks->obj_resize); - break; - case EVAS_CALLBACK_RESTACK: - l_mod = &(obj->callbacks->obj_restack); - break; - default: - return NULL; - break; - } - for (l = *l_mod; l; l = l->next) - { - Evas_Func_Node *fn; - - fn = (Evas_Func_Node *)l; - if ((fn->func == func) && (!fn->delete_me)) - { - void *data; - - data = fn->data; - fn->delete_me = 1; - obj->callbacks->deletions_waiting = 1; - if (!obj->callbacks->walking_list) - evas_object_event_callback_clear(obj); - return data; - } - } - */ for (l = obj->callbacks->callbacks; l; l = l->next) { Evas_Func_Node *fn; diff --git a/legacy/evas/src/lib/canvas/evas_events.c b/legacy/evas/src/lib/canvas/evas_events.c index edbea9fa70..720a7a5160 100644 --- a/legacy/evas/src/lib/canvas/evas_events.c +++ b/legacy/evas/src/lib/canvas/evas_events.c @@ -235,6 +235,7 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int if (e->events_frozen > 0) return; e->last_timestamp = timestamp; + _evas_walk(e); copy = evas_event_list_copy(e->pointer.object.in); for (l = copy; l; l = l->next) { @@ -259,9 +260,11 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int ev.timestamp = timestamp; if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_DOWN, &ev); + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); e->last_mouse_down_counter++; + _evas_unwalk(e); } /** @@ -286,6 +289,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t if (e->events_frozen > 0) return; e->last_timestamp = timestamp; + _evas_walk(e); copy = evas_event_list_copy(e->pointer.object.in); for (l = copy; l; l = l->next) { @@ -311,6 +315,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t ev.timestamp = timestamp; if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_UP, &ev); + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); e->last_mouse_up_counter++; @@ -348,6 +353,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev); } + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); if (e->pointer.inside) @@ -377,6 +383,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev); } + if (e->delete_me) break; } } else @@ -394,6 +401,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t { e->pointer.mouse_grabbed = 0; } + _evas_unwalk(e); } /** @@ -414,6 +422,7 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam if (e->events_frozen > 0) return; e->last_timestamp = timestamp; + _evas_walk(e); copy = evas_event_list_copy(e->pointer.object.in); for (l = copy; l; l = l->next) @@ -435,10 +444,11 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam ev.timestamp = timestamp; if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_WHEEL, &ev); + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); - return; + _evas_unwalk(e); } /** @@ -472,6 +482,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const //// e->pointer.canvas_x = evas_coord_screen_x_to_world(e, x); //// e->pointer.canvas_y = evas_coord_screen_y_to_world(e, y); if ((!e->pointer.inside) && (e->pointer.mouse_grabbed == 0)) return; + _evas_walk(e); /* if our mouse button is grabbed to any objects */ if (e->pointer.mouse_grabbed > 0) { @@ -517,6 +528,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const } else outs = evas_list_append(outs, obj); + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); while (outs) @@ -525,7 +537,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const obj = outs->data; outs = evas_list_remove(outs, obj); - if (!obj->mouse_grabbed) + if ((!obj->mouse_grabbed) && (!e->delete_me)) { e->pointer.object.in = evas_list_remove(e->pointer.object.in, obj); { @@ -619,6 +631,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev); } + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); /* go thru our current list of ins */ @@ -647,12 +660,14 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev); } + if (e->delete_me) break; } /* free our old list of ins */ evas_list_free(e->pointer.object.in); /* and set up the new one */ e->pointer.object.in = ins; } + _evas_unwalk(e); } /** @@ -677,6 +692,7 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data) if (e->pointer.mouse_grabbed != 0) return; + _evas_walk(e); /* get new list of ins */ ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y); for (l = ins; l; l = l->next) @@ -704,12 +720,14 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data) if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev); } + if (e->delete_me) break; } /* free our old list of ins */ e->pointer.object.in = evas_list_free(e->pointer.object.in); /* and set up the new one */ e->pointer.object.in = ins; evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data); + _evas_unwalk(e); } /** @@ -729,6 +747,7 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data) if (e->events_frozen > 0) return; e->last_timestamp = timestamp; + _evas_walk(e); /* if our mouse button is grabbed to any objects */ if (e->pointer.mouse_grabbed == 0) { @@ -759,11 +778,13 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data) if (e->events_frozen <= 0) evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev); } + if (e->delete_me) break; } if (copy) copy = evas_list_free(copy); /* free our old list of ins */ e->pointer.object.in = evas_list_free(e->pointer.object.in); } + _evas_unwalk(e); } /** @@ -781,6 +802,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch if (!keyname) return; if (e->events_frozen > 0) return; e->last_timestamp = timestamp; + _evas_walk(e); { Evas_Event_Key_Down ev; int exclusive; @@ -821,6 +843,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch if (g->exclusive) exclusive = 1; } } + if (e->delete_me) break; } e->walking_grabs--; if (e->walking_grabs <= 0) @@ -848,6 +871,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev); } } + _evas_unwalk(e); } /** @@ -865,6 +889,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char if (!keyname) return; if (e->events_frozen > 0) return; e->last_timestamp = timestamp; + _evas_walk(e); { Evas_Event_Key_Up ev; int exclusive; @@ -904,6 +929,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_UP, &ev); if (g->exclusive) exclusive = 1; } + if (e->delete_me) break; } e->walking_grabs--; if (e->walking_grabs <= 0) @@ -931,6 +957,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev); } } + _evas_unwalk(e); } /** diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index ff0eae4424..4db780b293 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/src/lib/canvas/evas_main.c @@ -85,7 +85,9 @@ evas_free(Evas *e) return; MAGIC_CHECK_END(); + if (e->walking_list > 0) return; del = 1; + e->walking_list++; while (del) { del = 0; @@ -101,6 +103,13 @@ evas_free(Evas *e) Evas_Object *o; o = (Evas_Object *)ll; + if ((o->callbacks) && (o->callbacks->walking_list)) + { + /* Defer free */ + e->delete_me = 1; + e->walking_list--; + return; + } if (!o->delete_me) del = 1; } @@ -114,7 +123,8 @@ evas_free(Evas *e) evas_layer_del(lay); evas_layer_free(lay); } - + e->walking_list--; + evas_font_path_clear(e); e->pointer.object.in = evas_list_free(e->pointer.object.in); @@ -958,3 +968,17 @@ evas_data_attach_get(Evas *e) MAGIC_CHECK_END(); return e->attach_data; } + +void +_evas_walk(Evas *e) +{ + e->walking_list++; +} + +void +_evas_unwalk(Evas *e) +{ + e->walking_list--; + if ((e->walking_list == 0) && (e->delete_me)) evas_free(e); +} + diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index d7283fdbf8..5d306c2d29 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -309,8 +309,8 @@ struct _Evas Evas_Hash *name_hash; unsigned char changed : 1; - unsigned char walking_layers : 1; + int walking_list; int events_frozen; struct { @@ -340,6 +340,7 @@ struct _Evas int last_mouse_down_counter; int last_mouse_up_counter; Evas_Font_Hinting_Flags hinting; + unsigned char delete_me : 1; }; struct _Evas_Layer @@ -455,7 +456,7 @@ struct _Evas_Func_Node void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info); void *data; Evas_Callback_Type type; - char delete_me : 1; + unsigned char delete_me : 1; }; struct _Evas_Data_Node @@ -770,6 +771,9 @@ void evas_module_use(Evas_Module *em); void evas_module_clean(void); void evas_module_shutdown(void); +void _evas_walk(Evas *e); +void _evas_unwalk(Evas *e); + EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name); #define EVAS_API_OVERRIDE(func, api, prefix) \