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