/** * g_closure_set_meta_marshal: (skip) * @closure: a #GClosure * @marshal_data: context-dependent data to pass to @meta_marshal * @meta_marshal: a #GClosureMarshal function * * Sets the meta marshaller of @closure. A meta marshaller wraps * @closure->marshal and modifies the way it is called in some * fashion. The most common use of this facility is for C callbacks. * The same marshallers (generated by <link * linkend="glib-genmarshal">glib-genmarshal</link>) are used * everywhere, but the way that we get the callback function * differs. In most cases we want to use @closure->callback, but in * other cases we want to use some different technique to retrieve the * callback function. * * For example, class closures for signals (see * g_signal_type_cclosure_new()) retrieve the callback function from a * fixed offset in the class structure. The meta marshaller retrieves * the right callback and passes it to the marshaller as the * @marshal_data argument. */ void g_closure_set_meta_marshal (GClosure *closure, gpointer marshal_data, GClosureMarshal meta_marshal) { GClosureNotifyData *notifiers; g_return_if_fail (closure != NULL); g_return_if_fail (meta_marshal != NULL); g_return_if_fail (closure->is_invalid == FALSE); g_return_if_fail (closure->in_marshal == FALSE); g_return_if_fail (closure->meta_marshal == 0); notifiers = closure->notifiers; closure->notifiers = g_renew (GClosureNotifyData, NULL, CLOSURE_N_NOTIFIERS (closure) + 1); if (notifiers) { /* usually the meta marshal will be setup right after creation, so the * g_memmove() should be rare-case scenario */ g_memmove (closure->notifiers + 1, notifiers, CLOSURE_N_NOTIFIERS (closure) * sizeof (notifiers[0])); g_free (notifiers); } closure->notifiers[0].data = marshal_data; closure->notifiers[0].notify = (GClosureNotify) meta_marshal; SET (closure, meta_marshal, 1); }
void g_closure_add_invalidate_notifier (GClosure *closure, gpointer notify_data, GClosureNotify notify_func) { guint i; g_return_if_fail (closure != NULL); g_return_if_fail (notify_func != NULL); g_return_if_fail (closure->is_invalid == FALSE); g_return_if_fail (closure->n_inotifiers < CLOSURE_MAX_N_INOTIFIERS); closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1); i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers++; closure->notifiers[i].data = notify_data; closure->notifiers[i].notify = notify_func; }
/** * g_closure_add_marshal_guards: (skip) * @closure: a #GClosure * @pre_marshal_data: data to pass to @pre_marshal_notify * @pre_marshal_notify: a function to call before the closure callback * @post_marshal_data: data to pass to @post_marshal_notify * @post_marshal_notify: a function to call after the closure callback * * Adds a pair of notifiers which get invoked before and after the * closure callback, respectively. This is typically used to protect * the extra arguments for the duration of the callback. See * g_object_watch_closure() for an example of marshal guards. */ void g_closure_add_marshal_guards (GClosure *closure, gpointer pre_marshal_data, GClosureNotify pre_marshal_notify, gpointer post_marshal_data, GClosureNotify post_marshal_notify) { guint i; g_return_if_fail (closure != NULL); g_return_if_fail (pre_marshal_notify != NULL); g_return_if_fail (post_marshal_notify != NULL); g_return_if_fail (closure->is_invalid == FALSE); g_return_if_fail (closure->in_marshal == FALSE); g_return_if_fail (closure->n_guards < CLOSURE_MAX_N_GUARDS); closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 2); if (closure->n_inotifiers) closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers + 1)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + 0)]; if (closure->n_inotifiers > 1) closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + 1)]; if (closure->n_fnotifiers) closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + 1)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 0]; if (closure->n_fnotifiers > 1) closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 1]; if (closure->n_guards) closure->notifiers[(closure->meta_marshal + closure->n_guards + closure->n_guards + 1)] = closure->notifiers[closure->meta_marshal + closure->n_guards]; i = closure->n_guards; closure->notifiers[closure->meta_marshal + i].data = pre_marshal_data; closure->notifiers[closure->meta_marshal + i].notify = pre_marshal_notify; closure->notifiers[closure->meta_marshal + i + 1].data = post_marshal_data; closure->notifiers[closure->meta_marshal + i + 1].notify = post_marshal_notify; INC (closure, n_guards); }
static inline gboolean closure_try_remove_inotify (GClosure *closure, gpointer notify_data, GClosureNotify notify_func) { GClosureNotifyData *ndata, *nlast; nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - 1; for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++) if (ndata->notify == notify_func && ndata->data == notify_data) { DEC (closure, n_inotifiers); if (ndata < nlast) *ndata = *nlast; return TRUE; } return FALSE; }
void g_closure_add_finalize_notifier (GClosure *closure, gpointer notify_data, GClosureNotify notify_func) { guint i; g_return_if_fail (closure != NULL); g_return_if_fail (notify_func != NULL); g_return_if_fail (closure->n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS); closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1); if (closure->n_inotifiers) closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + 0)]; i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers++; closure->notifiers[i].data = notify_data; closure->notifiers[i].notify = notify_func; }