|
1 /* GObject - GLib Type, Object, Parameter and Signal Library |
|
2 * Copyright (C) 2000-2001 Red Hat, Inc. |
|
3 * Copyright (C) 2005 Imendio AB |
|
4 * Portions copyright (c) 2006-2009 Nokia Corporation. All rights reserved. |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Lesser General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General |
|
17 * Public License along with this library; if not, write to the |
|
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
|
19 * Boston, MA 02111-1307, USA. |
|
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 #ifndef __G_CLOSURE_H__ |
|
26 #define __G_CLOSURE_H__ |
|
27 |
|
28 #include <gobject/gtype.h> |
|
29 |
|
30 G_BEGIN_DECLS |
|
31 |
|
32 /* --- defines --- */ |
|
33 /** |
|
34 * G_CLOSURE_NEEDS_MARSHAL: |
|
35 * @closure: a #GClosure |
|
36 * |
|
37 * Check if the closure still needs a marshaller. See g_closure_set_marshal(). |
|
38 * |
|
39 * Returns: %TRUE if a #GClosureMarshal marshaller has not yet been set on |
|
40 * @closure. |
|
41 */ |
|
42 #define G_CLOSURE_NEEDS_MARSHAL(closure) (((GClosure*) (closure))->marshal == NULL) |
|
43 /** |
|
44 * G_CLOSURE_N_NOTIFIERS: |
|
45 * @cl: a #GClosure |
|
46 * |
|
47 * Get the total number of notifiers connected with the closure @cl. |
|
48 * The count includes the meta marshaller, the finalize and invalidate notifiers |
|
49 * and the marshal guards. Note that each guard counts as two notifiers. |
|
50 * See g_closure_set_meta_marshal(), g_closure_add_finalize_notifier(), |
|
51 * g_closure_add_invalidate_notifier() and g_closure_add_marshal_guards(). |
|
52 * |
|
53 * Returns: number of notifiers |
|
54 */ |
|
55 #define G_CLOSURE_N_NOTIFIERS(cl) ((cl)->meta_marshal + ((cl)->n_guards << 1L) + \ |
|
56 (cl)->n_fnotifiers + (cl)->n_inotifiers) |
|
57 /** |
|
58 * G_CCLOSURE_SWAP_DATA: |
|
59 * @cclosure: a #GCClosure |
|
60 * |
|
61 * Checks whether the user data of the #GCClosure should be passed as the |
|
62 * first parameter to the callback. See g_cclosure_new_swap(). |
|
63 * |
|
64 * Returns: %TRUE if data has to be swapped. |
|
65 */ |
|
66 #define G_CCLOSURE_SWAP_DATA(cclosure) (((GClosure*) (cclosure))->derivative_flag) |
|
67 /** |
|
68 * G_CALLBACK: |
|
69 * @f: a function pointer. |
|
70 * |
|
71 * Cast a function pointer to a #GCallback. |
|
72 */ |
|
73 #define G_CALLBACK(f) ((GCallback) (f)) |
|
74 |
|
75 |
|
76 /* -- typedefs --- */ |
|
77 typedef struct _GClosure GClosure; |
|
78 typedef struct _GClosureNotifyData GClosureNotifyData; |
|
79 |
|
80 /** |
|
81 * GCallback: |
|
82 * |
|
83 * The type used for callback functions in structure definitions and function |
|
84 * signatures. This doesn't mean that all callback functions must take no |
|
85 * parameters and return void. The required signature of a callback function |
|
86 * is determined by the context in which is used (e.g. the signal to which it |
|
87 * is connected). Use G_CALLBACK() to cast the callback function to a #GCallback. |
|
88 */ |
|
89 typedef void (*GCallback) (void); |
|
90 /** |
|
91 * GClosureNotify: |
|
92 * @data: data specified when registering the notification callback |
|
93 * @closure: the #GClosure on which the notification is emitted |
|
94 * |
|
95 * The type used for the various notification callbacks which can be registered |
|
96 * on closures. |
|
97 */ |
|
98 typedef void (*GClosureNotify) (gpointer data, |
|
99 GClosure *closure); |
|
100 /** |
|
101 * GClosureMarshal: |
|
102 * @closure: the #GClosure to which the marshaller belongs |
|
103 * @return_value: a #GValue to store the return value. May be %NULL if the |
|
104 * callback of @closure doesn't return a value. |
|
105 * @n_param_values: the length of the @param_values array |
|
106 * @param_values: an array of #GValue<!-- -->s holding the arguments on |
|
107 * which to invoke the callback of @closure |
|
108 * @invocation_hint: the invocation hint given as the last argument |
|
109 * to g_closure_invoke() |
|
110 * @marshal_data: additional data specified when registering the marshaller, |
|
111 * see g_closure_set_marshal() and 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 * GCClosure: |
|
123 * @closure: the #GClosure |
|
124 * @callback: the callback function |
|
125 * |
|
126 * A #GCClosure is a specialization of #GClosure for C function callbacks. |
|
127 */ |
|
128 typedef struct _GCClosure GCClosure; |
|
129 |
|
130 |
|
131 /* --- structures --- */ |
|
132 struct _GClosureNotifyData |
|
133 { |
|
134 gpointer data; |
|
135 GClosureNotify notify; |
|
136 }; |
|
137 /** |
|
138 * GClosure: |
|
139 * @in_marshal: Indicates whether the closure is currently being invoked with |
|
140 * g_closure_invoke() |
|
141 * @is_invalid: Indicates whether the closure has been invalidated by |
|
142 * g_closure_invalidate() |
|
143 * |
|
144 * A #GClosure represents a callback supplied by the programmer. |
|
145 */ |
|
146 struct _GClosure |
|
147 { |
|
148 /*< private >*/ |
|
149 volatile guint ref_count : 15; |
|
150 volatile guint meta_marshal : 1; |
|
151 volatile guint n_guards : 1; |
|
152 volatile guint n_fnotifiers : 2; /* finalization notifiers */ |
|
153 volatile guint n_inotifiers : 8; /* invalidation notifiers */ |
|
154 volatile guint in_inotify : 1; |
|
155 volatile guint floating : 1; |
|
156 /*< protected >*/ |
|
157 volatile guint derivative_flag : 1; |
|
158 /*< public >*/ |
|
159 volatile guint in_marshal : 1; |
|
160 volatile guint is_invalid : 1; |
|
161 |
|
162 /*< private >*/ void (*marshal) (GClosure *closure, |
|
163 GValue /*out*/ *return_value, |
|
164 guint n_param_values, |
|
165 const GValue *param_values, |
|
166 gpointer invocation_hint, |
|
167 gpointer marshal_data); |
|
168 /*< protected >*/ gpointer data; |
|
169 |
|
170 /*< private >*/ GClosureNotifyData *notifiers; |
|
171 |
|
172 /* invariants/constrains: |
|
173 * - ->marshal and ->data are _invalid_ as soon as ->is_invalid==TRUE |
|
174 * - invocation of all inotifiers occours prior to fnotifiers |
|
175 * - order of inotifiers is random |
|
176 * inotifiers may _not_ free/invalidate parameter values (e.g. ->data) |
|
177 * - order of fnotifiers is random |
|
178 * - each notifier may only be removed before or during its invocation |
|
179 * - reference counting may only happen prior to fnotify invocation |
|
180 * (in that sense, fnotifiers are really finalization handlers) |
|
181 */ |
|
182 }; |
|
183 /* closure for C function calls, callback() is the user function |
|
184 */ |
|
185 struct _GCClosure |
|
186 { |
|
187 GClosure closure; |
|
188 gpointer callback; |
|
189 }; |
|
190 |
|
191 |
|
192 /* --- prototypes --- */ |
|
193 IMPORT_C GClosure* g_cclosure_new (GCallback callback_func, |
|
194 gpointer user_data, |
|
195 GClosureNotify destroy_data); |
|
196 IMPORT_C GClosure* g_cclosure_new_swap (GCallback callback_func, |
|
197 gpointer user_data, |
|
198 GClosureNotify destroy_data); |
|
199 IMPORT_C GClosure* g_signal_type_cclosure_new (GType itype, |
|
200 guint struct_offset); |
|
201 |
|
202 |
|
203 /* --- prototypes --- */ |
|
204 IMPORT_C GClosure* g_closure_ref (GClosure *closure); |
|
205 IMPORT_C void g_closure_sink (GClosure *closure); |
|
206 IMPORT_C void g_closure_unref (GClosure *closure); |
|
207 /* intimidating */ |
|
208 IMPORT_C GClosure* g_closure_new_simple (guint sizeof_closure, |
|
209 gpointer data); |
|
210 IMPORT_C void g_closure_add_finalize_notifier (GClosure *closure, |
|
211 gpointer notify_data, |
|
212 GClosureNotify notify_func); |
|
213 IMPORT_C void g_closure_remove_finalize_notifier (GClosure *closure, |
|
214 gpointer notify_data, |
|
215 GClosureNotify notify_func); |
|
216 IMPORT_C void g_closure_add_invalidate_notifier (GClosure *closure, |
|
217 gpointer notify_data, |
|
218 GClosureNotify notify_func); |
|
219 IMPORT_C void g_closure_remove_invalidate_notifier (GClosure *closure, |
|
220 gpointer notify_data, |
|
221 GClosureNotify notify_func); |
|
222 IMPORT_C void g_closure_add_marshal_guards (GClosure *closure, |
|
223 gpointer pre_marshal_data, |
|
224 GClosureNotify pre_marshal_notify, |
|
225 gpointer post_marshal_data, |
|
226 GClosureNotify post_marshal_notify); |
|
227 IMPORT_C void g_closure_set_marshal (GClosure *closure, |
|
228 GClosureMarshal marshal); |
|
229 IMPORT_C void g_closure_set_meta_marshal (GClosure *closure, |
|
230 gpointer marshal_data, |
|
231 GClosureMarshal meta_marshal); |
|
232 IMPORT_C void g_closure_invalidate (GClosure *closure); |
|
233 IMPORT_C void g_closure_invoke (GClosure *closure, |
|
234 GValue /*out*/ *return_value, |
|
235 guint n_param_values, |
|
236 const GValue *param_values, |
|
237 gpointer invocation_hint); |
|
238 |
|
239 /* FIXME: |
|
240 OK: data_object::destroy -> closure_invalidate(); |
|
241 MIS: closure_invalidate() -> disconnect(closure); |
|
242 MIS: disconnect(closure) -> (unlink) closure_unref(); |
|
243 OK: closure_finalize() -> g_free (data_string); |
|
244 |
|
245 random remarks: |
|
246 - need marshaller repo with decent aliasing to base types |
|
247 - provide marshaller collection, virtually covering anything out there |
|
248 */ |
|
249 |
|
250 G_END_DECLS |
|
251 |
|
252 #endif /* __G_CLOSURE_H__ */ |