Imported Upstream version 3.3.2
[platform/upstream/pygobject2.git] / gi / _gobject / pygtype.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * pygtk- Python bindings for the GTK toolkit.
3  * Copyright (C) 1998-2003  James Henstridge
4  *
5  *   pygtype.c: glue code to wrap the GType code.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20  * USA
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26
27 #include <pyglib.h>
28
29 #include "pygobject-private.h"
30 #include "pygparamspec.h"
31 #include "pygtype.h"
32
33 /* -------------- __gtype__ objects ---------------------------- */
34
35 typedef struct {
36     PyObject_HEAD
37     GType type;
38 } PyGTypeWrapper;
39
40 PYGLIB_DEFINE_TYPE("gobject.GType", PyGTypeWrapper_Type, PyGTypeWrapper);
41
42 static PyObject*
43 pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op)
44 {
45     if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type)
46         return _pyglib_generic_long_richcompare(((PyGTypeWrapper*)self)->type,
47                                                 ((PyGTypeWrapper*)other)->type,
48                                                 op);
49     else {
50         Py_INCREF(Py_NotImplemented);
51         return Py_NotImplemented;
52     }
53 }
54
55 static long
56 pyg_type_wrapper_hash(PyGTypeWrapper *self)
57 {
58     return (long)self->type;
59 }
60
61 static PyObject *
62 pyg_type_wrapper_repr(PyGTypeWrapper *self)
63 {
64     char buf[80];
65     const gchar *name = g_type_name(self->type);
66
67     g_snprintf(buf, sizeof(buf), "<GType %s (%lu)>",
68                name?name:"invalid", (unsigned long int) self->type);
69     return PYGLIB_PyUnicode_FromString(buf);
70 }
71
72 static void
73 pyg_type_wrapper_dealloc(PyGTypeWrapper *self)
74 {
75     PyObject_DEL(self);
76 }
77
78 static GQuark
79 _pyg_type_key(GType type) {
80     GQuark key;
81
82     if (g_type_is_a(type, G_TYPE_INTERFACE)) {
83         key = pyginterface_type_key;
84     } else if (g_type_is_a(type, G_TYPE_ENUM)) {
85         key = pygenum_class_key;
86     } else if (g_type_is_a(type, G_TYPE_FLAGS)) {
87         key = pygflags_class_key;
88     } else if (g_type_is_a(type, G_TYPE_POINTER)) {
89         key = pygpointer_class_key;
90     } else if (g_type_is_a(type, G_TYPE_BOXED)) {
91         key = pygboxed_type_key;
92     } else {
93         key = pygobject_class_key;
94     }
95
96     return key;
97 }
98
99 static PyObject *
100 _wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure)
101 {
102     GQuark key;
103     PyObject *py_type;
104
105     key = _pyg_type_key(self->type);
106
107     py_type = g_type_get_qdata(self->type, key);
108     if (!py_type)
109       py_type = Py_None;
110
111     Py_INCREF(py_type);
112     return py_type;
113 }
114
115 static int
116 _wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure)
117 {
118     GQuark key;
119     PyObject *py_type;
120
121     key = _pyg_type_key(self->type);
122
123     py_type = g_type_get_qdata(self->type, key);
124     Py_CLEAR(py_type);
125     if (value == Py_None)
126         g_type_set_qdata(self->type, key, NULL);
127     else if (PyType_Check(value)) {
128         Py_INCREF(value);
129         g_type_set_qdata(self->type, key, value);
130     } else {
131         PyErr_SetString(PyExc_TypeError, "Value must be None or a type object");
132         return -1;
133     }
134
135     return 0;
136 }
137
138 static PyObject *
139 _wrap_g_type_wrapper__get_name(PyGTypeWrapper *self, void *closure)
140 {
141    const char *name = g_type_name(self->type);
142    return PYGLIB_PyUnicode_FromString(name ? name : "invalid");
143 }
144
145 static PyObject *
146 _wrap_g_type_wrapper__get_parent(PyGTypeWrapper *self, void *closure)
147 {
148    return pyg_type_wrapper_new(g_type_parent(self->type));
149 }
150
151 static PyObject *
152 _wrap_g_type_wrapper__get_fundamental(PyGTypeWrapper *self, void *closure)
153 {
154    return pyg_type_wrapper_new(g_type_fundamental(self->type));
155 }
156
157 static PyObject *
158 _wrap_g_type_wrapper__get_children(PyGTypeWrapper *self, void *closure)
159 {
160   guint n_children, i;
161   GType *children;
162   PyObject *retval;
163
164   children = g_type_children(self->type, &n_children);
165
166   retval = PyList_New(n_children);
167   for (i = 0; i < n_children; i++)
168       PyList_SetItem(retval, i, pyg_type_wrapper_new(children[i]));
169   g_free(children);
170
171   return retval;
172 }
173
174 static PyObject *
175 _wrap_g_type_wrapper__get_interfaces(PyGTypeWrapper *self, void *closure)
176 {
177   guint n_interfaces, i;
178   GType *interfaces;
179   PyObject *retval;
180
181   interfaces = g_type_interfaces(self->type, &n_interfaces);
182
183   retval = PyList_New(n_interfaces);
184   for (i = 0; i < n_interfaces; i++)
185       PyList_SetItem(retval, i, pyg_type_wrapper_new(interfaces[i]));
186   g_free(interfaces);
187
188   return retval;
189 }
190
191 static PyObject *
192 _wrap_g_type_wrapper__get_depth(PyGTypeWrapper *self, void *closure)
193 {
194   return PYGLIB_PyLong_FromLong(g_type_depth(self->type));
195 }
196
197 static PyGetSetDef _PyGTypeWrapper_getsets[] = {
198     { "pytype", (getter)_wrap_g_type_wrapper__get_pytype, (setter)_wrap_g_type_wrapper__set_pytype },
199     { "name",  (getter)_wrap_g_type_wrapper__get_name, (setter)0 },
200     { "fundamental",  (getter)_wrap_g_type_wrapper__get_fundamental, (setter)0 },
201     { "parent",  (getter)_wrap_g_type_wrapper__get_parent, (setter)0 },
202     { "children",  (getter)_wrap_g_type_wrapper__get_children, (setter)0 },
203     { "interfaces",  (getter)_wrap_g_type_wrapper__get_interfaces, (setter)0 },
204     { "depth",  (getter)_wrap_g_type_wrapper__get_depth, (setter)0 },
205     { NULL, (getter)0, (setter)0 }
206 };
207
208 static PyObject*
209 _wrap_g_type_is_interface(PyGTypeWrapper *self)
210 {
211     return PyBool_FromLong(G_TYPE_IS_INTERFACE(self->type));
212 }
213
214 static PyObject*
215 _wrap_g_type_is_classed(PyGTypeWrapper *self)
216 {
217     return PyBool_FromLong(G_TYPE_IS_CLASSED(self->type));
218 }
219
220 static PyObject*
221 _wrap_g_type_is_instantiatable(PyGTypeWrapper *self)
222 {
223     return PyBool_FromLong(G_TYPE_IS_INSTANTIATABLE(self->type));
224 }
225
226 static PyObject*
227 _wrap_g_type_is_derivable(PyGTypeWrapper *self)
228 {
229     return PyBool_FromLong(G_TYPE_IS_DERIVABLE(self->type));
230 }
231
232 static PyObject*
233 _wrap_g_type_is_deep_derivable(PyGTypeWrapper *self)
234 {
235     return PyBool_FromLong(G_TYPE_IS_DEEP_DERIVABLE(self->type));
236 }
237
238 static PyObject*
239 _wrap_g_type_is_abstract(PyGTypeWrapper *self)
240 {
241     return PyBool_FromLong(G_TYPE_IS_ABSTRACT(self->type));
242 }
243
244 static PyObject*
245 _wrap_g_type_is_value_abstract(PyGTypeWrapper *self)
246 {
247     return PyBool_FromLong(G_TYPE_IS_VALUE_ABSTRACT(self->type));
248 }
249
250 static PyObject*
251 _wrap_g_type_is_value_type(PyGTypeWrapper *self)
252 {
253     return PyBool_FromLong(G_TYPE_IS_VALUE_TYPE(self->type));
254 }
255
256 static PyObject*
257 _wrap_g_type_has_value_table(PyGTypeWrapper *self)
258 {
259     return PyBool_FromLong(G_TYPE_HAS_VALUE_TABLE(self->type));
260 }
261
262 static PyObject*
263 _wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args)
264 {
265     char *type_name;
266     GType type;
267
268     if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name))
269         return NULL;
270
271     type = _pyg_type_from_name(type_name);
272     if (type == 0) {
273         PyErr_SetString(PyExc_RuntimeError, "unknown type name");
274         return NULL;
275     }
276
277     return pyg_type_wrapper_new(type);
278 }
279
280 static PyObject*
281 _wrap_g_type_is_a(PyGTypeWrapper *self, PyObject *args)
282 {
283     PyObject *gparent;
284     GType parent;
285
286     if (!PyArg_ParseTuple(args, "O:GType.is_a", &gparent))
287         return NULL;
288     else if ((parent = pyg_type_from_object(gparent)) == 0)
289         return NULL;
290
291     return PyBool_FromLong(g_type_is_a(self->type, parent));
292 }
293
294 static PyMethodDef _PyGTypeWrapper_methods[] = {
295     { "is_interface", (PyCFunction)_wrap_g_type_is_interface, METH_NOARGS },
296     { "is_classed", (PyCFunction)_wrap_g_type_is_classed, METH_NOARGS },
297     { "is_instantiatable", (PyCFunction)_wrap_g_type_is_instantiatable, METH_NOARGS },
298     { "is_derivable", (PyCFunction)_wrap_g_type_is_derivable, METH_NOARGS },
299     { "is_deep_derivable", (PyCFunction)_wrap_g_type_is_deep_derivable, METH_NOARGS },
300     { "is_abstract", (PyCFunction)_wrap_g_type_is_abstract, METH_NOARGS },
301     { "is_value_abstract", (PyCFunction)_wrap_g_type_is_value_abstract, METH_NOARGS },
302     { "is_value_type", (PyCFunction)_wrap_g_type_is_value_type, METH_NOARGS },
303     { "has_value_table", (PyCFunction)_wrap_g_type_has_value_table, METH_NOARGS },
304     { "from_name", (PyCFunction)_wrap_g_type_from_name, METH_VARARGS | METH_STATIC },
305     { "is_a", (PyCFunction)_wrap_g_type_is_a, METH_VARARGS },
306     { NULL,  0, 0 }
307 };
308
309 static int
310 pyg_type_wrapper_init(PyGTypeWrapper *self, PyObject *args, PyObject *kwargs)
311 {
312     static char *kwlist[] = { "object", NULL };
313     PyObject *py_object;
314     GType type;
315
316     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
317                                      "O:GType.__init__",
318                                      kwlist, &py_object))
319         return -1;
320
321     if (!(type = pyg_type_from_object(py_object)))
322         return -1;
323
324     self->type = type;
325
326     return 0;
327 }
328
329 /**
330  * pyg_type_wrapper_new:
331  * type: a GType
332  *
333  * Creates a Python wrapper for a GType.
334  *
335  * Returns: the Python wrapper.
336  */
337 PyObject *
338 pyg_type_wrapper_new(GType type)
339 {
340     PyGTypeWrapper *self;
341
342     self = (PyGTypeWrapper *)PyObject_NEW(PyGTypeWrapper,
343                                           &PyGTypeWrapper_Type);
344     if (self == NULL)
345         return NULL;
346
347     self->type = type;
348     return (PyObject *)self;
349 }
350
351 /**
352  * pyg_type_from_object_strict:
353  * obj: a Python object
354  * strict: if set to TRUE, raises an exception if it can't perform the
355  *         conversion
356  *
357  * converts a python object to a GType.  If strict is set, raises an 
358  * exception if it can't perform the conversion, otherwise returns
359  * PY_TYPE_OBJECT.
360  *
361  * Returns: the corresponding GType, or 0 on error.
362  */
363
364 GType
365 pyg_type_from_object_strict(PyObject *obj, gboolean strict)
366 {
367     PyObject *gtype;
368     GType type;
369
370     /* NULL check */
371     if (!obj) {
372         PyErr_SetString(PyExc_TypeError, "can't get type from NULL object");
373         return 0;
374     }
375
376     /* map some standard types to primitive GTypes ... */
377     if (obj == Py_None)
378         return G_TYPE_NONE;
379     if (PyType_Check(obj)) {
380         PyTypeObject *tp = (PyTypeObject *)obj;
381
382         if (tp == &PYGLIB_PyLong_Type)
383             return G_TYPE_INT;
384         else if (tp == &PyBool_Type)
385             return G_TYPE_BOOLEAN;
386         else if (tp == &PyLong_Type)
387             return G_TYPE_LONG;
388         else if (tp == &PyFloat_Type)
389             return G_TYPE_DOUBLE;
390         else if (tp == &PYGLIB_PyUnicode_Type)
391             return G_TYPE_STRING;
392         else if (tp == &PyBaseObject_Type)
393             return PY_TYPE_OBJECT;
394     }
395
396     if (Py_TYPE(obj) == &PyGTypeWrapper_Type) {
397         return ((PyGTypeWrapper *)obj)->type;
398     }
399
400     /* handle strings */
401     if (PYGLIB_PyUnicode_Check(obj)) {
402         gchar *name = PYGLIB_PyUnicode_AsString(obj);
403
404         type = _pyg_type_from_name(name);
405         if (type != 0) {
406             return type;
407         }
408     }
409
410     /* finally, look for a __gtype__ attribute on the object */
411     gtype = PyObject_GetAttrString(obj, "__gtype__");
412
413     if (gtype) {
414         if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) {
415             type = ((PyGTypeWrapper *)gtype)->type;
416             Py_DECREF(gtype);
417             return type;
418         }
419         Py_DECREF(gtype);
420     }
421
422     PyErr_Clear();
423
424     /* Some API like those that take GValues can hold a python object as
425      * a pointer.  This is potentially dangerous becuase everything is 
426      * passed in as a PyObject so we can't actually type check it.  Only
427      * fallback to PY_TYPE_OBJECT if strict checking is disabled
428      */
429     if (!strict)
430         return PY_TYPE_OBJECT;
431
432     PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
433     return 0;
434 }
435
436 /**
437  * pyg_type_from_object:
438  * obj: a Python object
439  *
440  * converts a python object to a GType.  Raises an exception if it
441  * can't perform the conversion.
442  *
443  * Returns: the corresponding GType, or 0 on error.
444  */
445 GType
446 pyg_type_from_object(PyObject *obj)
447 {
448     /* Legacy call always defaults to strict type checking */
449     return pyg_type_from_object_strict(obj, TRUE);
450 }
451
452 /* -------------- GValue marshalling ------------------ */
453
454 /**
455  * pyg_enum_get_value:
456  * @enum_type: the GType of the flag.
457  * @obj: a Python object representing the flag value
458  * @val: a pointer to the location to store the integer representation of the flag.
459  *
460  * Converts a Python object to the integer equivalent.  The conversion
461  * will depend on the type of the Python object.  If the object is an
462  * integer, it is passed through directly.  If it is a string, it will
463  * be treated as a full or short enum name as defined in the GType.
464  *
465  * Returns: 0 on success or -1 on failure
466  */
467 gint
468 pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val)
469 {
470     GEnumClass *eclass = NULL;
471     gint res = -1;
472
473     g_return_val_if_fail(val != NULL, -1);
474     if (!obj) {
475         *val = 0;
476         res = 0;
477     } else if (PYGLIB_PyLong_Check(obj)) {
478         *val = PYGLIB_PyLong_AsLong(obj);
479         res = 0;
480
481         if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
482             g_warning("expected enumeration type %s, but got %s instead",
483                       g_type_name(enum_type),
484                       g_type_name(((PyGEnum *) obj)->gtype));
485         }
486     /* Dumb code duplication, but probably not worth it to have yet another macro. */
487     } else if (PyLong_Check(obj)) {
488         *val = PyLong_AsLong(obj);
489         res = 0;
490
491         if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
492             g_warning("expected enumeration type %s, but got %s instead",
493                       g_type_name(enum_type),
494                       g_type_name(((PyGEnum *) obj)->gtype));
495         }
496     } else if (PYGLIB_PyUnicode_Check(obj)) {
497         GEnumValue *info;
498         char *str = PYGLIB_PyUnicode_AsString(obj);
499
500         if (enum_type != G_TYPE_NONE)
501             eclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
502         else {
503             PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value");
504             res = -1;
505         }
506         info = g_enum_get_value_by_name(eclass, str);
507         g_type_class_unref(eclass);
508
509         if (!info)
510             info = g_enum_get_value_by_nick(eclass, str);
511         if (info) {
512             *val = info->value;
513             res = 0;
514         } else {
515             PyErr_SetString(PyExc_TypeError, "could not convert string");
516             res = -1;
517         }
518     } else {
519         PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints");
520         res = -1;
521     }
522     return res;
523 }
524
525 /**
526  * pyg_flags_get_value:
527  * @flag_type: the GType of the flag.
528  * @obj: a Python object representing the flag value
529  * @val: a pointer to the location to store the integer representation of the flag.
530  *
531  * Converts a Python object to the integer equivalent.  The conversion
532  * will depend on the type of the Python object.  If the object is an
533  * integer, it is passed through directly.  If it is a string, it will
534  * be treated as a full or short flag name as defined in the GType.
535  * If it is a tuple, then the items are treated as strings and ORed
536  * together.
537  *
538  * Returns: 0 on success or -1 on failure
539  */
540 gint
541 pyg_flags_get_value(GType flag_type, PyObject *obj, gint *val)
542 {
543     GFlagsClass *fclass = NULL;
544     gint res = -1;
545
546     g_return_val_if_fail(val != NULL, -1);
547     if (!obj) {
548         *val = 0;
549         res = 0;
550     } else if (PYGLIB_PyLong_Check(obj)) {
551         *val = PYGLIB_PyLong_AsLong(obj);
552         res = 0;
553     } else if (PyLong_Check(obj)) {
554         *val = PyLong_AsLongLong(obj);
555         res = 0;
556     } else if (PYGLIB_PyUnicode_Check(obj)) {
557         GFlagsValue *info;
558         char *str = PYGLIB_PyUnicode_AsString(obj);
559
560         if (flag_type != G_TYPE_NONE)
561             fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
562         else {
563             PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
564             res = -1;
565         }
566         info = g_flags_get_value_by_name(fclass, str);
567         g_type_class_unref(fclass);
568
569         if (!info)
570             info = g_flags_get_value_by_nick(fclass, str);
571         if (info) {
572             *val = info->value;
573             res = 0;
574         } else {
575             PyErr_SetString(PyExc_TypeError, "could not convert string");
576             res = -1;
577         }
578     } else if (PyTuple_Check(obj)) {
579         int i, len;
580
581         len = PyTuple_Size(obj);
582         *val = 0;
583         res = 0;
584
585         if (flag_type != G_TYPE_NONE)
586             fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
587         else {
588             PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
589             res = -1;
590         }
591
592         for (i = 0; i < len; i++) {
593             PyObject *item = PyTuple_GetItem(obj, i);
594             char *str = PYGLIB_PyUnicode_AsString(item);
595             GFlagsValue *info = g_flags_get_value_by_name(fclass, str);
596
597             if (!info)
598                 info = g_flags_get_value_by_nick(fclass, str);
599             if (info) {
600                 *val |= info->value;
601             } else {
602                 PyErr_SetString(PyExc_TypeError, "could not convert string");
603                 res = -1;
604                 break;
605             }
606         }
607         g_type_class_unref(fclass);
608     } else {
609         PyErr_SetString(PyExc_TypeError,
610                         "flag values must be strings, ints, longs, or tuples");
611         res = -1;
612     }
613     return res;
614 }
615
616 typedef struct {
617     fromvaluefunc fromvalue;
618     tovaluefunc tovalue;
619 } PyGTypeMarshal;
620 static GQuark pyg_type_marshal_key = 0;
621
622 static PyGTypeMarshal *
623 pyg_type_lookup(GType type)
624 {
625     GType       ptype = type;
626     PyGTypeMarshal      *tm = NULL;
627
628     /* recursively lookup types */
629     while (ptype) {
630         if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
631             break;
632         ptype = g_type_parent(ptype);
633     }
634     return tm;
635 }
636
637 /**
638  * pyg_register_gtype_custom:
639  * @gtype: the GType for the new type
640  * @from_func: a function to convert GValues to Python objects
641  * @to_func: a function to convert Python objects to GValues
642  *
643  * In order to handle specific conversion of gboxed types or new
644  * fundamental types, you may use this function to register conversion
645  * handlers.
646  */
647
648 void
649 pyg_register_gtype_custom(GType gtype,
650                           fromvaluefunc from_func,
651                           tovaluefunc to_func)
652 {
653     PyGTypeMarshal *tm;
654
655     if (!pyg_type_marshal_key)
656         pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
657
658     tm = g_new(PyGTypeMarshal, 1);
659     tm->fromvalue = from_func;
660     tm->tovalue = to_func;
661     g_type_set_qdata(gtype, pyg_type_marshal_key, tm);
662 }
663
664 static int
665 pyg_value_array_from_pyobject(GValue *value,
666                               PyObject *obj,
667                               const GParamSpecValueArray *pspec)
668 {
669     int len;
670     GValueArray *value_array;
671     int i;
672
673     len = PySequence_Length(obj);
674     if (len == -1) {
675         PyErr_Clear();
676         return -1;
677     }
678
679     if (pspec && pspec->fixed_n_elements > 0 && len != pspec->fixed_n_elements)
680         return -1;
681
682     value_array = g_value_array_new(len);
683
684     for (i = 0; i < len; ++i) {
685         PyObject *item = PySequence_GetItem(obj, i);
686         GType type;
687         GValue item_value = { 0, };
688         int status;
689
690         if (! item) {
691             PyErr_Clear();
692             g_value_array_free(value_array);
693             return -1;
694         }
695
696         if (pspec && pspec->element_spec)
697             type = G_PARAM_SPEC_VALUE_TYPE(pspec->element_spec);
698         else if (item == Py_None)
699             type = G_TYPE_POINTER; /* store None as NULL */
700         else {
701             type = pyg_type_from_object((PyObject*)Py_TYPE(item));
702             if (! type) {
703                 PyErr_Clear();
704                 g_value_array_free(value_array);
705                 Py_DECREF(item);
706                 return -1;
707             }
708         }
709
710         g_value_init(&item_value, type);
711         status = (pspec && pspec->element_spec)
712             ? pyg_param_gvalue_from_pyobject(&item_value, item, pspec->element_spec)
713             : pyg_value_from_pyobject(&item_value, item);
714         Py_DECREF(item);
715
716         if (status == -1) {
717             g_value_array_free(value_array);
718             g_value_unset(&item_value);
719             return -1;
720         }
721
722         g_value_array_append(value_array, &item_value);
723         g_value_unset(&item_value);
724     }
725
726     g_value_take_boxed(value, value_array);
727     return 0;
728 }
729
730 static
731 PyObject *
732 pyg_get_gvariant_type()
733 {
734     static PyObject *variant_type = NULL;
735     PyObject *py_module;
736
737     if (variant_type == NULL) {
738         py_module = PyImport_ImportModule ("gi.repository.GLib");
739         if (py_module == NULL)
740             return NULL;
741
742         variant_type = PyObject_GetAttrString (py_module, "Variant");
743
744         Py_DECREF (py_module);
745     }
746
747     return variant_type;
748 }
749
750 /**
751  * pyg_value_from_pyobject:
752  * @value: the GValue object to store the converted value in.
753  * @obj: the Python object to convert.
754  *
755  * This function converts a Python object and stores the result in a
756  * GValue.  The GValue must be initialised in advance with
757  * g_value_init().  If the Python object can't be converted to the
758  * type of the GValue, then an error is returned.
759  *
760  * Returns: 0 on success, -1 on error.
761  */
762 int
763 pyg_value_from_pyobject(GValue *value, PyObject *obj)
764 {
765     PyObject *tmp;
766     GType value_type = G_VALUE_TYPE(value);
767
768     switch (G_TYPE_FUNDAMENTAL(value_type)) {
769     case G_TYPE_INTERFACE:
770         /* we only handle interface types that have a GObject prereq */
771         if (g_type_is_a(value_type, G_TYPE_OBJECT)) {
772             if (obj == Py_None)
773                 g_value_set_object(value, NULL);
774             else {
775                 if (!PyObject_TypeCheck(obj, &PyGObject_Type)) {
776                     return -1;
777                 }
778                 if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
779                                                 value_type)) {
780                     return -1;
781                 }
782                 g_value_set_object(value, pygobject_get(obj));
783             }
784         } else {
785             return -1;
786         }
787         break;
788     case G_TYPE_CHAR:
789 #if PY_VERSION_HEX < 0x03000000
790         if (PyString_Check(obj)) {
791             g_value_set_schar(value, PyString_AsString(obj)[0]);
792         } else
793 #endif
794         if (PyUnicode_Check(obj)) {
795             tmp = PyUnicode_AsUTF8String(obj);
796             g_value_set_schar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
797             Py_DECREF(tmp);
798         } else {
799             PyErr_Clear();
800             return -1;
801         }
802
803         break;
804     case G_TYPE_UCHAR:
805         if (PYGLIB_PyLong_Check(obj)) {
806             glong val;
807             val = PYGLIB_PyLong_AsLong(obj);
808             if (val >= 0 && val <= 255)
809               g_value_set_uchar(value, (guchar)PYGLIB_PyLong_AsLong (obj));
810             else
811               return -1;
812 #if PY_VERSION_HEX < 0x03000000
813         } else if (PyString_Check(obj)) {
814             g_value_set_uchar(value, PyString_AsString(obj)[0]);
815 #endif
816         } else if (PyUnicode_Check(obj)) {
817             tmp = PyUnicode_AsUTF8String(obj);
818             g_value_set_uchar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
819             Py_DECREF(tmp);
820         } else {
821             PyErr_Clear();
822             return -1;
823         }
824         break;
825     case G_TYPE_BOOLEAN:
826         g_value_set_boolean(value, PyObject_IsTrue(obj));
827         break;
828     case G_TYPE_INT:
829         g_value_set_int(value, PYGLIB_PyLong_AsLong(obj));
830         break;
831     case G_TYPE_UINT:
832         {
833             if (PYGLIB_PyLong_Check(obj)) {
834                 glong val;
835
836                 val = PYGLIB_PyLong_AsLong(obj);
837                 if (val >= 0 && val <= G_MAXUINT)
838                     g_value_set_uint(value, (guint)val);
839                 else
840                     return -1;
841             } else {
842                 g_value_set_uint(value, PyLong_AsUnsignedLong(obj));
843             }
844         }
845         break;
846     case G_TYPE_LONG:
847         g_value_set_long(value, PYGLIB_PyLong_AsLong(obj));
848         break;
849     case G_TYPE_ULONG:
850 #if PY_VERSION_HEX < 0x03000000
851         if (PyInt_Check(obj)) {
852             long val;
853
854             val = PYGLIB_PyLong_AsLong(obj);
855             if (val < 0) {
856                 PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
857                 return -1;
858             }
859             g_value_set_ulong(value, (gulong)val);
860         } else
861 #endif
862         if (PyLong_Check(obj))
863             g_value_set_ulong(value, PyLong_AsUnsignedLong(obj));
864         else
865             return -1;
866         break;
867     case G_TYPE_INT64:
868         g_value_set_int64(value, PyLong_AsLongLong(obj));
869         break;
870     case G_TYPE_UINT64:
871 #if PY_VERSION_HEX < 0x03000000
872         if (PyInt_Check(obj)) {
873             long v = PyInt_AsLong(obj);
874             if (v < 0) {
875                 PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
876                 return -1;
877             }
878             g_value_set_uint64(value, v);
879         } else
880 #endif
881         if (PyLong_Check(obj))
882             g_value_set_uint64(value, PyLong_AsUnsignedLongLong(obj));
883         else
884             return -1;
885         break;
886     case G_TYPE_ENUM:
887         {
888             gint val = 0;
889             if (pyg_enum_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
890                 PyErr_Clear();
891                 return -1;
892             }
893             g_value_set_enum(value, val);
894         }
895         break;
896     case G_TYPE_FLAGS:
897         {
898             gint val = 0;
899             if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
900                 PyErr_Clear();
901                 return -1;
902             }
903             g_value_set_flags(value, val);
904         }
905         break;
906     case G_TYPE_FLOAT:
907         g_value_set_float(value, PyFloat_AsDouble(obj));
908         break;
909     case G_TYPE_DOUBLE:
910         g_value_set_double(value, PyFloat_AsDouble(obj));
911         break;
912     case G_TYPE_STRING:
913         if (obj == Py_None) {
914             g_value_set_string(value, NULL);
915         } else {
916             PyObject* tmp_str = PyObject_Str(obj);
917             if (tmp_str == NULL) {
918                 PyErr_Clear();
919                 if (PyUnicode_Check(obj)) {
920                     tmp = PyUnicode_AsUTF8String(obj);
921                     g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp));
922                     Py_DECREF(tmp);
923                 } else {
924                     return -1;
925                 }
926             } else {
927 #if PY_VERSION_HEX < 0x03000000
928                g_value_set_string(value, PyString_AsString(tmp_str));
929 #else
930                tmp = PyUnicode_AsUTF8String(tmp_str);
931                g_value_set_string(value, PyBytes_AsString(tmp));
932                Py_DECREF(tmp);
933 #endif
934             }
935             Py_XDECREF(tmp_str);
936         }
937         break;
938     case G_TYPE_POINTER:
939         if (obj == Py_None)
940             g_value_set_pointer(value, NULL);
941         else if (PyObject_TypeCheck(obj, &PyGPointer_Type) &&
942                    G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype))
943             g_value_set_pointer(value, pyg_pointer_get(obj, gpointer));
944         else if (PYGLIB_CPointer_Check(obj))
945             g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL));
946         else if (G_VALUE_HOLDS_GTYPE (value))
947             g_value_set_gtype (value, pyg_type_from_object (obj));
948         else
949             return -1;
950         break;
951     case G_TYPE_BOXED: {
952         PyGTypeMarshal *bm;
953
954         if (obj == Py_None)
955             g_value_set_boxed(value, NULL);
956         else if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT))
957             g_value_set_boxed(value, obj);
958         else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) &&
959                    G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype))
960             g_value_set_boxed(value, pyg_boxed_get(obj, gpointer));
961         else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
962             GType type;
963             GValue *n_value;
964
965             type = pyg_type_from_object((PyObject*)Py_TYPE(obj));
966             if (G_UNLIKELY (! type)) {
967                 PyErr_Clear();
968                 return -1;
969             }
970             n_value = g_new0 (GValue, 1);
971             g_value_init (n_value, type);
972             g_value_take_boxed (value, n_value);
973             return pyg_value_from_pyobject (n_value, obj);
974         }
975         else if (PySequence_Check(obj) &&
976                    G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY))
977             return pyg_value_array_from_pyobject(value, obj, NULL);
978         else if (PYGLIB_PyUnicode_Check(obj) &&
979                  G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
980             GString *string;
981             char *buffer;
982             Py_ssize_t len;
983             if (PYGLIB_PyUnicode_AsStringAndSize(obj, &buffer, &len))
984                 return -1;
985             string = g_string_new_len(buffer, len);
986             g_value_set_boxed(value, string);
987             g_string_free (string, TRUE);
988             break;
989         }
990         else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
991             return bm->tovalue(value, obj);
992         else if (PYGLIB_CPointer_Check(obj))
993             g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL));
994         else
995             return -1;
996         break;
997     }
998     case G_TYPE_PARAM:
999         if (PyGParamSpec_Check(obj))
1000             g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
1001         else
1002             return -1;
1003         break;
1004     case G_TYPE_OBJECT:
1005         if (obj == Py_None) {
1006             g_value_set_object(value, NULL);
1007         } else if (PyObject_TypeCheck(obj, &PyGObject_Type) &&
1008                    G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
1009                                               G_VALUE_TYPE(value))) {
1010             g_value_set_object(value, pygobject_get(obj));
1011         } else
1012             return -1;
1013         break;
1014     case G_TYPE_VARIANT:
1015         {
1016             PyObject* variant_type = pyg_get_gvariant_type();
1017             if (obj == Py_None)
1018                 g_value_set_variant(value, NULL);
1019             else if (variant_type != NULL && PyObject_IsInstance(obj, variant_type))
1020                 g_value_set_variant(value, pyg_boxed_get(obj, GVariant));
1021             else
1022                 return -1;
1023             break;
1024         }
1025     default:
1026         {
1027             PyGTypeMarshal *bm;
1028             if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
1029                 return bm->tovalue(value, obj);
1030             break;
1031         }
1032     }
1033     if (PyErr_Occurred()) {
1034         g_value_unset(value);
1035         PyErr_Clear();
1036         return -1;
1037     }
1038     return 0;
1039 }
1040
1041 /**
1042  * pyg_value_as_pyobject:
1043  * @value: the GValue object.
1044  * @copy_boxed: true if boxed values should be copied.
1045  *
1046  * This function creates/returns a Python wrapper object that
1047  * represents the GValue passed as an argument.
1048  *
1049  * Returns: a PyObject representing the value.
1050  */
1051 PyObject *
1052 pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed)
1053 {
1054     gchar buf[128];
1055
1056     switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value))) {
1057     case G_TYPE_INTERFACE:
1058         if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_OBJECT))
1059             return pygobject_new(g_value_get_object(value));
1060         else
1061             break;
1062     case G_TYPE_CHAR: {
1063         gint8 val = g_value_get_schar(value);
1064         return PYGLIB_PyUnicode_FromStringAndSize((char *)&val, 1);
1065     }
1066     case G_TYPE_UCHAR: {
1067         guint8 val = g_value_get_uchar(value);
1068         return PYGLIB_PyBytes_FromStringAndSize((char *)&val, 1);
1069     }
1070     case G_TYPE_BOOLEAN: {
1071         return PyBool_FromLong(g_value_get_boolean(value));
1072     }
1073     case G_TYPE_INT:
1074         return PYGLIB_PyLong_FromLong(g_value_get_int(value));
1075     case G_TYPE_UINT:
1076         {
1077             /* in Python, the Int object is backed by a long.  If a
1078                long can hold the whole value of an unsigned int, use
1079                an Int.  Otherwise, use a Long object to avoid overflow.
1080                This matches the ULongArg behavior in codegen/argtypes.h */
1081 #if (G_MAXUINT <= G_MAXLONG)
1082             return PYGLIB_PyLong_FromLong((glong) g_value_get_uint(value));
1083 #else
1084             return PyLong_FromUnsignedLong((gulong) g_value_get_uint(value));
1085 #endif
1086         }
1087     case G_TYPE_LONG:
1088         return PYGLIB_PyLong_FromLong(g_value_get_long(value));
1089     case G_TYPE_ULONG:
1090         {
1091             gulong val = g_value_get_ulong(value);
1092
1093             if (val <= G_MAXLONG)
1094                 return PYGLIB_PyLong_FromLong((glong) val);
1095             else
1096                 return PyLong_FromUnsignedLong(val);
1097         }
1098     case G_TYPE_INT64:
1099         {
1100             gint64 val = g_value_get_int64(value);
1101
1102             if (G_MINLONG <= val && val <= G_MAXLONG)
1103                 return PYGLIB_PyLong_FromLong((glong) val);
1104             else
1105                 return PyLong_FromLongLong(val);
1106         }
1107     case G_TYPE_UINT64:
1108         {
1109             guint64 val = g_value_get_uint64(value);
1110
1111             if (val <= G_MAXLONG)
1112                 return PYGLIB_PyLong_FromLong((glong) val);
1113             else
1114                 return PyLong_FromUnsignedLongLong(val);
1115         }
1116     case G_TYPE_ENUM:
1117         return pyg_enum_from_gtype(G_VALUE_TYPE(value), g_value_get_enum(value));
1118     case G_TYPE_FLAGS:
1119         return pyg_flags_from_gtype(G_VALUE_TYPE(value), g_value_get_flags(value));
1120     case G_TYPE_FLOAT:
1121         return PyFloat_FromDouble(g_value_get_float(value));
1122     case G_TYPE_DOUBLE:
1123         return PyFloat_FromDouble(g_value_get_double(value));
1124     case G_TYPE_STRING:
1125         {
1126             const gchar *str = g_value_get_string(value);
1127
1128             if (str)
1129                 return PYGLIB_PyUnicode_FromString(str);
1130             Py_INCREF(Py_None);
1131             return Py_None;
1132         }
1133     case G_TYPE_POINTER:
1134         if (G_VALUE_HOLDS_GTYPE (value))
1135             return pyg_type_wrapper_new (g_value_get_gtype (value));
1136         else
1137             return pyg_pointer_new(G_VALUE_TYPE(value),
1138                                    g_value_get_pointer(value));
1139     case G_TYPE_BOXED: {
1140         PyGTypeMarshal *bm;
1141
1142         if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) {
1143             PyObject *ret = (PyObject *)g_value_dup_boxed(value);
1144             if (ret == NULL) {
1145                 Py_INCREF(Py_None);
1146                 return Py_None;
1147             }
1148             return ret;
1149         } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
1150             GValue *n_value = g_value_get_boxed (value);
1151             return pyg_value_as_pyobject(n_value, copy_boxed);
1152         } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY)) {
1153             GValueArray *array = (GValueArray *) g_value_get_boxed(value);
1154             PyObject *ret = PyList_New(array->n_values);
1155             int i;
1156             for (i = 0; i < array->n_values; ++i)
1157                 PyList_SET_ITEM(ret, i, pyg_value_as_pyobject
1158                                 (array->values + i, copy_boxed));
1159             return ret;
1160         } else if (G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
1161             GString *string = (GString *) g_value_get_boxed(value);
1162             PyObject *ret = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len);
1163             return ret;
1164         }
1165         bm = pyg_type_lookup(G_VALUE_TYPE(value));
1166         if (bm) {
1167             return bm->fromvalue(value);
1168         } else {
1169             if (copy_boxed)
1170                 return pyg_boxed_new(G_VALUE_TYPE(value),
1171                                      g_value_get_boxed(value), TRUE, TRUE);
1172             else
1173                 return pyg_boxed_new(G_VALUE_TYPE(value),
1174                                      g_value_get_boxed(value),FALSE,FALSE);
1175         }
1176     }
1177     case G_TYPE_PARAM:
1178         return pyg_param_spec_new(g_value_get_param(value));
1179     case G_TYPE_OBJECT:
1180         return pygobject_new(g_value_get_object(value));
1181     case G_TYPE_VARIANT:
1182         {
1183             GVariant *v = g_value_get_variant(value);
1184             if (v == NULL) {
1185                 Py_INCREF(Py_None);
1186                 return Py_None;
1187             }
1188             return pyg_boxed_new(G_TYPE_VARIANT, g_variant_ref(v), FALSE, FALSE);
1189         }
1190     default:
1191         {
1192             PyGTypeMarshal *bm;
1193             if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))))
1194                 return bm->fromvalue(value);
1195             break;
1196         }
1197     }
1198     g_snprintf(buf, sizeof(buf), "unknown type %s",
1199                g_type_name(G_VALUE_TYPE(value)));
1200     PyErr_SetString(PyExc_TypeError, buf);
1201     return NULL;
1202 }
1203
1204 /* -------------- PyGClosure ----------------- */
1205
1206 static void
1207 pyg_closure_invalidate(gpointer data, GClosure *closure)
1208 {
1209     PyGClosure *pc = (PyGClosure *)closure;
1210     PyGILState_STATE state;
1211
1212     state = pyglib_gil_state_ensure();
1213     Py_XDECREF(pc->callback);
1214     Py_XDECREF(pc->extra_args);
1215     Py_XDECREF(pc->swap_data);
1216     pyglib_gil_state_release(state);
1217
1218     pc->callback = NULL;
1219     pc->extra_args = NULL;
1220     pc->swap_data = NULL;
1221 }
1222
1223 static void
1224 pyg_closure_marshal(GClosure *closure,
1225                     GValue *return_value,
1226                     guint n_param_values,
1227                     const GValue *param_values,
1228                     gpointer invocation_hint,
1229                     gpointer marshal_data)
1230 {
1231     PyGILState_STATE state;
1232     PyGClosure *pc = (PyGClosure *)closure;
1233     PyObject *params, *ret;
1234     guint i;
1235
1236     state = pyglib_gil_state_ensure();
1237
1238     /* construct Python tuple for the parameter values */
1239     params = PyTuple_New(n_param_values);
1240     for (i = 0; i < n_param_values; i++) {
1241         /* swap in a different initial data for connect_object() */
1242         if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) {
1243             g_return_if_fail(pc->swap_data != NULL);
1244             Py_INCREF(pc->swap_data);
1245             PyTuple_SetItem(params, 0, pc->swap_data);
1246         } else {
1247             PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
1248
1249             /* error condition */
1250             if (!item) {
1251                 goto out;
1252             }
1253             PyTuple_SetItem(params, i, item);
1254         }
1255     }
1256     /* params passed to function may have extra arguments */
1257     if (pc->extra_args) {
1258         PyObject *tuple = params;
1259         params = PySequence_Concat(tuple, pc->extra_args);
1260         Py_DECREF(tuple);
1261     }
1262     ret = PyObject_CallObject(pc->callback, params);
1263     if (ret == NULL) {
1264         if (pc->exception_handler)
1265             pc->exception_handler(return_value, n_param_values, param_values);
1266         else
1267             PyErr_Print();
1268         goto out;
1269     }
1270
1271     if (return_value && pyg_value_from_pyobject(return_value, ret) != 0) {
1272         /* If we already have an exception set, use that, otherwise set a
1273          * generic one */
1274         if (!PyErr_Occurred())
1275             PyErr_SetString(PyExc_TypeError,
1276                             "can't convert return value to desired type");
1277
1278         if (pc->exception_handler)
1279             pc->exception_handler(return_value, n_param_values, param_values);
1280         else
1281             PyErr_Print();
1282     }
1283     Py_DECREF(ret);
1284
1285  out:
1286     Py_DECREF(params);
1287     pyglib_gil_state_release(state);
1288 }
1289
1290 /**
1291  * pyg_closure_new:
1292  * callback: a Python callable object
1293  * extra_args: a tuple of extra arguments, or None/NULL.
1294  * swap_data: an alternative python object to pass first.
1295  *
1296  * Creates a GClosure wrapping a Python callable and optionally a set
1297  * of additional function arguments.  This is needed to attach python
1298  * handlers to signals, for instance.
1299  *
1300  * Returns: the new closure.
1301  */
1302 GClosure *
1303 pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data)
1304 {
1305     GClosure *closure;
1306
1307     g_return_val_if_fail(callback != NULL, NULL);
1308     closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
1309     g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate);
1310     g_closure_set_marshal(closure, pyg_closure_marshal);
1311     Py_INCREF(callback);
1312     ((PyGClosure *)closure)->callback = callback;
1313     if (extra_args && extra_args != Py_None) {
1314         Py_INCREF(extra_args);
1315         if (!PyTuple_Check(extra_args)) {
1316             PyObject *tmp = PyTuple_New(1);
1317             PyTuple_SetItem(tmp, 0, extra_args);
1318             extra_args = tmp;
1319         }
1320         ((PyGClosure *)closure)->extra_args = extra_args;
1321     }
1322     if (swap_data) {
1323         Py_INCREF(swap_data);
1324         ((PyGClosure *)closure)->swap_data = swap_data;
1325         closure->derivative_flag = TRUE;
1326     }
1327     return closure;
1328 }
1329
1330 /**
1331  * pyg_closure_set_exception_handler:
1332  * @closure: a closure created with pyg_closure_new()
1333  * @handler: the handler to call when an exception occurs or NULL for none
1334  *
1335  * Sets the handler to call when an exception occurs during closure invocation.
1336  * The handler is responsible for providing a proper return value to the
1337  * closure invocation. If @handler is %NULL, the default handler will be used.
1338  * The default handler prints the exception to stderr and doesn't touch the
1339  * closure's return value.
1340  */
1341 void
1342 pyg_closure_set_exception_handler(GClosure *closure,
1343                                   PyClosureExceptionHandler handler)
1344 {
1345     PyGClosure *pygclosure;
1346
1347     g_return_if_fail(closure != NULL);
1348
1349     pygclosure = (PyGClosure *)closure;
1350     pygclosure->exception_handler = handler;
1351 }
1352 /* -------------- PySignalClassClosure ----------------- */
1353 /* a closure used for the `class closure' of a signal.  As this gets
1354  * all the info from the first argument to the closure and the
1355  * invocation hint, we can have a single closure that handles all
1356  * class closure cases.  We call a method by the name of the signal
1357  * with "do_" prepended.
1358  *
1359  *  We also remove the first argument from the * param list, as it is
1360  *  the instance object, which is passed * implicitly to the method
1361  *  object. */
1362
1363 static void
1364 pyg_signal_class_closure_marshal(GClosure *closure,
1365                                  GValue *return_value,
1366                                  guint n_param_values,
1367                                  const GValue *param_values,
1368                                  gpointer invocation_hint,
1369                                  gpointer marshal_data)
1370 {
1371     PyGILState_STATE state;
1372     GObject *object;
1373     PyObject *object_wrapper;
1374     GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint;
1375     gchar *method_name, *tmp;
1376     PyObject *method;
1377     PyObject *params, *ret;
1378     guint i, len;
1379
1380     state = pyglib_gil_state_ensure();
1381
1382     g_return_if_fail(invocation_hint != NULL);
1383     /* get the object passed as the first argument to the closure */
1384     object = g_value_get_object(&param_values[0]);
1385     g_return_if_fail(object != NULL && G_IS_OBJECT(object));
1386
1387     /* get the wrapper for this object */
1388     object_wrapper = pygobject_new(object);
1389     g_return_if_fail(object_wrapper != NULL);
1390
1391     /* construct method name for this class closure */
1392     method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL);
1393
1394     /* convert dashes to underscores.  For some reason, g_signal_name
1395      * seems to convert all the underscores in the signal name to
1396        dashes??? */
1397     for (tmp = method_name; *tmp != '\0'; tmp++)
1398         if (*tmp == '-') *tmp = '_';
1399
1400     method = PyObject_GetAttrString(object_wrapper, method_name);
1401     g_free(method_name);
1402
1403     if (!method) {
1404         PyErr_Clear();
1405         Py_DECREF(object_wrapper);
1406         pyglib_gil_state_release(state);
1407         return;
1408     }
1409     Py_DECREF(object_wrapper);
1410
1411     /* construct Python tuple for the parameter values; don't copy boxed values
1412        initially because we'll check after the call to see if a copy is needed. */
1413     params = PyTuple_New(n_param_values - 1);
1414     for (i = 1; i < n_param_values; i++) {
1415         PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
1416
1417         /* error condition */
1418         if (!item) {
1419             Py_DECREF(params);
1420             pyglib_gil_state_release(state);
1421             return;
1422         }
1423         PyTuple_SetItem(params, i - 1, item);
1424     }
1425
1426     ret = PyObject_CallObject(method, params);
1427
1428     /* Copy boxed values if others ref them, this needs to be done regardless of
1429        exception status. */
1430     len = PyTuple_Size(params);
1431     for (i = 0; i < len; i++) {
1432         PyObject *item = PyTuple_GetItem(params, i);
1433         if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type)
1434             && item->ob_refcnt != 1) {
1435             PyGBoxed* boxed_item = (PyGBoxed*)item;
1436             if (!boxed_item->free_on_dealloc) {
1437                 boxed_item->boxed = g_boxed_copy(boxed_item->gtype, boxed_item->boxed);
1438                 boxed_item->free_on_dealloc = TRUE;
1439             }
1440         }
1441     }
1442
1443     if (ret == NULL) {
1444         PyErr_Print();
1445         Py_DECREF(method);
1446         Py_DECREF(params);
1447         pyglib_gil_state_release(state);
1448         return;
1449     }
1450     Py_DECREF(method);
1451     Py_DECREF(params);
1452     if (return_value)
1453         pyg_value_from_pyobject(return_value, ret);
1454     Py_DECREF(ret);
1455     pyglib_gil_state_release(state);
1456 }
1457
1458 /**
1459  * pyg_signal_class_closure_get:
1460  *
1461  * Returns the GClosure used for the class closure of signals.  When
1462  * called, it will invoke the method do_signalname (for the signal
1463  * "signalname").
1464  *
1465  * Returns: the closure.
1466  */
1467 GClosure *
1468 pyg_signal_class_closure_get(void)
1469 {
1470     static GClosure *closure;
1471
1472     if (closure == NULL) {
1473         closure = g_closure_new_simple(sizeof(GClosure), NULL);
1474         g_closure_set_marshal(closure, pyg_signal_class_closure_marshal);
1475
1476         g_closure_ref(closure);
1477         g_closure_sink(closure);
1478     }
1479     return closure;
1480 }
1481
1482 GClosure *
1483 gclosure_from_pyfunc(PyGObject *object, PyObject *func)
1484 {
1485     GSList *l;
1486     PyGObjectData *inst_data;
1487     inst_data = pyg_object_peek_inst_data(object->obj);
1488     if (inst_data) {
1489         for (l = inst_data->closures; l; l = l->next) {
1490             PyGClosure *pyclosure = l->data;
1491             int res = PyObject_RichCompareBool(pyclosure->callback, func, Py_EQ);
1492             if (res == -1) {
1493                 PyErr_Clear(); // Is there anything else to do?
1494             } else if (res) {
1495                 return (GClosure*)pyclosure;
1496             }
1497         }
1498     }
1499     return NULL;
1500 }
1501
1502 /* ----- __doc__ descriptor for GObject and GInterface ----- */
1503
1504 static void
1505 object_doc_dealloc(PyObject *self)
1506 {
1507     PyObject_FREE(self);
1508 }
1509
1510 /* append information about signals of a particular gtype */
1511 static void
1512 add_signal_docs(GType gtype, GString *string)
1513 {
1514     GTypeClass *class = NULL;
1515     guint *signal_ids, n_ids = 0, i;
1516
1517     if (G_TYPE_IS_CLASSED(gtype))
1518         class = g_type_class_ref(gtype);
1519     signal_ids = g_signal_list_ids(gtype, &n_ids);
1520
1521     if (n_ids > 0) {
1522         g_string_append_printf(string, "Signals from %s:\n",
1523                                g_type_name(gtype));
1524
1525         for (i = 0; i < n_ids; i++) {
1526             GSignalQuery query;
1527             guint j;
1528
1529             g_signal_query(signal_ids[i], &query);
1530
1531             g_string_append(string, "  ");
1532             g_string_append(string, query.signal_name);
1533             g_string_append(string, " (");
1534             for (j = 0; j < query.n_params; j++) {
1535                 g_string_append(string, g_type_name(query.param_types[j]));
1536                 if (j != query.n_params - 1)
1537                     g_string_append(string, ", ");
1538             }
1539             g_string_append(string, ")");
1540             if (query.return_type && query.return_type != G_TYPE_NONE) {
1541                 g_string_append(string, " -> ");
1542                 g_string_append(string, g_type_name(query.return_type));
1543             }
1544             g_string_append(string, "\n");
1545         }
1546         g_free(signal_ids);
1547         g_string_append(string, "\n");
1548     }
1549     if (class)
1550         g_type_class_unref(class);
1551 }
1552
1553 static void
1554 add_property_docs(GType gtype, GString *string)
1555 {
1556     GObjectClass *class;
1557     GParamSpec **props;
1558     guint n_props = 0, i;
1559     gboolean has_prop = FALSE;
1560     G_CONST_RETURN gchar *blurb=NULL;
1561
1562     class = g_type_class_ref(gtype);
1563     props = g_object_class_list_properties(class, &n_props);
1564
1565     for (i = 0; i < n_props; i++) {
1566         if (props[i]->owner_type != gtype)
1567             continue; /* these are from a parent type */
1568
1569         /* print out the heading first */
1570         if (!has_prop) {
1571             g_string_append_printf(string, "Properties from %s:\n",
1572                                    g_type_name(gtype));
1573             has_prop = TRUE;
1574         }
1575         g_string_append_printf(string, "  %s -> %s: %s\n",
1576                                g_param_spec_get_name(props[i]),
1577                                g_type_name(props[i]->value_type),
1578                                g_param_spec_get_nick(props[i]));
1579
1580         /* g_string_append_printf crashes on win32 if the third
1581            argument is NULL. */
1582         blurb=g_param_spec_get_blurb(props[i]);
1583         if (blurb)
1584             g_string_append_printf(string, "    %s\n",blurb);
1585     }
1586     g_free(props);
1587     if (has_prop)
1588         g_string_append(string, "\n");
1589     g_type_class_unref(class);
1590 }
1591
1592 static PyObject *
1593 object_doc_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1594 {
1595     GType gtype = 0;
1596     GString *string;
1597     PyObject *pystring;
1598
1599     if (obj && pygobject_check(obj, &PyGObject_Type)) {
1600         gtype = G_OBJECT_TYPE(pygobject_get(obj));
1601         if (!gtype)
1602             PyErr_SetString(PyExc_RuntimeError, "could not get object type");
1603     } else {
1604         gtype = pyg_type_from_object(type);
1605     }
1606     if (!gtype)
1607         return NULL;
1608
1609     string = g_string_new_len(NULL, 512);
1610
1611     if (g_type_is_a(gtype, G_TYPE_INTERFACE))
1612         g_string_append_printf(string, "Interface %s\n\n", g_type_name(gtype));
1613     else if (g_type_is_a(gtype, G_TYPE_OBJECT))
1614         g_string_append_printf(string, "Object %s\n\n", g_type_name(gtype));
1615     else
1616         g_string_append_printf(string, "%s\n\n", g_type_name(gtype));
1617
1618     if (((PyTypeObject *) type)->tp_doc)
1619         g_string_append_printf(string, "%s\n\n", ((PyTypeObject *) type)->tp_doc);
1620
1621     if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
1622         GType parent = G_TYPE_OBJECT;
1623         GArray *parents = g_array_new(FALSE, FALSE, sizeof(GType));
1624         int iparent;
1625
1626         while (parent) {
1627             g_array_append_val(parents, parent);
1628             parent = g_type_next_base(gtype, parent);
1629         }
1630
1631         for (iparent = parents->len - 1; iparent >= 0; --iparent) {
1632             GType *interfaces;
1633             guint n_interfaces, i;
1634
1635             parent = g_array_index(parents, GType, iparent);
1636             add_signal_docs(parent, string);
1637             add_property_docs(parent, string);
1638
1639             /* add docs for implemented interfaces */
1640             interfaces = g_type_interfaces(parent, &n_interfaces);
1641             for (i = 0; i < n_interfaces; i++)
1642                 add_signal_docs(interfaces[i], string);
1643             g_free(interfaces);
1644         }
1645         g_array_free(parents, TRUE);
1646     }
1647
1648     pystring = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len);
1649     g_string_free(string, TRUE);
1650     return pystring;
1651 }
1652
1653 PYGLIB_DEFINE_TYPE("gobject.GObject.__doc__", PyGObjectDoc_Type, PyObject);
1654
1655 /**
1656  * pyg_object_descr_doc_get:
1657  *
1658  * Returns an object intended to be the __doc__ attribute of GObject
1659  * wrappers.  When read in the context of the object it will return
1660  * some documentation about the signals and properties of the object.
1661  *
1662  * Returns: the descriptor.
1663  */
1664 PyObject *
1665 pyg_object_descr_doc_get(void)
1666 {
1667     static PyObject *doc_descr = NULL;
1668
1669     if (!doc_descr) {
1670         Py_TYPE(&PyGObjectDoc_Type) = &PyType_Type;
1671         if (PyType_Ready(&PyGObjectDoc_Type))
1672             return NULL;
1673
1674         doc_descr = PyObject_NEW(PyObject, &PyGObjectDoc_Type);
1675         if (doc_descr == NULL)
1676             return NULL;
1677     }
1678     return doc_descr;
1679 }
1680
1681
1682 /**
1683  * pyg_pyobj_to_unichar_conv:
1684  *
1685  * Converts PyObject value to a unichar and write result to memory
1686  * pointed to by ptr.  Follows the calling convention of a ParseArgs
1687  * converter (O& format specifier) so it may be used to convert function
1688  * arguments.
1689  *
1690  * Returns: 1 if the conversion succeeds and 0 otherwise.  If the conversion
1691  *          did not succeesd, a Python exception is raised
1692  */
1693 int pyg_pyobj_to_unichar_conv(PyObject* py_obj, void* ptr)
1694 {
1695     gunichar* u = ptr;
1696     const Py_UNICODE* uni_buffer;
1697     PyObject* tmp_uni = NULL;
1698
1699     if (PyUnicode_Check(py_obj)) {
1700         tmp_uni = py_obj;
1701         Py_INCREF(tmp_uni);
1702     }
1703     else {
1704         tmp_uni = PyUnicode_FromObject(py_obj);
1705         if (tmp_uni == NULL)
1706             goto failure;
1707     }
1708
1709     if ( PyUnicode_GetSize(tmp_uni) != 1) {
1710         PyErr_SetString(PyExc_ValueError, "unicode character value must be 1 character uniode string");
1711         goto failure;
1712     }
1713     uni_buffer = PyUnicode_AsUnicode(tmp_uni);
1714     if ( uni_buffer == NULL)
1715         goto failure;
1716     *u = uni_buffer[0];
1717
1718     Py_DECREF(tmp_uni);
1719     return 1;
1720
1721   failure:
1722     Py_XDECREF(tmp_uni);
1723     return 0;
1724 }
1725
1726
1727 int
1728 pyg_param_gvalue_from_pyobject(GValue* value,
1729                                PyObject* py_obj,
1730                                const GParamSpec* pspec)
1731 {
1732     if (G_IS_PARAM_SPEC_UNICHAR(pspec)) {
1733         gunichar u;
1734
1735         if (!pyg_pyobj_to_unichar_conv(py_obj, &u)) {
1736             PyErr_Clear();
1737             return -1;
1738         }
1739         g_value_set_uint(value, u);
1740         return 0;
1741     }
1742     else if (G_IS_PARAM_SPEC_VALUE_ARRAY(pspec))
1743         return pyg_value_array_from_pyobject(value, py_obj,
1744                                              G_PARAM_SPEC_VALUE_ARRAY(pspec));
1745     else {
1746         return pyg_value_from_pyobject(value, py_obj);
1747     }
1748 }
1749
1750 PyObject*
1751 pyg_param_gvalue_as_pyobject(const GValue* gvalue,
1752                              gboolean copy_boxed,
1753                              const GParamSpec* pspec)
1754 {
1755     if (G_IS_PARAM_SPEC_UNICHAR(pspec)) {
1756         gunichar u;
1757         Py_UNICODE uni_buffer[2] = { 0, 0 };
1758
1759         u = g_value_get_uint(gvalue);
1760         uni_buffer[0] = u;
1761         return PyUnicode_FromUnicode(uni_buffer, 1);
1762     }
1763     else {
1764         return pyg_value_as_pyobject(gvalue, copy_boxed);
1765     }
1766 }
1767
1768 /**
1769  * pyg_type_registration_callback
1770  * @gtypename: type name
1771  * @callback: function to run
1772  *
1773  */
1774 typedef struct {
1775     PyGTypeRegistrationFunction callback;
1776     gpointer data;
1777 } CustomTypeData;
1778
1779 void
1780 pyg_type_register_custom_callback(const gchar *typename,
1781                                   PyGTypeRegistrationFunction callback,
1782                                   gpointer user_data)
1783 {
1784     CustomTypeData *data;
1785
1786     if (!custom_type_registration)
1787         custom_type_registration = g_hash_table_new_full (g_str_hash, g_str_equal,
1788                                                           g_free, g_free);
1789
1790     data = g_new (CustomTypeData, 1);
1791     data->callback = callback;
1792     data->data = user_data;
1793
1794     g_hash_table_insert(custom_type_registration,
1795                         g_strdup(typename),
1796                         data);
1797 }
1798
1799 PyTypeObject *
1800 pyg_type_get_custom(const gchar *name)
1801 {
1802     CustomTypeData *data;
1803     PyTypeObject *retval;
1804
1805     if (!custom_type_registration)
1806         return NULL;
1807
1808     data = g_hash_table_lookup(custom_type_registration, name);
1809     if (!data)
1810         return NULL;
1811
1812     retval = data->callback(name, data->data);
1813
1814     g_hash_table_remove(custom_type_registration, name);
1815
1816     return retval;
1817 }
1818
1819 GType
1820 _pyg_type_from_name(const gchar *name)
1821 {
1822     GType type;
1823
1824     type = g_type_from_name(name);
1825     if (type == G_TYPE_INVALID) {
1826         pyg_type_get_custom(name);
1827         type = g_type_from_name(name);
1828     }
1829
1830     return type;
1831 }
1832
1833 static PyObject *
1834 _pyg_strv_from_gvalue(const GValue *value)
1835 {
1836     gchar    **argv = (gchar **) g_value_get_boxed(value);
1837     int        argc = 0, i;
1838     PyObject  *py_argv;
1839
1840     if (argv) {
1841         while (argv[argc])
1842             argc++;
1843     }
1844     py_argv = PyList_New(argc);
1845     for (i = 0; i < argc; ++i)
1846         PyList_SET_ITEM(py_argv, i, PYGLIB_PyUnicode_FromString(argv[i]));
1847     return py_argv;
1848 }
1849
1850 static int
1851 _pyg_strv_to_gvalue(GValue *value, PyObject *obj)
1852 {
1853     Py_ssize_t argc, i;
1854     gchar **argv;
1855
1856     if (!(PyTuple_Check(obj) || PyList_Check(obj)))
1857         return -1;
1858
1859     argc = PySequence_Length(obj);
1860     for (i = 0; i < argc; ++i)
1861         if (!PYGLIB_PyUnicode_Check(PySequence_Fast_GET_ITEM(obj, i)))
1862             return -1;
1863     argv = g_new(gchar *, argc + 1);
1864     for (i = 0; i < argc; ++i)
1865         argv[i] = g_strdup(PYGLIB_PyUnicode_AsString(PySequence_Fast_GET_ITEM(obj, i)));
1866     argv[i] = NULL;
1867     g_value_take_boxed(value, argv);
1868     return 0;
1869 }
1870
1871 void
1872 pygobject_type_register_types(PyObject *d)
1873 {
1874     PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc;
1875     PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare;
1876     PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr;
1877     PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash;
1878     PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1879     PyGTypeWrapper_Type.tp_methods = _PyGTypeWrapper_methods;
1880     PyGTypeWrapper_Type.tp_getset = _PyGTypeWrapper_getsets;
1881     PyGTypeWrapper_Type.tp_init = (initproc)pyg_type_wrapper_init;
1882     PYGLIB_REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType");
1883
1884     /* This type lazily registered in pyg_object_descr_doc_get */
1885     PyGObjectDoc_Type.tp_dealloc = (destructor)object_doc_dealloc;
1886     PyGObjectDoc_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1887     PyGObjectDoc_Type.tp_descr_get = (descrgetfunc)object_doc_descr_get;
1888
1889     pyg_register_gtype_custom(G_TYPE_STRV,
1890                               _pyg_strv_from_gvalue,
1891                               _pyg_strv_to_gvalue);
1892 }