1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
6 * gimodule.c: wrapper for the gobject-introspection library.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
24 #include "pygi-private.h"
27 #include <pygobject.h>
28 #include <pyglib-python-compat.h>
31 _wrap_pyg_enum_add (PyObject *self,
35 static char *kwlist[] = { "g_type", NULL };
39 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
41 kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
45 g_type = pyg_type_from_object (py_g_type);
46 if (g_type == G_TYPE_INVALID) {
50 return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
54 _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
58 static char *kwlist[] = { "info", NULL };
59 PyGIBaseInfo *py_info;
62 GEnumValue *g_enum_values;
64 const gchar *type_name;
66 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
67 "O:enum_add_make_new_gtype",
68 kwlist, (PyObject *)&py_info)) {
72 if (!GI_IS_ENUM_INFO (py_info->info) ||
73 g_base_info_get_type ((GIBaseInfo *) py_info->info) != GI_INFO_TYPE_ENUM) {
74 PyErr_SetString (PyExc_TypeError, "info must be an EnumInfo with info type GI_INFO_TYPE_ENUM");
78 info = (GIEnumInfo *)py_info->info;
79 n_values = g_enum_info_get_n_values (info);
80 g_enum_values = g_new0 (GEnumValue, n_values + 1);
82 for (int i=0; i < n_values; i++) {
83 GIValueInfo *value_info;
84 GEnumValue *enum_value;
86 const gchar *c_identifier;
88 value_info = g_enum_info_get_value (info, i);
89 name = g_base_info_get_name ((GIBaseInfo *) value_info);
90 c_identifier = g_base_info_get_attribute ((GIBaseInfo *) value_info,
93 enum_value = &g_enum_values[i];
94 enum_value->value_nick = g_strdup (name);
95 enum_value->value = g_value_info_get_value (value_info);
97 if (c_identifier == NULL) {
98 enum_value->value_name = enum_value->value_nick;
100 enum_value->value_name = g_strdup (c_identifier);
103 g_base_info_unref ((GIBaseInfo *) value_info);
106 g_enum_values[n_values].value = 0;
107 g_enum_values[n_values].value_nick = NULL;
108 g_enum_values[n_values].value_name = NULL;
110 type_name = g_base_info_get_name ((GIBaseInfo *) info);
111 type_name = g_strdup (type_name);
112 g_type = g_enum_register_static (type_name, g_enum_values);
114 return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
118 _wrap_pyg_flags_add (PyObject *self,
122 static char *kwlist[] = { "g_type", NULL };
126 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
128 kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
132 g_type = pyg_type_from_object (py_g_type);
133 if (g_type == G_TYPE_INVALID) {
137 return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
141 _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
145 static char *kwlist[] = { "info", NULL };
146 PyGIBaseInfo *py_info;
149 GFlagsValue *g_flags_values;
151 const gchar *type_name;
153 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
154 "O:flags_add_make_new_gtype",
155 kwlist, (PyObject *)&py_info)) {
159 if (!GI_IS_ENUM_INFO (py_info->info) ||
160 g_base_info_get_type ((GIBaseInfo *) py_info->info) != GI_INFO_TYPE_FLAGS) {
161 PyErr_SetString (PyExc_TypeError, "info must be an EnumInfo with info type GI_INFO_TYPE_FLAGS");
165 info = (GIEnumInfo *)py_info->info;
166 n_values = g_enum_info_get_n_values (info);
167 g_flags_values = g_new0 (GFlagsValue, n_values + 1);
169 for (int i=0; i < n_values; i++) {
170 GIValueInfo *value_info;
171 GFlagsValue *flags_value;
173 const gchar *c_identifier;
175 value_info = g_enum_info_get_value (info, i);
176 name = g_base_info_get_name ((GIBaseInfo *) value_info);
177 c_identifier = g_base_info_get_attribute ((GIBaseInfo *) value_info,
180 flags_value = &g_flags_values[i];
181 flags_value->value_nick = g_strdup (name);
182 flags_value->value = g_value_info_get_value (value_info);
184 if (c_identifier == NULL) {
185 flags_value->value_name = flags_value->value_nick;
187 flags_value->value_name = g_strdup (c_identifier);
190 g_base_info_unref ((GIBaseInfo *) value_info);
193 g_flags_values[n_values].value = 0;
194 g_flags_values[n_values].value_nick = NULL;
195 g_flags_values[n_values].value_name = NULL;
197 type_name = g_base_info_get_name ((GIBaseInfo *) info);
198 type_name = g_strdup (type_name);
199 g_type = g_flags_register_static (type_name, g_flags_values);
201 return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
205 initialize_interface (GTypeInterface *iface, PyTypeObject *pytype)
207 // pygobject prints a warning if interface_init is NULL
211 _wrap_pyg_register_interface_info (PyObject *self, PyObject *args)
215 GInterfaceInfo *info;
217 if (!PyArg_ParseTuple (args, "O!:register_interface_info",
218 &PyGTypeWrapper_Type, &py_g_type)) {
222 g_type = pyg_type_from_object (py_g_type);
223 if (!g_type_is_a (g_type, G_TYPE_INTERFACE)) {
224 PyErr_SetString (PyExc_TypeError, "must be an interface");
228 info = g_new0 (GInterfaceInfo, 1);
229 info->interface_init = (GInterfaceInitFunc) initialize_interface;
231 pyg_register_interface_info (g_type, info);
237 find_vfunc_info (GIBaseInfo *vfunc_info,
238 GType implementor_gtype,
239 gpointer *implementor_class_ret,
240 gpointer *implementor_vtable_ret,
241 GIFieldInfo **field_info_ret)
243 GType ancestor_g_type = 0;
245 GIBaseInfo *ancestor_info;
246 GIStructInfo *struct_info;
247 gpointer implementor_class = NULL;
248 gboolean is_interface = FALSE;
250 ancestor_info = g_base_info_get_container (vfunc_info);
251 is_interface = g_base_info_get_type (ancestor_info) == GI_INFO_TYPE_INTERFACE;
253 ancestor_g_type = g_registered_type_info_get_g_type (
254 (GIRegisteredTypeInfo *) ancestor_info);
255 implementor_class = g_type_class_ref (implementor_gtype);
257 GTypeInstance *implementor_iface_class;
258 implementor_iface_class = g_type_interface_peek (implementor_class,
260 if (implementor_iface_class == NULL) {
261 g_type_class_unref (implementor_class);
262 PyErr_Format (PyExc_RuntimeError,
263 "Couldn't find GType of implementor of interface %s. "
264 "Forgot to set __gtype_name__?",
265 g_type_name (ancestor_g_type));
269 *implementor_vtable_ret = implementor_iface_class;
271 struct_info = g_interface_info_get_iface_struct ( (GIInterfaceInfo*) ancestor_info);
273 struct_info = g_object_info_get_class_struct ( (GIObjectInfo*) ancestor_info);
274 *implementor_vtable_ret = implementor_class;
277 *implementor_class_ret = implementor_class;
279 length = g_struct_info_get_n_fields (struct_info);
280 for (i = 0; i < length; i++) {
281 GIFieldInfo *field_info;
282 GITypeInfo *type_info;
284 field_info = g_struct_info_get_field (struct_info, i);
286 if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info),
287 g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) {
288 g_base_info_unref (field_info);
292 type_info = g_field_info_get_type (field_info);
293 if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) {
294 g_base_info_unref (type_info);
295 *field_info_ret = field_info;
299 g_base_info_unref (type_info);
300 g_base_info_unref (field_info);
303 g_base_info_unref (struct_info);
307 _wrap_pyg_hook_up_vfunc_implementation (PyObject *self, PyObject *args)
309 PyGIBaseInfo *py_info;
311 PyObject *py_function;
312 GType implementor_gtype = 0;
313 gpointer implementor_class = NULL;
314 gpointer implementor_vtable = NULL;
315 GIFieldInfo *field_info = NULL;
316 gpointer *method_ptr = NULL;
317 PyGICClosure *closure = NULL;
319 if (!PyArg_ParseTuple (args, "O!O!O:hook_up_vfunc_implementation",
320 &PyGIBaseInfo_Type, &py_info,
321 &PyGTypeWrapper_Type, &py_type,
325 implementor_gtype = pyg_type_from_object (py_type);
326 g_assert (G_TYPE_IS_CLASSED (implementor_gtype));
328 find_vfunc_info (py_info->info, implementor_gtype, &implementor_class, &implementor_vtable, &field_info);
329 if (field_info != NULL) {
330 GITypeInfo *type_info;
331 GIBaseInfo *interface_info;
332 GICallbackInfo *callback_info;
335 type_info = g_field_info_get_type (field_info);
337 interface_info = g_type_info_get_interface (type_info);
338 g_assert (g_base_info_get_type (interface_info) == GI_INFO_TYPE_CALLBACK);
340 callback_info = (GICallbackInfo*) interface_info;
341 offset = g_field_info_get_offset (field_info);
342 method_ptr = G_STRUCT_MEMBER_P (implementor_vtable, offset);
344 closure = _pygi_make_native_closure ( (GICallableInfo*) callback_info,
345 GI_SCOPE_TYPE_NOTIFIED, py_function, NULL);
347 *method_ptr = closure->closure;
349 g_base_info_unref (interface_info);
350 g_base_info_unref (type_info);
351 g_base_info_unref (field_info);
353 g_type_class_unref (implementor_class);
359 /* Not used, left around for future reference */
361 _wrap_pyg_has_vfunc_implementation (PyObject *self, PyObject *args)
363 PyGIBaseInfo *py_info;
366 gpointer implementor_class = NULL;
367 gpointer implementor_vtable = NULL;
368 GType implementor_gtype = 0;
369 GIFieldInfo *field_info = NULL;
371 if (!PyArg_ParseTuple (args, "O!O!:has_vfunc_implementation",
372 &PyGIBaseInfo_Type, &py_info,
373 &PyGTypeWrapper_Type, &py_type))
376 implementor_gtype = pyg_type_from_object (py_type);
377 g_assert (G_TYPE_IS_CLASSED (implementor_gtype));
380 find_vfunc_info (py_info->info, implementor_gtype, &implementor_class, &implementor_vtable, &field_info);
381 if (field_info != NULL) {
382 gpointer *method_ptr;
385 offset = g_field_info_get_offset (field_info);
386 method_ptr = G_STRUCT_MEMBER_P (implementor_vtable, offset);
387 if (*method_ptr != NULL) {
391 g_base_info_unref (field_info);
393 g_type_class_unref (implementor_class);
401 _wrap_pyg_variant_new_tuple (PyObject *self, PyObject *args)
404 GVariant **values = NULL;
405 GVariant *variant = NULL;
406 PyObject *py_variant = NULL;
410 if (!PyArg_ParseTuple (args, "O!:variant_new_tuple",
411 &PyTuple_Type, &py_values)) {
415 py_type = _pygi_type_import_by_name ("GLib", "Variant");
417 values = g_newa (GVariant*, PyTuple_Size (py_values));
419 for (i = 0; i < PyTuple_Size (py_values); i++) {
420 PyObject *value = PyTuple_GET_ITEM (py_values, i);
422 if (!PyObject_IsInstance (value, py_type)) {
423 PyErr_Format (PyExc_TypeError, "argument %" G_GSSIZE_FORMAT " is not a GLib.Variant", i);
427 values[i] = (GVariant *) ( (PyGPointer *) value)->pointer;
430 variant = g_variant_new_tuple (values, PyTuple_Size (py_values));
432 py_variant = _pygi_struct_new ( (PyTypeObject *) py_type, variant, FALSE);
438 _wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
442 PyObject *py_variant = NULL;
444 if (!PyArg_ParseTuple (args, "s:variant_type_from_string",
449 py_type = _pygi_type_import_by_name ("GLib", "VariantType");
451 py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE);
456 static PyMethodDef _gi_functions[] = {
457 { "enum_add", (PyCFunction) _wrap_pyg_enum_add, METH_VARARGS | METH_KEYWORDS },
458 { "enum_register_new_gtype_and_add", (PyCFunction) _wrap_pyg_enum_register_new_gtype_and_add, METH_VARARGS | METH_KEYWORDS },
459 { "flags_add", (PyCFunction) _wrap_pyg_flags_add, METH_VARARGS | METH_KEYWORDS },
460 { "flags_register_new_gtype_and_add", (PyCFunction) _wrap_pyg_flags_register_new_gtype_and_add, METH_VARARGS | METH_KEYWORDS },
462 { "register_interface_info", (PyCFunction) _wrap_pyg_register_interface_info, METH_VARARGS },
463 { "hook_up_vfunc_implementation", (PyCFunction) _wrap_pyg_hook_up_vfunc_implementation, METH_VARARGS },
464 { "variant_new_tuple", (PyCFunction) _wrap_pyg_variant_new_tuple, METH_VARARGS },
465 { "variant_type_from_string", (PyCFunction) _wrap_pyg_variant_type_from_string, METH_VARARGS },
469 static struct PyGI_API CAPI = {
470 pygi_type_import_by_g_type_real,
471 pygi_get_property_value_real,
472 pygi_set_property_value_real,
473 pygi_signal_closure_new_real,
474 pygi_register_foreign_struct_real,
477 PYGLIB_MODULE_START(_gi, "_gi")
481 if (pygobject_init (-1, -1, -1) == NULL) {
482 return PYGLIB_MODULE_ERROR_RETURN;
485 if (_pygobject_import() < 0) {
486 return PYGLIB_MODULE_ERROR_RETURN;
489 _pygi_repository_register_types (module);
490 _pygi_info_register_types (module);
491 _pygi_struct_register_types (module);
492 _pygi_boxed_register_types (module);
493 _pygi_argument_init();
495 api = PYGLIB_CPointer_WrapPointer ( (void *) &CAPI, "gi._API");
497 return PYGLIB_MODULE_ERROR_RETURN;
499 PyModule_AddObject (module, "_API", api);