1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: Invoke functionality
4 * Copyright (C) 2005 Matthias Clasen
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * 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.
25 #include <glib-object.h>
27 #include <girepository.h>
32 value_to_ffi_type (const GValue *gvalue, gpointer *value)
34 ffi_type *rettype = NULL;
35 GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));
36 g_assert (type != G_TYPE_INVALID);
43 rettype = &ffi_type_sint;
44 *value = (gpointer)&(gvalue->data[0].v_int);
48 rettype = &ffi_type_uint;
49 *value = (gpointer)&(gvalue->data[0].v_uint);
55 rettype = &ffi_type_pointer;
56 *value = (gpointer)&(gvalue->data[0].v_pointer);
59 rettype = &ffi_type_float;
60 *value = (gpointer)&(gvalue->data[0].v_float);
63 rettype = &ffi_type_double;
64 *value = (gpointer)&(gvalue->data[0].v_double);
67 rettype = &ffi_type_slong;
68 *value = (gpointer)&(gvalue->data[0].v_long);
71 rettype = &ffi_type_ulong;
72 *value = (gpointer)&(gvalue->data[0].v_ulong);
75 rettype = &ffi_type_sint64;
76 *value = (gpointer)&(gvalue->data[0].v_int64);
79 rettype = &ffi_type_uint64;
80 *value = (gpointer)&(gvalue->data[0].v_uint64);
83 rettype = &ffi_type_pointer;
85 g_warning ("Unsupported fundamental type: %s", g_type_name (type));
91 /* See comment aboe set_gargument_from_ffi_return_value() */
93 g_value_to_ffi_return_type (const GValue *gvalue,
94 const GIArgument *ffi_value,
97 ffi_type *rettype = NULL;
98 GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));
99 g_assert (type != G_TYPE_INVALID);
101 *value = (gpointer)&(ffi_value->v_long);
105 rettype = &ffi_type_sint8;
108 rettype = &ffi_type_uint8;
112 rettype = &ffi_type_sint;
115 rettype = &ffi_type_uint;
121 rettype = &ffi_type_pointer;
124 rettype = &ffi_type_float;
125 *value = (gpointer)&(ffi_value->v_float);
128 rettype = &ffi_type_double;
129 *value = (gpointer)&(ffi_value->v_double);
132 rettype = &ffi_type_slong;
135 rettype = &ffi_type_ulong;
138 rettype = &ffi_type_sint64;
139 *value = (gpointer)&(ffi_value->v_int64);
142 rettype = &ffi_type_uint64;
143 *value = (gpointer)&(ffi_value->v_uint64);
146 rettype = &ffi_type_pointer;
148 g_warning ("Unsupported fundamental type: %s", g_type_name (type));
155 g_value_from_ffi_value (GValue *gvalue,
156 const GIArgument *value)
158 switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) {
160 g_value_set_int (gvalue, (gint)value->v_long);
163 g_value_set_float (gvalue, (gfloat)value->v_float);
166 g_value_set_double (gvalue, (gdouble)value->v_double);
169 g_value_set_boolean (gvalue, (gboolean)value->v_long);
172 g_value_set_string (gvalue, (gchar*)value->v_pointer);
175 g_value_set_char (gvalue, (gchar)value->v_long);
178 g_value_set_uchar (gvalue, (guchar)value->v_ulong);
181 g_value_set_uint (gvalue, (guint)value->v_ulong);
184 g_value_set_pointer (gvalue, (gpointer)value->v_pointer);
187 g_value_set_long (gvalue, (glong)value->v_long);
190 g_value_set_ulong (gvalue, (gulong)value->v_ulong);
193 g_value_set_int64 (gvalue, (gint64)value->v_int64);
196 g_value_set_uint64 (gvalue, (guint64)value->v_uint64);
199 g_value_set_boxed (gvalue, (gpointer)value->v_pointer);
202 g_warning ("Unsupported fundamental type: %s",
203 g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
209 gi_cclosure_marshal_generic (GClosure *closure,
210 GValue *return_gvalue,
211 guint n_param_values,
212 const GValue *param_values,
213 gpointer invocation_hint,
214 gpointer marshal_data)
216 GIArgument return_ffi_value;
224 GCClosure *cc = (GCClosure*) closure;
226 if (return_gvalue && G_VALUE_TYPE (return_gvalue))
228 rtype = g_value_to_ffi_return_type (return_gvalue, &return_ffi_value,
233 rtype = &ffi_type_void;
234 rvalue = &return_ffi_value.v_long;
237 n_args = n_param_values + 1;
238 atypes = g_alloca (sizeof (ffi_type *) * n_args);
239 args = g_alloca (sizeof (gpointer) * n_args);
241 if (n_param_values > 0)
243 if (G_CCLOSURE_SWAP_DATA (closure))
245 atypes[n_args-1] = value_to_ffi_type (param_values + 0,
247 atypes[0] = &ffi_type_pointer;
248 args[0] = &closure->data;
252 atypes[0] = value_to_ffi_type (param_values + 0, &args[0]);
253 atypes[n_args-1] = &ffi_type_pointer;
254 args[n_args-1] = &closure->data;
259 atypes[0] = &ffi_type_pointer;
260 args[0] = &closure->data;
263 for (i = 1; i < n_args - 1; i++)
264 atypes[i] = value_to_ffi_type (param_values + i, &args[i]);
266 if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)
269 ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args);
271 if (return_gvalue && G_VALUE_TYPE (return_gvalue))
272 g_value_from_ffi_value (return_gvalue, &return_ffi_value);