1 /* GObject - GLib Type, Object, Parameter and Signal Library 2 * Copyright (C) 2000-2001 Red Hat, Inc. 3 * Copyright (C) 2005 Imendio AB 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General 16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 #ifndef __G_CLOSURE_H__ 19 #define __G_CLOSURE_H__ 20 21 #if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) 22 #error "Only <glib-object.h> can be included directly." 23 #endif 24 25 #include <gobject/gtype.h> 26 27 G_BEGIN_DECLS 28 29 /* --- defines --- */ 30 /** 31 * G_CLOSURE_NEEDS_MARSHAL: 32 * @closure: a #GClosure 33 * 34 * Check if the closure still needs a marshaller. See g_closure_set_marshal(). 35 * 36 * Returns: %TRUE if a #GClosureMarshal marshaller has not yet been set on 37 * @closure. 38 */ 39 #define G_CLOSURE_NEEDS_MARSHAL(closure) (((GClosure*) (closure))->marshal == NULL) 40 /** 41 * G_CLOSURE_N_NOTIFIERS: 42 * @cl: a #GClosure 43 * 44 * Get the total number of notifiers connected with the closure @cl. 45 * The count includes the meta marshaller, the finalize and invalidate notifiers 46 * and the marshal guards. Note that each guard counts as two notifiers. 47 * See g_closure_set_meta_marshal(), g_closure_add_finalize_notifier(), 48 * g_closure_add_invalidate_notifier() and g_closure_add_marshal_guards(). 49 * 50 * Returns: number of notifiers 51 */ 52 #define G_CLOSURE_N_NOTIFIERS(cl) (((cl)->n_guards << 1L) + \ 53 (cl)->n_fnotifiers + (cl)->n_inotifiers) 54 /** 55 * G_CCLOSURE_SWAP_DATA: 56 * @cclosure: a #GCClosure 57 * 58 * Checks whether the user data of the #GCClosure should be passed as the 59 * first parameter to the callback. See g_cclosure_new_swap(). 60 * 61 * Returns: %TRUE if data has to be swapped. 62 */ 63 #define G_CCLOSURE_SWAP_DATA(cclosure) (((GClosure*) (cclosure))->derivative_flag) 64 /** 65 * G_CALLBACK: 66 * @f: a function pointer. 67 * 68 * Cast a function pointer to a #GCallback. 69 */ 70 #define G_CALLBACK(f) ((GCallback) (f)) 71 72 73 /* -- typedefs --- */ 74 typedef struct _GClosure GClosure; 75 typedef struct _GClosureNotifyData GClosureNotifyData; 76 77 /** 78 * GCallback: 79 * 80 * The type used for callback functions in structure definitions and function 81 * signatures. This doesn't mean that all callback functions must take no 82 * parameters and return void. The required signature of a callback function 83 * is determined by the context in which is used (e.g. the signal to which it 84 * is connected). Use G_CALLBACK() to cast the callback function to a #GCallback. 85 */ 86 typedef void (*GCallback) (void); 87 /** 88 * GClosureNotify: 89 * @data: data specified when registering the notification callback 90 * @closure: the #GClosure on which the notification is emitted 91 * 92 * The type used for the various notification callbacks which can be registered 93 * on closures. 94 */ 95 typedef void (*GClosureNotify) (gpointer data, 96 GClosure *closure); 97 /** 98 * GClosureMarshal: 99 * @closure: the #GClosure to which the marshaller belongs 100 * @return_value: (nullable): a #GValue to store the return 101 * value. May be %NULL if the callback of @closure doesn't return a 102 * value. 103 * @n_param_values: the length of the @param_values array 104 * @param_values: (array length=n_param_values): an array of 105 * #GValues holding the arguments on which to invoke the 106 * callback of @closure 107 * @invocation_hint: (nullable): the invocation hint given as the 108 * last argument to g_closure_invoke() 109 * @marshal_data: (nullable): additional data specified when 110 * registering the marshaller, see g_closure_set_marshal() and 111 * g_closure_set_meta_marshal() 112 * 113 * The type used for marshaller functions. 114 */ 115 typedef void (*GClosureMarshal) (GClosure *closure, 116 GValue *return_value, 117 guint n_param_values, 118 const GValue *param_values, 119 gpointer invocation_hint, 120 gpointer marshal_data); 121 122 /** 123 * GVaClosureMarshal: 124 * @closure: the #GClosure to which the marshaller belongs 125 * @return_value: (nullable): a #GValue to store the return 126 * value. May be %NULL if the callback of @closure doesn't return a 127 * value. 128 * @instance: (type GObject.TypeInstance): the instance on which the closure is 129 * invoked. 130 * @args: va_list of arguments to be passed to the closure. 131 * @marshal_data: (nullable): additional data specified when 132 * registering the marshaller, see g_closure_set_marshal() and 133 * g_closure_set_meta_marshal() 134 * @n_params: the length of the @param_types array 135 * @param_types: (array length=n_params): the #GType of each argument from 136 * @args. 137 * 138 * This is the signature of va_list marshaller functions, an optional 139 * marshaller that can be used in some situations to avoid 140 * marshalling the signal argument into GValues. 141 */ 142 typedef void (* GVaClosureMarshal) (GClosure *closure, 143 GValue *return_value, 144 gpointer instance, 145 va_list args, 146 gpointer marshal_data, 147 int n_params, 148 GType *param_types); 149 150 /** 151 * GCClosure: 152 * @closure: the #GClosure 153 * @callback: the callback function 154 * 155 * A #GCClosure is a specialization of #GClosure for C function callbacks. 156 */ 157 typedef struct _GCClosure GCClosure; 158 159 160 /* --- structures --- */ 161 struct _GClosureNotifyData 162 { 163 gpointer data; 164 GClosureNotify notify; 165 }; 166 /** 167 * GClosure: 168 * @in_marshal: Indicates whether the closure is currently being invoked with 169 * g_closure_invoke() 170 * @is_invalid: Indicates whether the closure has been invalidated by 171 * g_closure_invalidate() 172 * 173 * A #GClosure represents a callback supplied by the programmer. 174 */ 175 struct _GClosure 176 { 177 /*< private >*/ 178 guint ref_count : 15; /* (atomic) */ 179 /* meta_marshal is not used anymore but must be zero for historical reasons 180 as it was exposed in the G_CLOSURE_N_NOTIFIERS macro */ 181 guint meta_marshal_nouse : 1; /* (atomic) */ 182 guint n_guards : 1; /* (atomic) */ 183 guint n_fnotifiers : 2; /* finalization notifiers (atomic) */ 184 guint n_inotifiers : 8; /* invalidation notifiers (atomic) */ 185 guint in_inotify : 1; /* (atomic) */ 186 guint floating : 1; /* (atomic) */ 187 /*< protected >*/ 188 guint derivative_flag : 1; /* (atomic) */ 189 /*< public >*/ 190 guint in_marshal : 1; /* (atomic) */ 191 guint is_invalid : 1; /* (atomic) */ 192 193 /*< private >*/ void (*marshal) (GClosure *closure, 194 GValue /*out*/ *return_value, 195 guint n_param_values, 196 const GValue *param_values, 197 gpointer invocation_hint, 198 gpointer marshal_data); 199 /*< protected >*/ gpointer data; 200 201 /*< private >*/ GClosureNotifyData *notifiers; 202 203 /* invariants/constraints: 204 * - ->marshal and ->data are _invalid_ as soon as ->is_invalid==TRUE 205 * - invocation of all inotifiers occurs prior to fnotifiers 206 * - order of inotifiers is random 207 * inotifiers may _not_ free/invalidate parameter values (e.g. ->data) 208 * - order of fnotifiers is random 209 * - each notifier may only be removed before or during its invocation 210 * - reference counting may only happen prior to fnotify invocation 211 * (in that sense, fnotifiers are really finalization handlers) 212 */ 213 }; 214 /* closure for C function calls, callback() is the user function 215 */ 216 struct _GCClosure 217 { 218 GClosure closure; 219 gpointer callback; 220 }; 221 222 223 /* --- prototypes --- */ 224 GLIB_AVAILABLE_IN_ALL 225 GClosure* g_cclosure_new (GCallback callback_func, 226 gpointer user_data, 227 GClosureNotify destroy_data); 228 GLIB_AVAILABLE_IN_ALL 229 GClosure* g_cclosure_new_swap (GCallback callback_func, 230 gpointer user_data, 231 GClosureNotify destroy_data); 232 GLIB_AVAILABLE_IN_ALL 233 GClosure* g_signal_type_cclosure_new (GType itype, 234 guint struct_offset); 235 236 237 /* --- prototypes --- */ 238 GLIB_AVAILABLE_IN_ALL 239 GClosure* g_closure_ref (GClosure *closure); 240 GLIB_AVAILABLE_IN_ALL 241 void g_closure_sink (GClosure *closure); 242 GLIB_AVAILABLE_IN_ALL 243 void g_closure_unref (GClosure *closure); 244 /* intimidating */ 245 GLIB_AVAILABLE_IN_ALL 246 GClosure* g_closure_new_simple (guint sizeof_closure, 247 gpointer data); 248 GLIB_AVAILABLE_IN_ALL 249 void g_closure_add_finalize_notifier (GClosure *closure, 250 gpointer notify_data, 251 GClosureNotify notify_func); 252 GLIB_AVAILABLE_IN_ALL 253 void g_closure_remove_finalize_notifier (GClosure *closure, 254 gpointer notify_data, 255 GClosureNotify notify_func); 256 GLIB_AVAILABLE_IN_ALL 257 void g_closure_add_invalidate_notifier (GClosure *closure, 258 gpointer notify_data, 259 GClosureNotify notify_func); 260 GLIB_AVAILABLE_IN_ALL 261 void g_closure_remove_invalidate_notifier (GClosure *closure, 262 gpointer notify_data, 263 GClosureNotify notify_func); 264 GLIB_AVAILABLE_IN_ALL 265 void g_closure_add_marshal_guards (GClosure *closure, 266 gpointer pre_marshal_data, 267 GClosureNotify pre_marshal_notify, 268 gpointer post_marshal_data, 269 GClosureNotify post_marshal_notify); 270 GLIB_AVAILABLE_IN_ALL 271 void g_closure_set_marshal (GClosure *closure, 272 GClosureMarshal marshal); 273 GLIB_AVAILABLE_IN_ALL 274 void g_closure_set_meta_marshal (GClosure *closure, 275 gpointer marshal_data, 276 GClosureMarshal meta_marshal); 277 GLIB_AVAILABLE_IN_ALL 278 void g_closure_invalidate (GClosure *closure); 279 GLIB_AVAILABLE_IN_ALL 280 void g_closure_invoke (GClosure *closure, 281 GValue /*out*/ *return_value, 282 guint n_param_values, 283 const GValue *param_values, 284 gpointer invocation_hint); 285 286 /* FIXME: 287 OK: data_object::destroy -> closure_invalidate(); 288 MIS: closure_invalidate() -> disconnect(closure); 289 MIS: disconnect(closure) -> (unlink) closure_unref(); 290 OK: closure_finalize() -> g_free (data_string); 291 292 random remarks: 293 - need marshaller repo with decent aliasing to base types 294 - provide marshaller collection, virtually covering anything out there 295 */ 296 297 GLIB_AVAILABLE_IN_ALL 298 void g_cclosure_marshal_generic (GClosure *closure, 299 GValue *return_gvalue, 300 guint n_param_values, 301 const GValue *param_values, 302 gpointer invocation_hint, 303 gpointer marshal_data); 304 305 GLIB_AVAILABLE_IN_ALL 306 void g_cclosure_marshal_generic_va (GClosure *closure, 307 GValue *return_value, 308 gpointer instance, 309 va_list args_list, 310 gpointer marshal_data, 311 int n_params, 312 GType *param_types); 313 314 315 G_END_DECLS 316 317 #endif /* __G_CLOSURE_H__ */ 318