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); DCHECK_PARAM_PTR_RET("cb", cb, 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 we have a type direct then we need to save off the direct * pointer and set the list to NULL so it'll be allocd' correctly */ 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] = (!pos ? cb : old); w->callbacks[t].list[1] = ( pos ? cb : old); } else { /* only have to move if we aren't at the end already */ if (pos != (w->callbacks[t].len - 1)) { printf("pos %d len %d\n", pos, w->callbacks[t].len); memmove(w->callbacks[t].list + ((pos + 1) * sizeof(void *)), w->callbacks[t].list + (pos * sizeof(void *)), (w->callbacks[t].len - 1) * sizeof(void *)); } w->callbacks[t].list[pos] = cb; } { int i; for (i = 0; i < EWL_CALLBACK_LEN(w, t); i++) { printf(" %d %p\n", i, w->callbacks[t].list[i]); } printf("----------------\n"); } DRETURN_INT(cb->id, DLEVEL_STABLE); } struct Ewl_Callback_Chain { void **list; unsigned short mask; unsigned short len; };