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;
};