Imported Upstream version 3.7.3
[platform/upstream/python-gobject.git] / gi / gimodule.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
5  *
6  *   gimodule.c: wrapper for the gobject-introspection library.
7  *
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.
12  *
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.
17  *
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
21  * USA
22  */
23
24 #include "pygi-private.h"
25 #include "pygi.h"
26 #include "pyglib.h"
27
28 #include <pygobject.h>
29 #include <pyglib-python-compat.h>
30
31 static PyObject *
32 _wrap_pyg_enum_add (PyObject *self,
33                     PyObject *args,
34                     PyObject *kwargs)
35 {
36     static char *kwlist[] = { "g_type", NULL };
37     PyObject *py_g_type;
38     GType g_type;
39
40     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
41                                       "O!:enum_add",
42                                       kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
43         return NULL;
44     }
45
46     g_type = pyg_type_from_object (py_g_type);
47     if (g_type == G_TYPE_INVALID) {
48         return NULL;
49     }
50
51     return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
52 }
53
54 static PyObject *
55 _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
56                                            PyObject *args,
57                                            PyObject *kwargs)
58 {
59     static char *kwlist[] = { "info", NULL };
60     PyGIBaseInfo *py_info;
61     GIEnumInfo *info;
62     gint n_values;
63     GEnumValue *g_enum_values;
64     int i;
65     const gchar *type_name;
66     GType g_type;
67
68     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
69                                       "O:enum_add_make_new_gtype",
70                                       kwlist, (PyObject *)&py_info)) {
71         return NULL;
72     }
73
74     if (!GI_IS_ENUM_INFO (py_info->info) ||
75             g_base_info_get_type ((GIBaseInfo *) py_info->info) != GI_INFO_TYPE_ENUM) {
76         PyErr_SetString (PyExc_TypeError, "info must be an EnumInfo with info type GI_INFO_TYPE_ENUM");
77         return NULL;
78     }
79
80     info = (GIEnumInfo *)py_info->info;
81     n_values = g_enum_info_get_n_values (info);
82     g_enum_values = g_new0 (GEnumValue, n_values + 1);
83
84     for (i = 0; i < n_values; i++) {
85         GIValueInfo *value_info;
86         GEnumValue *enum_value;
87         const gchar *name;
88         const gchar *c_identifier;
89
90         value_info = g_enum_info_get_value (info, i);
91         name = g_base_info_get_name ((GIBaseInfo *) value_info);
92         c_identifier = g_base_info_get_attribute ((GIBaseInfo *) value_info,
93                                                   "c:identifier");
94
95         enum_value = &g_enum_values[i];
96         enum_value->value_nick = g_strdup (name);
97         enum_value->value = g_value_info_get_value (value_info);
98
99         if (c_identifier == NULL) {
100             enum_value->value_name = enum_value->value_nick;
101         } else {
102             enum_value->value_name = g_strdup (c_identifier);
103         }
104
105         g_base_info_unref ((GIBaseInfo *) value_info);
106     }
107
108     g_enum_values[n_values].value = 0;
109     g_enum_values[n_values].value_nick = NULL;
110     g_enum_values[n_values].value_name = NULL;
111
112     type_name = g_base_info_get_name ((GIBaseInfo *) info);
113     type_name = g_strdup (type_name);
114     g_type = g_enum_register_static (type_name, g_enum_values);
115
116     return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
117 }
118
119 static PyObject *
120 _wrap_pyg_flags_add (PyObject *self,
121                      PyObject *args,
122                      PyObject *kwargs)
123 {
124     static char *kwlist[] = { "g_type", NULL };
125     PyObject *py_g_type;
126     GType g_type;
127
128     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
129                                       "O!:flags_add",
130                                       kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
131         return NULL;
132     }
133
134     g_type = pyg_type_from_object (py_g_type);
135     if (g_type == G_TYPE_INVALID) {
136         return NULL;
137     }
138
139     return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
140 }
141
142 static PyObject *
143 _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
144                                             PyObject *args,
145                                             PyObject *kwargs)
146 {
147     static char *kwlist[] = { "info", NULL };
148     PyGIBaseInfo *py_info;
149     GIEnumInfo *info;
150     gint n_values;
151     GFlagsValue *g_flags_values;
152     int i;
153     const gchar *type_name;
154     GType g_type;
155
156     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
157                                       "O:flags_add_make_new_gtype",
158                                       kwlist, (PyObject *)&py_info)) {
159         return NULL;
160     }
161
162     if (!GI_IS_ENUM_INFO (py_info->info) ||
163             g_base_info_get_type ((GIBaseInfo *) py_info->info) != GI_INFO_TYPE_FLAGS) {
164         PyErr_SetString (PyExc_TypeError, "info must be an EnumInfo with info type GI_INFO_TYPE_FLAGS");
165         return NULL;
166     }
167
168     info = (GIEnumInfo *)py_info->info;
169     n_values = g_enum_info_get_n_values (info);
170     g_flags_values = g_new0 (GFlagsValue, n_values + 1);
171
172     for (i = 0; i < n_values; i++) {
173         GIValueInfo *value_info;
174         GFlagsValue *flags_value;
175         const gchar *name;
176         const gchar *c_identifier;
177
178         value_info = g_enum_info_get_value (info, i);
179         name = g_base_info_get_name ((GIBaseInfo *) value_info);
180         c_identifier = g_base_info_get_attribute ((GIBaseInfo *) value_info,
181                                                   "c:identifier");
182
183         flags_value = &g_flags_values[i];
184         flags_value->value_nick = g_strdup (name);
185         flags_value->value = g_value_info_get_value (value_info);
186
187         if (c_identifier == NULL) {
188             flags_value->value_name = flags_value->value_nick;
189         } else {
190             flags_value->value_name = g_strdup (c_identifier);
191         }
192
193         g_base_info_unref ((GIBaseInfo *) value_info);
194     }
195
196     g_flags_values[n_values].value = 0;
197     g_flags_values[n_values].value_nick = NULL;
198     g_flags_values[n_values].value_name = NULL;
199
200     type_name = g_base_info_get_name ((GIBaseInfo *) info);
201     type_name = g_strdup (type_name);
202     g_type = g_flags_register_static (type_name, g_flags_values);
203
204     return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
205 }
206
207 static void
208 initialize_interface (GTypeInterface *iface, PyTypeObject *pytype)
209 {
210     // pygobject prints a warning if interface_init is NULL
211 }
212
213 static PyObject *
214 _wrap_pyg_register_interface_info (PyObject *self, PyObject *args)
215 {
216     PyObject *py_g_type;
217     GType g_type;
218     GInterfaceInfo *info;
219
220     if (!PyArg_ParseTuple (args, "O!:register_interface_info",
221                            &PyGTypeWrapper_Type, &py_g_type)) {
222         return NULL;
223     }
224
225     g_type = pyg_type_from_object (py_g_type);
226     if (!g_type_is_a (g_type, G_TYPE_INTERFACE)) {
227         PyErr_SetString (PyExc_TypeError, "must be an interface");
228         return NULL;
229     }
230
231     info = g_new0 (GInterfaceInfo, 1);
232     info->interface_init = (GInterfaceInitFunc) initialize_interface;
233
234     pyg_register_interface_info (g_type, info);
235
236     Py_RETURN_NONE;
237 }
238
239 static void
240 find_vfunc_info (GIBaseInfo *vfunc_info,
241                  GType implementor_gtype,
242                  gpointer *implementor_class_ret,
243                  gpointer *implementor_vtable_ret,
244                  GIFieldInfo **field_info_ret)
245 {
246     GType ancestor_g_type = 0;
247     int length, i;
248     GIBaseInfo *ancestor_info;
249     GIStructInfo *struct_info;
250     gpointer implementor_class = NULL;
251     gboolean is_interface = FALSE;
252
253     ancestor_info = g_base_info_get_container (vfunc_info);
254     is_interface = g_base_info_get_type (ancestor_info) == GI_INFO_TYPE_INTERFACE;
255
256     ancestor_g_type = g_registered_type_info_get_g_type (
257                           (GIRegisteredTypeInfo *) ancestor_info);
258     implementor_class = g_type_class_ref (implementor_gtype);
259     if (is_interface) {
260         GTypeInstance *implementor_iface_class;
261         implementor_iface_class = g_type_interface_peek (implementor_class,
262                                                          ancestor_g_type);
263         if (implementor_iface_class == NULL) {
264             g_type_class_unref (implementor_class);
265             PyErr_Format (PyExc_RuntimeError,
266                           "Couldn't find GType of implementor of interface %s. "
267                           "Forgot to set __gtype_name__?",
268                           g_type_name (ancestor_g_type));
269             return;
270         }
271
272         *implementor_vtable_ret = implementor_iface_class;
273
274         struct_info = g_interface_info_get_iface_struct ( (GIInterfaceInfo*) ancestor_info);
275     } else {
276         struct_info = g_object_info_get_class_struct ( (GIObjectInfo*) ancestor_info);
277         *implementor_vtable_ret = implementor_class;
278     }
279
280     *implementor_class_ret = implementor_class;
281
282     length = g_struct_info_get_n_fields (struct_info);
283     for (i = 0; i < length; i++) {
284         GIFieldInfo *field_info;
285         GITypeInfo *type_info;
286
287         field_info = g_struct_info_get_field (struct_info, i);
288
289         if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info),
290                     g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) {
291             g_base_info_unref (field_info);
292             continue;
293         }
294
295         type_info = g_field_info_get_type (field_info);
296         if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) {
297             g_base_info_unref (type_info);
298             *field_info_ret = field_info;
299             break;
300         }
301
302         g_base_info_unref (type_info);
303         g_base_info_unref (field_info);
304     }
305
306     g_base_info_unref (struct_info);
307 }
308
309 static PyObject *
310 _wrap_pyg_hook_up_vfunc_implementation (PyObject *self, PyObject *args)
311 {
312     PyGIBaseInfo *py_info;
313     PyObject *py_type;
314     PyObject *py_function;
315     GType implementor_gtype = 0;
316     gpointer implementor_class = NULL;
317     gpointer implementor_vtable = NULL;
318     GIFieldInfo *field_info = NULL;
319     gpointer *method_ptr = NULL;
320     PyGICClosure *closure = NULL;
321
322     if (!PyArg_ParseTuple (args, "O!O!O:hook_up_vfunc_implementation",
323                            &PyGIBaseInfo_Type, &py_info,
324                            &PyGTypeWrapper_Type, &py_type,
325                            &py_function))
326         return NULL;
327
328     implementor_gtype = pyg_type_from_object (py_type);
329     g_assert (G_TYPE_IS_CLASSED (implementor_gtype));
330
331     find_vfunc_info (py_info->info, implementor_gtype, &implementor_class, &implementor_vtable, &field_info);
332     if (field_info != NULL) {
333         GITypeInfo *type_info;
334         GIBaseInfo *interface_info;
335         GICallbackInfo *callback_info;
336         gint offset;
337
338         type_info = g_field_info_get_type (field_info);
339
340         interface_info = g_type_info_get_interface (type_info);
341         g_assert (g_base_info_get_type (interface_info) == GI_INFO_TYPE_CALLBACK);
342
343         callback_info = (GICallbackInfo*) interface_info;
344         offset = g_field_info_get_offset (field_info);
345         method_ptr = G_STRUCT_MEMBER_P (implementor_vtable, offset);
346
347         closure = _pygi_make_native_closure ( (GICallableInfo*) callback_info,
348                                               GI_SCOPE_TYPE_NOTIFIED, py_function, NULL);
349
350         *method_ptr = closure->closure;
351
352         g_base_info_unref (interface_info);
353         g_base_info_unref (type_info);
354         g_base_info_unref (field_info);
355     }
356     g_type_class_unref (implementor_class);
357
358     Py_RETURN_NONE;
359 }
360
361 #if 0
362 /* Not used, left around for future reference */
363 static PyObject *
364 _wrap_pyg_has_vfunc_implementation (PyObject *self, PyObject *args)
365 {
366     PyGIBaseInfo *py_info;
367     PyObject *py_type;
368     PyObject *py_ret;
369     gpointer implementor_class = NULL;
370     gpointer implementor_vtable = NULL;
371     GType implementor_gtype = 0;
372     GIFieldInfo *field_info = NULL;
373
374     if (!PyArg_ParseTuple (args, "O!O!:has_vfunc_implementation",
375                            &PyGIBaseInfo_Type, &py_info,
376                            &PyGTypeWrapper_Type, &py_type))
377         return NULL;
378
379     implementor_gtype = pyg_type_from_object (py_type);
380     g_assert (G_TYPE_IS_CLASSED (implementor_gtype));
381
382     py_ret = Py_False;
383     find_vfunc_info (py_info->info, implementor_gtype, &implementor_class, &implementor_vtable, &field_info);
384     if (field_info != NULL) {
385         gpointer *method_ptr;
386         gint offset;
387
388         offset = g_field_info_get_offset (field_info);
389         method_ptr = G_STRUCT_MEMBER_P (implementor_vtable, offset);
390         if (*method_ptr != NULL) {
391             py_ret = Py_True;
392         }
393
394         g_base_info_unref (field_info);
395     }
396     g_type_class_unref (implementor_class);
397
398     Py_INCREF(py_ret);
399     return py_ret;
400 }
401 #endif
402
403 static PyObject *
404 _wrap_pyg_variant_new_tuple (PyObject *self, PyObject *args)
405 {
406     PyObject *py_values;
407     GVariant **values = NULL;
408     GVariant *variant = NULL;
409     PyObject *py_variant = NULL;
410     PyObject *py_type;
411     gssize i;
412
413     if (!PyArg_ParseTuple (args, "O!:variant_new_tuple",
414                            &PyTuple_Type, &py_values)) {
415         return NULL;
416     }
417
418     py_type = _pygi_type_import_by_name ("GLib", "Variant");
419
420     values = g_newa (GVariant*, PyTuple_Size (py_values));
421
422     for (i = 0; i < PyTuple_Size (py_values); i++) {
423         PyObject *value = PyTuple_GET_ITEM (py_values, i);
424
425         if (!PyObject_IsInstance (value, py_type)) {
426             PyErr_Format (PyExc_TypeError, "argument %" G_GSSIZE_FORMAT " is not a GLib.Variant", i);
427             return NULL;
428         }
429
430         values[i] = (GVariant *) ( (PyGPointer *) value)->pointer;
431     }
432
433     variant = g_variant_new_tuple (values, PyTuple_Size (py_values));
434
435     py_variant = _pygi_struct_new ( (PyTypeObject *) py_type, variant, FALSE);
436
437     return py_variant;
438 }
439
440 static PyObject *
441 _wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
442 {
443     char *type_string;
444     PyObject *py_type;
445     PyObject *py_variant = NULL;
446
447     if (!PyArg_ParseTuple (args, "s:variant_type_from_string",
448                            &type_string)) {
449         return NULL;
450     }
451
452     py_type = _pygi_type_import_by_name ("GLib", "VariantType");
453
454     py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE);
455
456     return py_variant;
457 }
458
459 static PyObject *
460 _wrap_pyg_source_new (PyObject *self, PyObject *args)
461 {
462     return pyg_source_new ();
463 }
464
465 #define CHUNK_SIZE 8192
466
467 static PyObject*
468 pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs)
469 {
470     int max_count = -1;
471     PyObject *py_iochannel, *ret_obj = NULL;
472     gsize total_read = 0;
473     GError* error = NULL;
474     GIOStatus status = G_IO_STATUS_NORMAL;
475
476     if (!PyArg_ParseTuple (args, "Oi:pyg_channel_read", &py_iochannel, &max_count)) {
477         return NULL;
478     }
479     if (!pyg_boxed_check (py_iochannel, G_TYPE_IO_CHANNEL)) {
480         PyErr_SetString(PyExc_TypeError, "first argument is not a GLib.IOChannel");
481         return NULL;
482     }
483         
484     if (max_count == 0)
485         return PYGLIB_PyBytes_FromString("");
486     
487     while (status == G_IO_STATUS_NORMAL
488            && (max_count == -1 || total_read < max_count)) {
489         gsize single_read;
490         char* buf;
491         gsize buf_size;
492         
493         if (max_count == -1) 
494             buf_size = CHUNK_SIZE;
495         else {
496             buf_size = max_count - total_read;
497             if (buf_size > CHUNK_SIZE)
498                 buf_size = CHUNK_SIZE;
499         }
500         
501         if ( ret_obj == NULL ) {
502             ret_obj = PYGLIB_PyBytes_FromStringAndSize((char *)NULL, buf_size);
503             if (ret_obj == NULL)
504                 goto failure;
505         }
506         else if (buf_size + total_read > PYGLIB_PyBytes_Size(ret_obj)) {
507             if (PYGLIB_PyBytes_Resize(&ret_obj, buf_size + total_read) == -1)
508                 goto failure;
509         }
510        
511         buf = PYGLIB_PyBytes_AsString(ret_obj) + total_read;
512
513         pyglib_unblock_threads();
514         status = g_io_channel_read_chars(pyg_boxed_get (py_iochannel, GIOChannel),
515                                          buf, buf_size, &single_read, &error);
516         pyglib_block_threads();
517         if (pyglib_error_check(&error))
518             goto failure;
519         
520         total_read += single_read;
521     }
522         
523     if ( total_read != PYGLIB_PyBytes_Size(ret_obj) ) {
524         if (PYGLIB_PyBytes_Resize(&ret_obj, total_read) == -1)
525             goto failure;
526     }
527
528     return ret_obj;
529
530   failure:
531     Py_XDECREF(ret_obj);
532     return NULL;
533 }
534
535
536 static PyMethodDef _gi_functions[] = {
537     { "enum_add", (PyCFunction) _wrap_pyg_enum_add, METH_VARARGS | METH_KEYWORDS },
538     { "enum_register_new_gtype_and_add", (PyCFunction) _wrap_pyg_enum_register_new_gtype_and_add, METH_VARARGS | METH_KEYWORDS },
539     { "flags_add", (PyCFunction) _wrap_pyg_flags_add, METH_VARARGS | METH_KEYWORDS },
540     { "flags_register_new_gtype_and_add", (PyCFunction) _wrap_pyg_flags_register_new_gtype_and_add, METH_VARARGS | METH_KEYWORDS },
541
542     { "register_interface_info", (PyCFunction) _wrap_pyg_register_interface_info, METH_VARARGS },
543     { "hook_up_vfunc_implementation", (PyCFunction) _wrap_pyg_hook_up_vfunc_implementation, METH_VARARGS },
544     { "variant_new_tuple", (PyCFunction) _wrap_pyg_variant_new_tuple, METH_VARARGS },
545     { "variant_type_from_string", (PyCFunction) _wrap_pyg_variant_type_from_string, METH_VARARGS },
546     { "source_new", (PyCFunction) _wrap_pyg_source_new, METH_NOARGS },
547     { "source_set_callback", (PyCFunction) pyg_source_set_callback, METH_VARARGS },
548     { "io_channel_read", (PyCFunction) pyg_channel_read, METH_VARARGS },
549     { NULL, NULL, 0 }
550 };
551
552 static struct PyGI_API CAPI = {
553   pygi_type_import_by_g_type_real,
554   pygi_get_property_value_real,
555   pygi_set_property_value_real,
556   pygi_signal_closure_new_real,
557   pygi_register_foreign_struct_real,
558 };
559
560 PYGLIB_MODULE_START(_gi, "_gi")
561 {
562     PyObject *api;
563
564     if (pygobject_init (-1, -1, -1) == NULL) {
565         return PYGLIB_MODULE_ERROR_RETURN;
566     }
567
568     if (_pygobject_import() < 0) {
569         return PYGLIB_MODULE_ERROR_RETURN;
570     }
571
572     _pygi_repository_register_types (module);
573     _pygi_info_register_types (module);
574     _pygi_struct_register_types (module);
575     _pygi_boxed_register_types (module);
576     _pygi_ccallback_register_types (module);
577     _pygi_argument_init();
578
579     api = PYGLIB_CPointer_WrapPointer ( (void *) &CAPI, "gi._API");
580     if (api == NULL) {
581         return PYGLIB_MODULE_ERROR_RETURN;
582     }
583     PyModule_AddObject (module, "_API", api);
584 }
585 PYGLIB_MODULE_END