1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2001 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "gsourceclosure.h"
25 #include "gvaluetypes.h"
27 #include "glib-unix.h"
30 G_DEFINE_BOXED_TYPE (GIOChannel
, g_io_channel
, g_io_channel_ref
, g_io_channel_unref
)
33 g_io_condition_get_type (void)
35 static GType etype
= 0;
38 static const GFlagsValue values
[] = {
39 { G_IO_IN
, "G_IO_IN", "in" },
40 { G_IO_OUT
, "G_IO_OUT", "out" },
41 { G_IO_PRI
, "G_IO_PRI", "pri" },
42 { G_IO_ERR
, "G_IO_ERR", "err" },
43 { G_IO_HUP
, "G_IO_HUP", "hup" },
44 { G_IO_NVAL
, "G_IO_NVAL", "nval" },
47 etype
= g_flags_register_static ("GIOCondition", values
);
52 /* We need to hand-write this marshaler, since it doesn't have an
56 source_closure_marshal_BOOLEAN__VOID (GClosure
*closure
,
59 const GValue
*param_values
,
60 gpointer invocation_hint
,
61 gpointer marshal_data
)
64 GCClosure
*cc
= (GCClosure
*) closure
;
67 g_return_if_fail (return_value
!= NULL
);
68 g_return_if_fail (n_param_values
== 0);
70 callback
= (GSourceFunc
) (marshal_data
? marshal_data
: cc
->callback
);
72 v_return
= callback (closure
->data
);
74 g_value_set_boolean (return_value
, v_return
);
78 io_watch_closure_callback (GIOChannel
*channel
,
79 GIOCondition condition
,
82 GClosure
*closure
= data
;
84 GValue params
[2] = { G_VALUE_INIT
, G_VALUE_INIT
};
85 GValue result_value
= G_VALUE_INIT
;
88 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
89 g_value_init (¶ms
[0], G_TYPE_IO_CHANNEL
);
90 g_value_set_boxed (¶ms
[0], channel
);
92 g_value_init (¶ms
[1], G_TYPE_IO_CONDITION
);
93 g_value_set_flags (¶ms
[1], condition
);
95 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
97 result
= g_value_get_boolean (&result_value
);
98 g_value_unset (&result_value
);
99 g_value_unset (¶ms
[0]);
100 g_value_unset (¶ms
[1]);
106 g_child_watch_closure_callback (GPid pid
,
110 GClosure
*closure
= data
;
112 GValue params
[2] = { G_VALUE_INIT
, G_VALUE_INIT
};
113 GValue result_value
= G_VALUE_INIT
;
116 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
119 g_value_init (¶ms
[0], G_TYPE_ULONG
);
120 g_value_set_ulong (¶ms
[0], pid
);
123 g_value_init (¶ms
[0], G_TYPE_POINTER
);
124 g_value_set_pointer (¶ms
[0], pid
);
127 g_value_init (¶ms
[1], G_TYPE_INT
);
128 g_value_set_int (¶ms
[1], status
);
130 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
132 result
= g_value_get_boolean (&result_value
);
133 g_value_unset (&result_value
);
134 g_value_unset (¶ms
[0]);
135 g_value_unset (¶ms
[1]);
142 g_unix_fd_source_closure_callback (int fd
,
143 GIOCondition condition
,
146 GClosure
*closure
= data
;
148 GValue params
[2] = { G_VALUE_INIT
, G_VALUE_INIT
};
149 GValue result_value
= G_VALUE_INIT
;
152 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
154 g_value_init (¶ms
[0], G_TYPE_INT
);
155 g_value_set_int (¶ms
[0], fd
);
157 g_value_init (¶ms
[1], G_TYPE_IO_CONDITION
);
158 g_value_set_flags (¶ms
[1], condition
);
160 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
162 result
= g_value_get_boolean (&result_value
);
163 g_value_unset (&result_value
);
164 g_value_unset (¶ms
[0]);
165 g_value_unset (¶ms
[1]);
172 source_closure_callback (gpointer data
)
174 GClosure
*closure
= data
;
175 GValue result_value
= G_VALUE_INIT
;
178 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
180 g_closure_invoke (closure
, &result_value
, 0, NULL
, NULL
);
182 result
= g_value_get_boolean (&result_value
);
183 g_value_unset (&result_value
);
189 closure_callback_get (gpointer cb_data
,
194 GSourceFunc closure_callback
= source
->source_funcs
->closure_callback
;
196 if (!closure_callback
)
198 if (source
->source_funcs
== &g_io_watch_funcs
)
199 closure_callback
= (GSourceFunc
)io_watch_closure_callback
;
200 else if (source
->source_funcs
== &g_child_watch_funcs
)
201 closure_callback
= (GSourceFunc
)g_child_watch_closure_callback
;
203 else if (source
->source_funcs
== &g_unix_fd_source_funcs
)
204 closure_callback
= (GSourceFunc
)g_unix_fd_source_closure_callback
;
206 else if (source
->source_funcs
== &g_timeout_funcs
||
208 source
->source_funcs
== &g_unix_signal_funcs
||
210 source
->source_funcs
== &g_idle_funcs
)
211 closure_callback
= source_closure_callback
;
214 *func
= closure_callback
;
218 static GSourceCallbackFuncs closure_callback_funcs
= {
219 (void (*) (gpointer
)) g_closure_ref
,
220 (void (*) (gpointer
)) g_closure_unref
,
225 closure_invalidated (gpointer user_data
,
228 g_source_destroy (user_data
);
232 * g_source_set_closure:
233 * @source: the source
234 * @closure: a #GClosure
236 * Set the callback for a source as a #GClosure.
238 * If the source is not one of the standard GLib types, the @closure_callback
239 * and @closure_marshal fields of the #GSourceFuncs structure must have been
240 * filled in with pointers to appropriate functions.
243 g_source_set_closure (GSource
*source
,
246 g_return_if_fail (source
!= NULL
);
247 g_return_if_fail (closure
!= NULL
);
249 if (!source
->source_funcs
->closure_callback
&&
251 source
->source_funcs
!= &g_unix_fd_source_funcs
&&
252 source
->source_funcs
!= &g_unix_signal_funcs
&&
254 source
->source_funcs
!= &g_child_watch_funcs
&&
255 source
->source_funcs
!= &g_io_watch_funcs
&&
256 source
->source_funcs
!= &g_timeout_funcs
&&
257 source
->source_funcs
!= &g_idle_funcs
)
259 g_critical (G_STRLOC
": closure can not be set on closure without GSourceFuncs::closure_callback\n");
263 g_closure_ref (closure
);
264 g_closure_sink (closure
);
265 g_source_set_callback_indirect (source
, closure
, &closure_callback_funcs
);
267 g_closure_add_invalidate_notifier (closure
, source
, closure_invalidated
);
269 if (G_CLOSURE_NEEDS_MARSHAL (closure
))
271 GClosureMarshal marshal
= (GClosureMarshal
)source
->source_funcs
->closure_marshal
;
273 g_closure_set_marshal (closure
, marshal
);
274 else if (source
->source_funcs
== &g_idle_funcs
||
276 source
->source_funcs
== &g_unix_signal_funcs
||
278 source
->source_funcs
== &g_timeout_funcs
)
279 g_closure_set_marshal (closure
, source_closure_marshal_BOOLEAN__VOID
);
281 g_closure_set_marshal (closure
, g_cclosure_marshal_generic
);
286 dummy_closure_marshal (GClosure
*closure
,
287 GValue
*return_value
,
288 guint n_param_values
,
289 const GValue
*param_values
,
290 gpointer invocation_hint
,
291 gpointer marshal_data
)
293 if (G_VALUE_HOLDS_BOOLEAN (return_value
))
294 g_value_set_boolean (return_value
, TRUE
);
298 * g_source_set_dummy_callback:
299 * @source: the source
301 * Sets a dummy callback for @source. The callback will do nothing, and
302 * if the source expects a #gboolean return value, it will return %TRUE.
303 * (If the source expects any other type of return value, it will return
304 * a 0/%NULL value; whatever g_value_init() initializes a #GValue to for
307 * If the source is not one of the standard GLib types, the
308 * @closure_callback and @closure_marshal fields of the #GSourceFuncs
309 * structure must have been filled in with pointers to appropriate
313 g_source_set_dummy_callback (GSource
*source
)
317 closure
= g_closure_new_simple (sizeof (GClosure
), NULL
);
318 g_closure_set_meta_marshal (closure
, NULL
, dummy_closure_marshal
);
319 g_source_set_closure (source
, closure
);