00444bdf723378abe863a0f99393dd45dc229c14
[platform/upstream/pygobject2.git] / gi / _gobject / pygobject.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  *   pygobject.c: wrapper for the GObject type.
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 #include "pygobject-private.h"
29 #include "pyginterface.h"
30 #include "pygparamspec.h"
31
32 #include "pygi.h"
33
34
35 static void pygobject_dealloc(PyGObject *self);
36 static int  pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
37 static int  pygobject_clear(PyGObject *self);
38 static PyObject * pyg_type_get_bases(GType gtype);
39 static inline int pygobject_clear(PyGObject *self);
40 static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
41 static PyObject * pygbinding_weak_ref_new(GObject *obj);
42 static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
43 static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases,
44                                     gboolean check_for_present);
45 static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
46                                     gboolean check_for_present);
47 GType PY_TYPE_OBJECT = 0;
48 GQuark pygobject_class_key;
49 GQuark pygobject_class_init_key;
50 GQuark pygobject_wrapper_key;
51 GQuark pygobject_has_updated_constructor_key;
52 GQuark pygobject_instance_data_key;
53
54 /* Copied from glib. gobject uses hyphens in property names, but in Python
55  * we can only represent hyphens as underscores. Convert underscores to
56  * hyphens for glib compatibility. */
57 static void
58 canonicalize_key (gchar *key)
59 {
60     gchar *p;
61
62     for (p = key; *p != 0; p++)
63     {
64         gchar c = *p;
65
66         if (c != '-' &&
67             (c < '0' || c > '9') &&
68             (c < 'A' || c > 'Z') &&
69             (c < 'a' || c > 'z'))
70                 *p = '-';
71     }
72 }
73
74 /* -------------- class <-> wrapper manipulation --------------- */
75
76 void
77 pygobject_data_free(PyGObjectData *data)
78 {
79     /* This function may be called after the python interpreter has already
80      * been shut down. If this happens, we cannot do any python calls, so just
81      * free the memory. */
82     PyGILState_STATE state;
83     PyThreadState *_save = NULL;
84
85     GSList *closures, *tmp;
86
87     if (Py_IsInitialized()) {
88         state = pyglib_gil_state_ensure();
89         Py_DECREF(data->type);
90         /* We cannot use pyg_begin_allow_threads here because this is inside
91          * a branch. */
92         if (pyg_threads_enabled)
93             _save = PyEval_SaveThread();
94     }
95
96     tmp = closures = data->closures;
97 #ifndef NDEBUG
98     data->closures = NULL;
99     data->type = NULL;
100 #endif
101     while (tmp) {
102         GClosure *closure = tmp->data;
103  
104           /* we get next item first, because the current link gets
105            * invalidated by pygobject_unwatch_closure */
106         tmp = tmp->next;
107         g_closure_invalidate(closure);
108     }
109  
110     if (data->closures != NULL)
111         g_warning("invalidated all closures, but data->closures != NULL !");
112
113     g_free(data);
114
115     if (Py_IsInitialized()) {
116         if (pyg_threads_enabled)
117             PyEval_RestoreThread(_save);
118         pyglib_gil_state_release(state);
119     }
120 }
121
122 static inline PyGObjectData *
123 pygobject_data_new(void)
124 {
125     PyGObjectData *data;
126     data = g_new0(PyGObjectData, 1);
127     return data;
128 }
129
130 static inline PyGObjectData *
131 pygobject_get_inst_data(PyGObject *self)
132 {
133     PyGObjectData *inst_data;
134
135     if (G_UNLIKELY(!self->obj))
136         return NULL;
137     inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key);
138     if (inst_data == NULL)
139     {
140         inst_data = pygobject_data_new();
141
142         inst_data->type = Py_TYPE(self);
143         Py_INCREF((PyObject *) inst_data->type);
144
145         g_object_set_qdata_full(self->obj, pygobject_instance_data_key,
146                                 inst_data, (GDestroyNotify) pygobject_data_free);
147     }
148     return inst_data;
149 }
150
151
152 GHashTable *custom_type_registration = NULL;
153
154 PyTypeObject *PyGObject_MetaType = NULL;
155
156 /**
157  * pygobject_sink:
158  * @obj: a GObject
159  * 
160  * As Python handles reference counting for us, the "floating
161  * reference" code in GTK is not all that useful.  In fact, it can
162  * cause leaks.  This function should be called to remove the floating
163  * references on objects on construction.
164  **/
165 void
166 pygobject_sink(GObject *obj)
167 {
168     /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink().
169      * - if the object is new and owned by someone else, its ref has been sunk and
170      *   we need to keep the one from that someone and add our own "fresh ref"
171      * - if the object is not and owned by nobody, its ref is floating and we need
172      *   to transform it into a regular ref.
173      */
174     if (G_IS_INITIALLY_UNOWNED(obj)) {
175         g_object_ref_sink(obj);
176     }
177 }
178
179 typedef struct {
180     PyObject_HEAD
181     GParamSpec **props;
182     guint n_props;
183     guint index;
184 } PyGPropsIter;
185
186 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter);
187
188 static void
189 pyg_props_iter_dealloc(PyGPropsIter *self)
190 {
191     g_free(self->props);
192     PyObject_Del((PyObject*) self);
193 }
194
195 static PyObject*
196 pygobject_props_iter_next(PyGPropsIter *iter)
197 {
198     if (iter->index < iter->n_props)
199         return pyg_param_spec_new(iter->props[iter->index++]);
200     else {
201         PyErr_SetNone(PyExc_StopIteration);
202         return NULL;
203     }
204 }
205
206 typedef struct {
207     PyObject_HEAD
208     /* a reference to the object containing the properties */
209     PyGObject *pygobject;
210     GType      gtype;
211 } PyGProps;
212
213 static void
214 PyGProps_dealloc(PyGProps* self)
215 {
216     PyGObject *tmp;
217
218     PyObject_GC_UnTrack((PyObject*)self);
219
220     tmp = self->pygobject;
221     self->pygobject = NULL;
222     Py_XDECREF(tmp);
223
224     PyObject_GC_Del((PyObject*)self);
225 }
226
227 static PyObject*
228 build_parameter_list(GObjectClass *class)
229 {
230     GParamSpec **props;
231     guint n_props = 0, i;
232     PyObject *prop_str;
233     PyObject *props_list;
234
235     props = g_object_class_list_properties(class, &n_props);
236     props_list = PyList_New(n_props);
237     for (i = 0; i < n_props; i++) {
238         char *name;
239         name = g_strdup(g_param_spec_get_name(props[i]));
240         /* hyphens cannot belong in identifiers */
241         g_strdelimit(name, "-", '_');
242         prop_str = PYGLIB_PyUnicode_FromString(name);
243         
244         PyList_SetItem(props_list, i, prop_str);
245         g_free(name);
246     }
247
248     g_type_class_unref(class);
249
250     if (props)
251         g_free(props);
252     
253     return props_list;
254 }
255
256 static PyObject*
257 PyGProps_getattro(PyGProps *self, PyObject *attr)
258 {
259     char *attr_name, *property_name;
260     GObjectClass *class;
261     GParamSpec *pspec;
262     GValue value = { 0, };
263     PyObject *ret;
264
265     attr_name = PYGLIB_PyUnicode_AsString(attr);
266     if (!attr_name) {
267         PyErr_Clear();
268         return PyObject_GenericGetAttr((PyObject *)self, attr);
269     }
270
271     class = g_type_class_ref(self->gtype);
272     
273     if (!strcmp(attr_name, "__members__")) {
274         ret = build_parameter_list(class);
275         g_type_class_unref(class);
276         return ret;
277     }
278
279     /* g_object_class_find_property recurses through the class hierarchy,
280      * so the resulting pspec tells us the owner_type that owns the property
281      * we're dealing with. */
282     property_name = g_strdup(attr_name);
283     canonicalize_key(property_name);
284     pspec = g_object_class_find_property(class, property_name);
285     g_free(property_name);
286     g_type_class_unref(class);
287
288     if (!pspec) {
289         return PyObject_GenericGetAttr((PyObject *)self, attr);
290     }
291
292     if (!(pspec->flags & G_PARAM_READABLE)) {
293         PyErr_Format(PyExc_TypeError,
294                      "property '%s' is not readable", attr_name);
295         return NULL;
296     }
297
298     if (!self->pygobject) {
299         /* If we're doing it without an instance, return a GParamSpec */
300         return pyg_param_spec_new(pspec);
301     }
302
303     /* See if the property's class is from the gi repository. If so,
304      * use gi to correctly read the property value. */
305     ret = pygi_get_property_value (self->pygobject, pspec);
306     if (ret != NULL) {
307         return ret;
308     }
309     
310     /* If we reach here, it must be a property defined outside of gi.
311      * Just do a straightforward read. */
312     g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
313     pyg_begin_allow_threads;
314     g_object_get_property(self->pygobject->obj, pspec->name, &value);
315     pyg_end_allow_threads;
316     ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
317     g_value_unset(&value);
318     
319     return ret;
320 }
321
322 static gboolean
323 set_property_from_pspec(GObject *obj,
324                         GParamSpec *pspec,
325                         PyObject *pvalue)
326 {
327     GValue value = { 0, };
328
329     if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
330         PyErr_Format(PyExc_TypeError,
331                      "property '%s' can only be set in constructor",
332                      pspec->name);
333         return FALSE;
334     }   
335
336     if (!(pspec->flags & G_PARAM_WRITABLE)) {
337         PyErr_Format(PyExc_TypeError,
338                      "property '%s' is not writable", pspec->name);
339         return FALSE;
340     }   
341
342     g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
343     if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
344         PyErr_SetString(PyExc_TypeError,
345                         "could not convert argument to correct param type");
346         return FALSE;
347     }
348
349     pyg_begin_allow_threads;
350     g_object_set_property(obj, pspec->name, &value);
351     pyg_end_allow_threads;
352
353     g_value_unset(&value);
354     
355     return TRUE;
356 }
357
358 PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps);
359
360 static int
361 PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue)
362 {
363     GParamSpec *pspec;
364     char *attr_name, *property_name;
365     GObject *obj;
366     int ret = -1;
367     
368     if (pvalue == NULL) {
369         PyErr_SetString(PyExc_TypeError, "properties cannot be "
370                         "deleted");
371         return -1;
372     }
373
374     attr_name = PYGLIB_PyUnicode_AsString(attr);
375     if (!attr_name) {
376         PyErr_Clear();
377         return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
378     }
379
380     if (!self->pygobject) {
381         PyErr_SetString(PyExc_TypeError,
382                         "cannot set GOject properties without an instance");
383         return -1;
384     }
385
386     obj = self->pygobject->obj;
387
388     property_name = g_strdup(attr_name);
389     canonicalize_key(property_name);
390
391     /* g_object_class_find_property recurses through the class hierarchy,
392      * so the resulting pspec tells us the owner_type that owns the property
393      * we're dealing with. */
394     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj),
395                                          property_name);
396     g_free(property_name);
397     if (!pspec) {
398         return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue);
399     }
400
401     /* See if the property's class is from the gi repository. If so,
402      * use gi to correctly read the property value. */
403     ret = pygi_set_property_value (self->pygobject, pspec, pvalue);
404     if (ret == 0)
405         return 0;
406     else if (ret == -1)
407         if (PyErr_Occurred())
408             return -1;
409
410     /* If we reach here, it must be a property defined outside of gi.
411      * Just do a straightforward set. */
412     if (!set_property_from_pspec(obj, pspec, pvalue))
413         return -1;
414                                   
415     return 0;
416 }
417
418 static int
419 pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
420 {
421     if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
422         return -1;
423     return 0;
424 }
425
426 static PyObject*
427 pygobject_props_get_iter(PyGProps *self)
428 {
429     PyGPropsIter *iter;
430     GObjectClass *class;
431
432     iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type);
433     class = g_type_class_ref(self->gtype);
434     iter->props = g_object_class_list_properties(class, &iter->n_props);
435     iter->index = 0;
436     g_type_class_unref(class);
437     return (PyObject *) iter;
438 }
439
440 static Py_ssize_t
441 PyGProps_length(PyGProps *self)
442 {
443     GObjectClass *class;
444     GParamSpec **props;
445     guint n_props;
446     
447     class = g_type_class_ref(self->gtype);
448     props = g_object_class_list_properties(class, &n_props);
449     g_type_class_unref(class);
450     g_free(props);
451
452     return (Py_ssize_t)n_props;
453 }
454
455 static PySequenceMethods _PyGProps_as_sequence = {
456     (lenfunc) PyGProps_length,
457     0,
458     0,
459     0,
460     0,
461     0,
462     0
463 };
464
465 PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject);
466
467 static PyObject *
468 pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
469 {
470     PyGProps *gprops;
471
472     gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
473     if (obj == NULL || obj == Py_None) {
474         gprops->pygobject = NULL;
475         gprops->gtype = pyg_type_from_object(type);
476     } else {
477         if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
478             PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
479                             " descriptor on non-GObject instances");
480             return NULL;
481         }
482         Py_INCREF(obj);
483         gprops->pygobject = (PyGObject *) obj;
484         gprops->gtype = pyg_type_from_object(obj);
485     }
486     return (PyObject *) gprops;
487 }
488
489 /**
490  * pygobject_register_class:
491  * @dict: the module dictionary.  A reference to the type will be stored here.
492  * @type_name: not used ?
493  * @gtype: the GType of the GObject subclass.
494  * @type: the Python type object for this wrapper.
495  * @static_bases: a tuple of Python type objects that are the bases of
496  * this type
497  *
498  * This function is used to register a Python type as the wrapper for
499  * a particular GObject subclass.  It will also insert a reference to
500  * the wrapper class into the module dictionary passed as a reference,
501  * which simplifies initialisation.
502  */
503 void
504 pygobject_register_class(PyObject *dict, const gchar *type_name,
505                          GType gtype, PyTypeObject *type,
506                          PyObject *static_bases)
507 {
508     PyObject *o;
509     const char *class_name, *s;
510     PyObject *runtime_bases;
511     PyObject *bases_list, *bases, *mod_name;
512     int i;
513     
514     class_name = type->tp_name;
515     s = strrchr(class_name, '.');
516     if (s != NULL)
517         class_name = s + 1;
518
519     runtime_bases = pyg_type_get_bases(gtype);
520     if (static_bases) {
521         PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0);
522         bases_list = PySequence_List(static_bases);
523           /* we start at index 1 because we want to skip the primary
524            * base, otherwise we might get MRO conflict */
525         for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i)
526         {
527             PyObject *base = PyTuple_GET_ITEM(runtime_bases, i);
528             int contains = PySequence_Contains(bases_list, base);
529             if (contains < 0)
530                 PyErr_Print();
531             else if (!contains) {
532                 if (!PySequence_Contains(py_parent_type->tp_mro, base)) {
533 #if 0
534                     g_message("Adding missing base %s to type %s",
535                               ((PyTypeObject *)base)->tp_name, type->tp_name);
536 #endif
537                     PyList_Append(bases_list, base);
538                 }
539             }
540         }
541         bases = PySequence_Tuple(bases_list);
542         Py_DECREF(bases_list);
543         Py_DECREF(runtime_bases);
544     } else
545         bases = runtime_bases;
546
547     Py_TYPE(type) = PyGObject_MetaType;
548     type->tp_bases = bases;
549     if (G_LIKELY(bases)) {
550         type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
551         Py_INCREF(type->tp_base);
552     }
553
554     pygobject_inherit_slots(type, bases, TRUE);
555
556     if (PyType_Ready(type) < 0) {
557         g_warning ("couldn't make the type `%s' ready", type->tp_name);
558         return;
559     }
560
561     /* Set type.__module__ to the name of the module,
562      * otherwise it'll default to 'gobject', see #376099
563      */
564     s = strrchr(type->tp_name, '.');
565     if (s != NULL) {
566         mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name));
567         PyDict_SetItemString(type->tp_dict, "__module__", mod_name);
568         Py_DECREF(mod_name);
569     }
570     
571     if (gtype) {
572         o = pyg_type_wrapper_new(gtype);
573         PyDict_SetItemString(type->tp_dict, "__gtype__", o);
574         Py_DECREF(o);
575
576         /* stash a pointer to the python class with the GType */
577         Py_INCREF(type);
578         g_type_set_qdata(gtype, pygobject_class_key, type);
579     }
580
581     /* set up __doc__ descriptor on type */
582     PyDict_SetItemString(type->tp_dict, "__doc__",
583                          pyg_object_descr_doc_get());
584
585     PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
586 }
587
588 static void
589 pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
590 {
591     PyGObject *self = (PyGObject*) data;
592     PyGILState_STATE state;
593
594     state = pyglib_gil_state_ensure();
595
596     if (is_last_ref)
597         Py_DECREF(self);
598     else
599         Py_INCREF(self);
600
601     pyglib_gil_state_release(state);
602 }
603
604   /* Called when the inst_dict is first created; switches the 
605      reference counting strategy to start using toggle ref to keep the
606      wrapper alive while the GObject lives.  In contrast, while
607      inst_dict was NULL the python wrapper is allowed to die at
608      will and is recreated on demand. */
609 static inline void
610 pygobject_switch_to_toggle_ref(PyGObject *self)
611 {
612     g_assert(self->obj->ref_count >= 1);
613
614     if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF)
615         return; /* already using toggle ref */
616     self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF;
617       /* Note that add_toggle_ref will never immediately call back into 
618          pyg_toggle_notify */
619     Py_INCREF((PyObject *) self);
620     g_object_add_toggle_ref(self->obj, pyg_toggle_notify, self);
621     g_object_unref(self->obj);
622 }
623
624 /* Called when an custom gobject is initalized via g_object_new instead of
625    its constructor.  The next time the wrapper is access via 
626    pygobject_new_full it will sink the floating reference instead of
627    adding a new reference and causing a leak */
628  
629 void
630 pygobject_ref_float(PyGObject *self)
631 {
632     /* should only be floated once */
633     g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
634     
635     self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
636 }
637
638 /* Called by gobject_new_full, if the floating flag is set remove it, otherwise
639    ref the pyobject */
640 void
641 pygobject_ref_sink(PyGObject *self)
642 {
643     if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
644         self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
645     else
646         Py_INCREF ( (PyObject *) self);
647 }
648
649 /**
650  * pygobject_register_wrapper:
651  * @self: the wrapper instance
652  *
653  * In the constructor of PyGTK wrappers, this function should be
654  * called after setting the obj member.  It will tie the wrapper
655  * instance to the GObject so that the same wrapper instance will
656  * always be used for this GObject instance.
657  */
658 void
659 pygobject_register_wrapper(PyObject *self)
660 {
661     PyGObject *gself;
662
663     g_return_if_fail(self != NULL);
664     g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
665
666     gself = (PyGObject *)self;
667
668     g_assert(gself->obj->ref_count >= 1);
669       /* save wrapper pointer so we can access it later */
670     g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL);
671     if (gself->inst_dict)
672         pygobject_switch_to_toggle_ref(gself);
673 }
674
675 static PyObject *
676 pyg_type_get_bases(GType gtype)
677 {
678     GType *interfaces, parent_type, interface_type;
679     guint n_interfaces;
680     PyTypeObject *py_parent_type, *py_interface_type;
681     PyObject *bases;
682     int i;
683     
684     if (G_UNLIKELY(gtype == G_TYPE_OBJECT))
685         return NULL;
686
687     /* Lookup the parent type */
688     parent_type = g_type_parent(gtype);
689     py_parent_type = pygobject_lookup_class(parent_type);
690     interfaces = g_type_interfaces(gtype, &n_interfaces);
691     bases = PyTuple_New(n_interfaces + 1);
692     /* We will always put the parent at the first position in bases */
693     Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */
694     PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type);
695
696     /* And traverse interfaces */
697     if (n_interfaces) {
698         for (i = 0; i < n_interfaces; i++) {
699             interface_type = interfaces[i];
700             py_interface_type = pygobject_lookup_class(interface_type);
701             Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */
702             PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type);
703         }
704     }
705     g_free(interfaces);
706     return bases;
707 }
708
709 /**
710  * pygobject_new_with_interfaces
711  * @gtype: the GType of the GObject subclass.
712  *
713  * Creates a new PyTypeObject from the given GType with interfaces attached in
714  * bases.
715  *
716  * Returns: a PyTypeObject for the new type or NULL if it couldn't be created
717  */
718 static PyTypeObject *
719 pygobject_new_with_interfaces(GType gtype)
720 {
721     PyGILState_STATE state;
722     PyObject *o;
723     PyTypeObject *type;
724     PyObject *dict;
725     PyTypeObject *py_parent_type;
726     PyObject *bases;
727     PyObject *modules, *module;
728     gchar *type_name, *mod_name, *gtype_name;
729
730     state = pyglib_gil_state_ensure();
731
732     bases = pyg_type_get_bases(gtype);
733     py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0);
734
735     dict = PyDict_New();
736     
737     o = pyg_type_wrapper_new(gtype);
738     PyDict_SetItemString(dict, "__gtype__", o);
739     Py_DECREF(o);
740
741     /* set up __doc__ descriptor on type */
742     PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get());
743
744     /* generate the pygtk module name and extract the base type name */
745     gtype_name = (gchar*)g_type_name(gtype);
746     if (g_str_has_prefix(gtype_name, "Gtk")) {
747         mod_name = "gtk";
748         gtype_name += 3;
749         type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
750     } else if (g_str_has_prefix(gtype_name, "Gdk")) {
751         mod_name = "gtk.gdk";
752         gtype_name += 3;
753         type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
754     } else if (g_str_has_prefix(gtype_name, "Atk")) {
755         mod_name = "atk";
756         gtype_name += 3;
757         type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
758     } else if (g_str_has_prefix(gtype_name, "Pango")) {
759         mod_name = "pango";
760         gtype_name += 5;
761         type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
762     } else {
763         mod_name = "__main__";
764         type_name = g_strconcat(mod_name, ".", gtype_name, NULL);
765     }
766
767     type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type),
768                                                 "sNN", type_name, bases, dict);
769     g_free(type_name);
770
771     if (type == NULL) {
772         PyErr_Print();
773         pyglib_gil_state_release(state);
774         return NULL;
775     }
776
777       /* Workaround python tp_(get|set)attr slot inheritance bug.
778        * Fixes bug #144135. */
779     if (!type->tp_getattr && py_parent_type->tp_getattr) {
780         type->tp_getattro = NULL;
781         type->tp_getattr = py_parent_type->tp_getattr;
782     }
783     if (!type->tp_setattr && py_parent_type->tp_setattr) {
784         type->tp_setattro = NULL;
785         type->tp_setattr = py_parent_type->tp_setattr;
786     }
787       /* override more python stupid hacks behind our back */
788     type->tp_dealloc = py_parent_type->tp_dealloc;
789     type->tp_alloc = py_parent_type->tp_alloc;
790     type->tp_free = py_parent_type->tp_free;
791     type->tp_traverse = py_parent_type->tp_traverse;
792     type->tp_clear = py_parent_type->tp_clear;
793
794     pygobject_inherit_slots(type, bases, FALSE);
795
796     if (PyType_Ready(type) < 0) {
797         g_warning ("couldn't make the type `%s' ready", type->tp_name);
798         pyglib_gil_state_release(state);
799         return NULL;
800     }
801     /* insert type name in module dict */
802     modules = PyImport_GetModuleDict();
803     if ((module = PyDict_GetItemString(modules, mod_name)) != NULL) {
804         if (PyObject_SetAttrString(module, gtype_name, (PyObject *)type) < 0)
805             PyErr_Clear();
806     }
807
808     /* stash a pointer to the python class with the GType */
809     Py_INCREF(type);
810     g_type_set_qdata(gtype, pygobject_class_key, type);
811
812     pyglib_gil_state_release(state);
813
814     return type;
815 }
816
817 /* Pick appropriate value for given slot (at slot_offset inside
818  * PyTypeObject structure).  It must be a pointer, e.g. a pointer to a
819  * function.  We use the following heuristic:
820  *
821  * - Scan all types listed as bases of the type.
822  * - If for exactly one base type slot value is non-NULL and
823  *   different from that of 'object' and 'GObject', set current type
824  *   slot into that value.
825  * - Otherwise (if there is more than one such base type or none at
826  *   all) don't touch it and live with Python default.
827  *
828  * The intention here is to propagate slot from custom wrappers to
829  * wrappers created at runtime when appropriate.  We prefer to be on
830  * the safe side, so if there is potential collision (more than one
831  * custom slot value), we discard custom overrides altogether.
832  *
833  * When registering type with pygobject_register_class(), i.e. a type
834  * that has been manually created (likely with Codegen help),
835  * `check_for_present' should be set to TRUE.  In this case, the
836  * function will never overwrite any non-NULL slots already present in
837  * the type.  If `check_for_present' is FALSE, such non-NULL slots are
838  * though to be set by Python interpreter and so will be overwritten
839  * if heuristic above says so.
840  */
841 static void
842 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
843 {
844     static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
845 #if PY_VERSION_HEX < 0x03000000
846                                   offsetof(PyTypeObject, tp_compare),
847 #endif
848                                   offsetof(PyTypeObject, tp_richcompare),
849                                   offsetof(PyTypeObject, tp_hash),
850                                   offsetof(PyTypeObject, tp_iter),
851                                   offsetof(PyTypeObject, tp_repr),
852                                   offsetof(PyTypeObject, tp_str),
853                                   offsetof(PyTypeObject, tp_print) };
854     int i;
855
856     /* Happens when registering gobject.GObject itself, at least. */
857     if (!bases)
858         return;
859
860     for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i)
861         pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present);
862 }
863
864 static void
865 pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
866                         gboolean check_for_present)
867 {
868 #define TYPE_SLOT(type)  (* (void **) (((char *) (type)) + slot_offset))
869
870     void *found_slot = NULL;
871     int num_bases = PyTuple_Size(bases);
872     int i;
873
874     if (check_for_present && TYPE_SLOT(type) != NULL) {
875         /* We are requested to check if there is any custom slot value
876          * in this type already and there actually is.  Don't
877          * overwrite it.
878          */
879         return;
880     }
881
882     for (i = 0; i < num_bases; ++i) {
883         PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
884         void *slot = TYPE_SLOT(base_type);
885
886         if (slot == NULL)
887             continue;
888         if (slot == TYPE_SLOT(&PyGObject_Type) ||
889             slot == TYPE_SLOT(&PyBaseObject_Type))
890             continue;
891
892         if (found_slot != NULL && found_slot != slot) {
893             /* We have a conflict: more than one base use different
894              * custom slots.  To be on the safe side, we bail out.
895              */
896             return;
897         }
898
899         found_slot = slot;
900     }
901
902     /* Only perform the final assignment if at least one base has a
903      * custom value.  Otherwise just leave this type's slot untouched.
904      */
905     if (found_slot != NULL)
906         TYPE_SLOT(type) = found_slot;
907
908 #undef TYPE_SLOT
909 }
910
911 /**
912  * pygobject_lookup_class:
913  * @gtype: the GType of the GObject subclass.
914  *
915  * This function looks up the wrapper class used to represent
916  * instances of a GObject represented by @gtype.  If no wrapper class
917  * or interface has been registered for the given GType, then a new
918  * type will be created.
919  *
920  * Returns: The wrapper class for the GObject or NULL if the
921  *          GType has no registered type and a new type couldn't be created
922  */
923 PyTypeObject *
924 pygobject_lookup_class(GType gtype)
925 {
926     PyTypeObject *py_type;
927
928     if (gtype == G_TYPE_INTERFACE)
929         return &PyGInterface_Type;
930     
931     py_type = pyg_type_get_custom(g_type_name(gtype));
932     if (py_type)
933         return py_type;
934
935     py_type = g_type_get_qdata(gtype, pygobject_class_key);
936     if (py_type == NULL) {
937         py_type = g_type_get_qdata(gtype, pyginterface_type_key);
938
939     if (py_type == NULL)
940         py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype);
941
942         if (py_type == NULL) {
943             py_type = pygobject_new_with_interfaces(gtype);
944             g_type_set_qdata(gtype, pyginterface_type_key, py_type);
945         }
946     }
947     
948     return py_type;
949 }
950
951 /**
952  * pygobject_new_full:
953  * @obj: a GObject instance.
954  * @sink: whether to sink any floating reference found on the GObject. DEPRECATED.
955  * @g_class: the GObjectClass
956  *
957  * This function gets a reference to a wrapper for the given GObject
958  * instance.  If a wrapper has already been created, a new reference
959  * to that wrapper will be returned.  Otherwise, a wrapper instance
960  * will be created.
961  *
962  * Returns: a reference to the wrapper for the GObject.
963  */
964 PyObject *
965 pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
966 {
967     PyGObject *self;
968
969     if (obj == NULL) {
970         Py_INCREF(Py_None);
971         return Py_None;
972     }
973
974     /* we already have a wrapper for this object -- return it. */
975     self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
976     if (self != NULL) {
977         pygobject_ref_sink(self);
978     } else {
979         /* create wrapper */
980         PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
981         PyTypeObject *tp;
982         if (inst_data)
983             tp = inst_data->type;
984         else {
985             if (g_class)
986                 tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class));
987             else
988                 tp = pygobject_lookup_class(G_OBJECT_TYPE(obj));
989         }
990         g_assert(tp != NULL);
991         
992         /* need to bump type refcount if created with
993            pygobject_new_with_interfaces(). fixes bug #141042 */
994         if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
995             Py_INCREF(tp);
996         self = PyObject_GC_New(PyGObject, tp);
997         if (self == NULL)
998             return NULL;
999         self->inst_dict = NULL;
1000         self->weakreflist = NULL;
1001         self->private_flags.flags = 0;
1002         self->obj = obj;
1003         /* if we are creating a wrapper around a newly created object, it can have
1004            a floating ref (e.g. for methods like Gtk.Button.new()). Bug 640868 */
1005         g_object_ref_sink(obj);
1006         pygobject_register_wrapper((PyObject *)self);
1007         PyObject_GC_Track((PyObject *)self);
1008     }
1009
1010     return (PyObject *)self;
1011 }
1012
1013
1014 PyObject *
1015 pygobject_new(GObject *obj)
1016 {
1017     return pygobject_new_full(obj, TRUE, NULL);
1018 }
1019
1020 static void
1021 pygobject_unwatch_closure(gpointer data, GClosure *closure)
1022 {
1023     PyGObjectData *inst_data = data;
1024
1025     inst_data->closures = g_slist_remove (inst_data->closures, closure);
1026 }
1027
1028 /**
1029  * pygobject_watch_closure:
1030  * @self: a GObject wrapper instance
1031  * @closure: a GClosure to watch
1032  *
1033  * Adds a closure to the list of watched closures for the wrapper.
1034  * The closure must be one returned by pyg_closure_new().  When the
1035  * cycle GC traverses the wrapper instance, it will enumerate the
1036  * references to Python objects stored in watched closures.  If the
1037  * cycle GC tells the wrapper to clear itself, the watched closures
1038  * will be invalidated.
1039  */
1040 void
1041 pygobject_watch_closure(PyObject *self, GClosure *closure)
1042 {
1043     PyGObject *gself;
1044     PyGObjectData *data;
1045
1046     g_return_if_fail(self != NULL);
1047     g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type));
1048     g_return_if_fail(closure != NULL);
1049
1050     gself = (PyGObject *)self;
1051     data = pygobject_get_inst_data(gself);
1052     g_return_if_fail(g_slist_find(data->closures, closure) == NULL);
1053     data->closures = g_slist_prepend(data->closures, closure);
1054     g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure);
1055 }
1056
1057
1058 /* -------------- PyGObject behaviour ----------------- */
1059
1060 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
1061
1062 static void
1063 pygobject_dealloc(PyGObject *self)
1064 {
1065     /* Untrack must be done first. This is because followup calls such as
1066      * ClearWeakRefs could call into Python and cause new allocations to
1067      * happen, which could in turn could trigger the garbage collector,
1068      * which would then get confused as it is tracking this half-deallocated
1069      * object. */
1070     PyObject_GC_UnTrack((PyObject *)self);
1071
1072     PyObject_ClearWeakRefs((PyObject *)self);
1073       /* this forces inst_data->type to be updated, which could prove
1074        * important if a new wrapper has to be created and it is of a
1075        * unregistered type */
1076     pygobject_get_inst_data(self);
1077     pygobject_clear(self);
1078     /* the following causes problems with subclassed types */
1079     /* Py_TYPE(self)->tp_free((PyObject *)self); */
1080     PyObject_GC_Del(self);
1081 }
1082
1083 static PyObject*
1084 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1085 {
1086     int isinst;
1087
1088     isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1089     if (isinst == -1)
1090         return NULL;
1091     if (!isinst) {
1092         Py_INCREF(Py_NotImplemented);
1093         return Py_NotImplemented;
1094     }
1095     isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1096     if (isinst == -1)
1097         return NULL;
1098     if (!isinst) {
1099         Py_INCREF(Py_NotImplemented);
1100         return Py_NotImplemented;
1101     }
1102
1103     return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1104                                            ((PyGObject*)other)->obj,
1105                                            op);
1106 }
1107
1108 static long
1109 pygobject_hash(PyGObject *self)
1110 {
1111     return (long)self->obj;
1112 }
1113
1114 static PyObject *
1115 pygobject_repr(PyGObject *self)
1116 {
1117     gchar buf[256];
1118
1119     g_snprintf(buf, sizeof(buf),
1120                "<%s object at 0x%lx (%s at 0x%lx)>",
1121                Py_TYPE(self)->tp_name,
1122                (long)self,
1123                self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
1124                (long)self->obj);
1125     return PYGLIB_PyUnicode_FromString(buf);
1126 }
1127
1128
1129 static int
1130 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1131 {
1132     int ret = 0;
1133     GSList *tmp;
1134     PyGObjectData *data = pygobject_get_inst_data(self);
1135
1136     if (self->inst_dict) ret = visit(self->inst_dict, arg);
1137     if (ret != 0) return ret;
1138
1139     if (data) {
1140
1141         for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1142             PyGClosure *closure = tmp->data;
1143
1144             if (closure->callback) ret = visit(closure->callback, arg);
1145             if (ret != 0) return ret;
1146
1147             if (closure->extra_args) ret = visit(closure->extra_args, arg);
1148             if (ret != 0) return ret;
1149
1150             if (closure->swap_data) ret = visit(closure->swap_data, arg);
1151             if (ret != 0) return ret;
1152         }
1153     }
1154     return ret;
1155 }
1156
1157 static inline int
1158 pygobject_clear(PyGObject *self)
1159 {
1160     if (self->obj) {
1161         g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1162         if (self->inst_dict) {
1163             g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
1164             self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1165         } else {
1166             pyg_begin_allow_threads;
1167             g_object_unref(self->obj);
1168             pyg_end_allow_threads;
1169         }
1170         self->obj = NULL;
1171     }
1172     Py_CLEAR(self->inst_dict);
1173     return 0;
1174 }
1175
1176 static void
1177 pygobject_free(PyObject *op)
1178 {
1179     PyObject_GC_Del(op);
1180 }
1181
1182 gboolean
1183 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1184                                        guint *n_params, GParameter **params)
1185 {
1186     *n_params = 0;
1187     *params = NULL;
1188
1189     if (kwargs) {
1190         Py_ssize_t pos = 0;
1191         PyObject *key;
1192         PyObject *value;
1193
1194         *params = g_new0(GParameter, PyDict_Size(kwargs));
1195         while (PyDict_Next(kwargs, &pos, &key, &value)) {
1196             GParamSpec *pspec;
1197             GParameter *param = &(*params)[*n_params];
1198             const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1199
1200             pspec = g_object_class_find_property(class, key_str);
1201             if (!pspec) {
1202                 PyErr_Format(PyExc_TypeError,
1203                              "gobject `%s' doesn't support property `%s'",
1204                              G_OBJECT_CLASS_NAME(class), key_str);
1205                 return FALSE;
1206             }
1207             g_value_init(&param->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1208             if (pyg_param_gvalue_from_pyobject(&param->value, value, pspec) < 0) {
1209                 PyErr_Format(PyExc_TypeError,
1210                              "could not convert value for property `%s' from %s to %s",
1211                              key_str, Py_TYPE(value)->tp_name,
1212                              g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1213                 return FALSE;
1214             }
1215             param->name = g_strdup(key_str);
1216             ++(*n_params);
1217         }
1218     }
1219     return TRUE;
1220 }
1221
1222 /* ---------------- PyGObject methods ----------------- */
1223
1224 static int
1225 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1226 {
1227     GType object_type;
1228     guint n_params = 0, i;
1229     GParameter *params = NULL;
1230     GObjectClass *class;
1231
1232     if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
1233         return -1;
1234
1235     object_type = pyg_type_from_object((PyObject *)self);
1236     if (!object_type)
1237         return -1;
1238
1239     if (G_TYPE_IS_ABSTRACT(object_type)) {
1240         PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1241                      "(non-instantiable) type `%s'", g_type_name(object_type));
1242         return -1;
1243     }
1244
1245     if ((class = g_type_class_ref (object_type)) == NULL) {
1246         PyErr_SetString(PyExc_TypeError,
1247                         "could not get a reference to type class");
1248         return -1;
1249     }
1250
1251     if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, &params))
1252         goto cleanup;
1253
1254     if (pygobject_constructv(self, n_params, params))
1255         PyErr_SetString(PyExc_RuntimeError, "could not create object");
1256            
1257  cleanup:
1258     for (i = 0; i < n_params; i++) {
1259         g_free((gchar *) params[i].name);
1260         g_value_unset(&params[i].value);
1261     }
1262     g_free(params);
1263     g_type_class_unref(class);
1264     
1265     return (self->obj) ? 0 : -1;
1266 }
1267
1268 #define CHECK_GOBJECT(self) \
1269     if (!G_IS_OBJECT(self->obj)) {                                           \
1270         PyErr_Format(PyExc_TypeError,                                        \
1271                      "object at %p of type %s is not initialized",           \
1272                      self, Py_TYPE(self)->tp_name);                          \
1273         return NULL;                                                         \
1274     }
1275
1276 static PyObject *
1277 pygobject_get_property(PyGObject *self, PyObject *args)
1278 {
1279     gchar *param_name;
1280     GParamSpec *pspec;
1281     GValue value = { 0, };
1282     PyObject *ret;
1283
1284     if (!PyArg_ParseTuple(args, "s:GObject.get_property", &param_name))
1285         return NULL;
1286
1287     CHECK_GOBJECT(self);
1288     
1289     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1290                                          param_name);
1291     if (!pspec) {
1292         PyErr_Format(PyExc_TypeError,
1293                      "object of type `%s' does not have property `%s'",
1294                      g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1295         return NULL;
1296     }
1297     if (!(pspec->flags & G_PARAM_READABLE)) {
1298         PyErr_Format(PyExc_TypeError, "property %s is not readable",
1299                      param_name);
1300         return NULL;
1301     }
1302     g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1303     pyg_begin_allow_threads;
1304     g_object_get_property(self->obj, param_name, &value);
1305     pyg_end_allow_threads;
1306     ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
1307     g_value_unset(&value);
1308     return ret;
1309 }
1310
1311 static PyObject *
1312 pygobject_get_properties(PyGObject *self, PyObject *args)
1313 {
1314     GObjectClass *class;
1315     int len, i;
1316     PyObject *tuple;
1317
1318     if ((len = PyTuple_Size(args)) < 1) {
1319         PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1320         return NULL;
1321     }
1322
1323     tuple = PyTuple_New(len);
1324     class = G_OBJECT_GET_CLASS(self->obj);
1325     for (i = 0; i < len; i++) {
1326         PyObject *py_property = PyTuple_GetItem(args, i);
1327         gchar *property_name;
1328         GParamSpec *pspec;
1329         GValue value = { 0 };
1330         PyObject *item;
1331
1332         if (!PYGLIB_PyUnicode_Check(py_property)) {
1333             PyErr_SetString(PyExc_TypeError,
1334                             "Expected string argument for property.");
1335             return NULL;
1336         }
1337
1338         property_name = PYGLIB_PyUnicode_AsString(py_property);
1339
1340         pspec = g_object_class_find_property(class,
1341                                          property_name);
1342         if (!pspec) {
1343             PyErr_Format(PyExc_TypeError,
1344                          "object of type `%s' does not have property `%s'",
1345                          g_type_name(G_OBJECT_TYPE(self->obj)), property_name);
1346         return NULL;
1347         }
1348         if (!(pspec->flags & G_PARAM_READABLE)) {
1349             PyErr_Format(PyExc_TypeError, "property %s is not readable",
1350                         property_name);
1351             return NULL;
1352         }
1353         g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1354
1355         pyg_begin_allow_threads;
1356         g_object_get_property(self->obj, property_name, &value);
1357         pyg_end_allow_threads;
1358
1359         item = pyg_value_as_pyobject(&value, TRUE);
1360         PyTuple_SetItem(tuple, i, item);
1361
1362         g_value_unset(&value);
1363     }
1364
1365     return tuple;
1366 }
1367
1368 static PyObject *
1369 pygobject_set_property(PyGObject *self, PyObject *args)
1370 {
1371     gchar *param_name;
1372     GParamSpec *pspec;
1373     PyObject *pvalue;
1374
1375     if (!PyArg_ParseTuple(args, "sO:GObject.set_property", &param_name,
1376                           &pvalue))
1377         return NULL;
1378     
1379     CHECK_GOBJECT(self);
1380     
1381     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1382                                          param_name);
1383     if (!pspec) {
1384         PyErr_Format(PyExc_TypeError,
1385                      "object of type `%s' does not have property `%s'",
1386                      g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1387         return NULL;
1388     }
1389     
1390     if (!set_property_from_pspec(self->obj, pspec, pvalue))
1391         return NULL;
1392     
1393     Py_INCREF(Py_None);
1394     return Py_None;
1395 }
1396
1397 static PyObject *
1398 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1399 {    
1400     GObjectClass    *class;
1401     Py_ssize_t      pos;
1402     PyObject        *value;
1403     PyObject        *key;
1404     PyObject        *result = NULL;
1405
1406     CHECK_GOBJECT(self);
1407
1408     class = G_OBJECT_GET_CLASS(self->obj);
1409     
1410     g_object_freeze_notify (G_OBJECT(self->obj));
1411     pos = 0;
1412
1413     while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1414         gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1415         GParamSpec *pspec;
1416
1417         pspec = g_object_class_find_property(class, key_str);
1418         if (!pspec) {
1419             gchar buf[512];
1420
1421             g_snprintf(buf, sizeof(buf),
1422                        "object `%s' doesn't support property `%s'",
1423                        g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1424             PyErr_SetString(PyExc_TypeError, buf);
1425             goto exit;
1426         }
1427
1428         if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value))
1429             goto exit;
1430     }
1431
1432     result = Py_None;
1433
1434  exit:
1435     g_object_thaw_notify (G_OBJECT(self->obj));
1436     Py_XINCREF(result);
1437     return result;
1438 }
1439
1440 /* custom closure for gobject bindings */
1441 static void
1442 pygbinding_closure_invalidate(gpointer data, GClosure *closure)
1443 {
1444     PyGClosure *pc = (PyGClosure *)closure;
1445     PyGILState_STATE state;
1446
1447     state = pyglib_gil_state_ensure();
1448     Py_XDECREF(pc->callback);
1449     Py_XDECREF(pc->extra_args);
1450     pyglib_gil_state_release(state);
1451
1452     pc->callback = NULL;
1453     pc->extra_args = NULL;
1454 }
1455
1456 static void
1457 pygbinding_marshal (GClosure     *closure,
1458                     GValue       *return_value,
1459                     guint         n_param_values,
1460                     const GValue *param_values,
1461                     gpointer      invocation_hint,
1462                     gpointer      marshal_data)
1463 {
1464     PyGILState_STATE state;
1465     PyGClosure *pc = (PyGClosure *)closure;
1466     PyObject *params, *ret;
1467     GValue *out_value;
1468
1469     state = pyglib_gil_state_ensure();
1470
1471     /* construct Python tuple for the parameter values */
1472     params = PyTuple_New(2);
1473     PyTuple_SetItem (params, 0, pyg_value_as_pyobject(&param_values[0], FALSE));
1474     PyTuple_SetItem (params, 1, pyg_value_as_pyobject(&param_values[1], FALSE));
1475
1476     /* params passed to function may have extra arguments */
1477     if (pc->extra_args) {
1478         PyObject *tuple = params;
1479         params = PySequence_Concat(tuple, pc->extra_args);
1480         Py_DECREF(tuple);
1481     }
1482     ret = PyObject_CallObject(pc->callback, params);
1483     if (!ret) {
1484         PyErr_Print ();
1485         goto out;
1486     } else if (ret == Py_None) {
1487         g_value_set_boolean (return_value, FALSE);
1488         goto out;
1489     }
1490
1491     out_value = g_value_get_boxed (&param_values[2]);
1492     if (pyg_value_from_pyobject (out_value, ret) != 0) {
1493         PyErr_SetString (PyExc_ValueError, "can't convert value");
1494         PyErr_Print ();
1495         g_value_set_boolean (return_value, FALSE);
1496     } else {
1497         g_value_set_boolean (return_value, TRUE);
1498     }
1499
1500     Py_DECREF(ret);
1501
1502 out:
1503     Py_DECREF(params);
1504     pyglib_gil_state_release(state);
1505 }
1506
1507 static GClosure *
1508 pygbinding_closure_new (PyObject *callback, PyObject *extra_args)
1509 {
1510     GClosure *closure;
1511
1512     g_return_val_if_fail(callback != NULL, NULL);
1513     closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
1514     g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate);
1515     g_closure_set_marshal(closure, pygbinding_marshal);
1516     Py_INCREF(callback);
1517     ((PyGClosure *)closure)->callback = callback;
1518     if (extra_args && extra_args != Py_None) {
1519         Py_INCREF(extra_args);
1520         if (!PyTuple_Check(extra_args)) {
1521             PyObject *tmp = PyTuple_New(1);
1522             PyTuple_SetItem(tmp, 0, extra_args);
1523             extra_args = tmp;
1524         }
1525         ((PyGClosure *)closure)->extra_args = extra_args;
1526     }
1527     return closure;
1528 }
1529
1530 static PyObject *
1531 pygobject_bind_property(PyGObject *self, PyObject *args)
1532 {
1533         gchar *source_name, *target_name;
1534         gchar *source_canon, *target_canon;
1535         PyObject *target, *source_repr, *target_repr;
1536         PyObject *transform_to, *transform_from, *user_data = NULL;
1537         GBinding *binding;
1538         GBindingFlags flags = G_BINDING_DEFAULT;
1539         GClosure *to_closure = NULL, *from_closure = NULL;
1540
1541         transform_from = NULL;
1542         transform_to = NULL;
1543
1544         if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property",
1545                               &source_name, &target, &target_name, &flags,
1546                               &transform_to, &transform_from, &user_data))
1547                 return NULL;
1548
1549         CHECK_GOBJECT(self);
1550         if (!PyObject_TypeCheck(target, &PyGObject_Type)) {
1551                 PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject");
1552                 return NULL;
1553         }
1554
1555         if (transform_to && transform_to != Py_None) {
1556                 if (!PyCallable_Check (transform_to)) {
1557                         PyErr_SetString (PyExc_TypeError,
1558                                          "transform_to must be callable or None");
1559                         return NULL;
1560                 }
1561                 to_closure = pygbinding_closure_new (transform_to, user_data);
1562         }
1563
1564         if (transform_from && transform_from != Py_None) {
1565                 if (!PyCallable_Check (transform_from)) {
1566                         PyErr_SetString (PyExc_TypeError,
1567                                          "transform_from must be callable or None");
1568                         return NULL;
1569                 }
1570                 from_closure = pygbinding_closure_new (transform_from, user_data);
1571         }
1572
1573         /* Canonicalize underscores to hyphens. Note the results must be freed. */
1574         source_canon = g_strdelimit(g_strdup(source_name), "_", '-');
1575         target_canon = g_strdelimit(g_strdup(target_name), "_", '-');
1576
1577         binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon,
1578                                                         pygobject_get(target), target_canon,
1579                                                         flags, to_closure, from_closure);
1580         g_free(source_canon);
1581         g_free(target_canon);
1582         source_canon = target_canon = NULL;
1583
1584         if (binding == NULL) {
1585                 source_repr = PyObject_Repr((PyObject*)self);
1586                 target_repr = PyObject_Repr(target);
1587                 PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s",
1588                              PYGLIB_PyUnicode_AsString(source_repr), source_name,
1589                              PYGLIB_PyUnicode_AsString(target_repr), target_name);
1590                 Py_DECREF(source_repr);
1591                 Py_DECREF(target_repr);
1592                 return NULL;
1593         }
1594
1595         return pygbinding_weak_ref_new(G_OBJECT (binding));
1596 }
1597
1598 static PyObject *
1599 pygobject_connect(PyGObject *self, PyObject *args)
1600 {
1601     PyObject *first, *callback, *extra_args, *repr = NULL;
1602     gchar *name;
1603     guint sigid, len;
1604     gulong handlerid;
1605     GQuark detail = 0;
1606     GClosure *closure;
1607
1608     len = PyTuple_Size(args);
1609     if (len < 2) {
1610         PyErr_SetString(PyExc_TypeError,
1611                         "GObject.connect requires at least 2 arguments");
1612         return NULL;
1613     }
1614     first = PySequence_GetSlice(args, 0, 2);
1615     if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1616         Py_DECREF(first);
1617         return NULL;
1618     }
1619     Py_DECREF(first);
1620     if (!PyCallable_Check(callback)) {
1621         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1622         return NULL;
1623     }
1624     
1625     CHECK_GOBJECT(self);
1626     
1627     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1628                              &sigid, &detail, TRUE)) {
1629         repr = PyObject_Repr((PyObject*)self);
1630         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1631                      PYGLIB_PyUnicode_AsString(repr),
1632                      name);
1633         Py_DECREF(repr);
1634         return NULL;
1635     }
1636     extra_args = PySequence_GetSlice(args, 2, len);
1637     if (extra_args == NULL)
1638         return NULL;
1639
1640     closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1641     if (closure == NULL)
1642         closure = pyg_closure_new(callback, extra_args, NULL);
1643
1644     pygobject_watch_closure((PyObject *)self, closure);
1645     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1646                                                closure, FALSE);
1647     Py_DECREF(extra_args);
1648     return PyLong_FromUnsignedLong(handlerid);
1649 }
1650
1651 static PyObject *
1652 pygobject_connect_after(PyGObject *self, PyObject *args)
1653 {
1654     PyObject *first, *callback, *extra_args, *repr = NULL;
1655     gchar *name;
1656     guint sigid;
1657     gulong handlerid;
1658     Py_ssize_t len;
1659     GQuark detail;
1660     GClosure *closure;
1661
1662     len = PyTuple_Size(args);
1663     if (len < 2) {
1664         PyErr_SetString(PyExc_TypeError,
1665                         "GObject.connect_after requires at least 2 arguments");
1666         return NULL;
1667     }
1668     first = PySequence_GetSlice(args, 0, 2);
1669     if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1670                           &name, &callback)) {
1671         Py_DECREF(first);
1672         return NULL;
1673     }
1674     Py_DECREF(first);
1675     if (!PyCallable_Check(callback)) {
1676         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1677         return NULL;
1678     }
1679     
1680     CHECK_GOBJECT(self);
1681     
1682     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1683                              &sigid, &detail, TRUE)) {
1684         repr = PyObject_Repr((PyObject*)self);
1685         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1686                      PYGLIB_PyUnicode_AsString(repr),
1687                      name);
1688         Py_DECREF(repr);
1689         return NULL;
1690     }
1691     extra_args = PySequence_GetSlice(args, 2, len);
1692     if (extra_args == NULL)
1693         return NULL;
1694
1695     closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1696     if (closure == NULL)
1697         closure = pyg_closure_new(callback, extra_args, NULL);
1698
1699     pygobject_watch_closure((PyObject *)self, closure);
1700     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1701                                                closure, TRUE);
1702     Py_DECREF(extra_args);
1703     return PyLong_FromUnsignedLong(handlerid);
1704 }
1705
1706 static PyObject *
1707 pygobject_connect_object(PyGObject *self, PyObject *args)
1708 {
1709     PyObject *first, *callback, *extra_args, *object, *repr = NULL;
1710     gchar *name;
1711     guint sigid;
1712     gulong handlerid;
1713     Py_ssize_t len;
1714     GQuark detail;
1715     GClosure *closure;
1716
1717     len = PyTuple_Size(args);
1718     if (len < 3) {
1719         PyErr_SetString(PyExc_TypeError,
1720                 "GObject.connect_object requires at least 3 arguments");
1721         return NULL;
1722     }
1723     first = PySequence_GetSlice(args, 0, 3);
1724     if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1725                           &name, &callback, &object)) {
1726         Py_DECREF(first);
1727         return NULL;
1728     }
1729     Py_DECREF(first);
1730     if (!PyCallable_Check(callback)) {
1731         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1732         return NULL;
1733     }
1734     
1735     CHECK_GOBJECT(self);
1736     
1737     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1738                              &sigid, &detail, TRUE)) {
1739         repr = PyObject_Repr((PyObject*)self);
1740         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1741                      PYGLIB_PyUnicode_AsString(repr),
1742                      name);
1743         Py_DECREF(repr);
1744         return NULL;
1745     }
1746     extra_args = PySequence_GetSlice(args, 3, len);
1747     if (extra_args == NULL)
1748         return NULL;
1749
1750     closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1751     if (closure == NULL)
1752         closure = pyg_closure_new(callback, extra_args, object);
1753
1754     pygobject_watch_closure((PyObject *)self, closure);
1755     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1756                                                closure, FALSE);
1757     Py_DECREF(extra_args);
1758     return PyLong_FromUnsignedLong(handlerid);
1759 }
1760
1761 static PyObject *
1762 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1763 {
1764     PyObject *first, *callback, *extra_args, *object, *repr = NULL;
1765     gchar *name;
1766     guint sigid;
1767     gulong handlerid;
1768     Py_ssize_t len;
1769     GQuark detail;
1770     GClosure *closure;
1771
1772     len = PyTuple_Size(args);
1773     if (len < 3) {
1774         PyErr_SetString(PyExc_TypeError,
1775                 "GObject.connect_object_after requires at least 3 arguments");
1776         return NULL;
1777     }
1778     first = PySequence_GetSlice(args, 0, 3);
1779     if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1780                           &name, &callback, &object)) {
1781         Py_DECREF(first);
1782         return NULL;
1783     }
1784     Py_DECREF(first);
1785     if (!PyCallable_Check(callback)) {
1786         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1787         return NULL;
1788     }
1789     
1790     CHECK_GOBJECT(self);
1791     
1792     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1793                              &sigid, &detail, TRUE)) {
1794         repr = PyObject_Repr((PyObject*)self);
1795         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1796                      PYGLIB_PyUnicode_AsString(repr),
1797                      name);
1798         Py_DECREF(repr);
1799         return NULL;
1800     }
1801     extra_args = PySequence_GetSlice(args, 3, len);
1802     if (extra_args == NULL)
1803         return NULL;
1804
1805     closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1806     if (closure == NULL)
1807         closure = pyg_closure_new(callback, extra_args, object);
1808
1809     pygobject_watch_closure((PyObject *)self, closure);
1810     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1811                                                closure, TRUE);
1812     Py_DECREF(extra_args);
1813     return PyLong_FromUnsignedLong(handlerid);
1814 }
1815
1816 static PyObject *
1817 pygobject_disconnect(PyGObject *self, PyObject *args)
1818 {
1819     gulong handler_id;
1820
1821     if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
1822         return NULL;
1823     
1824     CHECK_GOBJECT(self);
1825     
1826     g_signal_handler_disconnect(self->obj, handler_id);
1827     Py_INCREF(Py_None);
1828     return Py_None;
1829 }
1830
1831 static PyObject *
1832 pygobject_handler_is_connected(PyGObject *self, PyObject *args)
1833 {
1834     gulong handler_id;
1835
1836     if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
1837         return NULL;
1838
1839     
1840     CHECK_GOBJECT(self);
1841     
1842     return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
1843 }
1844
1845 static PyObject *
1846 pygobject_handler_block(PyGObject *self, PyObject *args)
1847 {
1848     gulong handler_id;
1849
1850     if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
1851         return NULL;
1852
1853     CHECK_GOBJECT(self);
1854
1855     g_signal_handler_block(self->obj, handler_id);
1856     Py_INCREF(Py_None);
1857     return Py_None;
1858 }
1859
1860 static PyObject *
1861 pygobject_handler_unblock(PyGObject *self, PyObject *args)
1862 {
1863     gulong handler_id;
1864
1865     if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
1866         return NULL;
1867     g_signal_handler_unblock(self->obj, handler_id);
1868     Py_INCREF(Py_None);
1869     return Py_None;
1870 }
1871
1872 static PyObject *
1873 pygobject_emit(PyGObject *self, PyObject *args)
1874 {
1875     guint signal_id, i, j;
1876     Py_ssize_t len;
1877     GQuark detail;
1878     PyObject *first, *py_ret, *repr = NULL;
1879     gchar *name;
1880     GSignalQuery query;
1881     GValue *params, ret = { 0, };
1882     
1883     len = PyTuple_Size(args);
1884     if (len < 1) {
1885         PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1886         return NULL;
1887     }
1888     first = PySequence_GetSlice(args, 0, 1);
1889     if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1890         Py_DECREF(first);
1891         return NULL;
1892     }
1893     Py_DECREF(first);
1894     
1895     CHECK_GOBJECT(self);
1896     
1897     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1898                              &signal_id, &detail, TRUE)) {
1899         repr = PyObject_Repr((PyObject*)self);
1900         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1901                      PYGLIB_PyUnicode_AsString(repr),
1902                      name);
1903         Py_DECREF(repr);
1904         return NULL;
1905     }
1906     g_signal_query(signal_id, &query);
1907     if (len != query.n_params + 1) {
1908         gchar buf[128];
1909
1910         g_snprintf(buf, sizeof(buf),
1911                    "%d parameters needed for signal %s; %ld given",
1912                    query.n_params, name, (long int) (len - 1));
1913         PyErr_SetString(PyExc_TypeError, buf);
1914         return NULL;
1915     }
1916
1917     params = g_new0(GValue, query.n_params + 1);
1918     g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1919     g_value_set_object(&params[0], G_OBJECT(self->obj));
1920
1921     for (i = 0; i < query.n_params; i++)
1922         g_value_init(&params[i + 1],
1923                      query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1924     for (i = 0; i < query.n_params; i++) {
1925         PyObject *item = PyTuple_GetItem(args, i+1);
1926
1927         if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1928             gchar buf[128];
1929             g_snprintf(buf, sizeof(buf),
1930                        "could not convert type %s to %s required for parameter %d",
1931                        Py_TYPE(item)->tp_name,
1932                        G_VALUE_TYPE_NAME(&params[i+1]), i);
1933             PyErr_SetString(PyExc_TypeError, buf);
1934
1935             for (j = 0; j <= i; j++)
1936                 g_value_unset(&params[j]);
1937
1938             g_free(params);
1939             return NULL;
1940         }
1941     }    
1942
1943     if (query.return_type != G_TYPE_NONE)
1944         g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1945     
1946     g_signal_emitv(params, signal_id, detail, &ret);
1947
1948     for (i = 0; i < query.n_params + 1; i++)
1949         g_value_unset(&params[i]);
1950     
1951     g_free(params);
1952     if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1953         py_ret = pyg_value_as_pyobject(&ret, TRUE);
1954         g_value_unset(&ret);
1955     } else {
1956         Py_INCREF(Py_None);
1957         py_ret = Py_None;
1958     }
1959
1960     return py_ret;
1961 }
1962
1963 static PyObject *
1964 pygobject_stop_emission(PyGObject *self, PyObject *args)
1965 {
1966     gchar *signal;
1967     guint signal_id;
1968     GQuark detail;
1969     PyObject *repr = NULL;
1970
1971     if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
1972         return NULL;
1973     
1974     CHECK_GOBJECT(self);
1975     
1976     if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
1977                              &signal_id, &detail, TRUE)) {
1978         repr = PyObject_Repr((PyObject*)self);
1979         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1980                      PYGLIB_PyUnicode_AsString(repr),
1981                      signal);
1982         Py_DECREF(repr);
1983         return NULL;
1984     }
1985     g_signal_stop_emission(self->obj, signal_id, detail);
1986     Py_INCREF(Py_None);
1987     return Py_None;
1988 }
1989
1990 static PyObject *
1991 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1992 {
1993     GSignalInvocationHint *ihint;
1994     guint signal_id, i;
1995     Py_ssize_t len;
1996     PyObject *py_ret;
1997     const gchar *name;
1998     GSignalQuery query;
1999     GValue *params, ret = { 0, };
2000     
2001     CHECK_GOBJECT(self);
2002     
2003     ihint = g_signal_get_invocation_hint(self->obj);
2004     if (!ihint) {
2005         PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
2006                         "information for this object.");
2007         return NULL;
2008     }
2009
2010     signal_id = ihint->signal_id;
2011     name = g_signal_name(signal_id);
2012
2013     len = PyTuple_Size(args);
2014     if (signal_id == 0) {
2015         PyErr_SetString(PyExc_TypeError, "unknown signal name");
2016         return NULL;
2017     }
2018     g_signal_query(signal_id, &query);
2019     if (len != query.n_params) {
2020         gchar buf[128];
2021
2022         g_snprintf(buf, sizeof(buf),
2023                    "%d parameters needed for signal %s; %ld given",
2024                    query.n_params, name, (long int) len);
2025         PyErr_SetString(PyExc_TypeError, buf);
2026         return NULL;
2027     }
2028     params = g_new0(GValue, query.n_params + 1);
2029     g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
2030     g_value_set_object(&params[0], G_OBJECT(self->obj));
2031
2032     for (i = 0; i < query.n_params; i++)
2033         g_value_init(&params[i + 1],
2034                      query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2035     for (i = 0; i < query.n_params; i++) {
2036         PyObject *item = PyTuple_GetItem(args, i);
2037
2038         if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
2039             g_value_set_static_boxed(&params[i+1], pyg_boxed_get(item, void));
2040         }
2041         else if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
2042             gchar buf[128];
2043
2044             g_snprintf(buf, sizeof(buf),
2045                        "could not convert type %s to %s required for parameter %d",
2046                        Py_TYPE(item)->tp_name,
2047                        g_type_name(G_VALUE_TYPE(&params[i+1])), i);
2048             PyErr_SetString(PyExc_TypeError, buf);
2049             for (i = 0; i < query.n_params + 1; i++)
2050                 g_value_unset(&params[i]);
2051             g_free(params);
2052             return NULL;
2053         }
2054     }
2055     if (query.return_type != G_TYPE_NONE)
2056         g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2057     g_signal_chain_from_overridden(params, &ret);
2058     for (i = 0; i < query.n_params + 1; i++)
2059         g_value_unset(&params[i]);
2060     g_free(params);
2061     if (query.return_type != G_TYPE_NONE) {
2062         py_ret = pyg_value_as_pyobject(&ret, TRUE);
2063         g_value_unset(&ret);
2064     } else {
2065         Py_INCREF(Py_None);
2066         py_ret = Py_None;
2067     }
2068     return py_ret;
2069 }
2070
2071
2072 static PyObject *
2073 pygobject_weak_ref(PyGObject *self, PyObject *args)
2074 {
2075     int len;
2076     PyObject *callback = NULL, *user_data = NULL;
2077     PyObject *retval;
2078
2079     CHECK_GOBJECT(self);
2080
2081     if ((len = PySequence_Length(args)) >= 1) {
2082         callback = PySequence_ITEM(args, 0);
2083         user_data = PySequence_GetSlice(args, 1, len);
2084     }
2085     retval = pygobject_weak_ref_new(self->obj, callback, user_data);
2086     Py_XDECREF(callback);
2087     Py_XDECREF(user_data);
2088     return retval;
2089 }
2090
2091
2092 static PyObject *
2093 pygobject_copy(PyGObject *self)
2094 {
2095     PyErr_SetString(PyExc_TypeError,
2096                     "GObject descendants' instances are non-copyable");
2097     return NULL;
2098 }
2099
2100 static PyObject *
2101 pygobject_deepcopy(PyGObject *self, PyObject *args)
2102 {
2103     PyErr_SetString(PyExc_TypeError,
2104                     "GObject descendants' instances are non-copyable");
2105     return NULL;
2106 }
2107
2108
2109 static PyObject *
2110 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
2111 {
2112     PyObject *pyfunc = NULL, *repr = NULL;
2113     GClosure *closure = NULL;
2114     guint retval;
2115     
2116     CHECK_GOBJECT(self);
2117
2118     if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
2119         return NULL;
2120
2121     if (!PyCallable_Check(pyfunc)) {
2122         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2123         return NULL;
2124     }
2125
2126     closure = gclosure_from_pyfunc(self, pyfunc);
2127     if (!closure) {
2128         repr = PyObject_Repr((PyObject*)pyfunc);
2129         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2130                      PYGLIB_PyUnicode_AsString(repr));
2131         Py_DECREF(repr);
2132         return NULL;
2133     }
2134     
2135     retval = g_signal_handlers_disconnect_matched(self->obj,
2136                                                   G_SIGNAL_MATCH_CLOSURE,
2137                                                   0, 0,
2138                                                   closure,
2139                                                   NULL, NULL);
2140     return PYGLIB_PyLong_FromLong(retval);
2141 }
2142
2143 static PyObject *
2144 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
2145 {
2146     PyObject *pyfunc = NULL, *repr = NULL;
2147     GClosure *closure = NULL;
2148     guint retval;
2149     
2150     CHECK_GOBJECT(self);
2151
2152     if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
2153         return NULL;
2154
2155     if (!PyCallable_Check(pyfunc)) {
2156         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2157         return NULL;
2158     }
2159
2160     closure = gclosure_from_pyfunc(self, pyfunc);
2161     if (!closure) {
2162         repr = PyObject_Repr((PyObject*)pyfunc);
2163         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2164                      PYGLIB_PyUnicode_AsString(repr));
2165         Py_DECREF(repr);
2166         return NULL;
2167     }
2168     
2169     retval = g_signal_handlers_block_matched(self->obj,
2170                                              G_SIGNAL_MATCH_CLOSURE,
2171                                              0, 0,
2172                                              closure,
2173                                              NULL, NULL);
2174     return PYGLIB_PyLong_FromLong(retval);
2175 }
2176
2177 static PyObject *
2178 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2179 {
2180     PyObject *pyfunc = NULL, *repr = NULL;
2181     GClosure *closure = NULL;
2182     guint retval;
2183     
2184     CHECK_GOBJECT(self);
2185
2186     if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2187         return NULL;
2188
2189     if (!PyCallable_Check(pyfunc)) {
2190         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2191         return NULL;
2192     }
2193
2194     closure = gclosure_from_pyfunc(self, pyfunc);
2195     if (!closure) {
2196         repr = PyObject_Repr((PyObject*)pyfunc);
2197         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2198                      PYGLIB_PyUnicode_AsString(repr));
2199         Py_DECREF(repr);
2200         return NULL;
2201     }
2202     
2203     retval = g_signal_handlers_unblock_matched(self->obj,
2204                                                G_SIGNAL_MATCH_CLOSURE,
2205                                                0, 0,
2206                                                closure,
2207                                                NULL, NULL);
2208     return PYGLIB_PyLong_FromLong(retval);
2209 }
2210
2211
2212 static PyMethodDef pygobject_methods[] = {
2213     { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2214     { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2215     { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2216     { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2217     { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS },
2218     { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2219     { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2220     { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2221     { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2222     { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2223     { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2224     { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2225     { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
2226     { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
2227     { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
2228     { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2229     { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2230     { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2231     { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
2232     { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
2233     { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2234     { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2235     { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2236     { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2237     { NULL, NULL, 0 }
2238 };
2239
2240
2241 static PyObject *
2242 pygobject_get_dict(PyGObject *self, void *closure)
2243 {
2244     if (self->inst_dict == NULL) {
2245         self->inst_dict = PyDict_New();
2246         if (self->inst_dict == NULL)
2247             return NULL;
2248         if (G_LIKELY(self->obj))
2249             pygobject_switch_to_toggle_ref(self);
2250     }
2251     Py_INCREF(self->inst_dict);
2252     return self->inst_dict;
2253 }
2254
2255 static PyObject *
2256 pygobject_get_refcount(PyGObject *self, void *closure)
2257 {
2258     if (self->obj == NULL) {
2259         PyErr_Format(PyExc_TypeError, "GObject instance is not yet created");
2260         return NULL;
2261     }
2262     return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2263 }
2264
2265 static int
2266 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2267 {
2268     int res;
2269     PyGObject *gself = (PyGObject *) self;
2270     PyObject *inst_dict_before = gself->inst_dict;
2271       /* call parent type's setattro */
2272     res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2273     if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2274         if (G_LIKELY(gself->obj))
2275             pygobject_switch_to_toggle_ref(gself);
2276     }
2277     return res;
2278 }
2279
2280 static PyGetSetDef pygobject_getsets[] = {
2281     { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2282     { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2283     { NULL, 0, 0 }
2284 };
2285
2286 /* ------------------------------------ */
2287 /* ****** GObject weak reference ****** */
2288 /* ------------------------------------ */
2289
2290 typedef struct {
2291     PyObject_HEAD
2292     GObject *obj;
2293     PyObject *callback;
2294     PyObject *user_data;
2295     gboolean have_floating_ref;
2296 } PyGObjectWeakRef;
2297
2298 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2299
2300 static int
2301 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2302 {
2303     if (self->callback && visit(self->callback, arg) < 0)
2304         return -1;
2305     if (self->user_data && visit(self->user_data, arg) < 0)
2306         return -1;
2307     return 0;
2308 }
2309
2310 static void
2311 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2312 {
2313     self->obj = NULL;
2314     if (self->callback) {
2315         PyObject *retval;
2316         PyGILState_STATE state = pyglib_gil_state_ensure();
2317         retval = PyObject_Call(self->callback, self->user_data, NULL);
2318         if (retval) {
2319             if (retval != Py_None)
2320                 PyErr_Format(PyExc_TypeError,
2321                              "GObject weak notify callback returned a value"
2322                              " of type %s, should return None",
2323                              Py_TYPE(retval)->tp_name);
2324             Py_DECREF(retval);
2325             PyErr_Print();
2326         } else
2327             PyErr_Print();
2328         Py_CLEAR(self->callback);
2329         Py_CLEAR(self->user_data);
2330         if (self->have_floating_ref) {
2331             self->have_floating_ref = FALSE;
2332             Py_DECREF((PyObject *) self);
2333         }
2334         pyglib_gil_state_release(state);
2335     }
2336 }
2337
2338 static inline int
2339 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2340 {
2341     Py_CLEAR(self->callback);
2342     Py_CLEAR(self->user_data);
2343     if (self->obj) {
2344         g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2345         self->obj = NULL;
2346     }
2347     return 0;
2348 }
2349
2350 static void
2351 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2352 {
2353     PyObject_GC_UnTrack((PyObject *)self);
2354     pygobject_weak_ref_clear(self);
2355     PyObject_GC_Del(self);
2356 }
2357
2358 static PyObject *
2359 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2360 {
2361     PyGObjectWeakRef *self;
2362
2363     self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2364     self->callback = callback;
2365     self->user_data = user_data;
2366     Py_XINCREF(self->callback);
2367     Py_XINCREF(self->user_data);
2368     self->obj = obj;
2369     g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2370     if (callback != NULL) {
2371           /* when we have a callback, we should INCREF the weakref
2372            * object to make it stay alive even if it goes out of scope */
2373         self->have_floating_ref = TRUE;
2374         Py_INCREF((PyObject *) self);
2375     }
2376     return (PyObject *) self;
2377 }
2378
2379 static PyObject *
2380 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2381 {
2382     if (!self->obj) {
2383         PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2384         return NULL;
2385     }
2386     g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2387     self->obj = NULL;
2388     if (self->have_floating_ref) {
2389         self->have_floating_ref = FALSE;
2390         Py_DECREF(self);
2391     }
2392     Py_INCREF(Py_None);
2393     return Py_None;
2394 }
2395
2396 static PyMethodDef pygobject_weak_ref_methods[] = {
2397     { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2398     { NULL, NULL, 0}
2399 };
2400
2401 static PyObject *
2402 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2403 {
2404     static char *argnames[] = {NULL};
2405
2406     if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2407         return NULL;
2408
2409     if (self->obj)
2410         return pygobject_new_full(self->obj, FALSE, NULL);
2411     else {
2412         Py_INCREF(Py_None);
2413         return Py_None;
2414     }
2415 }
2416
2417
2418 /* -------------- GBinding Weak Reference ----------------- */
2419
2420 /**
2421  * BindingWeakRef
2422  *
2423  * The BindingWeakRef object is used to manage GBinding objects within python
2424  * created through GObject.bind_property. It is a sub-class PyGObjectWeakRef so
2425  * that we can maintain the same reference counting semantics between Python
2426  * and GObject Binding objects. This gives explicit direct control of the
2427  * binding lifetime by using the "unbind" method on the BindingWeakRef object
2428  * along with implicit management based on the lifetime of the source or
2429  * target objects.
2430  */
2431
2432 PYGLIB_DEFINE_TYPE("gi._gobject.GBindingWeakRef", PyGBindingWeakRef_Type, PyGObjectWeakRef);
2433
2434 static PyObject *
2435 pygbinding_weak_ref_new(GObject *obj)
2436 {
2437         PyGObjectWeakRef *self;
2438
2439         self = PyObject_GC_New(PyGObjectWeakRef, &PyGBindingWeakRef_Type);
2440         self->callback = NULL;
2441         self->user_data = NULL;
2442         self->obj = obj;
2443         g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2444         return (PyObject *) self;
2445 }
2446
2447 static PyObject *
2448 pygbinding_weak_ref_unbind(PyGObjectWeakRef *self, PyObject *args)
2449 {
2450     if (!self->obj) {
2451         PyErr_SetString(PyExc_ValueError, "weak binding ref already unreffed");
2452         return NULL;
2453     }
2454     g_object_unref(self->obj);
2455     Py_INCREF(Py_None);
2456     return Py_None;
2457 }
2458
2459 static PyMethodDef pygbinding_weak_ref_methods[] = {
2460     { "unbind", (PyCFunction)pygbinding_weak_ref_unbind, METH_NOARGS},
2461     { NULL, NULL, 0}
2462 };
2463
2464
2465 static gpointer
2466 pyobject_copy(gpointer boxed)
2467 {
2468     PyObject *object = boxed;
2469
2470     Py_INCREF(object);
2471     return object;
2472 }
2473
2474 static void
2475 pyobject_free(gpointer boxed)
2476 {
2477     PyObject *object = boxed;
2478     PyGILState_STATE state;
2479
2480     state = pyglib_gil_state_ensure();
2481     Py_DECREF(object);
2482     pyglib_gil_state_release(state);
2483 }
2484
2485 void
2486 pygobject_object_register_types(PyObject *d)
2487 {
2488     PyObject *o, *descr;
2489
2490     pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2491     pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2492     pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2493     pygobject_has_updated_constructor_key =
2494         g_quark_from_static_string("PyGObject::has-updated-constructor");
2495     pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2496
2497     /* GObject */
2498     if (!PY_TYPE_OBJECT)
2499         PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2500                                                       pyobject_copy,
2501                                                       pyobject_free);
2502     PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2503     PyGObject_Type.tp_richcompare = pygobject_richcompare;
2504     PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2505     PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2506     PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2507     PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2508                                Py_TPFLAGS_HAVE_GC);
2509     PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2510     PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2511     PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2512     PyGObject_Type.tp_methods = pygobject_methods;
2513     PyGObject_Type.tp_getset = pygobject_getsets;
2514     PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2515     PyGObject_Type.tp_init = (initproc)pygobject_init;
2516     PyGObject_Type.tp_free = (freefunc)pygobject_free;
2517     PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2518     PyGObject_Type.tp_new = PyType_GenericNew;
2519     pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2520                              &PyGObject_Type, NULL);
2521     PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2522                          pyg_object_descr_doc_get());
2523
2524     /* GProps */
2525     PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2526     PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2527     PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2528     PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2529     PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2530     PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2531         "Python attributes.";
2532     PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2533     PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2534     if (PyType_Ready(&PyGProps_Type) < 0)
2535         return;
2536
2537     /* GPropsDescr */
2538     PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2539     PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2540     if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2541         return;
2542     descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2543     PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2544     PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2545                         o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject"));
2546     Py_DECREF(o);
2547
2548     /* GPropsIter */
2549     PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2550     PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2551     PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2552     PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2553     if (PyType_Ready(&PyGPropsIter_Type) < 0)
2554         return;
2555
2556     PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2557     PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2558     PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2559     PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2560     PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2561     PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2562     PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2563     if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2564         return;
2565     PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
2566
2567     PyGBindingWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2568     PyGBindingWeakRef_Type.tp_doc = "A GBinding weak reference";
2569     PyGBindingWeakRef_Type.tp_methods = pygbinding_weak_ref_methods;
2570     PyGBindingWeakRef_Type.tp_base = &PyGObjectWeakRef_Type;
2571     if (PyType_Ready(&PyGBindingWeakRef_Type) < 0)
2572         return;
2573     PyDict_SetItemString(d, "GBindingWeakRef", (PyObject *) &PyGBindingWeakRef_Type);
2574 }