Imported Upstream version 2.28.6
[platform/upstream/pygobject2.git] / gi / _gobject / gobjectmodule.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  *   gobjectmodule.c: wrapper for the gobject library.
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 <gobject/gvaluecollector.h>
28 #include <pyglib.h>
29 #include <pythread.h>
30 #include "pygobject-private.h"
31 #include "pygboxed.h"
32 #include "pygenum.h"
33 #include "pygflags.h"
34 #include "pyginterface.h"
35 #include "pygparamspec.h"
36 #include "pygpointer.h"
37 #include "pygtype.h"
38
39 #ifdef HAVE_FFI_H
40 #include "ffi-marshaller.h"
41 static GSignalCMarshaller marshal_generic = g_cclosure_marshal_generic_ffi;
42 #else
43 static GSignalCMarshaller marshal_generic = 0;
44 #endif
45
46 static PyObject *_pyg_signal_accumulator_true_handled_func;
47 static GHashTable *log_handlers = NULL;
48 static gboolean log_handlers_disabled = FALSE;
49
50 static void pyg_flags_add_constants(PyObject *module, GType flags_type,
51                                     const gchar *strip_prefix);
52
53
54 /* -------------- GDK threading hooks ---------------------------- */
55
56 /**
57  * pyg_set_thread_block_funcs:
58  * @block_threads_func: a function to block Python threads.
59  * @unblock_threads_func: a function to unblock Python threads.
60  *
61  * an interface to allow pygtk to add hooks to handle threading
62  * similar to the old PyGTK 0.6.x releases.  May not work quite right
63  * anymore.
64  */
65 static void
66 pyg_set_thread_block_funcs (PyGThreadBlockFunc block_threads_func,
67                             PyGThreadBlockFunc unblock_threads_func)
68 {
69     g_return_if_fail(pygobject_api_functions.block_threads == NULL &&
70                      pygobject_api_functions.unblock_threads == NULL);
71
72     pygobject_api_functions.block_threads   = block_threads_func;
73     pygobject_api_functions.unblock_threads = unblock_threads_func;
74     pyglib_set_thread_block_funcs(block_threads_func,
75                                   unblock_threads_func);
76 }
77
78 /**
79  * pyg_destroy_notify:
80  * @user_data: a PyObject pointer.
81  *
82  * A function that can be used as a GDestroyNotify callback that will
83  * call Py_DECREF on the data.
84  */
85 void
86 pyg_destroy_notify(gpointer user_data)
87 {
88     PyObject *obj = (PyObject *)user_data;
89     PyGILState_STATE state;
90
91     state = pyglib_gil_state_ensure();
92     Py_DECREF(obj);
93     pyglib_gil_state_release(state);
94 }
95
96
97 /* ---------------- gobject module functions -------------------- */
98
99 static PyObject *
100 pyg_type_name (PyObject *self, PyObject *args)
101 {
102     PyObject *gtype;
103     GType type;
104     const gchar *name;
105
106 #if 0
107     if (PyErr_Warn(PyExc_DeprecationWarning,
108                    "gobject.type_name is deprecated; "
109                    "use GType.name instead"))
110         return NULL;
111 #endif
112
113     if (!PyArg_ParseTuple(args, "O:gobject.type_name", &gtype))
114         return NULL;
115     if ((type = pyg_type_from_object(gtype)) == 0)
116         return NULL;
117     name = g_type_name(type);
118     if (name)
119         return PYGLIB_PyUnicode_FromString(name);
120     PyErr_SetString(PyExc_RuntimeError, "unknown typecode");
121     return NULL;
122 }
123
124 static PyObject *
125 pyg_type_from_name (PyObject *self, PyObject *args)
126 {
127     const gchar *name;
128     GType type;
129 #if 0
130     if (PyErr_Warn(PyExc_DeprecationWarning,
131                    "gobject.type_from_name is deprecated; "
132                    "use GType.from_name instead"))
133         return NULL;
134 #endif
135     if (!PyArg_ParseTuple(args, "s:gobject.type_from_name", &name))
136         return NULL;
137     type = _pyg_type_from_name(name);
138     if (type != 0)
139         return pyg_type_wrapper_new(type);
140     PyErr_Format(PyExc_RuntimeError, "%s: unknown type name: %s",
141          PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
142                  name);
143     return NULL;
144 }
145
146 static PyObject *
147 pyg_type_parent (PyObject *self, PyObject *args)
148 {
149     PyObject *gtype;
150     GType type, parent;
151 #if 0
152     if (PyErr_Warn(PyExc_DeprecationWarning,
153                    "gobject.type_parent is deprecated; "
154                    "use GType.parent instead"))
155         return NULL;
156 #endif
157     if (!PyArg_ParseTuple(args, "O:gobject.type_parent", &gtype))
158         return NULL;
159     if ((type = pyg_type_from_object(gtype)) == 0)
160         return NULL;
161     parent = g_type_parent(type);
162     if (parent != 0)
163         return pyg_type_wrapper_new(parent);
164     PyErr_SetString(PyExc_RuntimeError, "no parent for type");
165     return NULL;
166 }
167
168 static PyObject *
169 pyg_type_is_a (PyObject *self, PyObject *args)
170 {
171     PyObject *gtype, *gparent;
172     GType type, parent;
173 #if 0
174     if (PyErr_Warn(PyExc_DeprecationWarning,
175                    "gobject.type_is_a is deprecated; "
176                    "use GType.is_a instead"))
177         return NULL;
178 #endif
179     if (!PyArg_ParseTuple(args, "OO:gobject.type_is_a", &gtype, &gparent))
180         return NULL;
181     if ((type = pyg_type_from_object(gtype)) == 0)
182         return NULL;
183     if ((parent = pyg_type_from_object(gparent)) == 0)
184         return NULL;
185     return PyBool_FromLong(g_type_is_a(type, parent));
186 }
187
188 static PyObject *
189 pyg_type_children (PyObject *self, PyObject *args)
190 {
191     PyObject *gtype, *list;
192     GType type, *children;
193     guint n_children, i;
194 #if 0
195     if (PyErr_Warn(PyExc_DeprecationWarning,
196                    "gobject.type_children is deprecated; "
197                    "use GType.children instead"))
198         return NULL;
199 #endif
200     if (!PyArg_ParseTuple(args, "O:gobject.type_children", &gtype))
201         return NULL;
202     if ((type = pyg_type_from_object(gtype)) == 0)
203         return NULL;
204     children = g_type_children(type, &n_children);
205     if (children) {
206         list = PyList_New(0);
207         for (i = 0; i < n_children; i++) {
208             PyObject *o;
209             PyList_Append(list, o=pyg_type_wrapper_new(children[i]));
210             Py_DECREF(o);
211         }
212         g_free(children);
213         return list;
214     }
215     PyErr_SetString(PyExc_RuntimeError, "invalid type, or no children");
216     return NULL;
217 }
218
219 static PyObject *
220 pyg_type_interfaces (PyObject *self, PyObject *args)
221 {
222     PyObject *gtype, *list;
223     GType type, *interfaces;
224     guint n_interfaces, i;
225 #if 0
226     if (PyErr_Warn(PyExc_DeprecationWarning,
227                    "gobject.type_interfaces is deprecated; "
228                    "use GType.interfaces instead"))
229         return NULL;
230 #endif
231     if (!PyArg_ParseTuple(args, "O:gobject.type_interfaces", &gtype))
232         return NULL;
233     if ((type = pyg_type_from_object(gtype)) == 0)
234         return NULL;
235     interfaces = g_type_interfaces(type, &n_interfaces);
236     if (interfaces) {
237         list = PyList_New(0);
238         for (i = 0; i < n_interfaces; i++) {
239             PyObject *o;
240             PyList_Append(list, o=pyg_type_wrapper_new(interfaces[i]));
241             Py_DECREF(o);
242         }
243         g_free(interfaces);
244         return list;
245     }
246     PyErr_SetString(PyExc_RuntimeError, "invalid type, or no interfaces");
247     return NULL;
248 }
249
250 static void
251 pyg_object_set_property (GObject *object, guint property_id,
252                          const GValue *value, GParamSpec *pspec)
253 {
254     PyObject *object_wrapper, *retval;
255     PyObject *py_pspec, *py_value;
256     PyGILState_STATE state;
257
258     state = pyglib_gil_state_ensure();
259
260     object_wrapper = pygobject_new(object);
261
262     if (object_wrapper == NULL) {
263         pyglib_gil_state_release(state);
264         return;
265     }
266
267     py_pspec = pyg_param_spec_new(pspec);
268     py_value = pyg_value_as_pyobject (value, TRUE);
269
270     retval = PyObject_CallMethod(object_wrapper, "do_set_property",
271                                  "OO", py_pspec, py_value);
272     if (retval) {
273         Py_DECREF(retval);
274     } else {
275         PyErr_Print();
276     }
277
278     Py_DECREF(object_wrapper);
279     Py_DECREF(py_pspec);
280     Py_DECREF(py_value);
281
282     pyglib_gil_state_release(state);
283 }
284
285 static void
286 pyg_object_get_property (GObject *object, guint property_id,
287                          GValue *value, GParamSpec *pspec)
288 {
289     PyObject *object_wrapper, *retval;
290     PyObject *py_pspec;
291     PyGILState_STATE state;
292
293     state = pyglib_gil_state_ensure();
294
295     object_wrapper = pygobject_new(object);
296
297     if (object_wrapper == NULL) {
298         pyglib_gil_state_release(state);
299         return;
300     }
301
302     py_pspec = pyg_param_spec_new(pspec);
303     retval = PyObject_CallMethod(object_wrapper, "do_get_property",
304                                  "O", py_pspec);
305     if (retval == NULL || pyg_value_from_pyobject(value, retval) < 0) {
306         PyErr_Print();
307     }
308     Py_DECREF(object_wrapper);
309     Py_DECREF(py_pspec);
310     Py_XDECREF(retval);
311
312     pyglib_gil_state_release(state);
313 }
314
315 static void
316 pyg_object_class_init(GObjectClass *class, PyObject *py_class)
317 {
318     class->set_property = pyg_object_set_property;
319     class->get_property = pyg_object_get_property;
320 }
321
322 typedef struct _PyGSignalAccumulatorData {
323     PyObject *callable;
324     PyObject *user_data;
325 } PyGSignalAccumulatorData;
326
327 static gboolean
328 _pyg_signal_accumulator(GSignalInvocationHint *ihint,
329                         GValue *return_accu,
330                         const GValue *handler_return,
331                         gpointer _data)
332 {
333     PyObject *py_ihint, *py_return_accu, *py_handler_return, *py_detail;
334     PyObject *py_retval;
335     gboolean retval = FALSE;
336     PyGSignalAccumulatorData *data = _data;
337     PyGILState_STATE state;
338
339     state = pyglib_gil_state_ensure();
340     if (ihint->detail)
341         py_detail = PYGLIB_PyUnicode_FromString(g_quark_to_string(ihint->detail));
342     else {
343         Py_INCREF(Py_None);
344         py_detail = Py_None;
345     }
346
347     py_ihint = Py_BuildValue("lNi", (long int) ihint->signal_id,
348                              py_detail, ihint->run_type);
349     py_handler_return = pyg_value_as_pyobject(handler_return, TRUE);
350     py_return_accu = pyg_value_as_pyobject(return_accu, FALSE);
351     if (data->user_data)
352         py_retval = PyObject_CallFunction(data->callable, "NNNO", py_ihint,
353                                           py_return_accu, py_handler_return,
354                                           data->user_data);
355     else
356         py_retval = PyObject_CallFunction(data->callable, "NNN", py_ihint,
357                                           py_return_accu, py_handler_return);
358     if (!py_retval)
359         PyErr_Print();
360     else {
361         if (!PyTuple_Check(py_retval) || PyTuple_Size(py_retval) != 2) {
362             PyErr_SetString(PyExc_TypeError, "accumulator function must return"
363                             " a (bool, object) tuple");
364             PyErr_Print();
365         } else {
366             retval = PyObject_IsTrue(PyTuple_GET_ITEM(py_retval, 0));
367             if (pyg_value_from_pyobject(return_accu, PyTuple_GET_ITEM(py_retval, 1))) {
368                 PyErr_Print();
369             }
370         }
371         Py_DECREF(py_retval);
372     }
373     pyglib_gil_state_release(state);
374     return retval;
375 }
376
377 static gboolean
378 create_signal (GType instance_type, const gchar *signal_name, PyObject *tuple)
379 {
380     GSignalFlags signal_flags;
381     PyObject *py_return_type, *py_param_types;
382     GType return_type;
383     guint n_params, i;
384     GType *param_types;
385     guint signal_id;
386     GSignalAccumulator accumulator = NULL;
387     PyGSignalAccumulatorData *accum_data = NULL;
388     PyObject *py_accum = NULL, *py_accum_data = NULL;
389
390     if (!PyArg_ParseTuple(tuple, "iOO|OO", &signal_flags, &py_return_type,
391                           &py_param_types, &py_accum, &py_accum_data))
392     {
393         gchar buf[128];
394
395         PyErr_Clear();
396         g_snprintf(buf, sizeof(buf),
397                    "value for __gsignals__['%s'] not in correct format", signal_name);
398         PyErr_SetString(PyExc_TypeError, buf);
399         return FALSE;
400     }
401
402     if (py_accum && py_accum != Py_None && !PyCallable_Check(py_accum))
403     {
404         gchar buf[128];
405
406         g_snprintf(buf, sizeof(buf),
407                    "accumulator for __gsignals__['%s'] must be callable", signal_name);
408         PyErr_SetString(PyExc_TypeError, buf);
409         return FALSE;
410     }
411
412     return_type = pyg_type_from_object(py_return_type);
413     if (!return_type)
414         return FALSE;
415     if (!PySequence_Check(py_param_types)) {
416         gchar buf[128];
417
418         g_snprintf(buf, sizeof(buf),
419                    "third element of __gsignals__['%s'] tuple must be a sequence", signal_name);
420         PyErr_SetString(PyExc_TypeError, buf);
421         return FALSE;
422     }
423     n_params = PySequence_Length(py_param_types);
424     param_types = g_new(GType, n_params);
425     for (i = 0; i < n_params; i++) {
426         PyObject *item = PySequence_GetItem(py_param_types, i);
427
428         param_types[i] = pyg_type_from_object(item);
429         if (param_types[i] == 0) {
430             Py_DECREF(item);
431             g_free(param_types);
432             return FALSE;
433         }
434         Py_DECREF(item);
435     }
436
437     if (py_accum == _pyg_signal_accumulator_true_handled_func)
438         accumulator = g_signal_accumulator_true_handled;
439     else {
440         if (py_accum != NULL && py_accum != Py_None) {
441             accum_data = g_new(PyGSignalAccumulatorData, 1);
442             accum_data->callable = py_accum;
443             Py_INCREF(py_accum);
444             accum_data->user_data = py_accum_data;
445             Py_XINCREF(py_accum_data);
446             accumulator = _pyg_signal_accumulator;
447         }
448     }
449
450     signal_id = g_signal_newv(signal_name, instance_type, signal_flags,
451                               pyg_signal_class_closure_get(),
452                               accumulator, accum_data,
453                               marshal_generic,
454                               return_type, n_params, param_types);
455     g_free(param_types);
456
457     if (signal_id == 0) {
458         gchar buf[128];
459
460         g_snprintf(buf, sizeof(buf), "could not create signal for %s",
461                    signal_name);
462         PyErr_SetString(PyExc_RuntimeError, buf);
463         return FALSE;
464     }
465     return TRUE;
466 }
467
468 static gboolean
469 override_signal(GType instance_type, const gchar *signal_name)
470 {
471     guint signal_id;
472
473     signal_id = g_signal_lookup(signal_name, instance_type);
474     if (!signal_id) {
475         gchar buf[128];
476
477         g_snprintf(buf, sizeof(buf), "could not look up %s", signal_name);
478         PyErr_SetString(PyExc_TypeError, buf);
479         return FALSE;
480     }
481     g_signal_override_class_closure(signal_id, instance_type,
482                                     pyg_signal_class_closure_get());
483     return TRUE;
484 }
485
486 static PyObject *
487 add_signals (GType instance_type, PyObject *signals)
488 {
489     gboolean ret = TRUE;
490     GObjectClass *oclass;
491     Py_ssize_t pos = 0;
492     PyObject *key, *value, *overridden_signals = NULL;
493
494     overridden_signals = PyDict_New();
495     oclass = g_type_class_ref(instance_type);
496     while (PyDict_Next(signals, &pos, &key, &value)) {
497         const gchar *signal_name;
498         gchar *signal_name_canon, *c;
499
500         if (!PYGLIB_PyUnicode_Check(key)) {
501             PyErr_SetString(PyExc_TypeError,
502                             "__gsignals__ keys must be strings");
503             ret = FALSE;
504             break;
505         }
506         signal_name = PYGLIB_PyUnicode_AsString (key);
507
508         if (value == Py_None ||
509             (PYGLIB_PyUnicode_Check(value) &&
510              !strcmp(PYGLIB_PyUnicode_AsString(value), "override")))
511         {
512               /* canonicalize signal name, replacing '-' with '_' */
513             signal_name_canon = g_strdup(signal_name);
514             for (c = signal_name_canon; *c; ++c)
515                 if (*c == '-')
516                     *c = '_';
517             if (PyDict_SetItemString(overridden_signals,
518                                      signal_name_canon, key)) {
519                 g_free(signal_name_canon);
520                 ret = FALSE;
521                 break;
522             }
523             g_free(signal_name_canon);
524
525             ret = override_signal(instance_type, signal_name);
526         } else {
527             ret = create_signal(instance_type, signal_name, value);
528         }
529
530         if (!ret)
531             break;
532     }
533     g_type_class_unref(oclass);
534     if (ret)
535         return overridden_signals;
536     else {
537         Py_XDECREF(overridden_signals);
538         return NULL;
539     }
540 }
541
542 static GParamSpec *
543 create_property (const gchar  *prop_name,
544                  GType         prop_type,
545                  const gchar  *nick,
546                  const gchar  *blurb,
547                  PyObject     *args,
548                  GParamFlags   flags)
549 {
550     GParamSpec *pspec = NULL;
551
552     switch (G_TYPE_FUNDAMENTAL(prop_type)) {
553     case G_TYPE_CHAR:
554         {
555             gchar minimum, maximum, default_value;
556
557             if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum,
558                                   &default_value))
559                 return NULL;
560             pspec = g_param_spec_char (prop_name, nick, blurb, minimum,
561                                        maximum, default_value, flags);
562         }
563         break;
564     case G_TYPE_UCHAR:
565         {
566             gchar minimum, maximum, default_value;
567
568             if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum,
569                                   &default_value))
570                 return NULL;
571             pspec = g_param_spec_uchar (prop_name, nick, blurb, minimum,
572                                         maximum, default_value, flags);
573         }
574         break;
575     case G_TYPE_BOOLEAN:
576         {
577             gboolean default_value;
578
579             if (!PyArg_ParseTuple(args, "i", &default_value))
580                 return NULL;
581             pspec = g_param_spec_boolean (prop_name, nick, blurb,
582                                           default_value, flags);
583         }
584         break;
585     case G_TYPE_INT:
586         {
587             gint minimum, maximum, default_value;
588
589             if (!PyArg_ParseTuple(args, "iii", &minimum, &maximum,
590                                   &default_value))
591                 return NULL;
592             pspec = g_param_spec_int (prop_name, nick, blurb, minimum,
593                                       maximum, default_value, flags);
594         }
595         break;
596     case G_TYPE_UINT:
597         {
598             guint minimum, maximum, default_value;
599
600             if (!PyArg_ParseTuple(args, "III", &minimum, &maximum,
601                                   &default_value))
602                 return NULL;
603             pspec = g_param_spec_uint (prop_name, nick, blurb, minimum,
604                                        maximum, default_value, flags);
605         }
606         break;
607     case G_TYPE_LONG:
608         {
609             glong minimum, maximum, default_value;
610
611             if (!PyArg_ParseTuple(args, "lll", &minimum, &maximum,
612                                   &default_value))
613                 return NULL;
614             pspec = g_param_spec_long (prop_name, nick, blurb, minimum,
615                                        maximum, default_value, flags);
616         }
617         break;
618     case G_TYPE_ULONG:
619         {
620             gulong minimum, maximum, default_value;
621
622             if (!PyArg_ParseTuple(args, "kkk", &minimum, &maximum,
623                                   &default_value))
624                 return NULL;
625             pspec = g_param_spec_ulong (prop_name, nick, blurb, minimum,
626                                         maximum, default_value, flags);
627         }
628         break;
629     case G_TYPE_INT64:
630         {
631             gint64 minimum, maximum, default_value;
632
633             if (!PyArg_ParseTuple(args, "LLL", &minimum, &maximum,
634                                   &default_value))
635                 return NULL;
636             pspec = g_param_spec_int64 (prop_name, nick, blurb, minimum,
637                                         maximum, default_value, flags);
638         }
639         break;
640     case G_TYPE_UINT64:
641         {
642             guint64 minimum, maximum, default_value;
643
644             if (!PyArg_ParseTuple(args, "KKK", &minimum, &maximum,
645                                   &default_value))
646                 return NULL;
647             pspec = g_param_spec_uint64 (prop_name, nick, blurb, minimum,
648                                          maximum, default_value, flags);
649         }
650         break;
651     case G_TYPE_ENUM:
652         {
653             gint default_value;
654             PyObject *pydefault;
655
656             if (!PyArg_ParseTuple(args, "O", &pydefault))
657                 return NULL;
658
659             if (pyg_enum_get_value(prop_type, pydefault,
660                                    (gint *)&default_value))
661                 return NULL;
662
663             pspec = g_param_spec_enum (prop_name, nick, blurb,
664                                        prop_type, default_value, flags);
665         }
666         break;
667     case G_TYPE_FLAGS:
668         {
669             guint default_value;
670             PyObject *pydefault;
671
672             if (!PyArg_ParseTuple(args, "O", &pydefault))
673                 return NULL;
674
675             if (pyg_flags_get_value(prop_type, pydefault,
676                                     (gint *)&default_value))
677                 return NULL;
678
679             pspec = g_param_spec_flags (prop_name, nick, blurb,
680                                         prop_type, default_value, flags);
681         }
682         break;
683     case G_TYPE_FLOAT:
684         {
685             gfloat minimum, maximum, default_value;
686
687             if (!PyArg_ParseTuple(args, "fff", &minimum, &maximum,
688                                   &default_value))
689                 return NULL;
690             pspec = g_param_spec_float (prop_name, nick, blurb, minimum,
691                                         maximum, default_value, flags);
692         }
693         break;
694     case G_TYPE_DOUBLE:
695         {
696             gdouble minimum, maximum, default_value;
697
698             if (!PyArg_ParseTuple(args, "ddd", &minimum, &maximum,
699                                   &default_value))
700                 return NULL;
701             pspec = g_param_spec_double (prop_name, nick, blurb, minimum,
702                                          maximum, default_value, flags);
703         }
704         break;
705     case G_TYPE_STRING:
706         {
707             const gchar *default_value;
708
709             if (!PyArg_ParseTuple(args, "z", &default_value))
710                 return NULL;
711             pspec = g_param_spec_string (prop_name, nick, blurb,
712                                          default_value, flags);
713         }
714         break;
715     case G_TYPE_PARAM:
716         if (!PyArg_ParseTuple(args, ""))
717             return NULL;
718         pspec = g_param_spec_param (prop_name, nick, blurb, prop_type, flags);
719         break;
720     case G_TYPE_BOXED:
721         if (!PyArg_ParseTuple(args, ""))
722             return NULL;
723         pspec = g_param_spec_boxed (prop_name, nick, blurb, prop_type, flags);
724         break;
725     case G_TYPE_POINTER:
726         if (!PyArg_ParseTuple(args, ""))
727             return NULL;
728         pspec = g_param_spec_pointer (prop_name, nick, blurb, flags);
729         break;
730     case G_TYPE_OBJECT:
731         if (!PyArg_ParseTuple(args, ""))
732             return NULL;
733         pspec = g_param_spec_object (prop_name, nick, blurb, prop_type, flags);
734         break;
735     default:
736         /* unhandled pspec type ... */
737         break;
738     }
739
740     if (!pspec) {
741         char buf[128];
742
743         g_snprintf(buf, sizeof(buf), "could not create param spec for type %s",
744                    g_type_name(prop_type));
745         PyErr_SetString(PyExc_TypeError, buf);
746         return NULL;
747     }
748
749     return pspec;
750 }
751
752 GParamSpec *
753 pyg_param_spec_from_object (PyObject *tuple)
754 {
755     gint val_length;
756     const gchar *prop_name;
757     GType prop_type;
758     const gchar *nick, *blurb;
759     PyObject *slice, *item, *py_prop_type;
760     GParamSpec *pspec;
761
762     val_length = PyTuple_Size(tuple);
763     if (val_length < 4) {
764         PyErr_SetString(PyExc_TypeError,
765                         "paramspec tuples must be at least 4 elements long");
766         return NULL;
767     }
768
769     slice = PySequence_GetSlice(tuple, 0, 4);
770     if (!slice) {
771         return NULL;
772     }
773
774     if (!PyArg_ParseTuple(slice, "sOzz", &prop_name, &py_prop_type, &nick, &blurb)) {
775         Py_DECREF(slice);
776         return NULL;
777     }
778
779     Py_DECREF(slice);
780
781     prop_type = pyg_type_from_object(py_prop_type);
782     if (!prop_type) {
783         return NULL;
784     }
785
786     item = PyTuple_GetItem(tuple, val_length-1);
787     if (!PYGLIB_PyLong_Check(item)) {
788         PyErr_SetString(PyExc_TypeError,
789                         "last element in tuple must be an int");
790         return NULL;
791     }
792
793     /* slice is the extra items in the tuple */
794     slice = PySequence_GetSlice(tuple, 4, val_length-1);
795     pspec = create_property(prop_name, prop_type,
796                             nick, blurb, slice,
797                             PYGLIB_PyLong_AsLong(item));
798
799     return pspec;
800 }
801
802 static gboolean
803 add_properties (GType instance_type, PyObject *properties)
804 {
805     gboolean ret = TRUE;
806     GObjectClass *oclass;
807     Py_ssize_t pos = 0;
808     PyObject *key, *value;
809
810     oclass = g_type_class_ref(instance_type);
811     while (PyDict_Next(properties, &pos, &key, &value)) {
812         const gchar *prop_name;
813         GType prop_type;
814         const gchar *nick, *blurb;
815         GParamFlags flags;
816         gint val_length;
817         PyObject *slice, *item, *py_prop_type;
818         GParamSpec *pspec;
819
820         /* values are of format (type,nick,blurb, type_specific_args, flags) */
821
822         if (!PYGLIB_PyUnicode_Check(key)) {
823             PyErr_SetString(PyExc_TypeError,
824                             "__gproperties__ keys must be strings");
825             ret = FALSE;
826             break;
827         }
828         prop_name = PYGLIB_PyUnicode_AsString (key);
829
830         if (!PyTuple_Check(value)) {
831             PyErr_SetString(PyExc_TypeError,
832                             "__gproperties__ values must be tuples");
833             ret = FALSE;
834             break;
835         }
836         val_length = PyTuple_Size(value);
837         if (val_length < 4) {
838             PyErr_SetString(PyExc_TypeError,
839                             "__gproperties__ values must be at least 4 elements long");
840             ret = FALSE;
841             break;
842         }
843
844         slice = PySequence_GetSlice(value, 0, 3);
845         if (!slice) {
846             ret = FALSE;
847             break;
848         }
849         if (!PyArg_ParseTuple(slice, "Ozz", &py_prop_type, &nick, &blurb)) {
850             Py_DECREF(slice);
851             ret = FALSE;
852             break;
853         }
854         Py_DECREF(slice);
855         prop_type = pyg_type_from_object(py_prop_type);
856         if (!prop_type) {
857             ret = FALSE;
858             break;
859         }
860         item = PyTuple_GetItem(value, val_length-1);
861         if (!PYGLIB_PyLong_Check(item)) {
862             PyErr_SetString(PyExc_TypeError,
863                 "last element in __gproperties__ value tuple must be an int");
864             ret = FALSE;
865             break;
866         }
867         flags = PYGLIB_PyLong_AsLong(item);
868
869         /* slice is the extra items in the tuple */
870         slice = PySequence_GetSlice(value, 3, val_length-1);
871         pspec = create_property(prop_name, prop_type, nick, blurb,
872                                 slice, flags);
873         Py_DECREF(slice);
874
875         if (pspec) {
876             g_object_class_install_property(oclass, 1, pspec);
877         } else {
878             PyObject *type, *value, *traceback;
879             ret = FALSE;
880             PyErr_Fetch(&type, &value, &traceback);
881             if (PYGLIB_PyUnicode_Check(value)) {
882                 char msg[256];
883                 g_snprintf(msg, 256,
884                            "%s (while registering property '%s' for GType '%s')",
885                PYGLIB_PyUnicode_AsString(value),
886                            prop_name, g_type_name(instance_type));
887                 Py_DECREF(value);
888                 value = PYGLIB_PyUnicode_FromString(msg);
889             }
890             PyErr_Restore(type, value, traceback);
891             break;
892         }
893     }
894
895     g_type_class_unref(oclass);
896     return ret;
897 }
898
899 static void
900 pyg_register_class_init(GType gtype, PyGClassInitFunc class_init)
901 {
902     GSList *list;
903
904     list = g_type_get_qdata(gtype, pygobject_class_init_key);
905     list = g_slist_prepend(list, class_init);
906     g_type_set_qdata(gtype, pygobject_class_init_key, list);
907 }
908
909 static int
910 pyg_run_class_init(GType gtype, gpointer gclass, PyTypeObject *pyclass)
911 {
912     GSList *list;
913     PyGClassInitFunc class_init;
914     GType parent_type;
915     int rv;
916
917     parent_type = g_type_parent(gtype);
918     if (parent_type) {
919         rv = pyg_run_class_init(parent_type, gclass, pyclass);
920         if (rv)
921             return rv;
922     }
923
924     list = g_type_get_qdata(gtype, pygobject_class_init_key);
925     for (; list; list = list->next) {
926         class_init = list->data;
927         rv = class_init(gclass, pyclass);
928         if (rv)
929             return rv;
930     }
931
932     return 0;
933 }
934
935 static PyObject *
936 _wrap_pyg_type_register(PyObject *self, PyObject *args)
937 {
938     PyTypeObject *class;
939     char *type_name = NULL;
940
941     if (!PyArg_ParseTuple(args, "O!|z:gobject.type_register",
942                           &PyType_Type, &class, &type_name))
943         return NULL;
944     if (!PyType_IsSubtype(class, &PyGObject_Type)) {
945         PyErr_SetString(PyExc_TypeError,
946                         "argument must be a GObject subclass");
947         return NULL;
948     }
949
950       /* Check if type already registered */
951     if (pyg_type_from_object((PyObject *) class) ==
952         pyg_type_from_object((PyObject *) class->tp_base))
953     {
954         if (pyg_type_register(class, type_name))
955             return NULL;
956     }
957
958     Py_INCREF(class);
959     return (PyObject *) class;
960 }
961
962 static char *
963 get_type_name_for_class(PyTypeObject *class)
964 {
965     gint i, name_serial;
966     char name_serial_str[16];
967     PyObject *module;
968     char *type_name = NULL;
969
970     /* make name for new GType */
971     name_serial = 1;
972     /* give up after 1000 tries, just in case.. */
973     while (name_serial < 1000)
974     {
975         g_free(type_name);
976         snprintf(name_serial_str, 16, "-v%i", name_serial);
977         module = PyObject_GetAttrString((PyObject *)class, "__module__");
978         if (module && PYGLIB_PyUnicode_Check(module)) {
979             type_name = g_strconcat(PYGLIB_PyUnicode_AsString(module), ".",
980                                     class->tp_name,
981                                     name_serial > 1 ? name_serial_str : NULL,
982                                     NULL);
983             Py_DECREF(module);
984         } else {
985             if (module)
986                 Py_DECREF(module);
987             else
988                 PyErr_Clear();
989             type_name = g_strconcat(class->tp_name,
990                                     name_serial > 1 ? name_serial_str : NULL,
991                                     NULL);
992         }
993         /* convert '.' in type name to '+', which isn't banned (grumble) */
994         for (i = 0; type_name[i] != '\0'; i++)
995             if (type_name[i] == '.')
996                 type_name[i] = '+';
997         if (_pyg_type_from_name(type_name) == 0)
998             break;              /* we now have a unique name */
999         ++name_serial;
1000     }
1001
1002     return type_name;
1003 }
1004
1005
1006 static GStaticPrivate pygobject_construction_wrapper = G_STATIC_PRIVATE_INIT;
1007
1008 static inline void
1009 pygobject_init_wrapper_set(PyObject *wrapper)
1010 {
1011     g_static_private_set(&pygobject_construction_wrapper, wrapper, NULL);
1012 }
1013
1014 static inline PyObject *
1015 pygobject_init_wrapper_get(void)
1016 {
1017     return (PyObject *) g_static_private_get(&pygobject_construction_wrapper);
1018 }
1019
1020 static void
1021 pygobject__g_instance_init(GTypeInstance   *instance,
1022                            gpointer         g_class)
1023 {
1024     GObject *object = (GObject *) instance;
1025     PyObject *wrapper, *args, *kwargs;
1026
1027     if (!g_type_get_qdata(G_OBJECT_TYPE(object),
1028                           pygobject_has_updated_constructor_key))
1029         return;
1030
1031     wrapper = g_object_get_qdata(object, pygobject_wrapper_key);
1032     if (wrapper == NULL) {
1033         wrapper = pygobject_init_wrapper_get();
1034         if (wrapper && ((PyGObject *) wrapper)->obj == NULL) {
1035             ((PyGObject *) wrapper)->obj = object;
1036             pygobject_register_wrapper(wrapper);
1037         }
1038     }
1039     pygobject_init_wrapper_set(NULL);
1040     if (wrapper == NULL) {
1041           /* this looks like a python object created through
1042            * g_object_new -> we have no python wrapper, so create it
1043            * now */
1044         PyGILState_STATE state;
1045         state = pyglib_gil_state_ensure();
1046         wrapper = pygobject_new_full(object, FALSE, g_class);
1047         args = PyTuple_New(0);
1048         kwargs = PyDict_New();
1049         if (Py_TYPE(wrapper)->tp_init(wrapper, args, kwargs))
1050             PyErr_Print();
1051         Py_DECREF(wrapper);
1052         Py_DECREF(args);
1053         Py_DECREF(kwargs);
1054         pyglib_gil_state_release(state);
1055     }
1056 }
1057
1058
1059 /*  This implementation is bad, see bug 566571 for an example why.
1060  *  Instead of scanning explicitly declared bases for interfaces, we
1061  *  should automatically initialize all implemented interfaces to
1062  *  prevent bugs like that one.  However, this will lead to
1063  *  performance degradation as each virtual method in derived classes
1064  *  will round-trip through do_*() stuff, *even* if it is not
1065  *  overriden.  We need to teach codegen to retain parent method
1066  *  instead of setting virtual to *_proxy_do_*() if corresponding
1067  *  do_*() is not overriden.  Ok, that was a messy explanation.
1068  */
1069 static void
1070 pyg_type_add_interfaces(PyTypeObject *class, GType instance_type,
1071                         PyObject *bases, gboolean new_interfaces,
1072                         GType *parent_interfaces, guint n_parent_interfaces)
1073 {
1074     int i;
1075
1076     if (!bases) {
1077         g_warning("type has no bases");
1078         return;
1079     }
1080
1081     for (i = 0; i < PyTuple_GET_SIZE(bases); ++i) {
1082         guint k;
1083         PyObject *base = PyTuple_GET_ITEM(bases, i);
1084         GType itype;
1085         gboolean is_new = TRUE;
1086         const GInterfaceInfo *iinfo;
1087         GInterfaceInfo iinfo_copy;
1088
1089         /* 'base' can also be a PyClassObject, see bug #566571. */
1090         if (!PyType_Check(base))
1091             continue;
1092
1093         if (!PyType_IsSubtype((PyTypeObject*) base, &PyGInterface_Type))
1094             continue;
1095
1096         itype = pyg_type_from_object(base);
1097
1098         /* Happens for _implementations_ of an interface. */
1099         if (!G_TYPE_IS_INTERFACE(itype))
1100             continue;
1101
1102         for (k = 0; k < n_parent_interfaces; ++k) {
1103             if (parent_interfaces[k] == itype) {
1104                 is_new = FALSE;
1105                 break;
1106             }
1107         }
1108
1109         if ((new_interfaces && !is_new) || (!new_interfaces && is_new))
1110             continue;
1111
1112         iinfo = pyg_lookup_interface_info(itype);
1113         if (!iinfo) {
1114             gchar *error;
1115             error = g_strdup_printf("Interface type %s "
1116                                     "has no Python implementation support",
1117                                     ((PyTypeObject *) base)->tp_name);
1118             PyErr_Warn(PyExc_RuntimeWarning, error);
1119             g_free(error);
1120             continue;
1121         }
1122
1123         iinfo_copy = *iinfo;
1124         iinfo_copy.interface_data = class;
1125         g_type_add_interface_static(instance_type, itype, &iinfo_copy);
1126     }
1127 }
1128
1129 int
1130 pyg_type_register(PyTypeObject *class, const char *type_name)
1131 {
1132     PyObject *gtype, *gsignals, *gproperties, *overridden_signals;
1133     GType parent_type, instance_type;
1134     GType *parent_interfaces;
1135     guint n_parent_interfaces;
1136     GTypeQuery query;
1137     gpointer gclass;
1138     gpointer has_new_constructor_api;
1139     GTypeInfo type_info = {
1140         0,    /* class_size */
1141
1142         (GBaseInitFunc) NULL,
1143         (GBaseFinalizeFunc) NULL,
1144
1145         (GClassInitFunc) pyg_object_class_init,
1146         (GClassFinalizeFunc) NULL,
1147         NULL, /* class_data */
1148
1149         0,    /* instance_size */
1150         0,    /* n_preallocs */
1151         (GInstanceInitFunc) pygobject__g_instance_init
1152     };
1153     gchar *new_type_name;
1154
1155     /* find the GType of the parent */
1156     parent_type = pyg_type_from_object((PyObject *)class);
1157     if (!parent_type)
1158         return -1;
1159
1160     parent_interfaces = g_type_interfaces(parent_type, &n_parent_interfaces);
1161
1162     if (type_name)
1163         /* care is taken below not to free this */
1164         new_type_name = (gchar *) type_name;
1165     else
1166         new_type_name = get_type_name_for_class(class);
1167
1168     /* set class_data that will be passed to the class_init function. */
1169     type_info.class_data = class;
1170
1171     /* fill in missing values of GTypeInfo struct */
1172     g_type_query(parent_type, &query);
1173     type_info.class_size = query.class_size;
1174     type_info.instance_size = query.instance_size;
1175
1176     /* create new typecode */
1177     instance_type = g_type_register_static(parent_type, new_type_name,
1178                                            &type_info, 0);
1179     if (instance_type == 0) {
1180         PyErr_Format(PyExc_RuntimeError,
1181                      "could not create new GType: %s (subclass of %s)",
1182                      new_type_name,
1183                      g_type_name(parent_type));
1184
1185         if (type_name == NULL)
1186             g_free(new_type_name);
1187
1188         return -1;
1189     }
1190
1191     if (type_name == NULL)
1192         g_free(new_type_name);
1193
1194     /* store pointer to the class with the GType */
1195     Py_INCREF(class);
1196     g_type_set_qdata(instance_type, g_quark_from_string("PyGObject::class"),
1197                      class);
1198
1199     /* set new value of __gtype__ on class */
1200     gtype = pyg_type_wrapper_new(instance_type);
1201     PyObject_SetAttrString((PyObject *)class, "__gtype__", gtype);
1202     Py_DECREF(gtype);
1203
1204       /* propagate new constructor API compatility flag from parent to child type */
1205     has_new_constructor_api =
1206         g_type_get_qdata(parent_type,
1207                          pygobject_has_updated_constructor_key);
1208     if (has_new_constructor_api != NULL)
1209         g_type_set_qdata(instance_type, pygobject_has_updated_constructor_key,
1210                          has_new_constructor_api);
1211
1212     /* if no __doc__, set it to the auto doc descriptor */
1213     if (PyDict_GetItemString(class->tp_dict, "__doc__") == NULL) {
1214         PyDict_SetItemString(class->tp_dict, "__doc__",
1215                              pyg_object_descr_doc_get());
1216     }
1217
1218     /*
1219      * Note: Interfaces to be implemented are searched twice.  First
1220      * we register interfaces that are already implemented by a parent
1221      * type.  The second time, the remaining interfaces are
1222      * registered, i.e. the ones that are not implemented by a parent
1223      * type.  In between these two loops, properties and signals are
1224      * registered.  It has to be done this way, in two steps,
1225      * otherwise glib will complain.  If registering all interfaces
1226      * always before properties, you get an error like:
1227      *
1228      *    ../gobject:121: Warning: Object class
1229      *    test_interface+MyObject doesn't implement property
1230      *    'some-property' from interface 'TestInterface'
1231      *
1232      * If, on the other hand, you register interfaces after
1233      * registering the properties, you get something like:
1234      *
1235      *     ../gobject:121: Warning: cannot add interface type
1236      *    `TestInterface' to type `test_interface+MyUnknown', since
1237      *    type `test_interface+MyUnknown' already conforms to
1238      *    interface
1239      *
1240      * This looks like a GLib quirk, but no bug has been filed
1241      * upstream.  However we have a unit test for this particular
1242      * problem, which can be found in test_interfaces.py, class
1243      * TestInterfaceImpl.
1244      *
1245      * See also comment above pyg_type_add_interfaces().
1246      */
1247     pyg_type_add_interfaces(class, instance_type, class->tp_bases, FALSE,
1248                             parent_interfaces, n_parent_interfaces);
1249
1250     /* we look this up in the instance dictionary, so we don't
1251      * accidentally get a parent type's __gsignals__ attribute. */
1252     gsignals = PyDict_GetItemString(class->tp_dict, "__gsignals__");
1253     if (gsignals) {
1254         if (!PyDict_Check(gsignals)) {
1255             PyErr_SetString(PyExc_TypeError,
1256                             "__gsignals__ attribute not a dict!");
1257             g_free(parent_interfaces);
1258             return -1;
1259         }
1260         if (!(overridden_signals = add_signals(instance_type, gsignals))) {
1261             g_free(parent_interfaces);
1262             return -1;
1263         }
1264         if (PyDict_SetItemString(class->tp_dict, "__gsignals__",
1265                                  overridden_signals)) {
1266             g_free(parent_interfaces);
1267             return -1;
1268         }
1269         Py_DECREF(overridden_signals);
1270     } else {
1271         PyErr_Clear();
1272     }
1273
1274     /* we look this up in the instance dictionary, so we don't
1275      * accidentally get a parent type's __gsignals__ attribute. */
1276     gproperties = PyDict_GetItemString(class->tp_dict, "__gproperties__");
1277     if (gproperties) {
1278         if (!PyDict_Check(gproperties)) {
1279             PyErr_SetString(PyExc_TypeError,
1280                             "__gproperties__ attribute not a dict!");
1281             g_free(parent_interfaces);
1282             return -1;
1283         }
1284         if (!add_properties(instance_type, gproperties)) {
1285             g_free(parent_interfaces);
1286             return -1;
1287         }
1288         PyDict_DelItemString(class->tp_dict, "__gproperties__");
1289         /* Borrowed reference. Py_DECREF(gproperties); */
1290     } else {
1291         PyErr_Clear();
1292     }
1293
1294     /* Register new interfaces, that are _not_ already defined by
1295      * the parent type.  FIXME: See above.
1296      */
1297     pyg_type_add_interfaces(class, instance_type, class->tp_bases, TRUE,
1298                             parent_interfaces, n_parent_interfaces);
1299
1300     gclass = g_type_class_ref(instance_type);
1301     if (pyg_run_class_init(instance_type, gclass, class)) {
1302         g_type_class_unref(gclass);
1303         g_free(parent_interfaces);
1304         return -1;
1305     }
1306     g_type_class_unref(gclass);
1307     g_free(parent_interfaces);
1308
1309     if (gsignals)
1310         PyDict_DelItemString(class->tp_dict, "__gsignals__");
1311
1312     return 0;
1313 }
1314
1315 static PyObject *
1316 pyg_signal_new(PyObject *self, PyObject *args)
1317 {
1318     gchar *signal_name;
1319     PyObject *py_type;
1320     GSignalFlags signal_flags;
1321     GType return_type;
1322     PyObject *py_return_type, *py_param_types;
1323
1324     GType instance_type = 0;
1325     Py_ssize_t n_params, i;
1326     GType *param_types;
1327
1328     guint signal_id;
1329
1330     if (!PyArg_ParseTuple(args, "sOiOO:gobject.signal_new", &signal_name,
1331                           &py_type, &signal_flags, &py_return_type,
1332                           &py_param_types))
1333         return NULL;
1334
1335     instance_type = pyg_type_from_object(py_type);
1336     if (!instance_type)
1337         return NULL;
1338     if (!(G_TYPE_IS_INSTANTIATABLE(instance_type) || G_TYPE_IS_INTERFACE(instance_type))) {
1339         PyErr_SetString(PyExc_TypeError,
1340                         "argument 2 must be an object type or interface type");
1341         return NULL;
1342     }
1343
1344     return_type = pyg_type_from_object(py_return_type);
1345     if (!return_type)
1346         return NULL;
1347
1348     if (!PySequence_Check(py_param_types)) {
1349         PyErr_SetString(PyExc_TypeError,
1350                         "argument 5 must be a sequence of GType codes");
1351         return NULL;
1352     }
1353     n_params = PySequence_Length(py_param_types);
1354     param_types = g_new(GType, n_params);
1355     for (i = 0; i < n_params; i++) {
1356         PyObject *item = PySequence_GetItem(py_param_types, i);
1357
1358         param_types[i] = pyg_type_from_object(item);
1359         if (param_types[i] == 0) {
1360             PyErr_Clear();
1361             Py_DECREF(item);
1362             PyErr_SetString(PyExc_TypeError,
1363                             "argument 5 must be a sequence of GType codes");
1364             g_free(param_types);
1365             return NULL;
1366         }
1367         Py_DECREF(item);
1368     }
1369
1370     signal_id = g_signal_newv(signal_name, instance_type, signal_flags,
1371                               pyg_signal_class_closure_get(),
1372                               (GSignalAccumulator)0, NULL,
1373                               (GSignalCMarshaller)0,
1374                               return_type, n_params, param_types);
1375     g_free(param_types);
1376     if (signal_id != 0)
1377         return PYGLIB_PyLong_FromLong(signal_id);
1378     PyErr_SetString(PyExc_RuntimeError, "could not create signal");
1379     return NULL;
1380 }
1381
1382 static PyObject *
1383 pyg_signal_list_names (PyObject *self, PyObject *args, PyObject *kwargs)
1384 {
1385     static char *kwlist[] = { "type", NULL };
1386     PyObject *py_itype, *list;
1387     GObjectClass *class = NULL;
1388     GType itype;
1389     guint n;
1390     guint *ids;
1391     guint i;
1392     gpointer iface = NULL;
1393
1394     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1395                                      "O:gobject.signal_list_names",
1396                                      kwlist, &py_itype))
1397         return NULL;
1398     if ((itype = pyg_type_from_object(py_itype)) == 0)
1399         return NULL;
1400
1401     if (G_TYPE_IS_INSTANTIATABLE(itype)) {
1402         class = g_type_class_ref(itype);
1403         if (!class) {
1404             PyErr_SetString(PyExc_RuntimeError,
1405                             "could not get a reference to type class");
1406             return NULL;
1407         }
1408     } else if (!G_TYPE_IS_INTERFACE(itype)) {
1409         PyErr_SetString(PyExc_TypeError,
1410                         "type must be instantiable or an interface");
1411         return NULL;
1412     } else {
1413         iface = g_type_default_interface_ref(itype);
1414     }
1415
1416     ids = g_signal_list_ids(itype, &n);
1417
1418     list = PyTuple_New((gint)n);
1419     if (list != NULL) {
1420         for (i = 0; i < n; i++)
1421             PyTuple_SetItem(list, i,
1422                         PYGLIB_PyUnicode_FromString(g_signal_name(ids[i])));
1423     }
1424
1425     g_free(ids);
1426     if (class)
1427         g_type_class_unref(class);
1428     else
1429        g_type_default_interface_unref(iface);
1430
1431     return list;
1432 }
1433
1434 static PyObject *
1435 pyg_signal_list_ids (PyObject *self, PyObject *args, PyObject *kwargs)
1436 {
1437     static char *kwlist[] = { "type", NULL };
1438     PyObject *py_itype, *list;
1439     GObjectClass *class = NULL;
1440     GType itype;
1441     guint n;
1442     guint *ids;
1443     guint i;
1444     gpointer iface = NULL;
1445
1446     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1447                                      "O:gobject.signal_list_ids",
1448                                      kwlist, &py_itype))
1449         return NULL;
1450     if ((itype = pyg_type_from_object(py_itype)) == 0)
1451         return NULL;
1452
1453     if (G_TYPE_IS_INSTANTIATABLE(itype)) {
1454         class = g_type_class_ref(itype);
1455         if (!class) {
1456             PyErr_SetString(PyExc_RuntimeError,
1457                             "could not get a reference to type class");
1458             return NULL;
1459         }
1460     } else if (!G_TYPE_IS_INTERFACE(itype)) {
1461         PyErr_SetString(PyExc_TypeError,
1462                         "type must be instantiable or an interface");
1463         return NULL;
1464     } else {
1465         iface = g_type_default_interface_ref(itype);
1466     }
1467
1468     ids = g_signal_list_ids(itype, &n);
1469
1470     list = PyTuple_New((gint)n);
1471     if (list == NULL) {
1472         g_free(ids);
1473         g_type_class_unref(class);
1474         return NULL;
1475     }
1476
1477     for (i = 0; i < n; i++)
1478         PyTuple_SetItem(list, i, PYGLIB_PyLong_FromLong(ids[i]));
1479     g_free(ids);
1480     if (class)
1481         g_type_class_unref(class);
1482     else
1483        g_type_default_interface_unref(iface);
1484
1485     return list;
1486 }
1487
1488 static PyObject *
1489 pyg_signal_lookup (PyObject *self, PyObject *args, PyObject *kwargs)
1490 {
1491     static char *kwlist[] = { "name", "type", NULL };
1492     PyObject *py_itype;
1493     GObjectClass *class = NULL;
1494     GType itype;
1495     gchar *signal_name;
1496     guint id;
1497     gpointer iface = NULL;
1498
1499     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO:gobject.signal_lookup",
1500                                      kwlist, &signal_name, &py_itype))
1501         return NULL;
1502     if ((itype = pyg_type_from_object(py_itype)) == 0)
1503         return NULL;
1504
1505     if (G_TYPE_IS_INSTANTIATABLE(itype)) {
1506         class = g_type_class_ref(itype);
1507         if (!class) {
1508             PyErr_SetString(PyExc_RuntimeError,
1509                             "could not get a reference to type class");
1510             return NULL;
1511         }
1512     } else if (!G_TYPE_IS_INTERFACE(itype)) {
1513         PyErr_SetString(PyExc_TypeError,
1514                         "type must be instantiable or an interface");
1515         return NULL;
1516     } else {
1517         iface = g_type_default_interface_ref(itype);
1518     }
1519
1520     id = g_signal_lookup(signal_name, itype);
1521
1522     if (class)
1523         g_type_class_unref(class);
1524     else
1525        g_type_default_interface_unref(iface);
1526     return PYGLIB_PyLong_FromLong(id);
1527 }
1528
1529 static PyObject *
1530 pyg_signal_name (PyObject *self, PyObject *args, PyObject *kwargs)
1531 {
1532     static char *kwlist[] = { "signal_id", NULL };
1533     const gchar *signal_name;
1534     guint id;
1535
1536     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:gobject.signal_name",
1537                                      kwlist, &id))
1538         return NULL;
1539     signal_name = g_signal_name(id);
1540     if (signal_name)
1541         return PYGLIB_PyUnicode_FromString(signal_name);
1542
1543     Py_INCREF(Py_None);
1544     return Py_None;
1545 }
1546
1547 static PyObject *
1548 pyg_signal_query (PyObject *self, PyObject *args, PyObject *kwargs)
1549 {
1550     static char *kwlist1[] = { "name", "type", NULL };
1551     static char *kwlist2[] = { "signal_id", NULL };
1552     PyObject *py_query, *params_list, *py_itype;
1553     GObjectClass *class = NULL;
1554     GType itype;
1555     gchar *signal_name;
1556     guint i;
1557     GSignalQuery query;
1558     guint id;
1559     gpointer iface = NULL;
1560
1561     if (PyArg_ParseTupleAndKeywords(args, kwargs, "sO:gobject.signal_query",
1562                                      kwlist1, &signal_name, &py_itype)) {
1563         if ((itype = pyg_type_from_object(py_itype)) == 0)
1564             return NULL;
1565
1566         if (G_TYPE_IS_INSTANTIATABLE(itype)) {
1567             class = g_type_class_ref(itype);
1568             if (!class) {
1569                 PyErr_SetString(PyExc_RuntimeError,
1570                                 "could not get a reference to type class");
1571                 return NULL;
1572             }
1573         } else if (!G_TYPE_IS_INTERFACE(itype)) {
1574             PyErr_SetString(PyExc_TypeError,
1575                             "type must be instantiable or an interface");
1576             return NULL;
1577         } else {
1578             iface = g_type_default_interface_ref(itype);
1579         }
1580         id = g_signal_lookup(signal_name, itype);
1581     } else {
1582         PyErr_Clear();
1583         if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1584                                          "i:gobject.signal_query",
1585                                          kwlist2, &id)) {
1586             PyErr_Clear();
1587             PyErr_SetString(PyExc_TypeError,
1588                             "Usage: one of:\n"
1589                             "  gobject.signal_query(name, type)\n"
1590                             "  gobject.signal_query(signal_id)");
1591
1592         return NULL;
1593         }
1594     }
1595
1596     g_signal_query(id, &query);
1597
1598     if (query.signal_id == 0) {
1599         Py_INCREF(Py_None);
1600         py_query = Py_None;
1601         goto done;
1602     }
1603     py_query = PyTuple_New(6);
1604     if (py_query == NULL) {
1605         goto done;
1606     }
1607     params_list = PyTuple_New(query.n_params);
1608     if (params_list == NULL) {
1609         Py_DECREF(py_query);
1610         py_query = NULL;
1611         goto done;
1612     }
1613
1614     PyTuple_SET_ITEM(py_query, 0, PYGLIB_PyLong_FromLong(query.signal_id));
1615     PyTuple_SET_ITEM(py_query, 1, PYGLIB_PyUnicode_FromString(query.signal_name));
1616     PyTuple_SET_ITEM(py_query, 2, pyg_type_wrapper_new(query.itype));
1617     PyTuple_SET_ITEM(py_query, 3, PYGLIB_PyLong_FromLong(query.signal_flags));
1618     PyTuple_SET_ITEM(py_query, 4, pyg_type_wrapper_new(query.return_type));
1619     for (i = 0; i < query.n_params; i++) {
1620         PyTuple_SET_ITEM(params_list, i,
1621                          pyg_type_wrapper_new(query.param_types[i]));
1622     }
1623     PyTuple_SET_ITEM(py_query, 5, params_list);
1624
1625  done:
1626     if (class)
1627         g_type_class_unref(class);
1628     if (iface)
1629         g_type_default_interface_unref(iface);
1630
1631     return py_query;
1632 }
1633
1634 static PyObject *
1635 pyg_object_class_list_properties (PyObject *self, PyObject *args)
1636 {
1637     GParamSpec **specs;
1638     PyObject *py_itype, *list;
1639     GType itype;
1640     GObjectClass *class = NULL;
1641     gpointer iface = NULL;
1642     guint nprops;
1643     guint i;
1644
1645     if (!PyArg_ParseTuple(args, "O:gobject.list_properties",
1646                           &py_itype))
1647         return NULL;
1648     if ((itype = pyg_type_from_object(py_itype)) == 0)
1649         return NULL;
1650
1651     if (G_TYPE_IS_INTERFACE(itype)) {
1652         iface = g_type_default_interface_ref(itype);
1653         if (!iface) {
1654             PyErr_SetString(PyExc_RuntimeError,
1655                             "could not get a reference to interface type");
1656             return NULL;
1657         }
1658         specs = g_object_interface_list_properties(iface, &nprops);
1659     } else if (g_type_is_a(itype, G_TYPE_OBJECT)) {
1660         class = g_type_class_ref(itype);
1661         if (!class) {
1662             PyErr_SetString(PyExc_RuntimeError,
1663                             "could not get a reference to type class");
1664             return NULL;
1665         }
1666         specs = g_object_class_list_properties(class, &nprops);
1667     } else {
1668         PyErr_SetString(PyExc_TypeError,
1669                         "type must be derived from GObject or an interface");
1670         return NULL;
1671     }
1672
1673     list = PyTuple_New(nprops);
1674     if (list == NULL) {
1675         g_free(specs);
1676         g_type_class_unref(class);
1677         return NULL;
1678     }
1679     for (i = 0; i < nprops; i++) {
1680         PyTuple_SetItem(list, i, pyg_param_spec_new(specs[i]));
1681     }
1682     g_free(specs);
1683     if (class)
1684         g_type_class_unref(class);
1685     else
1686         g_type_default_interface_unref(iface);
1687
1688     return list;
1689 }
1690
1691 static PyObject *
1692 pyg_object_new (PyGObject *self, PyObject *args, PyObject *kwargs)
1693 {
1694     PyObject *pytype;
1695     GType type;
1696     GObject *obj = NULL;
1697     GObjectClass *class;
1698     guint n_params = 0, i;
1699     GParameter *params = NULL;
1700
1701     if (!PyArg_ParseTuple (args, "O:gobject.new", &pytype)) {
1702         return NULL;
1703     }
1704
1705     if ((type = pyg_type_from_object (pytype)) == 0)
1706         return NULL;
1707
1708     if (G_TYPE_IS_ABSTRACT(type)) {
1709         PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
1710                      "(non-instantiable) type `%s'", g_type_name(type));
1711         return NULL;
1712     }
1713
1714     if ((class = g_type_class_ref (type)) == NULL) {
1715         PyErr_SetString(PyExc_TypeError,
1716                         "could not get a reference to type class");
1717         return NULL;
1718     }
1719
1720     if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, &params))
1721         goto cleanup;
1722
1723     obj = g_object_newv(type, n_params, params);
1724     if (!obj)
1725         PyErr_SetString (PyExc_RuntimeError, "could not create object");
1726
1727  cleanup:
1728     for (i = 0; i < n_params; i++) {
1729         g_free((gchar *) params[i].name);
1730         g_value_unset(&params[i].value);
1731     }
1732     g_free(params);
1733     g_type_class_unref(class);
1734
1735     if (obj) {
1736         pygobject_sink (obj);
1737         self = (PyGObject *) pygobject_new_full((GObject *)obj, FALSE, NULL);
1738         g_object_unref(obj);
1739     } else
1740         self = NULL;
1741
1742     return (PyObject *) self;
1743 }
1744
1745 gboolean
1746 pyg_handler_marshal(gpointer user_data)
1747 {
1748     PyObject *tuple, *ret;
1749     gboolean res;
1750     PyGILState_STATE state;
1751
1752     g_return_val_if_fail(user_data != NULL, FALSE);
1753
1754     state = pyglib_gil_state_ensure();
1755
1756     tuple = (PyObject *)user_data;
1757     ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0),
1758                               PyTuple_GetItem(tuple, 1));
1759     if (!ret) {
1760         PyErr_Print();
1761         res = FALSE;
1762     } else {
1763         res = PyObject_IsTrue(ret);
1764         Py_DECREF(ret);
1765     }
1766
1767     pyglib_gil_state_release(state);
1768
1769     return res;
1770 }
1771
1772 static int
1773 pygobject_gil_state_ensure (void)
1774 {
1775     return pyglib_gil_state_ensure ();
1776 }
1777
1778 static void
1779 pygobject_gil_state_release (int flag)
1780 {
1781     pyglib_gil_state_release(flag);
1782 }
1783
1784 static PyObject *
1785 pyg_threads_init (PyObject *unused, PyObject *args, PyObject *kwargs)
1786 {
1787     if (!pyglib_enable_threads())
1788         return NULL;
1789
1790     Py_INCREF(Py_None);
1791     return Py_None;
1792 }
1793
1794 /* Only for backwards compatibility */
1795 int
1796 pygobject_enable_threads(void)
1797 {
1798     if (!pyglib_enable_threads())
1799         return -1;
1800     return 0;
1801 }
1802
1803 static void
1804 pyg_note_threads_enabled(void)
1805 {
1806     pygobject_api_functions.threads_enabled = TRUE;
1807 }
1808
1809 static PyObject *
1810 pyg_signal_accumulator_true_handled(PyObject *unused, PyObject *args)
1811 {
1812     PyErr_SetString(PyExc_TypeError,
1813                     "signal_accumulator_true_handled can only"
1814                     " be used as accumulator argument when registering signals");
1815     return NULL;
1816 }
1817
1818 static gboolean
1819 marshal_emission_hook(GSignalInvocationHint *ihint,
1820                       guint n_param_values,
1821                       const GValue *param_values,
1822                       gpointer user_data)
1823 {
1824     PyGILState_STATE state;
1825     gboolean retval = FALSE;
1826     PyObject *func, *args;
1827     PyObject *retobj;
1828     PyObject *params;
1829     guint i;
1830
1831     state = pyglib_gil_state_ensure();
1832
1833     /* construct Python tuple for the parameter values */
1834     params = PyTuple_New(n_param_values);
1835
1836     for (i = 0; i < n_param_values; i++) {
1837         PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);
1838
1839         /* error condition */
1840         if (!item) {
1841             goto out;
1842         }
1843         PyTuple_SetItem(params, i, item);
1844     }
1845
1846     args = (PyObject *)user_data;
1847     func = PyTuple_GetItem(args, 0);
1848     args = PySequence_Concat(params, PyTuple_GetItem(args, 1));
1849     Py_DECREF(params);
1850
1851     /* params passed to function may have extra arguments */
1852
1853     retobj = PyObject_CallObject(func, args);
1854     Py_DECREF(args);
1855     if (retobj == NULL) {
1856         PyErr_Print();
1857     }
1858
1859     retval = (retobj == Py_True ? TRUE : FALSE);
1860     Py_XDECREF(retobj);
1861 out:
1862     pyglib_gil_state_release(state);
1863     return retval;
1864 }
1865
1866 static PyObject *
1867 pyg_add_emission_hook(PyGObject *self, PyObject *args)
1868 {
1869     PyObject *first, *callback, *extra_args, *data;
1870     gchar *name;
1871     gulong hook_id;
1872     guint sigid;
1873     Py_ssize_t len;
1874     GQuark detail = 0;
1875     GType gtype;
1876     PyObject *pygtype;
1877
1878     len = PyTuple_Size(args);
1879     if (len < 3) {
1880         PyErr_SetString(PyExc_TypeError,
1881                         "gobject.add_emission_hook requires at least 3 arguments");
1882         return NULL;
1883     }
1884     first = PySequence_GetSlice(args, 0, 3);
1885     if (!PyArg_ParseTuple(first, "OsO:add_emission_hook",
1886                           &pygtype, &name, &callback)) {
1887         Py_DECREF(first);
1888         return NULL;
1889     }
1890     Py_DECREF(first);
1891
1892     if ((gtype = pyg_type_from_object(pygtype)) == 0) {
1893         return NULL;
1894     }
1895     if (!PyCallable_Check(callback)) {
1896         PyErr_SetString(PyExc_TypeError, "third argument must be callable");
1897         return NULL;
1898     }
1899
1900     if (!g_signal_parse_name(name, gtype, &sigid, &detail, TRUE)) {
1901         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1902                         PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1903                      name);
1904         return NULL;
1905     }
1906     extra_args = PySequence_GetSlice(args, 3, len);
1907     if (extra_args == NULL)
1908         return NULL;
1909
1910     data = Py_BuildValue("(ON)", callback, extra_args);
1911     if (data == NULL)
1912       return NULL;
1913
1914     hook_id = g_signal_add_emission_hook(sigid, detail,
1915                                          marshal_emission_hook,
1916                                          data,
1917                                          (GDestroyNotify)pyg_destroy_notify);
1918
1919     return PyLong_FromUnsignedLong(hook_id);
1920 }
1921
1922 static PyObject *
1923 pyg_remove_emission_hook(PyGObject *self, PyObject *args)
1924 {
1925     PyObject *pygtype;
1926     char *name;
1927     guint signal_id;
1928     gulong hook_id;
1929     GType gtype;
1930
1931     if (!PyArg_ParseTuple(args, "Osk:gobject.remove_emission_hook",
1932                           &pygtype, &name, &hook_id))
1933         return NULL;
1934
1935     if ((gtype = pyg_type_from_object(pygtype)) == 0) {
1936         return NULL;
1937     }
1938
1939     if (!g_signal_parse_name(name, gtype, &signal_id, NULL, TRUE)) {
1940         PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
1941                  PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
1942                  name);
1943         return NULL;
1944     }
1945
1946     g_signal_remove_emission_hook(signal_id, hook_id);
1947
1948     Py_INCREF(Py_None);
1949     return Py_None;
1950 }
1951
1952 static PyObject *
1953 pyg__install_metaclass(PyObject *dummy, PyTypeObject *metaclass)
1954 {
1955     Py_INCREF(metaclass);
1956     PyGObject_MetaType = metaclass;
1957     Py_INCREF(metaclass);
1958
1959     Py_TYPE(&PyGObject_Type) = metaclass;
1960
1961     Py_INCREF(Py_None);
1962     return Py_None;
1963 }
1964
1965 static PyMethodDef _gobject_functions[] = {
1966     { "type_name", pyg_type_name, METH_VARARGS },
1967     { "type_from_name", pyg_type_from_name, METH_VARARGS },
1968     { "type_parent", pyg_type_parent, METH_VARARGS },
1969     { "type_is_a", pyg_type_is_a, METH_VARARGS },
1970     { "type_children", pyg_type_children, METH_VARARGS },
1971     { "type_interfaces", pyg_type_interfaces, METH_VARARGS },
1972     { "type_register", _wrap_pyg_type_register, METH_VARARGS },
1973     { "signal_new", pyg_signal_new, METH_VARARGS },
1974     { "signal_list_names",
1975       (PyCFunction)pyg_signal_list_names, METH_VARARGS|METH_KEYWORDS },
1976     { "signal_list_ids",
1977       (PyCFunction)pyg_signal_list_ids, METH_VARARGS|METH_KEYWORDS },
1978     { "signal_lookup",
1979       (PyCFunction)pyg_signal_lookup, METH_VARARGS|METH_KEYWORDS },
1980     { "signal_name",
1981       (PyCFunction)pyg_signal_name, METH_VARARGS|METH_KEYWORDS },
1982     { "signal_query",
1983       (PyCFunction)pyg_signal_query, METH_VARARGS|METH_KEYWORDS },
1984     { "list_properties",
1985       pyg_object_class_list_properties, METH_VARARGS },
1986     { "new",
1987       (PyCFunction)pyg_object_new, METH_VARARGS|METH_KEYWORDS },
1988     { "threads_init",
1989       (PyCFunction)pyg_threads_init, METH_VARARGS|METH_KEYWORDS },
1990     { "signal_accumulator_true_handled",
1991       (PyCFunction)pyg_signal_accumulator_true_handled, METH_VARARGS },
1992     { "add_emission_hook",
1993       (PyCFunction)pyg_add_emission_hook, METH_VARARGS },
1994     { "remove_emission_hook",
1995       (PyCFunction)pyg_remove_emission_hook, METH_VARARGS },
1996     { "_install_metaclass",
1997       (PyCFunction)pyg__install_metaclass, METH_O },
1998
1999     { NULL, NULL, 0 }
2000 };
2001
2002
2003 /* ----------------- Constant extraction ------------------------ */
2004
2005 /**
2006  * pyg_constant_strip_prefix:
2007  * @name: the constant name.
2008  * @strip_prefix: the prefix to strip.
2009  *
2010  * Advances the pointer @name by strlen(@strip_prefix) characters.  If
2011  * the resulting name does not start with a letter or underscore, the
2012  * @name pointer will be rewound.  This is to ensure that the
2013  * resulting name is a valid identifier.  Hence the returned string is
2014  * a pointer into the string @name.
2015  *
2016  * Returns: the stripped constant name.
2017  */
2018 const gchar *
2019 pyg_constant_strip_prefix(const gchar *name, const gchar *strip_prefix)
2020 {
2021     gint prefix_len;
2022     guint i;
2023
2024     prefix_len = strlen(strip_prefix);
2025
2026     /* Check so name starts with strip_prefix, if it doesn't:
2027      * return the rest of the part which doesn't match
2028      */
2029     for (i = 0; i < prefix_len; i++) {
2030         if (name[i] != strip_prefix[i] && name[i] != '_') {
2031             return &name[i];
2032         }
2033     }
2034
2035     /* strip off prefix from value name, while keeping it a valid
2036      * identifier */
2037     for (i = prefix_len; i >= 0; i--) {
2038         if (g_ascii_isalpha(name[i]) || name[i] == '_') {
2039             return &name[i];
2040         }
2041     }
2042     return name;
2043 }
2044
2045 /**
2046  * pyg_enum_add_constants:
2047  * @module: a Python module
2048  * @enum_type: the GType of the enumeration.
2049  * @strip_prefix: the prefix to strip from the constant names.
2050  *
2051  * Adds constants to the given Python module for each value name of
2052  * the enumeration.  A prefix will be stripped from each enum name.
2053  */
2054 static void
2055 pyg_enum_add_constants(PyObject *module, GType enum_type,
2056                        const gchar *strip_prefix)
2057 {
2058     GEnumClass *eclass;
2059     guint i;
2060
2061     if (!G_TYPE_IS_ENUM(enum_type)) {
2062         if (G_TYPE_IS_FLAGS(enum_type)) /* See bug #136204 */
2063             pyg_flags_add_constants(module, enum_type, strip_prefix);
2064         else
2065             g_warning("`%s' is not an enum type", g_type_name(enum_type));
2066         return;
2067     }
2068     g_return_if_fail (strip_prefix != NULL);
2069
2070     eclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
2071
2072     for (i = 0; i < eclass->n_values; i++) {
2073         const gchar *name = eclass->values[i].value_name;
2074         gint value = eclass->values[i].value;
2075
2076         PyModule_AddIntConstant(module,
2077                                 (char*) pyg_constant_strip_prefix(name, strip_prefix),
2078                                 (long) value);
2079     }
2080
2081     g_type_class_unref(eclass);
2082 }
2083
2084 /**
2085  * pyg_flags_add_constants:
2086  * @module: a Python module
2087  * @flags_type: the GType of the flags type.
2088  * @strip_prefix: the prefix to strip from the constant names.
2089  *
2090  * Adds constants to the given Python module for each value name of
2091  * the flags set.  A prefix will be stripped from each flag name.
2092  */
2093 static void
2094 pyg_flags_add_constants(PyObject *module, GType flags_type,
2095                         const gchar *strip_prefix)
2096 {
2097     GFlagsClass *fclass;
2098     guint i;
2099
2100     if (!G_TYPE_IS_FLAGS(flags_type)) {
2101         if (G_TYPE_IS_ENUM(flags_type)) /* See bug #136204 */
2102             pyg_enum_add_constants(module, flags_type, strip_prefix);
2103         else
2104             g_warning("`%s' is not an flags type", g_type_name(flags_type));
2105         return;
2106     }
2107     g_return_if_fail (strip_prefix != NULL);
2108
2109     fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type));
2110
2111     for (i = 0; i < fclass->n_values; i++) {
2112         const gchar *name = fclass->values[i].value_name;
2113         guint value = fclass->values[i].value;
2114
2115         PyModule_AddIntConstant(module,
2116                                 (char*) pyg_constant_strip_prefix(name, strip_prefix),
2117                                 (long) value);
2118     }
2119
2120     g_type_class_unref(fclass);
2121 }
2122
2123 /**
2124  * pyg_error_check:
2125  * @error: a pointer to the GError.
2126  *
2127  * Checks to see if the GError has been set.  If the error has been
2128  * set, then the gobject.GError Python exception will be raised, and
2129  * the GError cleared.
2130  *
2131  * Returns: True if an error was set.
2132  *
2133  * Deprecated: Since 2.16, use pyglib_error_check instead.
2134  */
2135 gboolean
2136 pyg_error_check(GError **error)
2137 {
2138 #if 0
2139     if (PyErr_Warn(PyExc_DeprecationWarning,
2140                    "pyg_error_check is deprecated, use "
2141                    "pyglib_error_check instead"))
2142         return NULL;
2143 #endif
2144     return pyglib_error_check(error);
2145 }
2146
2147 /**
2148  * pyg_gerror_exception_check:
2149  * @error: a standard GLib GError ** output parameter
2150  *
2151  * Checks to see if a GError exception has been raised, and if so
2152  * translates the python exception to a standard GLib GError.  If the
2153  * raised exception is not a GError then PyErr_Print() is called.
2154  *
2155  * Returns: 0 if no exception has been raised, -1 if it is a
2156  * valid gobject.GError, -2 otherwise.
2157  *
2158  * Deprecated: Since 2.16, use pyglib_gerror_exception_check instead.
2159  */
2160 gboolean
2161 pyg_gerror_exception_check(GError **error)
2162 {
2163 #if 0
2164     if (PyErr_Warn(PyExc_DeprecationWarning,
2165                    "pyg_gerror_exception_check is deprecated, use "
2166                    "pyglib_gerror_exception_check instead"))
2167         return NULL;
2168 #endif
2169     return pyglib_gerror_exception_check(error);
2170 }
2171
2172 /**
2173  * pyg_parse_constructor_args: helper function for PyGObject constructors
2174  * @obj_type: GType of the GObject, for parameter introspection
2175  * @arg_names: %NULL-terminated array of constructor argument names
2176  * @prop_names: %NULL-terminated array of property names, with direct
2177  * correspondence to @arg_names
2178  * @params: GParameter array where parameters will be placed; length
2179  * of this array must be at least equal to the number of
2180  * arguments/properties
2181  * @nparams: output parameter to contain actual number of arguments found
2182  * @py_args: array of PyObject* containing the actual constructor arguments
2183  *
2184  * Parses an array of PyObject's and creates a GParameter array
2185  *
2186  * Return value: %TRUE if all is successful, otherwise %FALSE and
2187  * python exception set.
2188  **/
2189 static gboolean
2190 pyg_parse_constructor_args(GType        obj_type,
2191                            char       **arg_names,
2192                            char       **prop_names,
2193                            GParameter  *params,
2194                            guint       *nparams,
2195                            PyObject   **py_args)
2196 {
2197     guint arg_i, param_i;
2198     GObjectClass *oclass;
2199
2200     oclass = g_type_class_ref(obj_type);
2201     g_return_val_if_fail(oclass, FALSE);
2202
2203     for (param_i = arg_i = 0; arg_names[arg_i]; ++arg_i) {
2204         GParamSpec *spec;
2205         if (!py_args[arg_i])
2206             continue;
2207         spec = g_object_class_find_property(oclass, prop_names[arg_i]);
2208         params[param_i].name = prop_names[arg_i];
2209         g_value_init(&params[param_i].value, spec->value_type);
2210         if (pyg_value_from_pyobject(&params[param_i].value, py_args[arg_i]) == -1) {
2211             int i;
2212             PyErr_Format(PyExc_TypeError, "could not convert parameter '%s' of type '%s'",
2213                          arg_names[arg_i], g_type_name(spec->value_type));
2214             g_type_class_unref(oclass);
2215             for (i = 0; i < param_i; ++i)
2216                 g_value_unset(&params[i].value);
2217             return FALSE;
2218         }
2219         ++param_i;
2220     }
2221     g_type_class_unref(oclass);
2222     *nparams = param_i;
2223     return TRUE;
2224 }
2225
2226 int
2227 pygobject_constructv(PyGObject  *self,
2228                      guint       n_parameters,
2229                      GParameter *parameters)
2230 {
2231     if (self->obj == NULL) {
2232         GObject *obj;
2233         pygobject_init_wrapper_set((PyObject *) self);
2234         obj = g_object_newv(pyg_type_from_object((PyObject *) self),
2235                             n_parameters, parameters);
2236         pygobject_sink (obj);
2237         pygobject_init_wrapper_set(NULL);
2238         if (self->obj == NULL) {
2239             self->obj = obj;
2240             pygobject_register_wrapper((PyObject *) self);
2241         }
2242     } else {
2243         int i;
2244         for (i = 0; i < n_parameters; ++i)
2245             g_object_set_property(self->obj,
2246                                   parameters[i].name,
2247                                   &parameters[i].value);
2248     }
2249     return 0;
2250 }
2251
2252 /* This function is mostly juste copy-paste from g_object_new, but
2253  * calls pygobject_constructv instead of g_object_newv */
2254 int
2255 pygobject_construct(PyGObject *self, const char *first_property_name, ...)
2256 {
2257     va_list var_args;
2258     GObjectClass *class;
2259     GParameter *params;
2260     const gchar *name;
2261     guint n_params = 0, n_alloced_params = 16;
2262     GType object_type = pyg_type_from_object((PyObject *) self);
2263     int retval;
2264
2265     if (!first_property_name)
2266         return pygobject_constructv(self, 0, NULL);
2267
2268     va_start(var_args, first_property_name);
2269     class = g_type_class_ref(object_type);
2270
2271     params = g_new(GParameter, n_alloced_params);
2272     name = first_property_name;
2273     while (name)
2274     {
2275         gchar *error = NULL;
2276         GParamSpec *pspec = g_object_class_find_property(class, name);
2277
2278         if (!pspec)
2279         {
2280             g_warning("%s: object class `%s' has no property named `%s'",
2281                       G_STRFUNC,
2282                       g_type_name(object_type),
2283                       name);
2284             break;
2285         }
2286         if (n_params >= n_alloced_params)
2287         {
2288             n_alloced_params += 16;
2289             params = g_renew(GParameter, params, n_alloced_params);
2290         }
2291         params[n_params].name = name;
2292         params[n_params].value.g_type = 0;
2293         g_value_init(&params[n_params].value, G_PARAM_SPEC_VALUE_TYPE(pspec));
2294         G_VALUE_COLLECT(&params[n_params].value, var_args, 0, &error);
2295         if (error)
2296         {
2297             g_warning("%s: %s", G_STRFUNC, error);
2298             g_free(error);
2299             g_value_unset(&params[n_params].value);
2300             break;
2301         }
2302         n_params++;
2303         name = va_arg(var_args, gchar*);
2304     }
2305
2306     retval = pygobject_constructv(self, n_params, params);
2307
2308     while (n_params--)
2309         g_value_unset(&params[n_params].value);
2310     g_free(params);
2311     va_end(var_args);
2312     g_type_class_unref(class);
2313     return retval;
2314 }
2315
2316 void
2317 pyg_set_object_has_new_constructor(GType type)
2318 {
2319     g_type_set_qdata(type, pygobject_has_updated_constructor_key, GINT_TO_POINTER(1));
2320 }
2321
2322 PyObject *
2323 pyg_integer_richcompare(PyObject *v, PyObject *w, int op)
2324 {
2325     PyObject *result;
2326     gboolean t;
2327
2328     switch (op) {
2329     case Py_EQ: t = PYGLIB_PyLong_AS_LONG(v) == PYGLIB_PyLong_AS_LONG(w); break;
2330     case Py_NE: t = PYGLIB_PyLong_AS_LONG(v) != PYGLIB_PyLong_AS_LONG(w); break;
2331     case Py_LE: t = PYGLIB_PyLong_AS_LONG(v) <= PYGLIB_PyLong_AS_LONG(w); break;
2332     case Py_GE: t = PYGLIB_PyLong_AS_LONG(v) >= PYGLIB_PyLong_AS_LONG(w); break;
2333     case Py_LT: t = PYGLIB_PyLong_AS_LONG(v) <  PYGLIB_PyLong_AS_LONG(w); break;
2334     case Py_GT: t = PYGLIB_PyLong_AS_LONG(v) >  PYGLIB_PyLong_AS_LONG(w); break;
2335     default: g_assert_not_reached();
2336     }
2337
2338     result = t ? Py_True : Py_False;
2339     Py_INCREF(result);
2340     return result;
2341 }
2342
2343 static void
2344 _log_func(const gchar *log_domain,
2345           GLogLevelFlags log_level,
2346           const gchar *message,
2347           gpointer user_data)
2348 {
2349     if (G_LIKELY(Py_IsInitialized()))
2350     {
2351         PyGILState_STATE state;
2352         PyObject* warning = user_data;
2353
2354         state = pyglib_gil_state_ensure();
2355         PyErr_Warn(warning, (char *) message);
2356         pyglib_gil_state_release(state);
2357     } else
2358         g_log_default_handler(log_domain, log_level, message, user_data);
2359 }
2360
2361 static void
2362 add_warning_redirection(const char *domain,
2363                         PyObject   *warning)
2364 {
2365     g_return_if_fail(domain != NULL);
2366     g_return_if_fail(warning != NULL);
2367
2368     if (!log_handlers_disabled)
2369     {
2370         guint handler;
2371         gpointer old_handler;
2372
2373         if (!log_handlers)
2374             log_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
2375
2376         if ((old_handler = g_hash_table_lookup(log_handlers, domain)))
2377             g_log_remove_handler(domain, GPOINTER_TO_UINT(old_handler));
2378
2379         handler = g_log_set_handler(domain, G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING,
2380                                     _log_func, warning);
2381         g_hash_table_insert(log_handlers, g_strdup(domain), GUINT_TO_POINTER(handler));
2382     }
2383 }
2384
2385 static void
2386 remove_handler(gpointer domain,
2387                gpointer handler,
2388                gpointer unused)
2389 {
2390     g_log_remove_handler(domain, GPOINTER_TO_UINT(handler));
2391 }
2392
2393 static void
2394 disable_warning_redirections(void)
2395 {
2396     log_handlers_disabled = TRUE;
2397
2398     if (log_handlers)
2399     {
2400         g_hash_table_foreach(log_handlers, remove_handler, NULL);
2401         g_hash_table_destroy(log_handlers);
2402         log_handlers = NULL;
2403     }
2404 }
2405
2406 /* ----------------- gobject module initialisation -------------- */
2407
2408 struct _PyGObject_Functions pygobject_api_functions = {
2409   pygobject_register_class,
2410   pygobject_register_wrapper,
2411   pygobject_register_sinkfunc,
2412   pygobject_lookup_class,
2413   pygobject_new,
2414
2415   pyg_closure_new,
2416   pygobject_watch_closure,
2417   pyg_destroy_notify,
2418
2419   pyg_type_from_object,
2420   pyg_type_wrapper_new,
2421   pyg_enum_get_value,
2422   pyg_flags_get_value,
2423   pyg_register_gtype_custom,
2424   pyg_value_from_pyobject,
2425   pyg_value_as_pyobject,
2426
2427   pyg_register_interface,
2428
2429   &PyGBoxed_Type,
2430   pyg_register_boxed,
2431   pyg_boxed_new,
2432
2433   &PyGPointer_Type,
2434   pyg_register_pointer,
2435   pyg_pointer_new,
2436
2437   pyg_enum_add_constants,
2438   pyg_flags_add_constants,
2439
2440   pyg_constant_strip_prefix,
2441
2442   pyg_error_check,
2443
2444   pyg_set_thread_block_funcs,
2445   (PyGThreadBlockFunc)0, /* block_threads */
2446   (PyGThreadBlockFunc)0, /* unblock_threads */
2447
2448   &PyGParamSpec_Type,
2449   pyg_param_spec_new,
2450   pyg_param_spec_from_object,
2451
2452   pyg_pyobj_to_unichar_conv,
2453   pyg_parse_constructor_args,
2454   pyg_param_gvalue_as_pyobject,
2455   pyg_param_gvalue_from_pyobject,
2456
2457   &PyGEnum_Type,
2458   pyg_enum_add,
2459   pyg_enum_from_gtype,
2460
2461   &PyGFlags_Type,
2462   pyg_flags_add,
2463   pyg_flags_from_gtype,
2464
2465   FALSE, /* threads_enabled */
2466   pygobject_enable_threads,
2467   pygobject_gil_state_ensure,
2468   pygobject_gil_state_release,
2469   pyg_register_class_init,
2470   pyg_register_interface_info,
2471
2472   pyg_closure_set_exception_handler,
2473   pygobject_constructv,
2474   pygobject_construct,
2475   pyg_set_object_has_new_constructor,
2476
2477   add_warning_redirection,
2478   disable_warning_redirections,
2479
2480   pyg_type_register_custom_callback,
2481   pyg_gerror_exception_check,
2482
2483   pyglib_option_group_new,
2484   pyg_type_from_object_strict
2485 };
2486
2487 /* for addon libraries ... */
2488 static void
2489 pygobject_register_api(PyObject *d)
2490 {
2491     PyObject *api;
2492
2493     api = PYGLIB_CPointer_WrapPointer(&pygobject_api_functions, "gobject._PyGObject_API");
2494     PyDict_SetItemString(d, "_PyGObject_API", api);
2495     Py_DECREF(api);
2496 }
2497
2498 /* some constants */
2499 static void
2500 pygobject_register_constants(PyObject *m)
2501 {
2502     /* PyFloat_ return a new ref, and add object takes the ref */
2503     PyModule_AddObject(m,       "G_MINFLOAT", PyFloat_FromDouble(G_MINFLOAT));
2504     PyModule_AddObject(m,       "G_MAXFLOAT", PyFloat_FromDouble(G_MAXFLOAT));
2505     PyModule_AddObject(m,       "G_MINDOUBLE", PyFloat_FromDouble(G_MINDOUBLE));
2506     PyModule_AddObject(m,       "G_MAXDOUBLE", PyFloat_FromDouble(G_MAXDOUBLE));
2507     PyModule_AddIntConstant(m,  "G_MINSHORT", G_MINSHORT);
2508     PyModule_AddIntConstant(m,  "G_MAXSHORT", G_MAXSHORT);
2509     PyModule_AddIntConstant(m,  "G_MAXUSHORT", G_MAXUSHORT);
2510     PyModule_AddIntConstant(m,  "G_MININT", G_MININT);
2511     PyModule_AddIntConstant(m,  "G_MAXINT", G_MAXINT);
2512     PyModule_AddObject(m,       "G_MINLONG", PyLong_FromLong(G_MINLONG));
2513     PyModule_AddObject(m,       "G_MAXLONG", PyLong_FromLong(G_MAXLONG));
2514     PyModule_AddObject(m,       "G_MAXULONG", PyLong_FromUnsignedLong(G_MAXULONG));
2515     PyModule_AddIntConstant(m,  "G_MININT8", G_MININT8);
2516     PyModule_AddIntConstant(m,  "G_MAXINT8", G_MAXINT8);
2517     PyModule_AddIntConstant(m,  "G_MAXUINT8", G_MAXUINT8);
2518     PyModule_AddIntConstant(m,  "G_MININT16", G_MININT16);
2519     PyModule_AddIntConstant(m,  "G_MAXINT16", G_MAXINT16);
2520     PyModule_AddIntConstant(m,  "G_MAXUINT16", G_MAXUINT16);
2521     PyModule_AddIntConstant(m,  "G_MININT32", G_MININT32);
2522     PyModule_AddIntConstant(m,  "G_MAXINT32", G_MAXINT32);
2523     PyModule_AddObject(m,       "G_MININT64", PyLong_FromLongLong(G_MININT64));
2524     PyModule_AddObject(m,       "G_MAXINT64", PyLong_FromLongLong(G_MAXINT64));
2525     PyModule_AddObject(m,       "G_MAXUINT64", PyLong_FromUnsignedLongLong(G_MAXUINT64));
2526 #if PY_VERSION_HEX < 0x02050000 /* 2.3, 2.4 */
2527     PyModule_AddObject(m,       "G_MAXSIZE", PyLong_FromUnsignedLongLong(G_MAXSIZE));
2528     PyModule_AddObject(m,       "G_MAXSSIZE", PyLong_FromUnsignedLongLong(G_MAXSSIZE));
2529 #elif PY_VERSION_HEX < 0x02060000 /* 2.5 */
2530     PyModule_AddObject(m,       "G_MAXSIZE", PYGLIB_PyLong_FromSize_t(G_MAXSIZE));
2531     PyModule_AddObject(m,       "G_MAXSSIZE", PYGLIB_PyLong_FromSsize_t(G_MAXSSIZE));
2532 #else /* 2.6+ */
2533     PyModule_AddObject(m,       "G_MAXSIZE", PyLong_FromSize_t(G_MAXSIZE));
2534     PyModule_AddObject(m,       "G_MAXSSIZE", PyLong_FromSsize_t(G_MAXSSIZE));
2535 #endif
2536     PyModule_AddObject(m,       "G_MINOFFSET", PyLong_FromLongLong(G_MINOFFSET));
2537     PyModule_AddObject(m,       "G_MAXOFFSET", PyLong_FromLongLong(G_MAXOFFSET));
2538
2539     /* in order for test_properties to pass, G_MAXUINT must be initialized using
2540        PyLong_FromUnsignedLong, despite AFAICT it is unecessary for 32bit int types.
2541        In the interests of consistancy I did the same for MAXUINT32 */
2542     PyModule_AddObject(m,       "G_MAXUINT32", PyLong_FromUnsignedLong(G_MAXUINT32));
2543     PyModule_AddObject(m,       "G_MAXUINT", PyLong_FromUnsignedLong(G_MAXUINT));
2544
2545     PyModule_AddIntConstant(m, "SIGNAL_RUN_FIRST", G_SIGNAL_RUN_FIRST);
2546     PyModule_AddIntConstant(m, "SIGNAL_RUN_LAST", G_SIGNAL_RUN_LAST);
2547     PyModule_AddIntConstant(m, "SIGNAL_RUN_CLEANUP", G_SIGNAL_RUN_CLEANUP);
2548     PyModule_AddIntConstant(m, "SIGNAL_NO_RECURSE", G_SIGNAL_NO_RECURSE);
2549     PyModule_AddIntConstant(m, "SIGNAL_DETAILED", G_SIGNAL_DETAILED);
2550     PyModule_AddIntConstant(m, "SIGNAL_ACTION", G_SIGNAL_ACTION);
2551     PyModule_AddIntConstant(m, "SIGNAL_NO_HOOKS", G_SIGNAL_NO_HOOKS);
2552
2553     PyModule_AddIntConstant(m, "PARAM_READABLE", G_PARAM_READABLE);
2554     PyModule_AddIntConstant(m, "PARAM_WRITABLE", G_PARAM_WRITABLE);
2555     PyModule_AddIntConstant(m, "PARAM_CONSTRUCT", G_PARAM_CONSTRUCT);
2556     PyModule_AddIntConstant(m, "PARAM_CONSTRUCT_ONLY", G_PARAM_CONSTRUCT_ONLY);
2557     PyModule_AddIntConstant(m, "PARAM_LAX_VALIDATION", G_PARAM_LAX_VALIDATION);
2558     PyModule_AddIntConstant(m, "PARAM_READWRITE", G_PARAM_READWRITE);
2559
2560     /* The rest of the types are set in __init__.py */
2561     PyModule_AddObject(m, "TYPE_INVALID", pyg_type_wrapper_new(G_TYPE_INVALID));
2562     PyModule_AddObject(m, "TYPE_GSTRING", pyg_type_wrapper_new(G_TYPE_GSTRING));
2563 }
2564
2565 /* features */
2566 static void
2567 pygobject_register_features(PyObject *d)
2568 {
2569     PyObject *features;
2570
2571     features = PyDict_New();
2572 #ifdef HAVE_FFI_H
2573     PyDict_SetItemString(features, "generic-c-marshaller", Py_True);
2574 #endif
2575     PyDict_SetItemString(d, "features", features);
2576     Py_DECREF(features);
2577 }
2578
2579 static void
2580 pygobject_register_version_tuples(PyObject *d)
2581 {
2582     PyObject *tuple;
2583
2584     /* pygobject version */
2585     tuple = Py_BuildValue ("(iii)",
2586                            PYGOBJECT_MAJOR_VERSION,
2587                            PYGOBJECT_MINOR_VERSION,
2588                            PYGOBJECT_MICRO_VERSION);
2589     PyDict_SetItemString(d, "pygobject_version", tuple);
2590
2591     /* backwards compatibility */
2592     PyDict_SetItemString(d, "pygtk_version", tuple);
2593     Py_DECREF(tuple);
2594 }
2595
2596 static void
2597 pygobject_register_warnings(PyObject *d)
2598 {
2599     PyObject *warning;
2600
2601     warning = PyErr_NewException("gobject.Warning", PyExc_Warning, NULL);
2602     PyDict_SetItemString(d, "Warning", warning);
2603     add_warning_redirection("GLib", warning);
2604     add_warning_redirection("GLib-GObject", warning);
2605     add_warning_redirection("GThread", warning);
2606 }
2607
2608
2609 PYGLIB_MODULE_START(_gobject, "_gobject")
2610 {
2611     PyObject *d;
2612
2613     g_type_init();
2614     pyglib_init();
2615
2616     d = PyModule_GetDict(module);
2617     pygobject_register_api(d);
2618     pygobject_register_constants(module);
2619     pygobject_register_features(d);
2620     pygobject_register_version_tuples(d);
2621     pygobject_register_warnings(d);
2622     pygobject_type_register_types(d);
2623     pygobject_object_register_types(d);
2624     pygobject_interface_register_types(d);
2625     pygobject_paramspec_register_types(d);
2626     pygobject_boxed_register_types(d);
2627     pygobject_pointer_register_types(d);
2628     pygobject_enum_register_types(d);
2629     pygobject_flags_register_types(d);
2630
2631       /* signal registration recognizes this special accumulator 'constant' */
2632     _pyg_signal_accumulator_true_handled_func = \
2633         PyDict_GetItemString(d, "signal_accumulator_true_handled");
2634
2635     pygobject_api_functions.threads_enabled = pyglib_threads_enabled();
2636     _pyglib_notify_on_enabling_threads(pyg_note_threads_enabled);
2637 }
2638 PYGLIB_MODULE_END