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"
28 #include <pygobject.h>
29 #include <pyglib-python-compat.h>
32 _wrap_pyg_enum_add (PyObject *self,
36 static char *kwlist[] = { "g_type", NULL };
40 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
42 kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
46 g_type = pyg_type_from_object (py_g_type);
47 if (g_type == G_TYPE_INVALID) {
51 return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
55 _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
59 static char *kwlist[] = { "info", NULL };
60 PyGIBaseInfo *py_info;
63 GEnumValue *g_enum_values;
65 const gchar *namespace;
66 const gchar *type_name;
70 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
71 "O:enum_add_make_new_gtype",
72 kwlist, (PyObject *)&py_info)) {
76 if (!GI_IS_ENUM_INFO (py_info->info) ||
77 g_base_info_get_type ((GIBaseInfo *) py_info->info) != GI_INFO_TYPE_ENUM) {
78 PyErr_SetString (PyExc_TypeError, "info must be an EnumInfo with info type GI_INFO_TYPE_ENUM");
82 info = (GIEnumInfo *)py_info->info;
83 n_values = g_enum_info_get_n_values (info);
85 /* The new memory is zero filled which fulfills the registration
86 * function requirement that the last item is zeroed out as a terminator.
88 g_enum_values = g_new0 (GEnumValue, n_values + 1);
90 for (i = 0; i < n_values; i++) {
91 GIValueInfo *value_info;
92 GEnumValue *enum_value;
94 const gchar *c_identifier;
96 value_info = g_enum_info_get_value (info, i);
97 name = g_base_info_get_name ((GIBaseInfo *) value_info);
98 c_identifier = g_base_info_get_attribute ((GIBaseInfo *) value_info,
101 enum_value = &g_enum_values[i];
102 enum_value->value_nick = g_strdup (name);
103 enum_value->value = g_value_info_get_value (value_info);
105 if (c_identifier == NULL) {
106 enum_value->value_name = enum_value->value_nick;
108 enum_value->value_name = g_strdup (c_identifier);
111 g_base_info_unref ((GIBaseInfo *) value_info);
114 namespace = g_base_info_get_namespace ((GIBaseInfo *) info);
115 type_name = g_base_info_get_name ((GIBaseInfo *) info);
116 full_name = g_strconcat (namespace, type_name, NULL);
118 /* If enum registration fails, free all the memory allocated
119 * for the values array. This needs to leak when successful
120 * as GObject keeps a reference to the data as specified in the docs.
122 g_type = g_enum_register_static (full_name, g_enum_values);
123 if (g_type == G_TYPE_INVALID) {
124 for (i = 0; i < n_values; i++) {
125 GEnumValue *enum_value = &g_enum_values[i];
127 /* Only free value_name if it is different from value_nick to avoid
128 * a double free. The pointer might have been is re-used in the case
129 * c_identifier was NULL in the above loop.
131 if (enum_value->value_name != enum_value->value_nick)
132 g_free ((gchar *) enum_value->value_name);
133 g_free ((gchar *) enum_value->value_nick);
136 PyErr_Format (PyExc_RuntimeError, "Unable to register enum '%s'", full_name);
138 g_free (g_enum_values);
144 return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
148 _wrap_pyg_flags_add (PyObject *self,
152 static char *kwlist[] = { "g_type", NULL };
156 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
158 kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
162 g_type = pyg_type_from_object (py_g_type);
163 if (g_type == G_TYPE_INVALID) {
167 return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
171 _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
175 static char *kwlist[] = { "info", NULL };
176 PyGIBaseInfo *py_info;
179 GFlagsValue *g_flags_values;
181 const gchar *namespace;
182 const gchar *type_name;
186 if (!PyArg_ParseTupleAndKeywords (args, kwargs,
187 "O:flags_add_make_new_gtype",
188 kwlist, (PyObject *)&py_info)) {
192 if (!GI_IS_ENUM_INFO (py_info->info) ||
193 g_base_info_get_type ((GIBaseInfo *) py_info->info) != GI_INFO_TYPE_FLAGS) {
194 PyErr_SetString (PyExc_TypeError, "info must be an EnumInfo with info type GI_INFO_TYPE_FLAGS");
198 info = (GIEnumInfo *)py_info->info;
199 n_values = g_enum_info_get_n_values (info);
201 /* The new memory is zero filled which fulfills the registration
202 * function requirement that the last item is zeroed out as a terminator.
204 g_flags_values = g_new0 (GFlagsValue, n_values + 1);
206 for (i = 0; i < n_values; i++) {
207 GIValueInfo *value_info;
208 GFlagsValue *flags_value;
210 const gchar *c_identifier;
212 value_info = g_enum_info_get_value (info, i);
213 name = g_base_info_get_name ((GIBaseInfo *) value_info);
214 c_identifier = g_base_info_get_attribute ((GIBaseInfo *) value_info,
217 flags_value = &g_flags_values[i];
218 flags_value->value_nick = g_strdup (name);
219 flags_value->value = g_value_info_get_value (value_info);
221 if (c_identifier == NULL) {
222 flags_value->value_name = flags_value->value_nick;
224 flags_value->value_name = g_strdup (c_identifier);
227 g_base_info_unref ((GIBaseInfo *) value_info);
230 namespace = g_base_info_get_namespace ((GIBaseInfo *) info);
231 type_name = g_base_info_get_name ((GIBaseInfo *) info);
232 full_name = g_strconcat (namespace, type_name, NULL);
234 /* If enum registration fails, free all the memory allocated
235 * for the values array. This needs to leak when successful
236 * as GObject keeps a reference to the data as specified in the docs.
238 g_type = g_flags_register_static (full_name, g_flags_values);
239 if (g_type == G_TYPE_INVALID) {
240 for (i = 0; i < n_values; i++) {
241 GFlagsValue *flags_value = &g_flags_values[i];
243 /* Only free value_name if it is different from value_nick to avoid
244 * a double free. The pointer might have been is re-used in the case
245 * c_identifier was NULL in the above loop.
247 if (flags_value->value_name != flags_value->value_nick)
248 g_free ((gchar *) flags_value->value_name);
249 g_free ((gchar *) flags_value->value_nick);
252 PyErr_Format (PyExc_RuntimeError, "Unable to register flags '%s'", full_name);
254 g_free (g_flags_values);
260 return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
264 initialize_interface (GTypeInterface *iface, PyTypeObject *pytype)
266 // pygobject prints a warning if interface_init is NULL
270 _wrap_pyg_register_interface_info (PyObject *self, PyObject *args)
274 GInterfaceInfo *info;
276 if (!PyArg_ParseTuple (args, "O!:register_interface_info",
277 &PyGTypeWrapper_Type, &py_g_type)) {
281 g_type = pyg_type_from_object (py_g_type);
282 if (!g_type_is_a (g_type, G_TYPE_INTERFACE)) {
283 PyErr_SetString (PyExc_TypeError, "must be an interface");
287 info = g_new0 (GInterfaceInfo, 1);
288 info->interface_init = (GInterfaceInitFunc) initialize_interface;
290 pyg_register_interface_info (g_type, info);
296 find_vfunc_info (GIBaseInfo *vfunc_info,
297 GType implementor_gtype,
298 gpointer *implementor_class_ret,
299 gpointer *implementor_vtable_ret,
300 GIFieldInfo **field_info_ret)
302 GType ancestor_g_type = 0;
304 GIBaseInfo *ancestor_info;
305 GIStructInfo *struct_info;
306 gpointer implementor_class = NULL;
307 gboolean is_interface = FALSE;
309 ancestor_info = g_base_info_get_container (vfunc_info);
310 is_interface = g_base_info_get_type (ancestor_info) == GI_INFO_TYPE_INTERFACE;
312 ancestor_g_type = g_registered_type_info_get_g_type (
313 (GIRegisteredTypeInfo *) ancestor_info);
314 implementor_class = g_type_class_ref (implementor_gtype);
316 GTypeInstance *implementor_iface_class;
317 implementor_iface_class = g_type_interface_peek (implementor_class,
319 if (implementor_iface_class == NULL) {
320 g_type_class_unref (implementor_class);
321 PyErr_Format (PyExc_RuntimeError,
322 "Couldn't find GType of implementor of interface %s. "
323 "Forgot to set __gtype_name__?",
324 g_type_name (ancestor_g_type));
328 *implementor_vtable_ret = implementor_iface_class;
330 struct_info = g_interface_info_get_iface_struct ( (GIInterfaceInfo*) ancestor_info);
332 struct_info = g_object_info_get_class_struct ( (GIObjectInfo*) ancestor_info);
333 *implementor_vtable_ret = implementor_class;
336 *implementor_class_ret = implementor_class;
338 length = g_struct_info_get_n_fields (struct_info);
339 for (i = 0; i < length; i++) {
340 GIFieldInfo *field_info;
341 GITypeInfo *type_info;
343 field_info = g_struct_info_get_field (struct_info, i);
345 if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info),
346 g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) {
347 g_base_info_unref (field_info);
351 type_info = g_field_info_get_type (field_info);
352 if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) {
353 g_base_info_unref (type_info);
354 *field_info_ret = field_info;
358 g_base_info_unref (type_info);
359 g_base_info_unref (field_info);
362 g_base_info_unref (struct_info);
366 _wrap_pyg_hook_up_vfunc_implementation (PyObject *self, PyObject *args)
368 PyGIBaseInfo *py_info;
370 PyObject *py_function;
371 GType implementor_gtype = 0;
372 gpointer implementor_class = NULL;
373 gpointer implementor_vtable = NULL;
374 GIFieldInfo *field_info = NULL;
375 gpointer *method_ptr = NULL;
376 PyGICClosure *closure = NULL;
378 if (!PyArg_ParseTuple (args, "O!O!O:hook_up_vfunc_implementation",
379 &PyGIBaseInfo_Type, &py_info,
380 &PyGTypeWrapper_Type, &py_type,
384 implementor_gtype = pyg_type_from_object (py_type);
385 g_assert (G_TYPE_IS_CLASSED (implementor_gtype));
387 find_vfunc_info (py_info->info, implementor_gtype, &implementor_class, &implementor_vtable, &field_info);
388 if (field_info != NULL) {
389 GITypeInfo *type_info;
390 GIBaseInfo *interface_info;
391 GICallbackInfo *callback_info;
394 type_info = g_field_info_get_type (field_info);
396 interface_info = g_type_info_get_interface (type_info);
397 g_assert (g_base_info_get_type (interface_info) == GI_INFO_TYPE_CALLBACK);
399 callback_info = (GICallbackInfo*) interface_info;
400 offset = g_field_info_get_offset (field_info);
401 method_ptr = G_STRUCT_MEMBER_P (implementor_vtable, offset);
403 closure = _pygi_make_native_closure ( (GICallableInfo*) callback_info,
404 GI_SCOPE_TYPE_NOTIFIED, py_function, NULL);
406 *method_ptr = closure->closure;
408 g_base_info_unref (interface_info);
409 g_base_info_unref (type_info);
410 g_base_info_unref (field_info);
412 g_type_class_unref (implementor_class);
418 /* Not used, left around for future reference */
420 _wrap_pyg_has_vfunc_implementation (PyObject *self, PyObject *args)
422 PyGIBaseInfo *py_info;
425 gpointer implementor_class = NULL;
426 gpointer implementor_vtable = NULL;
427 GType implementor_gtype = 0;
428 GIFieldInfo *field_info = NULL;
430 if (!PyArg_ParseTuple (args, "O!O!:has_vfunc_implementation",
431 &PyGIBaseInfo_Type, &py_info,
432 &PyGTypeWrapper_Type, &py_type))
435 implementor_gtype = pyg_type_from_object (py_type);
436 g_assert (G_TYPE_IS_CLASSED (implementor_gtype));
439 find_vfunc_info (py_info->info, implementor_gtype, &implementor_class, &implementor_vtable, &field_info);
440 if (field_info != NULL) {
441 gpointer *method_ptr;
444 offset = g_field_info_get_offset (field_info);
445 method_ptr = G_STRUCT_MEMBER_P (implementor_vtable, offset);
446 if (*method_ptr != NULL) {
450 g_base_info_unref (field_info);
452 g_type_class_unref (implementor_class);
460 _wrap_pyg_variant_new_tuple (PyObject *self, PyObject *args)
463 GVariant **values = NULL;
464 GVariant *variant = NULL;
465 PyObject *py_variant = NULL;
469 if (!PyArg_ParseTuple (args, "O!:variant_new_tuple",
470 &PyTuple_Type, &py_values)) {
474 py_type = _pygi_type_import_by_name ("GLib", "Variant");
476 values = g_newa (GVariant*, PyTuple_Size (py_values));
478 for (i = 0; i < PyTuple_Size (py_values); i++) {
479 PyObject *value = PyTuple_GET_ITEM (py_values, i);
481 if (!PyObject_IsInstance (value, py_type)) {
482 PyErr_Format (PyExc_TypeError, "argument %" G_GSSIZE_FORMAT " is not a GLib.Variant", i);
486 values[i] = (GVariant *) ( (PyGPointer *) value)->pointer;
489 variant = g_variant_new_tuple (values, PyTuple_Size (py_values));
491 py_variant = _pygi_struct_new ( (PyTypeObject *) py_type, variant, FALSE);
497 _wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
501 PyObject *py_variant = NULL;
503 if (!PyArg_ParseTuple (args, "s:variant_type_from_string",
508 py_type = _pygi_type_import_by_name ("GLib", "VariantType");
510 py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE);
516 _wrap_pyg_source_new (PyObject *self, PyObject *args)
518 return pyg_source_new ();
521 #define CHUNK_SIZE 8192
524 pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs)
527 PyObject *py_iochannel, *ret_obj = NULL;
528 gsize total_read = 0;
529 GError* error = NULL;
530 GIOStatus status = G_IO_STATUS_NORMAL;
532 if (!PyArg_ParseTuple (args, "Oi:pyg_channel_read", &py_iochannel, &max_count)) {
535 if (!pyg_boxed_check (py_iochannel, G_TYPE_IO_CHANNEL)) {
536 PyErr_SetString(PyExc_TypeError, "first argument is not a GLib.IOChannel");
541 return PYGLIB_PyBytes_FromString("");
543 while (status == G_IO_STATUS_NORMAL
544 && (max_count == -1 || total_read < max_count)) {
550 buf_size = CHUNK_SIZE;
552 buf_size = max_count - total_read;
553 if (buf_size > CHUNK_SIZE)
554 buf_size = CHUNK_SIZE;
557 if ( ret_obj == NULL ) {
558 ret_obj = PYGLIB_PyBytes_FromStringAndSize((char *)NULL, buf_size);
562 else if (buf_size + total_read > PYGLIB_PyBytes_Size(ret_obj)) {
563 if (PYGLIB_PyBytes_Resize(&ret_obj, buf_size + total_read) == -1)
567 buf = PYGLIB_PyBytes_AsString(ret_obj) + total_read;
569 pyglib_unblock_threads();
570 status = g_io_channel_read_chars(pyg_boxed_get (py_iochannel, GIOChannel),
571 buf, buf_size, &single_read, &error);
572 pyglib_block_threads();
573 if (pyglib_error_check(&error))
576 total_read += single_read;
579 if ( total_read != PYGLIB_PyBytes_Size(ret_obj) ) {
580 if (PYGLIB_PyBytes_Resize(&ret_obj, total_read) == -1)
592 static PyMethodDef _gi_functions[] = {
593 { "enum_add", (PyCFunction) _wrap_pyg_enum_add, METH_VARARGS | METH_KEYWORDS },
594 { "enum_register_new_gtype_and_add", (PyCFunction) _wrap_pyg_enum_register_new_gtype_and_add, METH_VARARGS | METH_KEYWORDS },
595 { "flags_add", (PyCFunction) _wrap_pyg_flags_add, METH_VARARGS | METH_KEYWORDS },
596 { "flags_register_new_gtype_and_add", (PyCFunction) _wrap_pyg_flags_register_new_gtype_and_add, METH_VARARGS | METH_KEYWORDS },
598 { "register_interface_info", (PyCFunction) _wrap_pyg_register_interface_info, METH_VARARGS },
599 { "hook_up_vfunc_implementation", (PyCFunction) _wrap_pyg_hook_up_vfunc_implementation, METH_VARARGS },
600 { "variant_new_tuple", (PyCFunction) _wrap_pyg_variant_new_tuple, METH_VARARGS },
601 { "variant_type_from_string", (PyCFunction) _wrap_pyg_variant_type_from_string, METH_VARARGS },
602 { "source_new", (PyCFunction) _wrap_pyg_source_new, METH_NOARGS },
603 { "source_set_callback", (PyCFunction) pyg_source_set_callback, METH_VARARGS },
604 { "io_channel_read", (PyCFunction) pyg_channel_read, METH_VARARGS },
608 static struct PyGI_API CAPI = {
609 pygi_type_import_by_g_type_real,
610 pygi_get_property_value_real,
611 pygi_set_property_value_real,
612 pygi_signal_closure_new_real,
613 pygi_register_foreign_struct_real,
616 PYGLIB_MODULE_START(_gi, "_gi")
620 if (pygobject_init (-1, -1, -1) == NULL) {
621 return PYGLIB_MODULE_ERROR_RETURN;
624 if (_pygobject_import() < 0) {
625 return PYGLIB_MODULE_ERROR_RETURN;
628 _pygi_repository_register_types (module);
629 _pygi_info_register_types (module);
630 _pygi_struct_register_types (module);
631 _pygi_boxed_register_types (module);
632 _pygi_ccallback_register_types (module);
633 _pygi_argument_init();
635 api = PYGLIB_CPointer_WrapPointer ( (void *) &CAPI, "gi._API");
637 return PYGLIB_MODULE_ERROR_RETURN;
639 PyModule_AddObject (module, "_API", api);