Imported Upstream version 3.1.0
[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 /* -------------- PyGObject behaviour ----------------- */
997
998 PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject);
999
1000 static void
1001 pygobject_dealloc(PyGObject *self)
1002 {
1003     /* Untrack must be done first. This is because followup calls such as
1004      * ClearWeakRefs could call into Python and cause new allocations to
1005      * happen, which could in turn could trigger the garbage collector,
1006      * which would then get confused as it is tracking this half-deallocated
1007      * object. */
1008     PyObject_GC_UnTrack((PyObject *)self);
1009
1010     PyObject_ClearWeakRefs((PyObject *)self);
1011       /* this forces inst_data->type to be updated, which could prove
1012        * important if a new wrapper has to be created and it is of a
1013        * unregistered type */
1014     pygobject_get_inst_data(self);
1015     pygobject_clear(self);
1016     /* the following causes problems with subclassed types */
1017     /* Py_TYPE(self)->tp_free((PyObject *)self); */
1018     PyObject_GC_Del(self);
1019 }
1020
1021 static PyObject*
1022 pygobject_richcompare(PyObject *self, PyObject *other, int op)
1023 {
1024     int isinst;
1025
1026     isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
1027     if (isinst == -1)
1028         return NULL;
1029     if (!isinst) {
1030         Py_INCREF(Py_NotImplemented);
1031         return Py_NotImplemented;
1032     }
1033     isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
1034     if (isinst == -1)
1035         return NULL;
1036     if (!isinst) {
1037         Py_INCREF(Py_NotImplemented);
1038         return Py_NotImplemented;
1039     }
1040
1041     return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
1042                                            ((PyGObject*)other)->obj,
1043                                            op);
1044 }
1045
1046 static long
1047 pygobject_hash(PyGObject *self)
1048 {
1049     return (long)self->obj;
1050 }
1051
1052 static PyObject *
1053 pygobject_repr(PyGObject *self)
1054 {
1055     gchar buf[256];
1056
1057     g_snprintf(buf, sizeof(buf),
1058                "<%s object at 0x%lx (%s at 0x%lx)>",
1059                Py_TYPE(self)->tp_name,
1060                (long)self,
1061                self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
1062                (long)self->obj);
1063     return PYGLIB_PyUnicode_FromString(buf);
1064 }
1065
1066
1067 static int
1068 pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
1069 {
1070     int ret = 0;
1071     GSList *tmp;
1072     PyGObjectData *data = pygobject_get_inst_data(self);
1073
1074     if (self->inst_dict) ret = visit(self->inst_dict, arg);
1075     if (ret != 0) return ret;
1076
1077     if (data) {
1078
1079         for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
1080             PyGClosure *closure = tmp->data;
1081
1082             if (closure->callback) ret = visit(closure->callback, arg);
1083             if (ret != 0) return ret;
1084
1085             if (closure->extra_args) ret = visit(closure->extra_args, arg);
1086             if (ret != 0) return ret;
1087
1088             if (closure->swap_data) ret = visit(closure->swap_data, arg);
1089             if (ret != 0) return ret;
1090         }
1091     }
1092     return ret;
1093 }
1094
1095 static inline int
1096 pygobject_clear(PyGObject *self)
1097 {
1098     if (self->obj) {
1099         g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL);
1100         if (self->inst_dict) {
1101             g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
1102             self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF;
1103         } else {
1104             pyg_begin_allow_threads;
1105             g_object_unref(self->obj);
1106             pyg_end_allow_threads;
1107         }
1108         self->obj = NULL;
1109     }
1110     Py_CLEAR(self->inst_dict);
1111     return 0;
1112 }
1113
1114 static void
1115 pygobject_free(PyObject *op)
1116 {
1117     PyObject_GC_Del(op);
1118 }
1119
1120 gboolean
1121 pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs,
1122                                        guint *n_params, GParameter **params)
1123 {
1124     *n_params = 0;
1125     *params = NULL;
1126
1127     if (kwargs) {
1128         Py_ssize_t pos = 0;
1129         PyObject *key;
1130         PyObject *value;
1131
1132         *params = g_new0(GParameter, PyDict_Size(kwargs));
1133         while (PyDict_Next(kwargs, &pos, &key, &value)) {
1134             GParamSpec *pspec;
1135             GParameter *param = &(*params)[*n_params];
1136             const gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1137
1138             pspec = g_object_class_find_property(class, key_str);
1139             if (!pspec) {
1140                 PyErr_Format(PyExc_TypeError,
1141                              "gobject `%s' doesn't support property `%s'",
1142                              G_OBJECT_CLASS_NAME(class), key_str);
1143                 return FALSE;
1144             }
1145             g_value_init(&param->value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1146             if (pyg_param_gvalue_from_pyobject(&param->value, value, pspec) < 0) {
1147                 PyErr_Format(PyExc_TypeError,
1148                              "could not convert value for property `%s' from %s to %s",
1149                              key_str, Py_TYPE(value)->tp_name,
1150                              g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
1151                 return FALSE;
1152             }
1153             param->name = g_strdup(key_str);
1154             ++(*n_params);
1155         }
1156     }
1157     return TRUE;
1158 }
1159
1160 /* ---------------- PyGObject methods ----------------- */
1161
1162 static int
1163 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
1164 {
1165     GType object_type;
1166     guint n_params = 0, i;
1167     GParameter *params = NULL;
1168     GObjectClass *class;
1169
1170     if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
1171         return -1;
1172
1173     object_type = pyg_type_from_object((PyObject *)self);
1174     if (!object_type)
1175         return -1;
1176
1177     if (G_TYPE_IS_ABSTRACT(object_type)) {
1178         PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1179                      "(non-instantiable) type `%s'", g_type_name(object_type));
1180         return -1;
1181     }
1182
1183     if ((class = g_type_class_ref (object_type)) == NULL) {
1184         PyErr_SetString(PyExc_TypeError,
1185                         "could not get a reference to type class");
1186         return -1;
1187     }
1188
1189     if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, &params))
1190         goto cleanup;
1191
1192     if (pygobject_constructv(self, n_params, params))
1193         PyErr_SetString(PyExc_RuntimeError, "could not create object");
1194            
1195  cleanup:
1196     for (i = 0; i < n_params; i++) {
1197         g_free((gchar *) params[i].name);
1198         g_value_unset(&params[i].value);
1199     }
1200     g_free(params);
1201     g_type_class_unref(class);
1202     
1203     return (self->obj) ? 0 : -1;
1204 }
1205
1206 #define CHECK_GOBJECT(self) \
1207     if (!G_IS_OBJECT(self->obj)) {                                           \
1208         PyErr_Format(PyExc_TypeError,                                        \
1209                      "object at %p of type %s is not initialized",           \
1210                      self, Py_TYPE(self)->tp_name);                          \
1211         return NULL;                                                         \
1212     }
1213
1214 static PyObject *
1215 pygobject_get_property(PyGObject *self, PyObject *args)
1216 {
1217     gchar *param_name;
1218     GParamSpec *pspec;
1219     GValue value = { 0, };
1220     PyObject *ret;
1221
1222     if (!PyArg_ParseTuple(args, "s:GObject.get_property", &param_name))
1223         return NULL;
1224
1225     CHECK_GOBJECT(self);
1226     
1227     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1228                                          param_name);
1229     if (!pspec) {
1230         PyErr_Format(PyExc_TypeError,
1231                      "object of type `%s' does not have property `%s'",
1232                      g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1233         return NULL;
1234     }
1235     if (!(pspec->flags & G_PARAM_READABLE)) {
1236         PyErr_Format(PyExc_TypeError, "property %s is not readable",
1237                      param_name);
1238         return NULL;
1239     }
1240     g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1241     pyg_begin_allow_threads;
1242     g_object_get_property(self->obj, param_name, &value);
1243     pyg_end_allow_threads;
1244     ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
1245     g_value_unset(&value);
1246     return ret;
1247 }
1248
1249 static PyObject *
1250 pygobject_get_properties(PyGObject *self, PyObject *args)
1251 {
1252     GObjectClass *class;
1253     int len, i;
1254     PyObject *tuple;
1255
1256     if ((len = PyTuple_Size(args)) < 1) {
1257         PyErr_SetString(PyExc_TypeError, "requires at least one argument");
1258         return NULL;
1259     }
1260
1261     tuple = PyTuple_New(len);
1262     class = G_OBJECT_GET_CLASS(self->obj);
1263     for (i = 0; i < len; i++) {
1264         PyObject *py_property = PyTuple_GetItem(args, i);
1265         gchar *property_name;
1266         GParamSpec *pspec;
1267         GValue value = { 0 };
1268         PyObject *item;
1269
1270         if (!PYGLIB_PyUnicode_Check(py_property)) {
1271             PyErr_SetString(PyExc_TypeError,
1272                             "Expected string argument for property.");
1273             return NULL;
1274         }
1275
1276         property_name = PYGLIB_PyUnicode_AsString(py_property);
1277
1278         pspec = g_object_class_find_property(class,
1279                                          property_name);
1280         if (!pspec) {
1281             PyErr_Format(PyExc_TypeError,
1282                          "object of type `%s' does not have property `%s'",
1283                          g_type_name(G_OBJECT_TYPE(self->obj)), property_name);
1284         return NULL;
1285         }
1286         if (!(pspec->flags & G_PARAM_READABLE)) {
1287             PyErr_Format(PyExc_TypeError, "property %s is not readable",
1288                         property_name);
1289             return NULL;
1290         }
1291         g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
1292
1293         pyg_begin_allow_threads;
1294         g_object_get_property(self->obj, property_name, &value);
1295         pyg_end_allow_threads;
1296
1297         item = pyg_value_as_pyobject(&value, TRUE);
1298         PyTuple_SetItem(tuple, i, item);
1299
1300         g_value_unset(&value);
1301     }
1302
1303     return tuple;
1304 }
1305
1306 static PyObject *
1307 pygobject_set_property(PyGObject *self, PyObject *args)
1308 {
1309     gchar *param_name;
1310     GParamSpec *pspec;
1311     PyObject *pvalue;
1312
1313     if (!PyArg_ParseTuple(args, "sO:GObject.set_property", &param_name,
1314                           &pvalue))
1315         return NULL;
1316     
1317     CHECK_GOBJECT(self);
1318     
1319     pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
1320                                          param_name);
1321     if (!pspec) {
1322         PyErr_Format(PyExc_TypeError,
1323                      "object of type `%s' does not have property `%s'",
1324                      g_type_name(G_OBJECT_TYPE(self->obj)), param_name);
1325         return NULL;
1326     }
1327     
1328     if (!set_property_from_pspec(self->obj, param_name, pspec, pvalue))
1329         return NULL;
1330     
1331     Py_INCREF(Py_None);
1332     return Py_None;
1333 }
1334
1335 static PyObject *
1336 pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
1337 {    
1338     GObjectClass    *class;
1339     Py_ssize_t      pos;
1340     PyObject        *value;
1341     PyObject        *key;
1342     PyObject        *result = NULL;
1343
1344     CHECK_GOBJECT(self);
1345
1346     class = G_OBJECT_GET_CLASS(self->obj);
1347     
1348     g_object_freeze_notify (G_OBJECT(self->obj));
1349     pos = 0;
1350
1351     while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
1352         gchar *key_str = PYGLIB_PyUnicode_AsString(key);
1353         GParamSpec *pspec;
1354
1355         pspec = g_object_class_find_property(class, key_str);
1356         if (!pspec) {
1357             gchar buf[512];
1358
1359             g_snprintf(buf, sizeof(buf),
1360                        "object `%s' doesn't support property `%s'",
1361                        g_type_name(G_OBJECT_TYPE(self->obj)), key_str);
1362             PyErr_SetString(PyExc_TypeError, buf);
1363             goto exit;
1364         }
1365
1366         if (!set_property_from_pspec(G_OBJECT(self->obj), key_str, pspec, value))
1367             goto exit;
1368     }
1369
1370     result = Py_None;
1371
1372  exit:
1373     g_object_thaw_notify (G_OBJECT(self->obj));
1374     Py_XINCREF(result);
1375     return result;
1376 }
1377
1378 static PyObject *
1379 pygobject_freeze_notify(PyGObject *self, PyObject *args)
1380 {
1381     if (!PyArg_ParseTuple(args, ":GObject.freeze_notify"))
1382         return NULL;
1383     
1384     CHECK_GOBJECT(self);
1385     
1386     g_object_freeze_notify(self->obj);
1387     Py_INCREF(Py_None);
1388     return Py_None;
1389 }
1390
1391 static PyObject *
1392 pygobject_notify(PyGObject *self, PyObject *args)
1393 {
1394     char *property_name;
1395
1396     if (!PyArg_ParseTuple(args, "s:GObject.notify", &property_name))
1397         return NULL;
1398     
1399     CHECK_GOBJECT(self);
1400     
1401     g_object_notify(self->obj, property_name);
1402     Py_INCREF(Py_None);
1403     return Py_None;
1404 }
1405
1406 static PyObject *
1407 pygobject_thaw_notify(PyGObject *self, PyObject *args)
1408 {
1409     if (!PyArg_ParseTuple(args, ":GObject.thaw_notify"))
1410         return NULL;
1411     
1412     CHECK_GOBJECT(self);
1413     
1414     g_object_thaw_notify(self->obj);
1415     Py_INCREF(Py_None);
1416     return Py_None;
1417 }
1418
1419 static PyObject *
1420 pygobject_get_data(PyGObject *self, PyObject *args)
1421 {
1422     char *key;
1423     GQuark quark;
1424     PyObject *data;
1425
1426     if (!PyArg_ParseTuple(args, "s:GObject.get_data", &key))
1427         return NULL;
1428     
1429     CHECK_GOBJECT(self);
1430     
1431     quark = g_quark_from_string(key);
1432     data = g_object_get_qdata(self->obj, quark);
1433     if (!data) data = Py_None;
1434     Py_INCREF(data);
1435     return data;
1436 }
1437
1438 static PyObject *
1439 pygobject_set_data(PyGObject *self, PyObject *args)
1440 {
1441     char *key;
1442     GQuark quark;
1443     PyObject *data;
1444
1445     if (!PyArg_ParseTuple(args, "sO:GObject.set_data", &key, &data))
1446         return NULL;
1447     
1448     CHECK_GOBJECT(self);
1449     
1450     quark = g_quark_from_string(key);
1451     Py_INCREF(data);
1452     g_object_set_qdata_full(self->obj, quark, data, pyg_destroy_notify);
1453     Py_INCREF(Py_None);
1454     return Py_None;
1455 }
1456
1457 static PyObject *
1458 pygobject_connect(PyGObject *self, PyObject *args)
1459 {
1460     PyObject *first, *callback, *extra_args;
1461     gchar *name;
1462     guint sigid, len;
1463     gulong handlerid;
1464     GQuark detail = 0;
1465     GClosure *closure;
1466
1467     len = PyTuple_Size(args);
1468     if (len < 2) {
1469         PyErr_SetString(PyExc_TypeError,
1470                         "GObject.connect requires at least 2 arguments");
1471         return NULL;
1472     }
1473     first = PySequence_GetSlice(args, 0, 2);
1474     if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) {
1475         Py_DECREF(first);
1476         return NULL;
1477     }
1478     Py_DECREF(first);
1479     if (!PyCallable_Check(callback)) {
1480         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1481         return NULL;
1482     }
1483     
1484     CHECK_GOBJECT(self);
1485     
1486     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1487                              &sigid, &detail, TRUE)) {
1488         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1489                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1490                      name);
1491         return NULL;
1492     }
1493     extra_args = PySequence_GetSlice(args, 2, len);
1494     if (extra_args == NULL)
1495         return NULL;
1496
1497     closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1498     if (closure == NULL)
1499         closure = pyg_closure_new(callback, extra_args, NULL);
1500
1501     pygobject_watch_closure((PyObject *)self, closure);
1502     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1503                                                closure, FALSE);
1504     Py_DECREF(extra_args);
1505     return PyLong_FromUnsignedLong(handlerid);
1506 }
1507
1508 static PyObject *
1509 pygobject_connect_after(PyGObject *self, PyObject *args)
1510 {
1511     PyObject *first, *callback, *extra_args;
1512     gchar *name;
1513     guint sigid;
1514     gulong handlerid;
1515     Py_ssize_t len;
1516     GQuark detail;
1517     GClosure *closure;
1518
1519     len = PyTuple_Size(args);
1520     if (len < 2) {
1521         PyErr_SetString(PyExc_TypeError,
1522                         "GObject.connect_after requires at least 2 arguments");
1523         return NULL;
1524     }
1525     first = PySequence_GetSlice(args, 0, 2);
1526     if (!PyArg_ParseTuple(first, "sO:GObject.connect_after",
1527                           &name, &callback)) {
1528         Py_DECREF(first);
1529         return NULL;
1530     }
1531     Py_DECREF(first);
1532     if (!PyCallable_Check(callback)) {
1533         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1534         return NULL;
1535     }
1536     
1537     CHECK_GOBJECT(self);
1538     
1539     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1540                              &sigid, &detail, TRUE)) {
1541         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1542                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1543                      name);
1544         return NULL;
1545     }
1546     extra_args = PySequence_GetSlice(args, 2, len);
1547     if (extra_args == NULL)
1548         return NULL;
1549
1550     closure = pygi_signal_closure_new(self, name, callback, extra_args, NULL);
1551     if (closure == NULL)
1552         closure = pyg_closure_new(callback, extra_args, NULL);
1553
1554     pygobject_watch_closure((PyObject *)self, closure);
1555     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1556                                                closure, TRUE);
1557     Py_DECREF(extra_args);
1558     return PyLong_FromUnsignedLong(handlerid);
1559 }
1560
1561 static PyObject *
1562 pygobject_connect_object(PyGObject *self, PyObject *args)
1563 {
1564     PyObject *first, *callback, *extra_args, *object;
1565     gchar *name;
1566     guint sigid;
1567     gulong handlerid;
1568     Py_ssize_t len;
1569     GQuark detail;
1570     GClosure *closure;
1571
1572     len = PyTuple_Size(args);
1573     if (len < 3) {
1574         PyErr_SetString(PyExc_TypeError,
1575                 "GObject.connect_object requires at least 3 arguments");
1576         return NULL;
1577     }
1578     first = PySequence_GetSlice(args, 0, 3);
1579     if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object",
1580                           &name, &callback, &object)) {
1581         Py_DECREF(first);
1582         return NULL;
1583     }
1584     Py_DECREF(first);
1585     if (!PyCallable_Check(callback)) {
1586         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1587         return NULL;
1588     }
1589     
1590     CHECK_GOBJECT(self);
1591     
1592     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1593                              &sigid, &detail, TRUE)) {
1594         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1595                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1596                      name);
1597         return NULL;
1598     }
1599     extra_args = PySequence_GetSlice(args, 3, len);
1600     if (extra_args == NULL)
1601         return NULL;
1602
1603     closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1604     if (closure == NULL)
1605         closure = pyg_closure_new(callback, extra_args, object);
1606
1607     pygobject_watch_closure((PyObject *)self, closure);
1608     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1609                                                closure, FALSE);
1610     Py_DECREF(extra_args);
1611     return PyLong_FromUnsignedLong(handlerid);
1612 }
1613
1614 static PyObject *
1615 pygobject_connect_object_after(PyGObject *self, PyObject *args)
1616 {
1617     PyObject *first, *callback, *extra_args, *object;
1618     gchar *name;
1619     guint sigid;
1620     gulong handlerid;
1621     Py_ssize_t len;
1622     GQuark detail;
1623     GClosure *closure;
1624
1625     len = PyTuple_Size(args);
1626     if (len < 3) {
1627         PyErr_SetString(PyExc_TypeError,
1628                 "GObject.connect_object_after requires at least 3 arguments");
1629         return NULL;
1630     }
1631     first = PySequence_GetSlice(args, 0, 3);
1632     if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after",
1633                           &name, &callback, &object)) {
1634         Py_DECREF(first);
1635         return NULL;
1636     }
1637     Py_DECREF(first);
1638     if (!PyCallable_Check(callback)) {
1639         PyErr_SetString(PyExc_TypeError, "second argument must be callable");
1640         return NULL;
1641     }
1642     
1643     CHECK_GOBJECT(self);
1644     
1645     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1646                              &sigid, &detail, TRUE)) {
1647         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1648                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1649                      name);
1650         return NULL;
1651     }
1652     extra_args = PySequence_GetSlice(args, 3, len);
1653     if (extra_args == NULL)
1654         return NULL;
1655
1656     closure = pygi_signal_closure_new(self, name, callback, extra_args, object);
1657     if (closure == NULL)
1658         closure = pyg_closure_new(callback, extra_args, object);
1659
1660     pygobject_watch_closure((PyObject *)self, closure);
1661     handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail,
1662                                                closure, TRUE);
1663     Py_DECREF(extra_args);
1664     return PyLong_FromUnsignedLong(handlerid);
1665 }
1666
1667 static PyObject *
1668 pygobject_disconnect(PyGObject *self, PyObject *args)
1669 {
1670     gulong handler_id;
1671
1672     if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
1673         return NULL;
1674     
1675     CHECK_GOBJECT(self);
1676     
1677     g_signal_handler_disconnect(self->obj, handler_id);
1678     Py_INCREF(Py_None);
1679     return Py_None;
1680 }
1681
1682 static PyObject *
1683 pygobject_handler_is_connected(PyGObject *self, PyObject *args)
1684 {
1685     gulong handler_id;
1686
1687     if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
1688         return NULL;
1689
1690     
1691     CHECK_GOBJECT(self);
1692     
1693     return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
1694 }
1695
1696 static PyObject *
1697 pygobject_handler_block(PyGObject *self, PyObject *args)
1698 {
1699     gulong handler_id;
1700
1701     if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
1702         return NULL;
1703     
1704     CHECK_GOBJECT(self);
1705     
1706     g_signal_handler_block(self->obj, handler_id);
1707     Py_INCREF(Py_None);
1708     return Py_None;
1709 }
1710
1711 static PyObject *
1712 pygobject_handler_unblock(PyGObject *self, PyObject *args)
1713 {
1714     gulong handler_id;
1715
1716     if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
1717         return NULL;
1718     g_signal_handler_unblock(self->obj, handler_id);
1719     Py_INCREF(Py_None);
1720     return Py_None;
1721 }
1722
1723 static PyObject *
1724 pygobject_emit(PyGObject *self, PyObject *args)
1725 {
1726     guint signal_id, i;
1727     Py_ssize_t len;
1728     GQuark detail;
1729     PyObject *first, *py_ret;
1730     gchar *name;
1731     GSignalQuery query;
1732     GValue *params, ret = { 0, };
1733     
1734     len = PyTuple_Size(args);
1735     if (len < 1) {
1736         PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg");
1737         return NULL;
1738     }
1739     first = PySequence_GetSlice(args, 0, 1);
1740     if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) {
1741         Py_DECREF(first);
1742         return NULL;
1743     }
1744     Py_DECREF(first);
1745     
1746     CHECK_GOBJECT(self);
1747     
1748     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
1749                              &signal_id, &detail, TRUE)) {
1750         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1751                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1752                      name);
1753         return NULL;
1754     }
1755     g_signal_query(signal_id, &query);
1756     if (len != query.n_params + 1) {
1757         gchar buf[128];
1758
1759         g_snprintf(buf, sizeof(buf),
1760                    "%d parameters needed for signal %s; %ld given",
1761                    query.n_params, name, (long int) (len - 1));
1762         PyErr_SetString(PyExc_TypeError, buf);
1763         return NULL;
1764     }
1765
1766     params = g_new0(GValue, query.n_params + 1);
1767     g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1768     g_value_set_object(&params[0], G_OBJECT(self->obj));
1769
1770     for (i = 0; i < query.n_params; i++)
1771         g_value_init(&params[i + 1],
1772                      query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1773     for (i = 0; i < query.n_params; i++) {
1774         PyObject *item = PyTuple_GetItem(args, i+1);
1775
1776         if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1777             gchar buf[128];
1778             g_snprintf(buf, sizeof(buf),
1779                        "could not convert type %s to %s required for parameter %d",
1780                        Py_TYPE(item)->tp_name,
1781                 g_type_name(G_VALUE_TYPE(&params[i+1])), i);
1782             PyErr_SetString(PyExc_TypeError, buf);
1783
1784             for (i = 0; i < query.n_params + 1; i++)
1785                 g_value_unset(&params[i]);
1786
1787             g_free(params);
1788             return NULL;
1789         }
1790     }    
1791
1792     if (query.return_type != G_TYPE_NONE)
1793         g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1794     
1795     g_signal_emitv(params, signal_id, detail, &ret);
1796
1797     for (i = 0; i < query.n_params + 1; i++)
1798         g_value_unset(&params[i]);
1799     
1800     g_free(params);
1801     if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) {
1802         py_ret = pyg_value_as_pyobject(&ret, TRUE);
1803         g_value_unset(&ret);
1804     } else {
1805         Py_INCREF(Py_None);
1806         py_ret = Py_None;
1807     }
1808
1809     return py_ret;
1810 }
1811
1812 static PyObject *
1813 pygobject_stop_emission(PyGObject *self, PyObject *args)
1814 {
1815     gchar *signal;
1816     guint signal_id;
1817     GQuark detail;
1818
1819     if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
1820         return NULL;
1821     
1822     CHECK_GOBJECT(self);
1823     
1824     if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
1825                              &signal_id, &detail, TRUE)) {
1826         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1827                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1828                      signal);
1829         return NULL;
1830     }
1831     g_signal_stop_emission(self->obj, signal_id, detail);
1832     Py_INCREF(Py_None);
1833     return Py_None;
1834 }
1835
1836 static PyObject *
1837 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
1838 {
1839     GSignalInvocationHint *ihint;
1840     guint signal_id, i;
1841     Py_ssize_t len;
1842     PyObject *py_ret;
1843     const gchar *name;
1844     GSignalQuery query;
1845     GValue *params, ret = { 0, };
1846     
1847     CHECK_GOBJECT(self);
1848     
1849     ihint = g_signal_get_invocation_hint(self->obj);
1850     if (!ihint) {
1851         PyErr_SetString(PyExc_TypeError, "could not find signal invocation "
1852                         "information for this object.");
1853         return NULL;
1854     }
1855
1856     signal_id = ihint->signal_id;
1857     name = g_signal_name(signal_id);
1858
1859     len = PyTuple_Size(args);
1860     if (signal_id == 0) {
1861         PyErr_SetString(PyExc_TypeError, "unknown signal name");
1862         return NULL;
1863     }
1864     g_signal_query(signal_id, &query);
1865     if (len != query.n_params) {
1866         gchar buf[128];
1867
1868         g_snprintf(buf, sizeof(buf),
1869                    "%d parameters needed for signal %s; %ld given",
1870                    query.n_params, name, (long int) len);
1871         PyErr_SetString(PyExc_TypeError, buf);
1872         return NULL;
1873     }
1874     params = g_new0(GValue, query.n_params + 1);
1875     g_value_init(&params[0], G_OBJECT_TYPE(self->obj));
1876     g_value_set_object(&params[0], G_OBJECT(self->obj));
1877
1878     for (i = 0; i < query.n_params; i++)
1879         g_value_init(&params[i + 1],
1880                      query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1881     for (i = 0; i < query.n_params; i++) {
1882         PyObject *item = PyTuple_GetItem(args, i);
1883
1884         if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) {
1885             g_value_set_static_boxed(&params[i+1], pyg_boxed_get(item, void));
1886         }
1887         else if (pyg_value_from_pyobject(&params[i+1], item) < 0) {
1888             gchar buf[128];
1889
1890             g_snprintf(buf, sizeof(buf),
1891                        "could not convert type %s to %s required for parameter %d",
1892                        Py_TYPE(item)->tp_name,
1893                        g_type_name(G_VALUE_TYPE(&params[i+1])), i);
1894             PyErr_SetString(PyExc_TypeError, buf);
1895             for (i = 0; i < query.n_params + 1; i++)
1896                 g_value_unset(&params[i]);
1897             g_free(params);
1898             return NULL;
1899         }
1900     }
1901     if (query.return_type != G_TYPE_NONE)
1902         g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1903     g_signal_chain_from_overridden(params, &ret);
1904     for (i = 0; i < query.n_params + 1; i++)
1905         g_value_unset(&params[i]);
1906     g_free(params);
1907     if (query.return_type != G_TYPE_NONE) {
1908         py_ret = pyg_value_as_pyobject(&ret, TRUE);
1909         g_value_unset(&ret);
1910     } else {
1911         Py_INCREF(Py_None);
1912         py_ret = Py_None;
1913     }
1914     return py_ret;
1915 }
1916
1917
1918 static PyObject *
1919 pygobject_weak_ref(PyGObject *self, PyObject *args)
1920 {
1921     int len;
1922     PyObject *callback = NULL, *user_data = NULL;
1923     PyObject *retval;
1924
1925     CHECK_GOBJECT(self);
1926
1927     if ((len = PySequence_Length(args)) >= 1) {
1928         callback = PySequence_ITEM(args, 0);
1929         user_data = PySequence_GetSlice(args, 1, len);
1930     }
1931     retval = pygobject_weak_ref_new(self->obj, callback, user_data);
1932     Py_XDECREF(callback);
1933     Py_XDECREF(user_data);
1934     return retval;
1935 }
1936
1937
1938 static PyObject *
1939 pygobject_copy(PyGObject *self)
1940 {
1941     PyErr_SetString(PyExc_TypeError,
1942                     "GObject descendants' instances are non-copyable");
1943     return NULL;
1944 }
1945
1946 static PyObject *
1947 pygobject_deepcopy(PyGObject *self, PyObject *args)
1948 {
1949     PyErr_SetString(PyExc_TypeError,
1950                     "GObject descendants' instances are non-copyable");
1951     return NULL;
1952 }
1953
1954
1955 static PyObject *
1956 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
1957 {
1958     PyObject *pyfunc = NULL;
1959     GClosure *closure = NULL;
1960     guint retval;
1961     
1962     CHECK_GOBJECT(self);
1963
1964     if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc))
1965         return NULL;
1966
1967     if (!PyCallable_Check(pyfunc)) {
1968         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
1969         return NULL;
1970     }
1971
1972     closure = gclosure_from_pyfunc(self, pyfunc);
1973     if (!closure) {
1974         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
1975                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
1976         return NULL;
1977     }
1978     
1979     retval = g_signal_handlers_disconnect_matched(self->obj,
1980                                                   G_SIGNAL_MATCH_CLOSURE,
1981                                                   0, 0,
1982                                                   closure,
1983                                                   NULL, NULL);
1984     return PYGLIB_PyLong_FromLong(retval);
1985 }
1986
1987 static PyObject *
1988 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
1989 {
1990     PyObject *pyfunc = NULL;
1991     GClosure *closure = NULL;
1992     guint retval;
1993     
1994     CHECK_GOBJECT(self);
1995
1996     if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc))
1997         return NULL;
1998
1999     if (!PyCallable_Check(pyfunc)) {
2000         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2001         return NULL;
2002     }
2003
2004     closure = gclosure_from_pyfunc(self, pyfunc);
2005     if (!closure) {
2006         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2007                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2008         return NULL;
2009     }
2010     
2011     retval = g_signal_handlers_block_matched(self->obj,
2012                                              G_SIGNAL_MATCH_CLOSURE,
2013                                              0, 0,
2014                                              closure,
2015                                              NULL, NULL);
2016     return PYGLIB_PyLong_FromLong(retval);
2017 }
2018
2019 static PyObject *
2020 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
2021 {
2022     PyObject *pyfunc = NULL;
2023     GClosure *closure = NULL;
2024     guint retval;
2025     
2026     CHECK_GOBJECT(self);
2027
2028     if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc))
2029         return NULL;
2030
2031     if (!PyCallable_Check(pyfunc)) {
2032         PyErr_SetString(PyExc_TypeError, "first argument must be callable");
2033         return NULL;
2034     }
2035
2036     closure = gclosure_from_pyfunc(self, pyfunc);
2037     if (!closure) {
2038         PyErr_Format(PyExc_TypeError, "nothing connected to %s",
2039                      PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
2040         return NULL;
2041     }
2042     
2043     retval = g_signal_handlers_unblock_matched(self->obj,
2044                                                G_SIGNAL_MATCH_CLOSURE,
2045                                                0, 0,
2046                                                closure,
2047                                                NULL, NULL);
2048     return PYGLIB_PyLong_FromLong(retval);
2049 }
2050
2051 static PyMethodDef pygobject_methods[] = {
2052     { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
2053     { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
2054     { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
2055     { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
2056     { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
2057     { "notify", (PyCFunction)pygobject_notify, METH_VARARGS },
2058     { "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS },
2059     { "get_data", (PyCFunction)pygobject_get_data, METH_VARARGS },
2060     { "set_data", (PyCFunction)pygobject_set_data, METH_VARARGS },
2061     { "connect", (PyCFunction)pygobject_connect, METH_VARARGS },
2062     { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
2063     { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
2064     { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
2065     { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2066     { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
2067     { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
2068     { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
2069     { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
2070     { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
2071     { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
2072     { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
2073     { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
2074     { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
2075     { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
2076     { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
2077     { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
2078     { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
2079     { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS },
2080     { NULL, NULL, 0 }
2081 };
2082
2083
2084 static PyObject *
2085 pygobject_get_dict(PyGObject *self, void *closure)
2086 {
2087     if (self->inst_dict == NULL) {
2088         self->inst_dict = PyDict_New();
2089         if (self->inst_dict == NULL)
2090             return NULL;
2091         if (G_LIKELY(self->obj))
2092             pygobject_switch_to_toggle_ref(self);
2093     }
2094     Py_INCREF(self->inst_dict);
2095     return self->inst_dict;
2096 }
2097
2098 static PyObject *
2099 pygobject_get_refcount(PyGObject *self, void *closure)
2100 {
2101     return PYGLIB_PyLong_FromLong(self->obj->ref_count);
2102 }
2103
2104 static int
2105 pygobject_setattro(PyObject *self, PyObject *name, PyObject *value)
2106 {
2107     int res;
2108     PyGObject *gself = (PyGObject *) self;
2109     PyObject *inst_dict_before = gself->inst_dict;
2110       /* call parent type's setattro */
2111     res = PyGObject_Type.tp_base->tp_setattro(self, name, value);
2112     if (inst_dict_before == NULL && gself->inst_dict != NULL) {
2113         if (G_LIKELY(gself->obj))
2114             pygobject_switch_to_toggle_ref(gself);
2115     }
2116     return res;
2117 }
2118
2119 static PyGetSetDef pygobject_getsets[] = {
2120     { "__dict__", (getter)pygobject_get_dict, (setter)0 },
2121     { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, },
2122     { NULL, 0, 0 }
2123 };
2124
2125 /* ------------------------------------ */
2126 /* ****** GObject weak reference ****** */
2127 /* ------------------------------------ */
2128
2129 typedef struct {
2130     PyObject_HEAD
2131     GObject *obj;
2132     PyObject *callback;
2133     PyObject *user_data;
2134     gboolean have_floating_ref;
2135 } PyGObjectWeakRef;
2136
2137 PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef);
2138
2139 static int
2140 pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg)
2141 {
2142     if (self->callback && visit(self->callback, arg) < 0)
2143         return -1;
2144     if (self->user_data && visit(self->user_data, arg) < 0)
2145         return -1;
2146     return 0;
2147 }
2148
2149 static void
2150 pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy)
2151 {
2152     self->obj = NULL;
2153     if (self->callback) {
2154         PyObject *retval;
2155         PyGILState_STATE state = pyglib_gil_state_ensure();
2156         retval = PyObject_Call(self->callback, self->user_data, NULL);
2157         if (retval) {
2158             if (retval != Py_None)
2159                 PyErr_Format(PyExc_TypeError,
2160                              "GObject weak notify callback returned a value"
2161                              " of type %s, should return None",
2162                              Py_TYPE(retval)->tp_name);
2163             Py_DECREF(retval);
2164             PyErr_Print();
2165         } else
2166             PyErr_Print();
2167         Py_CLEAR(self->callback);
2168         Py_CLEAR(self->user_data);
2169         if (self->have_floating_ref) {
2170             self->have_floating_ref = FALSE;
2171             Py_DECREF((PyObject *) self);
2172         }
2173         pyglib_gil_state_release(state);
2174     }
2175 }
2176
2177 static inline int
2178 pygobject_weak_ref_clear(PyGObjectWeakRef *self)
2179 {
2180     Py_CLEAR(self->callback);
2181     Py_CLEAR(self->user_data);
2182     if (self->obj) {
2183         g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2184         self->obj = NULL;
2185     }
2186     return 0;
2187 }
2188
2189 static void
2190 pygobject_weak_ref_dealloc(PyGObjectWeakRef *self)
2191 {
2192     PyObject_GC_UnTrack((PyObject *)self);
2193     pygobject_weak_ref_clear(self);
2194     PyObject_GC_Del(self);
2195 }
2196
2197 static PyObject *
2198 pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data)
2199 {
2200     PyGObjectWeakRef *self;
2201
2202     self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type);
2203     self->callback = callback;
2204     self->user_data = user_data;
2205     Py_XINCREF(self->callback);
2206     Py_XINCREF(self->user_data);
2207     self->obj = obj;
2208     g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2209     if (callback != NULL) {
2210           /* when we have a callback, we should INCREF the weakref
2211            * object to make it stay alive even if it goes out of scope */
2212         self->have_floating_ref = TRUE;
2213         Py_INCREF((PyObject *) self);
2214     }
2215     return (PyObject *) self;
2216 }
2217
2218 static PyObject *
2219 pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args)
2220 {
2221     if (!self->obj) {
2222         PyErr_SetString(PyExc_ValueError, "weak ref already unreffed");
2223         return NULL;
2224     }
2225     g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
2226     self->obj = NULL;
2227     if (self->have_floating_ref) {
2228         self->have_floating_ref = FALSE;
2229         Py_DECREF(self);
2230     }
2231     Py_INCREF(Py_None);
2232     return Py_None;
2233 }
2234
2235 static PyMethodDef pygobject_weak_ref_methods[] = {
2236     { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS},
2237     { NULL, NULL, 0}
2238 };
2239
2240 static PyObject *
2241 pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
2242 {
2243     static char *argnames[] = {NULL};
2244
2245     if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames))
2246         return NULL;
2247
2248     if (self->obj)
2249         return pygobject_new_full(self->obj, FALSE, NULL);
2250     else {
2251         Py_INCREF(Py_None);
2252         return Py_None;
2253     }
2254 }
2255
2256 static gpointer
2257 pyobject_copy(gpointer boxed)
2258 {
2259     PyObject *object = boxed;
2260
2261     Py_INCREF(object);
2262     return object;
2263 }
2264
2265 static void
2266 pyobject_free(gpointer boxed)
2267 {
2268     PyObject *object = boxed;
2269     PyGILState_STATE state;
2270
2271     state = pyglib_gil_state_ensure();
2272     Py_DECREF(object);
2273     pyglib_gil_state_release(state);
2274 }
2275
2276 void
2277 pygobject_object_register_types(PyObject *d)
2278 {
2279     PyObject *o, *descr;
2280
2281     pygobject_class_key = g_quark_from_static_string("PyGObject::class");
2282     pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
2283     pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
2284     pygobject_has_updated_constructor_key =
2285         g_quark_from_static_string("PyGObject::has-updated-constructor");
2286     pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data");
2287
2288     /* GObject */
2289     if (!PY_TYPE_OBJECT)
2290         PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
2291                                                       pyobject_copy,
2292                                                       pyobject_free);
2293     PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
2294     PyGObject_Type.tp_richcompare = pygobject_richcompare;
2295     PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
2296     PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
2297     PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
2298     PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2299                                Py_TPFLAGS_HAVE_GC);
2300     PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse;
2301     PyGObject_Type.tp_clear = (inquiry)pygobject_clear;
2302     PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
2303     PyGObject_Type.tp_methods = pygobject_methods;
2304     PyGObject_Type.tp_getset = pygobject_getsets;
2305     PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
2306     PyGObject_Type.tp_init = (initproc)pygobject_init;
2307     PyGObject_Type.tp_free = (freefunc)pygobject_free;
2308     PyGObject_Type.tp_alloc = PyType_GenericAlloc;
2309     PyGObject_Type.tp_new = PyType_GenericNew;
2310     pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
2311                              &PyGObject_Type, NULL);
2312     PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
2313                          pyg_object_descr_doc_get());
2314
2315     /* GProps */
2316     PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc;
2317     PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence;
2318     PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro;
2319     PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro;
2320     PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2321     PyGProps_Type.tp_doc = "The properties of the GObject accessible as "
2322         "Python attributes.";
2323     PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse;
2324     PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter;
2325     if (PyType_Ready(&PyGProps_Type) < 0)
2326         return;
2327
2328     /* GPropsDescr */
2329     PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2330     PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get;
2331     if (PyType_Ready(&PyGPropsDescr_Type) < 0)
2332         return;
2333     descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
2334     PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
2335     PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__",
2336                         o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject"));
2337     Py_DECREF(o);
2338
2339     /* GPropsIter */
2340     PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc;
2341     PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
2342     PyGPropsIter_Type.tp_doc = "GObject properties iterator";
2343     PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next;
2344     if (PyType_Ready(&PyGPropsIter_Type) < 0)
2345         return;
2346
2347     PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc;
2348     PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call;
2349     PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
2350     PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference";
2351     PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse;
2352     PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear;
2353     PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods;
2354     if (PyType_Ready(&PyGObjectWeakRef_Type) < 0)
2355         return;
2356     PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
2357 }