static int ewl_callback_insert(Ewl_Widget *w, Ewl_Callback_Type t, Ewl_Callback *cb, unsigned int pos) { Ewl_Callback *old = NULL; DENTER_FUNCTION(DLEVEL_STABLE); DCHECK_PARAM_PTR_RET("w", w, 0); /* set direct if possible */ if (!EWL_CALLBACK_LEN(w, t)) { w->callbacks[t].list = (void *)cb; w->callbacks[t].len = 1; EWL_CALLBACK_SET_DIRECT(w, t); DRETURN_INT(cb->id, DLEVEL_STABLE); } w->callbacks[t].len ++; if (w->callbacks[t].mask & EWL_CALLBACK_TYPE_DIRECT) { old = (Ewl_Callback *)w->callbacks[t].list; w->callbacks[t].list = NULL; EWL_CALLBACK_SET_NODIRECT(w, t); } w->callbacks[t].list = realloc(w->callbacks[t].list, w->callbacks[t].len * sizeof(void *)); /* if old is set this was a direct so we can just set 0,1 and be * done with it */ if (old) { w->callbacks[t].list[0] = old; w->callbacks[t].list[1] = cb; } else { memmove(w->callbacks[t].list + ((pos + 1) * sizeof(void *)), w->callbacks[t].list + (pos * sizeof(void *)), w->callbacks[t].len); w->callbacks[t].list[pos] = cb; } DRETURN_INT(cb->id, DLEVEL_STABLE); } struct Ewl_Callback_Chain { void **list; unsigned short mask; unsigned short len; };