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.1 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 volatile GType etype
= 0;
37 if (g_once_init_enter (&etype
))
39 static const GFlagsValue values
[] = {
40 { G_IO_IN
, "G_IO_IN", "in" },
41 { G_IO_OUT
, "G_IO_OUT", "out" },
42 { G_IO_PRI
, "G_IO_PRI", "pri" },
43 { G_IO_ERR
, "G_IO_ERR", "err" },
44 { G_IO_HUP
, "G_IO_HUP", "hup" },
45 { G_IO_NVAL
, "G_IO_NVAL", "nval" },
48 GType type_id
= g_flags_register_static ("GIOCondition", values
);
49 g_once_init_leave (&etype
, type_id
);
54 /* We need to hand-write this marshaler, since it doesn't have an
58 source_closure_marshal_BOOLEAN__VOID (GClosure
*closure
,
61 const GValue
*param_values
,
62 gpointer invocation_hint
,
63 gpointer marshal_data
)
66 GCClosure
*cc
= (GCClosure
*) closure
;
69 g_return_if_fail (return_value
!= NULL
);
70 g_return_if_fail (n_param_values
== 0);
72 callback
= (GSourceFunc
) (marshal_data
? marshal_data
: cc
->callback
);
74 v_return
= callback (closure
->data
);
76 g_value_set_boolean (return_value
, v_return
);
80 io_watch_closure_callback (GIOChannel
*channel
,
81 GIOCondition condition
,
84 GClosure
*closure
= data
;
86 GValue params
[2] = { G_VALUE_INIT
, G_VALUE_INIT
};
87 GValue result_value
= G_VALUE_INIT
;
90 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
91 g_value_init (¶ms
[0], G_TYPE_IO_CHANNEL
);
92 g_value_set_boxed (¶ms
[0], channel
);
94 g_value_init (¶ms
[1], G_TYPE_IO_CONDITION
);
95 g_value_set_flags (¶ms
[1], condition
);
97 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
99 result
= g_value_get_boolean (&result_value
);
100 g_value_unset (&result_value
);
101 g_value_unset (¶ms
[0]);
102 g_value_unset (¶ms
[1]);
108 g_child_watch_closure_callback (GPid pid
,
112 GClosure
*closure
= data
;
114 GValue params
[2] = { G_VALUE_INIT
, G_VALUE_INIT
};
115 GValue result_value
= G_VALUE_INIT
;
118 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
121 g_value_init (¶ms
[0], G_TYPE_ULONG
);
122 g_value_set_ulong (¶ms
[0], pid
);
125 g_value_init (¶ms
[0], G_TYPE_POINTER
);
126 g_value_set_pointer (¶ms
[0], pid
);
129 g_value_init (¶ms
[1], G_TYPE_INT
);
130 g_value_set_int (¶ms
[1], status
);
132 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
134 result
= g_value_get_boolean (&result_value
);
135 g_value_unset (&result_value
);
136 g_value_unset (¶ms
[0]);
137 g_value_unset (¶ms
[1]);
144 g_unix_fd_source_closure_callback (int fd
,
145 GIOCondition condition
,
148 GClosure
*closure
= data
;
150 GValue params
[2] = { G_VALUE_INIT
, G_VALUE_INIT
};
151 GValue result_value
= G_VALUE_INIT
;
154 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
156 g_value_init (¶ms
[0], G_TYPE_INT
);
157 g_value_set_int (¶ms
[0], fd
);
159 g_value_init (¶ms
[1], G_TYPE_IO_CONDITION
);
160 g_value_set_flags (¶ms
[1], condition
);
162 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
164 result
= g_value_get_boolean (&result_value
);
165 g_value_unset (&result_value
);
166 g_value_unset (¶ms
[0]);
167 g_value_unset (¶ms
[1]);
174 source_closure_callback (gpointer data
)
176 GClosure
*closure
= data
;
177 GValue result_value
= G_VALUE_INIT
;
180 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
182 g_closure_invoke (closure
, &result_value
, 0, NULL
, NULL
);
184 result
= g_value_get_boolean (&result_value
);
185 g_value_unset (&result_value
);
191 closure_callback_get (gpointer cb_data
,
196 GSourceFunc closure_callback
= source
->source_funcs
->closure_callback
;
198 if (!closure_callback
)
200 if (source
->source_funcs
== &g_io_watch_funcs
)
201 closure_callback
= (GSourceFunc
)io_watch_closure_callback
;
202 else if (source
->source_funcs
== &g_child_watch_funcs
)
203 closure_callback
= (GSourceFunc
)g_child_watch_closure_callback
;
205 else if (source
->source_funcs
== &g_unix_fd_source_funcs
)
206 closure_callback
= (GSourceFunc
)g_unix_fd_source_closure_callback
;
208 else if (source
->source_funcs
== &g_timeout_funcs
||
210 source
->source_funcs
== &g_unix_signal_funcs
||
212 source
->source_funcs
== &g_idle_funcs
)
213 closure_callback
= source_closure_callback
;
216 *func
= closure_callback
;
220 static GSourceCallbackFuncs closure_callback_funcs
= {
221 (void (*) (gpointer
)) g_closure_ref
,
222 (void (*) (gpointer
)) g_closure_unref
,
227 closure_invalidated (gpointer user_data
,
230 g_source_destroy (user_data
);
234 * g_source_set_closure:
235 * @source: the source
236 * @closure: a #GClosure
238 * Set the callback for a source as a #GClosure.
240 * If the source is not one of the standard GLib types, the @closure_callback
241 * and @closure_marshal fields of the #GSourceFuncs structure must have been
242 * filled in with pointers to appropriate functions.
245 g_source_set_closure (GSource
*source
,
248 g_return_if_fail (source
!= NULL
);
249 g_return_if_fail (closure
!= NULL
);
251 if (!source
->source_funcs
->closure_callback
&&
253 source
->source_funcs
!= &g_unix_fd_source_funcs
&&
254 source
->source_funcs
!= &g_unix_signal_funcs
&&
256 source
->source_funcs
!= &g_child_watch_funcs
&&
257 source
->source_funcs
!= &g_io_watch_funcs
&&
258 source
->source_funcs
!= &g_timeout_funcs
&&
259 source
->source_funcs
!= &g_idle_funcs
)
261 g_critical (G_STRLOC
": closure can not be set on closure without GSourceFuncs::closure_callback\n");
265 g_closure_ref (closure
);
266 g_closure_sink (closure
);
267 g_source_set_callback_indirect (source
, closure
, &closure_callback_funcs
);
269 g_closure_add_invalidate_notifier (closure
, source
, closure_invalidated
);
271 if (G_CLOSURE_NEEDS_MARSHAL (closure
))
273 GClosureMarshal marshal
= (GClosureMarshal
)source
->source_funcs
->closure_marshal
;
275 g_closure_set_marshal (closure
, marshal
);
276 else if (source
->source_funcs
== &g_idle_funcs
||
278 source
->source_funcs
== &g_unix_signal_funcs
||
280 source
->source_funcs
== &g_timeout_funcs
)
281 g_closure_set_marshal (closure
, source_closure_marshal_BOOLEAN__VOID
);
283 g_closure_set_marshal (closure
, g_cclosure_marshal_generic
);
288 dummy_closure_marshal (GClosure
*closure
,
289 GValue
*return_value
,
290 guint n_param_values
,
291 const GValue
*param_values
,
292 gpointer invocation_hint
,
293 gpointer marshal_data
)
295 if (G_VALUE_HOLDS_BOOLEAN (return_value
))
296 g_value_set_boolean (return_value
, TRUE
);
300 * g_source_set_dummy_callback:
301 * @source: the source
303 * Sets a dummy callback for @source. The callback will do nothing, and
304 * if the source expects a #gboolean return value, it will return %TRUE.
305 * (If the source expects any other type of return value, it will return
306 * a 0/%NULL value; whatever g_value_init() initializes a #GValue to for
309 * If the source is not one of the standard GLib types, the
310 * @closure_callback and @closure_marshal fields of the #GSourceFuncs
311 * structure must have been filled in with pointers to appropriate
315 g_source_set_dummy_callback (GSource
*source
)
319 closure
= g_closure_new_simple (sizeof (GClosure
), NULL
);
320 g_closure_set_meta_marshal (closure
, NULL
, dummy_closure_marshal
);
321 g_source_set_closure (source
, closure
);