sl@0: /* GObject - GLib Type, Object, Parameter and Signal Library sl@0: * Copyright (C) 2000-2001 Red Hat, Inc. sl@0: * Copyright (C) 2005 Imendio AB sl@0: * Portions copyright (c) 2006-2009 Nokia Corporation. All rights reserved. sl@0: * sl@0: * This library is free software; you can redistribute it and/or sl@0: * modify it under the terms of the GNU Lesser General Public sl@0: * License as published by the Free Software Foundation; either sl@0: * version 2 of the License, or (at your option) any later version. sl@0: * sl@0: * This library is distributed in the hope that it will be useful, sl@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of sl@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU sl@0: * Lesser General Public License for more details. sl@0: * sl@0: * You should have received a copy of the GNU Lesser General sl@0: * Public License along with this library; if not, write to the sl@0: * Free Software Foundation, Inc., 59 Temple Place, Suite 330, sl@0: * Boston, MA 02111-1307, USA. sl@0: */ sl@0: #if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) sl@0: #error "Only can be included directly." sl@0: #endif sl@0: sl@0: #ifndef __G_CLOSURE_H__ sl@0: #define __G_CLOSURE_H__ sl@0: sl@0: #include sl@0: sl@0: G_BEGIN_DECLS sl@0: sl@0: /* --- defines --- */ sl@0: /** sl@0: * G_CLOSURE_NEEDS_MARSHAL: sl@0: * @closure: a #GClosure sl@0: * sl@0: * Check if the closure still needs a marshaller. See g_closure_set_marshal(). sl@0: * sl@0: * Returns: %TRUE if a #GClosureMarshal marshaller has not yet been set on sl@0: * @closure. sl@0: */ sl@0: #define G_CLOSURE_NEEDS_MARSHAL(closure) (((GClosure*) (closure))->marshal == NULL) sl@0: /** sl@0: * G_CLOSURE_N_NOTIFIERS: sl@0: * @cl: a #GClosure sl@0: * sl@0: * Get the total number of notifiers connected with the closure @cl. sl@0: * The count includes the meta marshaller, the finalize and invalidate notifiers sl@0: * and the marshal guards. Note that each guard counts as two notifiers. sl@0: * See g_closure_set_meta_marshal(), g_closure_add_finalize_notifier(), sl@0: * g_closure_add_invalidate_notifier() and g_closure_add_marshal_guards(). sl@0: * sl@0: * Returns: number of notifiers sl@0: */ sl@0: #define G_CLOSURE_N_NOTIFIERS(cl) ((cl)->meta_marshal + ((cl)->n_guards << 1L) + \ sl@0: (cl)->n_fnotifiers + (cl)->n_inotifiers) sl@0: /** sl@0: * G_CCLOSURE_SWAP_DATA: sl@0: * @cclosure: a #GCClosure sl@0: * sl@0: * Checks whether the user data of the #GCClosure should be passed as the sl@0: * first parameter to the callback. See g_cclosure_new_swap(). sl@0: * sl@0: * Returns: %TRUE if data has to be swapped. sl@0: */ sl@0: #define G_CCLOSURE_SWAP_DATA(cclosure) (((GClosure*) (cclosure))->derivative_flag) sl@0: /** sl@0: * G_CALLBACK: sl@0: * @f: a function pointer. sl@0: * sl@0: * Cast a function pointer to a #GCallback. sl@0: */ sl@0: #define G_CALLBACK(f) ((GCallback) (f)) sl@0: sl@0: sl@0: /* -- typedefs --- */ sl@0: typedef struct _GClosure GClosure; sl@0: typedef struct _GClosureNotifyData GClosureNotifyData; sl@0: sl@0: /** sl@0: * GCallback: sl@0: * sl@0: * The type used for callback functions in structure definitions and function sl@0: * signatures. This doesn't mean that all callback functions must take no sl@0: * parameters and return void. The required signature of a callback function sl@0: * is determined by the context in which is used (e.g. the signal to which it sl@0: * is connected). Use G_CALLBACK() to cast the callback function to a #GCallback. sl@0: */ sl@0: typedef void (*GCallback) (void); sl@0: /** sl@0: * GClosureNotify: sl@0: * @data: data specified when registering the notification callback sl@0: * @closure: the #GClosure on which the notification is emitted sl@0: * sl@0: * The type used for the various notification callbacks which can be registered sl@0: * on closures. sl@0: */ sl@0: typedef void (*GClosureNotify) (gpointer data, sl@0: GClosure *closure); sl@0: /** sl@0: * GClosureMarshal: sl@0: * @closure: the #GClosure to which the marshaller belongs sl@0: * @return_value: a #GValue to store the return value. May be %NULL if the sl@0: * callback of @closure doesn't return a value. sl@0: * @n_param_values: the length of the @param_values array sl@0: * @param_values: an array of #GValues holding the arguments on sl@0: * which to invoke the callback of @closure sl@0: * @invocation_hint: the invocation hint given as the last argument sl@0: * to g_closure_invoke() sl@0: * @marshal_data: additional data specified when registering the marshaller, sl@0: * see g_closure_set_marshal() and g_closure_set_meta_marshal() sl@0: * sl@0: * The type used for marshaller functions. sl@0: */ sl@0: typedef void (*GClosureMarshal) (GClosure *closure, sl@0: GValue *return_value, sl@0: guint n_param_values, sl@0: const GValue *param_values, sl@0: gpointer invocation_hint, sl@0: gpointer marshal_data); sl@0: /** sl@0: * GCClosure: sl@0: * @closure: the #GClosure sl@0: * @callback: the callback function sl@0: * sl@0: * A #GCClosure is a specialization of #GClosure for C function callbacks. sl@0: */ sl@0: typedef struct _GCClosure GCClosure; sl@0: sl@0: sl@0: /* --- structures --- */ sl@0: struct _GClosureNotifyData sl@0: { sl@0: gpointer data; sl@0: GClosureNotify notify; sl@0: }; sl@0: /** sl@0: * GClosure: sl@0: * @in_marshal: Indicates whether the closure is currently being invoked with sl@0: * g_closure_invoke() sl@0: * @is_invalid: Indicates whether the closure has been invalidated by sl@0: * g_closure_invalidate() sl@0: * sl@0: * A #GClosure represents a callback supplied by the programmer. sl@0: */ sl@0: struct _GClosure sl@0: { sl@0: /*< private >*/ sl@0: volatile guint ref_count : 15; sl@0: volatile guint meta_marshal : 1; sl@0: volatile guint n_guards : 1; sl@0: volatile guint n_fnotifiers : 2; /* finalization notifiers */ sl@0: volatile guint n_inotifiers : 8; /* invalidation notifiers */ sl@0: volatile guint in_inotify : 1; sl@0: volatile guint floating : 1; sl@0: /*< protected >*/ sl@0: volatile guint derivative_flag : 1; sl@0: /*< public >*/ sl@0: volatile guint in_marshal : 1; sl@0: volatile guint is_invalid : 1; sl@0: sl@0: /*< private >*/ void (*marshal) (GClosure *closure, sl@0: GValue /*out*/ *return_value, sl@0: guint n_param_values, sl@0: const GValue *param_values, sl@0: gpointer invocation_hint, sl@0: gpointer marshal_data); sl@0: /*< protected >*/ gpointer data; sl@0: sl@0: /*< private >*/ GClosureNotifyData *notifiers; sl@0: sl@0: /* invariants/constrains: sl@0: * - ->marshal and ->data are _invalid_ as soon as ->is_invalid==TRUE sl@0: * - invocation of all inotifiers occours prior to fnotifiers sl@0: * - order of inotifiers is random sl@0: * inotifiers may _not_ free/invalidate parameter values (e.g. ->data) sl@0: * - order of fnotifiers is random sl@0: * - each notifier may only be removed before or during its invocation sl@0: * - reference counting may only happen prior to fnotify invocation sl@0: * (in that sense, fnotifiers are really finalization handlers) sl@0: */ sl@0: }; sl@0: /* closure for C function calls, callback() is the user function sl@0: */ sl@0: struct _GCClosure sl@0: { sl@0: GClosure closure; sl@0: gpointer callback; sl@0: }; sl@0: sl@0: sl@0: /* --- prototypes --- */ sl@0: IMPORT_C GClosure* g_cclosure_new (GCallback callback_func, sl@0: gpointer user_data, sl@0: GClosureNotify destroy_data); sl@0: IMPORT_C GClosure* g_cclosure_new_swap (GCallback callback_func, sl@0: gpointer user_data, sl@0: GClosureNotify destroy_data); sl@0: IMPORT_C GClosure* g_signal_type_cclosure_new (GType itype, sl@0: guint struct_offset); sl@0: sl@0: sl@0: /* --- prototypes --- */ sl@0: IMPORT_C GClosure* g_closure_ref (GClosure *closure); sl@0: IMPORT_C void g_closure_sink (GClosure *closure); sl@0: IMPORT_C void g_closure_unref (GClosure *closure); sl@0: /* intimidating */ sl@0: IMPORT_C GClosure* g_closure_new_simple (guint sizeof_closure, sl@0: gpointer data); sl@0: IMPORT_C void g_closure_add_finalize_notifier (GClosure *closure, sl@0: gpointer notify_data, sl@0: GClosureNotify notify_func); sl@0: IMPORT_C void g_closure_remove_finalize_notifier (GClosure *closure, sl@0: gpointer notify_data, sl@0: GClosureNotify notify_func); sl@0: IMPORT_C void g_closure_add_invalidate_notifier (GClosure *closure, sl@0: gpointer notify_data, sl@0: GClosureNotify notify_func); sl@0: IMPORT_C void g_closure_remove_invalidate_notifier (GClosure *closure, sl@0: gpointer notify_data, sl@0: GClosureNotify notify_func); sl@0: IMPORT_C void g_closure_add_marshal_guards (GClosure *closure, sl@0: gpointer pre_marshal_data, sl@0: GClosureNotify pre_marshal_notify, sl@0: gpointer post_marshal_data, sl@0: GClosureNotify post_marshal_notify); sl@0: IMPORT_C void g_closure_set_marshal (GClosure *closure, sl@0: GClosureMarshal marshal); sl@0: IMPORT_C void g_closure_set_meta_marshal (GClosure *closure, sl@0: gpointer marshal_data, sl@0: GClosureMarshal meta_marshal); sl@0: IMPORT_C void g_closure_invalidate (GClosure *closure); sl@0: IMPORT_C void g_closure_invoke (GClosure *closure, sl@0: GValue /*out*/ *return_value, sl@0: guint n_param_values, sl@0: const GValue *param_values, sl@0: gpointer invocation_hint); sl@0: sl@0: /* FIXME: sl@0: OK: data_object::destroy -> closure_invalidate(); sl@0: MIS: closure_invalidate() -> disconnect(closure); sl@0: MIS: disconnect(closure) -> (unlink) closure_unref(); sl@0: OK: closure_finalize() -> g_free (data_string); sl@0: sl@0: random remarks: sl@0: - need marshaller repo with decent aliasing to base types sl@0: - provide marshaller collection, virtually covering anything out there sl@0: */ sl@0: sl@0: G_END_DECLS sl@0: sl@0: #endif /* __G_CLOSURE_H__ */