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