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, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gsourceclosure.h"
27 #include "gvaluetypes.h"
29 G_DEFINE_BOXED_TYPE (GIOChannel
, g_io_channel
, g_io_channel_ref
, g_io_channel_unref
)
32 g_io_condition_get_type (void)
34 static GType etype
= 0;
37 static const GFlagsValue values
[] = {
38 { G_IO_IN
, "G_IO_IN", "in" },
39 { G_IO_OUT
, "G_IO_OUT", "out" },
40 { G_IO_PRI
, "G_IO_PRI", "pri" },
41 { G_IO_ERR
, "G_IO_ERR", "err" },
42 { G_IO_HUP
, "G_IO_HUP", "hup" },
43 { G_IO_NVAL
, "G_IO_NVAL", "nval" },
46 etype
= g_flags_register_static ("GIOCondition", values
);
51 /* We need to hand-write this marshaler, since it doesn't have an
55 source_closure_marshal_BOOLEAN__VOID (GClosure
*closure
,
58 const GValue
*param_values
,
59 gpointer invocation_hint
,
60 gpointer marshal_data
)
63 GCClosure
*cc
= (GCClosure
*) closure
;
66 g_return_if_fail (return_value
!= NULL
);
67 g_return_if_fail (n_param_values
== 0);
69 callback
= (GSourceFunc
) (marshal_data
? marshal_data
: cc
->callback
);
71 v_return
= callback (closure
->data
);
73 g_value_set_boolean (return_value
, v_return
);
77 io_watch_closure_callback (GIOChannel
*channel
,
78 GIOCondition condition
,
81 GClosure
*closure
= data
;
83 GValue params
[2] = { { 0, }, { 0, } };
84 GValue result_value
= { 0, };
87 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
88 g_value_init (¶ms
[0], G_TYPE_IO_CHANNEL
);
89 g_value_set_boxed (¶ms
[0], channel
);
91 g_value_init (¶ms
[1], G_TYPE_IO_CONDITION
);
92 g_value_set_flags (¶ms
[1], condition
);
94 g_closure_invoke (closure
, &result_value
, 2, params
, NULL
);
96 result
= g_value_get_boolean (&result_value
);
97 g_value_unset (&result_value
);
98 g_value_unset (¶ms
[0]);
99 g_value_unset (¶ms
[1]);
105 source_closure_callback (gpointer data
)
107 GClosure
*closure
= data
;
108 GValue result_value
= { 0, };
111 g_value_init (&result_value
, G_TYPE_BOOLEAN
);
113 g_closure_invoke (closure
, &result_value
, 0, NULL
, NULL
);
115 result
= g_value_get_boolean (&result_value
);
116 g_value_unset (&result_value
);
122 closure_callback_get (gpointer cb_data
,
127 GSourceFunc closure_callback
= source
->source_funcs
->closure_callback
;
129 if (!closure_callback
)
131 if (source
->source_funcs
== &g_io_watch_funcs
)
132 closure_callback
= (GSourceFunc
)io_watch_closure_callback
;
133 else if (source
->source_funcs
== &g_timeout_funcs
||
134 source
->source_funcs
== &g_idle_funcs
)
135 closure_callback
= source_closure_callback
;
138 *func
= closure_callback
;
142 static GSourceCallbackFuncs closure_callback_funcs
= {
143 (void (*) (gpointer
)) g_closure_ref
,
144 (void (*) (gpointer
)) g_closure_unref
,
149 * g_source_set_closure:
150 * @source: the source
151 * @closure: a #GClosure
153 * Set the callback for a source as a #GClosure.
155 * If the source is not one of the standard GLib types, the @closure_callback
156 * and @closure_marshal fields of the #GSourceFuncs structure must have been
157 * filled in with pointers to appropriate functions.
160 g_source_set_closure (GSource
*source
,
163 g_return_if_fail (source
!= NULL
);
164 g_return_if_fail (closure
!= NULL
);
166 if (!source
->source_funcs
->closure_callback
&&
167 source
->source_funcs
!= &g_io_watch_funcs
&&
168 source
->source_funcs
!= &g_timeout_funcs
&&
169 source
->source_funcs
!= &g_idle_funcs
)
171 g_critical (G_STRLOC
"closure can not be set on closure without GSourceFuncs::closure_callback\n");
175 g_closure_ref (closure
);
176 g_closure_sink (closure
);
177 g_source_set_callback_indirect (source
, closure
, &closure_callback_funcs
);
179 if (G_CLOSURE_NEEDS_MARSHAL (closure
))
181 GClosureMarshal marshal
= (GClosureMarshal
)source
->source_funcs
->closure_marshal
;
184 if (source
->source_funcs
== &g_idle_funcs
||
185 source
->source_funcs
== &g_timeout_funcs
)
186 marshal
= source_closure_marshal_BOOLEAN__VOID
;
187 else if (source
->source_funcs
== &g_io_watch_funcs
)
188 marshal
= g_cclosure_marshal_BOOLEAN__FLAGS
;
191 g_closure_set_marshal (closure
, marshal
);