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