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