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