Imported Upstream version 3.25.1
[platform/upstream/pygobject2.git] / gi / 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, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <pyglib.h>
26
27 #include "pygobject-object.h"
28 #include "pygboxed.h"
29 #include "pygenum.h"
30 #include "pygflags.h"
31 #include "pygparamspec.h"
32 #include "pygtype.h"
33 #include "pygpointer.h"
34 #include "pyginterface.h"
35
36 #include "pygi-type.h"
37 #include "pygi-value.h"
38
39 /* -------------- __gtype__ objects ---------------------------- */
40
41 typedef struct {
42     PyObject_HEAD
43     GType type;
44 } PyGTypeWrapper;
45
46 PYGLIB_DEFINE_TYPE("gobject.GType", PyGTypeWrapper_Type, PyGTypeWrapper);
47
48 static PyObject*
49 pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op)
50 {
51     if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type)
52         return _pyglib_generic_long_richcompare(((PyGTypeWrapper*)self)->type,
53                                                 ((PyGTypeWrapper*)other)->type,
54                                                 op);
55     else {
56         Py_INCREF(Py_NotImplemented);
57         return Py_NotImplemented;
58     }
59 }
60
61 static long
62 pyg_type_wrapper_hash(PyGTypeWrapper *self)
63 {
64     return (long)self->type;
65 }
66
67 static PyObject *
68 pyg_type_wrapper_repr(PyGTypeWrapper *self)
69 {
70     char buf[80];
71     const gchar *name = g_type_name(self->type);
72
73     g_snprintf(buf, sizeof(buf), "<GType %s (%lu)>",
74                name?name:"invalid", (unsigned long int) self->type);
75     return PYGLIB_PyUnicode_FromString(buf);
76 }
77
78 static void
79 pyg_type_wrapper_dealloc(PyGTypeWrapper *self)
80 {
81     PyObject_DEL(self);
82 }
83
84 static GQuark
85 _pyg_type_key(GType type) {
86     GQuark key;
87
88     if (g_type_is_a(type, G_TYPE_INTERFACE)) {
89         key = pyginterface_type_key;
90     } else if (g_type_is_a(type, G_TYPE_ENUM)) {
91         key = pygenum_class_key;
92     } else if (g_type_is_a(type, G_TYPE_FLAGS)) {
93         key = pygflags_class_key;
94     } else if (g_type_is_a(type, G_TYPE_POINTER)) {
95         key = pygpointer_class_key;
96     } else if (g_type_is_a(type, G_TYPE_BOXED)) {
97         key = pygboxed_type_key;
98     } else {
99         key = pygobject_class_key;
100     }
101
102     return key;
103 }
104
105 static PyObject *
106 _wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure)
107 {
108     GQuark key;
109     PyObject *py_type;
110
111     key = _pyg_type_key(self->type);
112
113     py_type = g_type_get_qdata(self->type, key);
114     if (!py_type)
115       py_type = Py_None;
116
117     Py_INCREF(py_type);
118     return py_type;
119 }
120
121 static int
122 _wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure)
123 {
124     GQuark key;
125     PyObject *py_type;
126
127     key = _pyg_type_key(self->type);
128
129     py_type = g_type_get_qdata(self->type, key);
130     Py_CLEAR(py_type);
131     if (value == Py_None)
132         g_type_set_qdata(self->type, key, NULL);
133     else if (PyType_Check(value)) {
134         Py_INCREF(value);
135         g_type_set_qdata(self->type, key, value);
136     } else {
137         PyErr_SetString(PyExc_TypeError, "Value must be None or a type object");
138         return -1;
139     }
140
141     return 0;
142 }
143
144 static PyObject *
145 _wrap_g_type_wrapper__get_name(PyGTypeWrapper *self, void *closure)
146 {
147    const char *name = g_type_name(self->type);
148    return PYGLIB_PyUnicode_FromString(name ? name : "invalid");
149 }
150
151 static PyObject *
152 _wrap_g_type_wrapper__get_parent(PyGTypeWrapper *self, void *closure)
153 {
154    return pyg_type_wrapper_new(g_type_parent(self->type));
155 }
156
157 static PyObject *
158 _wrap_g_type_wrapper__get_fundamental(PyGTypeWrapper *self, void *closure)
159 {
160    return pyg_type_wrapper_new(g_type_fundamental(self->type));
161 }
162
163 static PyObject *
164 _wrap_g_type_wrapper__get_children(PyGTypeWrapper *self, void *closure)
165 {
166   guint n_children, i;
167   GType *children;
168   PyObject *retval;
169
170   children = g_type_children(self->type, &n_children);
171
172   retval = PyList_New(n_children);
173   for (i = 0; i < n_children; i++)
174       PyList_SetItem(retval, i, pyg_type_wrapper_new(children[i]));
175   g_free(children);
176
177   return retval;
178 }
179
180 static PyObject *
181 _wrap_g_type_wrapper__get_interfaces(PyGTypeWrapper *self, void *closure)
182 {
183   guint n_interfaces, i;
184   GType *interfaces;
185   PyObject *retval;
186
187   interfaces = g_type_interfaces(self->type, &n_interfaces);
188
189   retval = PyList_New(n_interfaces);
190   for (i = 0; i < n_interfaces; i++)
191       PyList_SetItem(retval, i, pyg_type_wrapper_new(interfaces[i]));
192   g_free(interfaces);
193
194   return retval;
195 }
196
197 static PyObject *
198 _wrap_g_type_wrapper__get_depth(PyGTypeWrapper *self, void *closure)
199 {
200   return PYGLIB_PyLong_FromLong(g_type_depth(self->type));
201 }
202
203 static PyGetSetDef _PyGTypeWrapper_getsets[] = {
204     { "pytype", (getter)_wrap_g_type_wrapper__get_pytype, (setter)_wrap_g_type_wrapper__set_pytype },
205     { "name",  (getter)_wrap_g_type_wrapper__get_name, (setter)0 },
206     { "fundamental",  (getter)_wrap_g_type_wrapper__get_fundamental, (setter)0 },
207     { "parent",  (getter)_wrap_g_type_wrapper__get_parent, (setter)0 },
208     { "children",  (getter)_wrap_g_type_wrapper__get_children, (setter)0 },
209     { "interfaces",  (getter)_wrap_g_type_wrapper__get_interfaces, (setter)0 },
210     { "depth",  (getter)_wrap_g_type_wrapper__get_depth, (setter)0 },
211     { NULL, (getter)0, (setter)0 }
212 };
213
214 static PyObject*
215 _wrap_g_type_is_interface(PyGTypeWrapper *self)
216 {
217     return PyBool_FromLong(G_TYPE_IS_INTERFACE(self->type));
218 }
219
220 static PyObject*
221 _wrap_g_type_is_classed(PyGTypeWrapper *self)
222 {
223     return PyBool_FromLong(G_TYPE_IS_CLASSED(self->type));
224 }
225
226 static PyObject*
227 _wrap_g_type_is_instantiatable(PyGTypeWrapper *self)
228 {
229     return PyBool_FromLong(G_TYPE_IS_INSTANTIATABLE(self->type));
230 }
231
232 static PyObject*
233 _wrap_g_type_is_derivable(PyGTypeWrapper *self)
234 {
235     return PyBool_FromLong(G_TYPE_IS_DERIVABLE(self->type));
236 }
237
238 static PyObject*
239 _wrap_g_type_is_deep_derivable(PyGTypeWrapper *self)
240 {
241     return PyBool_FromLong(G_TYPE_IS_DEEP_DERIVABLE(self->type));
242 }
243
244 static PyObject*
245 _wrap_g_type_is_abstract(PyGTypeWrapper *self)
246 {
247     return PyBool_FromLong(G_TYPE_IS_ABSTRACT(self->type));
248 }
249
250 static PyObject*
251 _wrap_g_type_is_value_abstract(PyGTypeWrapper *self)
252 {
253     return PyBool_FromLong(G_TYPE_IS_VALUE_ABSTRACT(self->type));
254 }
255
256 static PyObject*
257 _wrap_g_type_is_value_type(PyGTypeWrapper *self)
258 {
259     return PyBool_FromLong(G_TYPE_IS_VALUE_TYPE(self->type));
260 }
261
262 static PyObject*
263 _wrap_g_type_has_value_table(PyGTypeWrapper *self)
264 {
265     return PyBool_FromLong(G_TYPE_HAS_VALUE_TABLE(self->type));
266 }
267
268 static PyObject*
269 _wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args)
270 {
271     char *type_name;
272     GType type;
273
274     if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name))
275         return NULL;
276
277     type = g_type_from_name(type_name);
278     if (type == 0) {
279         PyErr_SetString(PyExc_RuntimeError, "unknown type name");
280         return NULL;
281     }
282
283     return pyg_type_wrapper_new(type);
284 }
285
286 static PyObject*
287 _wrap_g_type_is_a(PyGTypeWrapper *self, PyObject *args)
288 {
289     PyObject *gparent;
290     GType parent;
291
292     if (!PyArg_ParseTuple(args, "O:GType.is_a", &gparent))
293         return NULL;
294     else if ((parent = pyg_type_from_object(gparent)) == 0)
295         return NULL;
296
297     return PyBool_FromLong(g_type_is_a(self->type, parent));
298 }
299
300 static PyMethodDef _PyGTypeWrapper_methods[] = {
301     { "is_interface", (PyCFunction)_wrap_g_type_is_interface, METH_NOARGS },
302     { "is_classed", (PyCFunction)_wrap_g_type_is_classed, METH_NOARGS },
303     { "is_instantiatable", (PyCFunction)_wrap_g_type_is_instantiatable, METH_NOARGS },
304     { "is_derivable", (PyCFunction)_wrap_g_type_is_derivable, METH_NOARGS },
305     { "is_deep_derivable", (PyCFunction)_wrap_g_type_is_deep_derivable, METH_NOARGS },
306     { "is_abstract", (PyCFunction)_wrap_g_type_is_abstract, METH_NOARGS },
307     { "is_value_abstract", (PyCFunction)_wrap_g_type_is_value_abstract, METH_NOARGS },
308     { "is_value_type", (PyCFunction)_wrap_g_type_is_value_type, METH_NOARGS },
309     { "has_value_table", (PyCFunction)_wrap_g_type_has_value_table, METH_NOARGS },
310     { "from_name", (PyCFunction)_wrap_g_type_from_name, METH_VARARGS | METH_STATIC },
311     { "is_a", (PyCFunction)_wrap_g_type_is_a, METH_VARARGS },
312     { NULL,  0, 0 }
313 };
314
315 static int
316 pyg_type_wrapper_init(PyGTypeWrapper *self, PyObject *args, PyObject *kwargs)
317 {
318     static char *kwlist[] = { "object", NULL };
319     PyObject *py_object;
320     GType type;
321
322     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
323                                      "O:GType.__init__",
324                                      kwlist, &py_object))
325         return -1;
326
327     if (!(type = pyg_type_from_object(py_object)))
328         return -1;
329
330     self->type = type;
331
332     return 0;
333 }
334
335 /**
336  * pyg_type_wrapper_new:
337  * type: a GType
338  *
339  * Creates a Python wrapper for a GType.
340  *
341  * Returns: the Python wrapper.
342  */
343 PyObject *
344 pyg_type_wrapper_new(GType type)
345 {
346     PyGTypeWrapper *self;
347
348     self = (PyGTypeWrapper *)PyObject_NEW(PyGTypeWrapper,
349                                           &PyGTypeWrapper_Type);
350     if (self == NULL)
351         return NULL;
352
353     self->type = type;
354     return (PyObject *)self;
355 }
356
357 /**
358  * pyg_type_from_object_strict:
359  * obj: a Python object
360  * strict: if set to TRUE, raises an exception if it can't perform the
361  *         conversion
362  *
363  * converts a python object to a GType.  If strict is set, raises an 
364  * exception if it can't perform the conversion, otherwise returns
365  * PY_TYPE_OBJECT.
366  *
367  * Returns: the corresponding GType, or 0 on error.
368  */
369
370 GType
371 pyg_type_from_object_strict(PyObject *obj, gboolean strict)
372 {
373     PyObject *gtype;
374     GType type;
375
376     /* NULL check */
377     if (!obj) {
378         PyErr_SetString(PyExc_TypeError, "can't get type from NULL object");
379         return 0;
380     }
381
382     /* map some standard types to primitive GTypes ... */
383     if (obj == Py_None)
384         return G_TYPE_NONE;
385     if (PyType_Check(obj)) {
386         PyTypeObject *tp = (PyTypeObject *)obj;
387
388         if (tp == &PYGLIB_PyLong_Type)
389             return G_TYPE_INT;
390         else if (tp == &PyBool_Type)
391             return G_TYPE_BOOLEAN;
392         else if (tp == &PyLong_Type)
393             return G_TYPE_LONG;
394         else if (tp == &PyFloat_Type)
395             return G_TYPE_DOUBLE;
396         else if (tp == &PYGLIB_PyUnicode_Type)
397             return G_TYPE_STRING;
398         else if (tp == &PyBaseObject_Type)
399             return PY_TYPE_OBJECT;
400     }
401
402     if (Py_TYPE(obj) == &PyGTypeWrapper_Type) {
403         return ((PyGTypeWrapper *)obj)->type;
404     }
405
406     /* handle strings */
407     if (PYGLIB_PyUnicode_Check(obj)) {
408         gchar *name = PYGLIB_PyUnicode_AsString(obj);
409
410         type = g_type_from_name(name);
411         if (type != 0) {
412             return type;
413         }
414     }
415
416     /* finally, look for a __gtype__ attribute on the object */
417     gtype = PyObject_GetAttrString(obj, "__gtype__");
418
419     if (gtype) {
420         if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) {
421             type = ((PyGTypeWrapper *)gtype)->type;
422             Py_DECREF(gtype);
423             return type;
424         }
425         Py_DECREF(gtype);
426     }
427
428     PyErr_Clear();
429
430     /* Some API like those that take GValues can hold a python object as
431      * a pointer.  This is potentially dangerous becuase everything is 
432      * passed in as a PyObject so we can't actually type check it.  Only
433      * fallback to PY_TYPE_OBJECT if strict checking is disabled
434      */
435     if (!strict)
436         return PY_TYPE_OBJECT;
437
438     PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
439     return 0;
440 }
441
442 /**
443  * pyg_type_from_object:
444  * obj: a Python object
445  *
446  * converts a python object to a GType.  Raises an exception if it
447  * can't perform the conversion.
448  *
449  * Returns: the corresponding GType, or 0 on error.
450  */
451 GType
452 pyg_type_from_object(PyObject *obj)
453 {
454     /* Legacy call always defaults to strict type checking */
455     return pyg_type_from_object_strict(obj, TRUE);
456 }
457
458 /**
459  * pyg_enum_get_value:
460  * @enum_type: the GType of the flag.
461  * @obj: a Python object representing the flag value
462  * @val: a pointer to the location to store the integer representation of the flag.
463  *
464  * Converts a Python object to the integer equivalent.  The conversion
465  * will depend on the type of the Python object.  If the object is an
466  * integer, it is passed through directly.  If it is a string, it will
467  * be treated as a full or short enum name as defined in the GType.
468  *
469  * Returns: 0 on success or -1 on failure
470  */
471 gint
472 pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val)
473 {
474     GEnumClass *eclass = NULL;
475     gint res = -1;
476
477     g_return_val_if_fail(val != NULL, -1);
478     if (!obj) {
479         *val = 0;
480         res = 0;
481     } else if (PYGLIB_PyLong_Check(obj)) {
482         *val = PYGLIB_PyLong_AsLong(obj);
483         res = 0;
484
485         if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
486             g_warning("expected enumeration type %s, but got %s instead",
487                       g_type_name(enum_type),
488                       g_type_name(((PyGEnum *) obj)->gtype));
489         }
490     /* Dumb code duplication, but probably not worth it to have yet another macro. */
491     } else if (PyLong_Check(obj)) {
492         *val = PyLong_AsLong(obj);
493         res = 0;
494
495         if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) {
496             g_warning("expected enumeration type %s, but got %s instead",
497                       g_type_name(enum_type),
498                       g_type_name(((PyGEnum *) obj)->gtype));
499         }
500     } else if (PYGLIB_PyUnicode_Check(obj)) {
501         GEnumValue *info;
502         char *str = PYGLIB_PyUnicode_AsString(obj);
503
504         if (enum_type != G_TYPE_NONE)
505             eclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
506         else {
507             PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value");
508             res = -1;
509         }
510         info = g_enum_get_value_by_name(eclass, str);
511         g_type_class_unref(eclass);
512
513         if (!info)
514             info = g_enum_get_value_by_nick(eclass, str);
515         if (info) {
516             *val = info->value;
517             res = 0;
518         } else {
519             PyErr_SetString(PyExc_TypeError, "could not convert string");
520             res = -1;
521         }
522     } else {
523         PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints");
524         res = -1;
525     }
526     return res;
527 }
528
529 /**
530  * pyg_flags_get_value:
531  * @flag_type: the GType of the flag.
532  * @obj: a Python object representing the flag value
533  * @val: a pointer to the location to store the integer representation of the flag.
534  *
535  * Converts a Python object to the integer equivalent.  The conversion
536  * will depend on the type of the Python object.  If the object is an
537  * integer, it is passed through directly.  If it is a string, it will
538  * be treated as a full or short flag name as defined in the GType.
539  * If it is a tuple, then the items are treated as strings and ORed
540  * together.
541  *
542  * Returns: 0 on success or -1 on failure
543  */
544 gint
545 pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val)
546 {
547     GFlagsClass *fclass = NULL;
548     gint res = -1;
549
550     g_return_val_if_fail(val != NULL, -1);
551     if (!obj) {
552         *val = 0;
553         res = 0;
554     } else if (PYGLIB_PyLong_Check(obj)) {
555         *val = PYGLIB_PyLong_AsUnsignedLong(obj);
556         res = 0;
557     } else if (PyLong_Check(obj)) {
558         *val = PyLong_AsLongLong(obj);
559         res = 0;
560     } else if (PYGLIB_PyUnicode_Check(obj)) {
561         GFlagsValue *info;
562         char *str = PYGLIB_PyUnicode_AsString(obj);
563
564         if (flag_type != G_TYPE_NONE)
565             fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
566         else {
567             PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
568             res = -1;
569         }
570         info = g_flags_get_value_by_name(fclass, str);
571         g_type_class_unref(fclass);
572
573         if (!info)
574             info = g_flags_get_value_by_nick(fclass, str);
575         if (info) {
576             *val = info->value;
577             res = 0;
578         } else {
579             PyErr_SetString(PyExc_TypeError, "could not convert string");
580             res = -1;
581         }
582     } else if (PyTuple_Check(obj)) {
583         int i, len;
584
585         len = PyTuple_Size(obj);
586         *val = 0;
587         res = 0;
588
589         if (flag_type != G_TYPE_NONE)
590             fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type));
591         else {
592             PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value");
593             res = -1;
594         }
595
596         for (i = 0; i < len; i++) {
597             PyObject *item = PyTuple_GetItem(obj, i);
598             char *str = PYGLIB_PyUnicode_AsString(item);
599             GFlagsValue *info = g_flags_get_value_by_name(fclass, str);
600
601             if (!info)
602                 info = g_flags_get_value_by_nick(fclass, str);
603             if (info) {
604                 *val |= info->value;
605             } else {
606                 PyErr_SetString(PyExc_TypeError, "could not convert string");
607                 res = -1;
608                 break;
609             }
610         }
611         g_type_class_unref(fclass);
612     } else {
613         PyErr_SetString(PyExc_TypeError,
614                         "flag values must be strings, ints, longs, or tuples");
615         res = -1;
616     }
617     return res;
618 }
619
620 static GQuark pyg_type_marshal_key = 0;
621
622 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         pygi_type_import_by_g_type (ptype);
631         if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
632             break;
633         ptype = g_type_parent(ptype);
634     }
635     return tm;
636 }
637
638 /**
639  * pyg_register_gtype_custom:
640  * @gtype: the GType for the new type
641  * @from_func: a function to convert GValues to Python objects
642  * @to_func: a function to convert Python objects to GValues
643  *
644  * In order to handle specific conversion of gboxed types or new
645  * fundamental types, you may use this function to register conversion
646  * handlers.
647  */
648
649 void
650 pyg_register_gtype_custom(GType gtype,
651                           fromvaluefunc from_func,
652                           tovaluefunc to_func)
653 {
654     PyGTypeMarshal *tm;
655
656     if (!pyg_type_marshal_key)
657         pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
658
659     tm = g_new(PyGTypeMarshal, 1);
660     tm->fromvalue = from_func;
661     tm->tovalue = to_func;
662     g_type_set_qdata(gtype, pyg_type_marshal_key, tm);
663 }
664
665 /* -------------- PyGClosure ----------------- */
666
667 static void
668 pyg_closure_invalidate(gpointer data, GClosure *closure)
669 {
670     PyGClosure *pc = (PyGClosure *)closure;
671     PyGILState_STATE state;
672
673     state = PyGILState_Ensure();
674     Py_XDECREF(pc->callback);
675     Py_XDECREF(pc->extra_args);
676     Py_XDECREF(pc->swap_data);
677     PyGILState_Release(state);
678
679     pc->callback = NULL;
680     pc->extra_args = NULL;
681     pc->swap_data = NULL;
682 }
683
684 static void
685 pyg_closure_marshal(GClosure *closure,
686                     GValue *return_value,
687                     guint n_param_values,
688                     const GValue *param_values,
689                     gpointer invocation_hint,
690                     gpointer marshal_data)
691 {
692     PyGILState_STATE state;
693     PyGClosure *pc = (PyGClosure *)closure;
694     PyObject *params, *ret;
695     guint i;
696
697     state = PyGILState_Ensure();
698
699     /* construct Python tuple for the parameter values */
700     params = PyTuple_New(n_param_values);
701     for (i = 0; i < n_param_values; i++) {
702         /* swap in a different initial data for connect_object() */
703         if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) {
704             g_return_if_fail(pc->swap_data != NULL);
705             Py_INCREF(pc->swap_data);
706             PyTuple_SetItem(params, 0, pc->swap_data);
707         } else {
708             PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
709
710             /* error condition */
711             if (!item) {
712             if (!PyErr_Occurred ())
713                 PyErr_SetString (PyExc_TypeError,
714                                  "can't convert parameter to desired type");
715
716             if (pc->exception_handler)
717                 pc->exception_handler (return_value, n_param_values, param_values);
718             else
719                 PyErr_Print();
720
721             goto out;
722             }
723             PyTuple_SetItem(params, i, item);
724         }
725     }
726     /* params passed to function may have extra arguments */
727     if (pc->extra_args) {
728         PyObject *tuple = params;
729         params = PySequence_Concat(tuple, pc->extra_args);
730         Py_DECREF(tuple);
731     }
732     ret = PyObject_CallObject(pc->callback, params);
733     if (ret == NULL) {
734         if (pc->exception_handler)
735             pc->exception_handler(return_value, n_param_values, param_values);
736         else
737             PyErr_Print();
738         goto out;
739     }
740
741     if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) {
742         /* If we already have an exception set, use that, otherwise set a
743          * generic one */
744         if (!PyErr_Occurred())
745             PyErr_SetString(PyExc_TypeError,
746                             "can't convert return value to desired type");
747
748         if (pc->exception_handler)
749             pc->exception_handler(return_value, n_param_values, param_values);
750         else
751             PyErr_Print();
752     }
753     Py_DECREF(ret);
754
755  out:
756     Py_DECREF(params);
757     PyGILState_Release(state);
758 }
759
760 /**
761  * pyg_closure_new:
762  * callback: a Python callable object
763  * extra_args: a tuple of extra arguments, or None/NULL.
764  * swap_data: an alternative python object to pass first.
765  *
766  * Creates a GClosure wrapping a Python callable and optionally a set
767  * of additional function arguments.  This is needed to attach python
768  * handlers to signals, for instance.
769  *
770  * Returns: the new closure.
771  */
772 GClosure *
773 pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data)
774 {
775     GClosure *closure;
776
777     g_return_val_if_fail(callback != NULL, NULL);
778     closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
779     g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate);
780     g_closure_set_marshal(closure, pyg_closure_marshal);
781     Py_INCREF(callback);
782     ((PyGClosure *)closure)->callback = callback;
783     if (extra_args && extra_args != Py_None) {
784         Py_INCREF(extra_args);
785         if (!PyTuple_Check(extra_args)) {
786             PyObject *tmp = PyTuple_New(1);
787             PyTuple_SetItem(tmp, 0, extra_args);
788             extra_args = tmp;
789         }
790         ((PyGClosure *)closure)->extra_args = extra_args;
791     }
792     if (swap_data) {
793         Py_INCREF(swap_data);
794         ((PyGClosure *)closure)->swap_data = swap_data;
795         closure->derivative_flag = TRUE;
796     }
797     return closure;
798 }
799
800 /**
801  * pyg_closure_set_exception_handler:
802  * @closure: a closure created with pyg_closure_new()
803  * @handler: the handler to call when an exception occurs or NULL for none
804  *
805  * Sets the handler to call when an exception occurs during closure invocation.
806  * The handler is responsible for providing a proper return value to the
807  * closure invocation. If @handler is %NULL, the default handler will be used.
808  * The default handler prints the exception to stderr and doesn't touch the
809  * closure's return value.
810  */
811 void
812 pyg_closure_set_exception_handler(GClosure *closure,
813                                   PyClosureExceptionHandler handler)
814 {
815     PyGClosure *pygclosure;
816
817     g_return_if_fail(closure != NULL);
818
819     pygclosure = (PyGClosure *)closure;
820     pygclosure->exception_handler = handler;
821 }
822 /* -------------- PySignalClassClosure ----------------- */
823 /* a closure used for the `class closure' of a signal.  As this gets
824  * all the info from the first argument to the closure and the
825  * invocation hint, we can have a single closure that handles all
826  * class closure cases.  We call a method by the name of the signal
827  * with "do_" prepended.
828  *
829  *  We also remove the first argument from the * param list, as it is
830  *  the instance object, which is passed * implicitly to the method
831  *  object. */
832
833 static void
834 pyg_signal_class_closure_marshal(GClosure *closure,
835                                  GValue *return_value,
836                                  guint n_param_values,
837                                  const GValue *param_values,
838                                  gpointer invocation_hint,
839                                  gpointer marshal_data)
840 {
841     PyGILState_STATE state;
842     GObject *object;
843     PyObject *object_wrapper;
844     GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint;
845     gchar *method_name, *tmp;
846     PyObject *method;
847     PyObject *params, *ret;
848     guint i, len;
849
850     state = PyGILState_Ensure();
851
852     g_return_if_fail(invocation_hint != NULL);
853     /* get the object passed as the first argument to the closure */
854     object = g_value_get_object(&param_values[0]);
855     g_return_if_fail(object != NULL && G_IS_OBJECT(object));
856
857     /* get the wrapper for this object */
858     object_wrapper = pygobject_new(object);
859     g_return_if_fail(object_wrapper != NULL);
860
861     /* construct method name for this class closure */
862     method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL);
863
864     /* convert dashes to underscores.  For some reason, g_signal_name
865      * seems to convert all the underscores in the signal name to
866        dashes??? */
867     for (tmp = method_name; *tmp != '\0'; tmp++)
868         if (*tmp == '-') *tmp = '_';
869
870     method = PyObject_GetAttrString(object_wrapper, method_name);
871     g_free(method_name);
872
873     if (!method) {
874         PyErr_Clear();
875         Py_DECREF(object_wrapper);
876         PyGILState_Release(state);
877         return;
878     }
879     Py_DECREF(object_wrapper);
880
881     /* construct Python tuple for the parameter values; don't copy boxed values
882        initially because we'll check after the call to see if a copy is needed. */
883     params = PyTuple_New(n_param_values - 1);
884     for (i = 1; i < n_param_values; i++) {
885         PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
886
887         /* error condition */
888         if (!item) {
889             Py_DECREF(params);
890             PyGILState_Release(state);
891             return;
892         }
893         PyTuple_SetItem(params, i - 1, item);
894     }
895
896     ret = PyObject_CallObject(method, params);
897
898     /* Copy boxed values if others ref them, this needs to be done regardless of
899        exception status. */
900     len = PyTuple_Size(params);
901     for (i = 0; i < len; i++) {
902         PyObject *item = PyTuple_GetItem(params, i);
903         if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type)
904             && item->ob_refcnt != 1) {
905             PyGBoxed* boxed_item = (PyGBoxed*)item;
906             if (!boxed_item->free_on_dealloc) {
907                 gpointer boxed_ptr = pyg_boxed_get_ptr (boxed_item);
908                 pyg_boxed_set_ptr (boxed_item, g_boxed_copy (boxed_item->gtype, boxed_ptr));
909                 boxed_item->free_on_dealloc = TRUE;
910             }
911         }
912     }
913
914     if (ret == NULL) {
915         PyErr_Print();
916         Py_DECREF(method);
917         Py_DECREF(params);
918         PyGILState_Release(state);
919         return;
920     }
921     Py_DECREF(method);
922     Py_DECREF(params);
923     if (G_IS_VALUE(return_value))
924         pyg_value_from_pyobject(return_value, ret);
925     Py_DECREF(ret);
926     PyGILState_Release(state);
927 }
928
929 /**
930  * pyg_signal_class_closure_get:
931  *
932  * Returns the GClosure used for the class closure of signals.  When
933  * called, it will invoke the method do_signalname (for the signal
934  * "signalname").
935  *
936  * Returns: the closure.
937  */
938 GClosure *
939 pyg_signal_class_closure_get(void)
940 {
941     static GClosure *closure;
942
943     if (closure == NULL) {
944         closure = g_closure_new_simple(sizeof(GClosure), NULL);
945         g_closure_set_marshal(closure, pyg_signal_class_closure_marshal);
946
947         g_closure_ref(closure);
948         g_closure_sink(closure);
949     }
950     return closure;
951 }
952
953 /* ----- __doc__ descriptor for GObject and GInterface ----- */
954
955 static void
956 object_doc_dealloc(PyObject *self)
957 {
958     PyObject_FREE(self);
959 }
960
961 /* append information about signals of a particular gtype */
962 static void
963 add_signal_docs(GType gtype, GString *string)
964 {
965     GTypeClass *class = NULL;
966     guint *signal_ids, n_ids = 0, i;
967
968     if (G_TYPE_IS_CLASSED(gtype))
969         class = g_type_class_ref(gtype);
970     signal_ids = g_signal_list_ids(gtype, &n_ids);
971
972     if (n_ids > 0) {
973         g_string_append_printf(string, "Signals from %s:\n",
974                                g_type_name(gtype));
975
976         for (i = 0; i < n_ids; i++) {
977             GSignalQuery query;
978             guint j;
979
980             g_signal_query(signal_ids[i], &query);
981
982             g_string_append(string, "  ");
983             g_string_append(string, query.signal_name);
984             g_string_append(string, " (");
985             for (j = 0; j < query.n_params; j++) {
986                 g_string_append(string, g_type_name(query.param_types[j]));
987                 if (j != query.n_params - 1)
988                     g_string_append(string, ", ");
989             }
990             g_string_append(string, ")");
991             if (query.return_type && query.return_type != G_TYPE_NONE) {
992                 g_string_append(string, " -> ");
993                 g_string_append(string, g_type_name(query.return_type));
994             }
995             g_string_append(string, "\n");
996         }
997         g_free(signal_ids);
998         g_string_append(string, "\n");
999     }
1000     if (class)
1001         g_type_class_unref(class);
1002 }
1003
1004 static void
1005 add_property_docs(GType gtype, GString *string)
1006 {
1007     GObjectClass *class;
1008     GParamSpec **props;
1009     guint n_props = 0, i;
1010     gboolean has_prop = FALSE;
1011     G_CONST_RETURN gchar *blurb=NULL;
1012
1013     class = g_type_class_ref(gtype);
1014     props = g_object_class_list_properties(class, &n_props);
1015
1016     for (i = 0; i < n_props; i++) {
1017         if (props[i]->owner_type != gtype)
1018             continue; /* these are from a parent type */
1019
1020         /* print out the heading first */
1021         if (!has_prop) {
1022             g_string_append_printf(string, "Properties from %s:\n",
1023                                    g_type_name(gtype));
1024             has_prop = TRUE;
1025         }
1026         g_string_append_printf(string, "  %s -> %s: %s\n",
1027                                g_param_spec_get_name(props[i]),
1028                                g_type_name(props[i]->value_type),
1029                                g_param_spec_get_nick(props[i]));
1030
1031         /* g_string_append_printf crashes on win32 if the third
1032            argument is NULL. */
1033         blurb=g_param_spec_get_blurb(props[i]);
1034         if (blurb)
1035             g_string_append_printf(string, "    %s\n",blurb);
1036     }
1037     g_free(props);
1038     if (has_prop)
1039         g_string_append(string, "\n");
1040     g_type_class_unref(class);
1041 }
1042
1043 static PyObject *
1044 object_doc_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1045 {
1046     GType gtype = 0;
1047     GString *string;
1048     PyObject *pystring;
1049
1050     if (obj && pygobject_check(obj, &PyGObject_Type)) {
1051         gtype = G_OBJECT_TYPE(pygobject_get(obj));
1052         if (!gtype)
1053             PyErr_SetString(PyExc_RuntimeError, "could not get object type");
1054     } else {
1055         gtype = pyg_type_from_object(type);
1056     }
1057     if (!gtype)
1058         return NULL;
1059
1060     string = g_string_new_len(NULL, 512);
1061
1062     if (g_type_is_a(gtype, G_TYPE_INTERFACE))
1063         g_string_append_printf(string, "Interface %s\n\n", g_type_name(gtype));
1064     else if (g_type_is_a(gtype, G_TYPE_OBJECT))
1065         g_string_append_printf(string, "Object %s\n\n", g_type_name(gtype));
1066     else
1067         g_string_append_printf(string, "%s\n\n", g_type_name(gtype));
1068
1069     if (((PyTypeObject *) type)->tp_doc)
1070         g_string_append_printf(string, "%s\n\n", ((PyTypeObject *) type)->tp_doc);
1071
1072     if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
1073         GType parent = G_TYPE_OBJECT;
1074         GArray *parents = g_array_new(FALSE, FALSE, sizeof(GType));
1075         int iparent;
1076
1077         while (parent) {
1078             g_array_append_val(parents, parent);
1079             parent = g_type_next_base(gtype, parent);
1080         }
1081
1082         for (iparent = parents->len - 1; iparent >= 0; --iparent) {
1083             GType *interfaces;
1084             guint n_interfaces, i;
1085
1086             parent = g_array_index(parents, GType, iparent);
1087             add_signal_docs(parent, string);
1088             add_property_docs(parent, string);
1089
1090             /* add docs for implemented interfaces */
1091             interfaces = g_type_interfaces(parent, &n_interfaces);
1092             for (i = 0; i < n_interfaces; i++)
1093                 add_signal_docs(interfaces[i], string);
1094             g_free(interfaces);
1095         }
1096         g_array_free(parents, TRUE);
1097     }
1098
1099     pystring = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len);
1100     g_string_free(string, TRUE);
1101     return pystring;
1102 }
1103
1104 PYGLIB_DEFINE_TYPE("gobject.GObject.__doc__", PyGObjectDoc_Type, PyObject);
1105
1106 /**
1107  * pyg_object_descr_doc_get:
1108  *
1109  * Returns an object intended to be the __doc__ attribute of GObject
1110  * wrappers.  When read in the context of the object it will return
1111  * some documentation about the signals and properties of the object.
1112  *
1113  * Returns: the descriptor.
1114  */
1115 PyObject *
1116 pyg_object_descr_doc_get(void)
1117 {
1118     static PyObject *doc_descr = NULL;
1119
1120     if (!doc_descr) {
1121         Py_TYPE(&PyGObjectDoc_Type) = &PyType_Type;
1122         if (PyType_Ready(&PyGObjectDoc_Type))
1123             return NULL;
1124
1125         doc_descr = PyObject_NEW(PyObject, &PyGObjectDoc_Type);
1126         if (doc_descr == NULL)
1127             return NULL;
1128     }
1129     return doc_descr;
1130 }
1131
1132
1133 /**
1134  * pyg_pyobj_to_unichar_conv:
1135  *
1136  * Converts PyObject value to a unichar and write result to memory
1137  * pointed to by ptr.  Follows the calling convention of a ParseArgs
1138  * converter (O& format specifier) so it may be used to convert function
1139  * arguments.
1140  *
1141  * Returns: 1 if the conversion succeeds and 0 otherwise.  If the conversion
1142  *          did not succeesd, a Python exception is raised
1143  */
1144 int pyg_pyobj_to_unichar_conv(PyObject* py_obj, void* ptr)
1145 {
1146     gunichar* u = ptr;
1147     const Py_UNICODE* uni_buffer;
1148     PyObject* tmp_uni = NULL;
1149
1150     if (PyUnicode_Check(py_obj)) {
1151         tmp_uni = py_obj;
1152         Py_INCREF(tmp_uni);
1153     }
1154     else {
1155         tmp_uni = PyUnicode_FromObject(py_obj);
1156         if (tmp_uni == NULL)
1157             goto failure;
1158     }
1159
1160     if ( PyUnicode_GetSize(tmp_uni) != 1) {
1161         PyErr_SetString(PyExc_ValueError, "unicode character value must be 1 character uniode string");
1162         goto failure;
1163     }
1164     uni_buffer = PyUnicode_AsUnicode(tmp_uni);
1165     if ( uni_buffer == NULL)
1166         goto failure;
1167     *u = uni_buffer[0];
1168
1169     Py_DECREF(tmp_uni);
1170     return 1;
1171
1172   failure:
1173     Py_XDECREF(tmp_uni);
1174     return 0;
1175 }
1176
1177 gboolean
1178 pyg_gtype_is_custom(GType gtype)
1179 {
1180     return g_type_get_qdata (gtype, pygobject_custom_key) != NULL;
1181 }
1182
1183 void
1184 pygobject_type_register_types(PyObject *d)
1185 {
1186     PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc;
1187     PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare;
1188     PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr;
1189     PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash;
1190     PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1191     PyGTypeWrapper_Type.tp_methods = _PyGTypeWrapper_methods;
1192     PyGTypeWrapper_Type.tp_getset = _PyGTypeWrapper_getsets;
1193     PyGTypeWrapper_Type.tp_init = (initproc)pyg_type_wrapper_init;
1194     PYGLIB_REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType");
1195
1196     /* This type lazily registered in pyg_object_descr_doc_get */
1197     PyGObjectDoc_Type.tp_dealloc = (destructor)object_doc_dealloc;
1198     PyGObjectDoc_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1199     PyGObjectDoc_Type.tp_descr_get = (descrgetfunc)object_doc_descr_get;
1200
1201     pyg_register_gtype_custom(G_TYPE_STRV,
1202                               pyg_strv_from_gvalue,
1203                               pyg_strv_to_gvalue);
1204 }