11b97f54bf1d630298ad947dff8ed1f616f068ea
[platform/upstream/python-gobject.git] / gi / _glib / glibmodule.c
1 /* -*- Mode: C; c-set-style: python; c-basic-offset: 4  -*-
2  * pyglib - Python bindings for GLib toolkit.
3  * Copyright (C) 1998-2003  James Henstridge
4  *               2004-2008  Johan Dahlin
5  *
6  *   glibmodule.c: wrapper for the glib library.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include <Python.h>
29 #include <glib.h>
30 #include "pyglib.h"
31 #include "pyglib-private.h"
32 #include "pygiochannel.h"
33 #include "pygmaincontext.h"
34 #include "pygmainloop.h"
35 #include "pygoptioncontext.h"
36 #include "pygoptiongroup.h"
37 #include "pygsource.h"
38 #include "pygspawn.h"
39
40 #define PYGLIB_MAJOR_VERSION PYGOBJECT_MAJOR_VERSION
41 #define PYGLIB_MINOR_VERSION PYGOBJECT_MINOR_VERSION
42 #define PYGLIB_MICRO_VERSION PYGOBJECT_MICRO_VERSION
43
44
45 /* ---------------- glib module functions -------------------- */
46
47 struct _PyGChildData {
48     PyObject *func;
49     PyObject *data;
50 };
51
52 static gint
53 get_handler_priority(gint *priority, PyObject *kwargs)
54 {
55     Py_ssize_t len, pos;
56     PyObject *key, *val;
57
58     /* no keyword args? leave as default */
59     if (kwargs == NULL) return 0;
60
61     len = PyDict_Size(kwargs);
62     if (len == 0) return 0;
63
64     if (len != 1) {
65         PyErr_SetString(PyExc_TypeError,
66                         "expecting at most one keyword argument");
67         return -1;
68     }
69     pos = 0;
70     PyDict_Next(kwargs, &pos, &key, &val);
71     if (!PYGLIB_PyUnicode_Check(key)) {
72         PyErr_SetString(PyExc_TypeError,
73                         "keyword argument name is not a string");
74         return -1;
75     }
76
77     if (strcmp(PYGLIB_PyUnicode_AsString(key), "priority") != 0) {
78         PyErr_SetString(PyExc_TypeError,
79                         "only 'priority' keyword argument accepted");
80         return -1;
81     }
82
83     *priority = PYGLIB_PyLong_AsLong(val);
84     if (PyErr_Occurred()) {
85         PyErr_Clear();
86         PyErr_SetString(PyExc_ValueError, "could not get priority value");
87         return -1;
88     }
89     return 0;
90 }
91
92 static PyObject *
93 pyglib_threads_init(PyObject *unused, PyObject *args, PyObject *kwargs)
94 {
95     if (!pyglib_enable_threads())
96         return NULL;
97
98     Py_INCREF(Py_None);
99     return Py_None;
100 }
101
102 static PyObject *
103 pyglib_idle_add(PyObject *self, PyObject *args, PyObject *kwargs)
104 {
105     PyObject *first, *callback, *cbargs = NULL, *data;
106     gint len, priority = G_PRIORITY_DEFAULT_IDLE;
107     guint handler_id;
108
109     len = PyTuple_Size(args);
110     if (len < 1) {
111         PyErr_SetString(PyExc_TypeError,
112                         "idle_add requires at least 1 argument");
113         return NULL;
114     }
115     first = PySequence_GetSlice(args, 0, 1);
116     if (!PyArg_ParseTuple(first, "O:idle_add", &callback)) {
117         Py_DECREF(first);
118         return NULL;
119     }
120     Py_DECREF(first);
121     if (!PyCallable_Check(callback)) {
122         PyErr_SetString(PyExc_TypeError, "first argument not callable");
123         return NULL;
124     }
125     if (get_handler_priority(&priority, kwargs) < 0)
126         return NULL;
127
128     cbargs = PySequence_GetSlice(args, 1, len);
129     if (cbargs == NULL)
130         return NULL;
131
132     data = Py_BuildValue("(ON)", callback, cbargs);
133     if (data == NULL)
134         return NULL;
135     handler_id = g_idle_add_full(priority,
136                                  _pyglib_handler_marshal, data,
137                                  _pyglib_destroy_notify);
138     return PYGLIB_PyLong_FromLong(handler_id);
139 }
140
141
142 static PyObject *
143 pyglib_timeout_add(PyObject *self, PyObject *args, PyObject *kwargs)
144 {
145     PyObject *first, *callback, *cbargs = NULL, *data;
146     gint len, priority = G_PRIORITY_DEFAULT;
147     guint interval, handler_id;
148
149     len = PyTuple_Size(args);
150     if (len < 2) {
151         PyErr_SetString(PyExc_TypeError,
152                         "timeout_add requires at least 2 args");
153         return NULL;
154     }
155     first = PySequence_GetSlice(args, 0, 2);
156     if (!PyArg_ParseTuple(first, "IO:timeout_add", &interval, &callback)) {
157         Py_DECREF(first);
158         return NULL;
159     }
160     Py_DECREF(first);
161     if (!PyCallable_Check(callback)) {
162         PyErr_SetString(PyExc_TypeError, "second argument not callable");
163         return NULL;
164     }
165     if (get_handler_priority(&priority, kwargs) < 0)
166         return NULL;
167
168     cbargs = PySequence_GetSlice(args, 2, len);
169     if (cbargs == NULL)
170         return NULL;
171
172     data = Py_BuildValue("(ON)", callback, cbargs);
173     if (data == NULL)
174         return NULL;
175     handler_id = g_timeout_add_full(priority, interval,
176                                     _pyglib_handler_marshal, data,
177                                     _pyglib_destroy_notify);
178     return PYGLIB_PyLong_FromLong(handler_id);
179 }
180
181 static PyObject *
182 pyglib_timeout_add_seconds(PyObject *self, PyObject *args, PyObject *kwargs)
183 {
184     PyObject *first, *callback, *cbargs = NULL, *data;
185     gint len, priority = G_PRIORITY_DEFAULT;
186     guint interval, handler_id;
187
188     len = PyTuple_Size(args);
189     if (len < 2) {
190         PyErr_SetString(PyExc_TypeError,
191                         "timeout_add_seconds requires at least 2 args");
192         return NULL;
193     }
194     first = PySequence_GetSlice(args, 0, 2);
195     if (!PyArg_ParseTuple(first, "IO:timeout_add_seconds", &interval, &callback)) {
196         Py_DECREF(first);
197         return NULL;
198     }
199     Py_DECREF(first);
200     if (!PyCallable_Check(callback)) {
201         PyErr_SetString(PyExc_TypeError, "second argument not callable");
202         return NULL;
203     }
204     if (get_handler_priority(&priority, kwargs) < 0)
205         return NULL;
206
207     cbargs = PySequence_GetSlice(args, 2, len);
208     if (cbargs == NULL)
209         return NULL;
210
211     data = Py_BuildValue("(ON)", callback, cbargs);
212     if (data == NULL)
213         return NULL;
214     handler_id = g_timeout_add_seconds_full(priority, interval,
215                                             _pyglib_handler_marshal, data,
216                                             _pyglib_destroy_notify);
217     return PYGLIB_PyLong_FromLong(handler_id);
218 }
219
220 static gboolean
221 iowatch_marshal(GIOChannel *source,
222                 GIOCondition condition,
223                 gpointer user_data)
224 {
225     PyGILState_STATE state;
226     PyObject *tuple, *func, *firstargs, *args, *ret;
227     gboolean res;
228
229     g_return_val_if_fail(user_data != NULL, FALSE);
230
231     state = pyglib_gil_state_ensure();
232
233     tuple = (PyObject *)user_data;
234     func = PyTuple_GetItem(tuple, 0);
235
236     /* arg vector is (fd, condtion, *args) */
237     firstargs = Py_BuildValue("(Oi)", PyTuple_GetItem(tuple, 1), condition);
238     args = PySequence_Concat(firstargs, PyTuple_GetItem(tuple, 2));
239     Py_DECREF(firstargs);
240
241     ret = PyObject_CallObject(func, args);
242     Py_DECREF(args);
243     if (!ret) {
244         PyErr_Print();
245         res = FALSE;
246     } else {
247         if (ret == Py_None) {
248             if (PyErr_Warn(PyExc_Warning,
249                            "_glib.io_add_watch callback returned None; "
250                            "should return True/False")) {
251                 PyErr_Print();
252             }
253         }
254         res = PyObject_IsTrue(ret);
255         Py_DECREF(ret);
256     }
257
258     pyglib_gil_state_release(state);
259
260     return res;
261 }
262
263 static PyObject *
264 pyglib_io_add_watch(PyObject *self, PyObject *args, PyObject *kwargs)
265 {
266     PyObject *first, *pyfd, *callback, *cbargs = NULL, *data;
267     gint fd, priority = G_PRIORITY_DEFAULT, condition;
268     Py_ssize_t len;
269     GIOChannel *iochannel;
270     guint handler_id;
271
272     len = PyTuple_Size(args);
273     if (len < 3) {
274         PyErr_SetString(PyExc_TypeError,
275                         "io_add_watch requires at least 3 args");
276         return NULL;
277     }
278     first = PySequence_GetSlice(args, 0, 3);
279     if (!PyArg_ParseTuple(first, "OiO:io_add_watch", &pyfd, &condition,
280                           &callback)) {
281         Py_DECREF(first);
282         return NULL;
283     }
284     Py_DECREF(first);
285     fd = PyObject_AsFileDescriptor(pyfd);
286     if (fd < 0) {
287         return NULL;
288     }
289     if (!PyCallable_Check(callback)) {
290         PyErr_SetString(PyExc_TypeError, "third argument not callable");
291         return NULL;
292     }
293     if (get_handler_priority(&priority, kwargs) < 0)
294         return NULL;
295
296     cbargs = PySequence_GetSlice(args, 3, len);
297     if (cbargs == NULL)
298       return NULL;
299     data = Py_BuildValue("(OON)", callback, pyfd, cbargs);
300     if (data == NULL)
301       return NULL;
302     iochannel = g_io_channel_unix_new(fd);
303     handler_id = g_io_add_watch_full(iochannel, priority, condition,
304                                      iowatch_marshal, data,
305                                      (GDestroyNotify)_pyglib_destroy_notify);
306     g_io_channel_unref(iochannel);
307     
308     return PYGLIB_PyLong_FromLong(handler_id);
309 }
310
311 static PyObject *
312 pyglib_source_remove(PyObject *self, PyObject *args)
313 {
314     guint tag;
315
316     if (!PyArg_ParseTuple(args, "i:source_remove", &tag))
317         return NULL;
318
319     return PyBool_FromLong(g_source_remove(tag));
320 }
321
322 static PyObject *
323 pyglib_main_context_default(PyObject *unused)
324 {
325     return pyglib_main_context_new(g_main_context_default());
326 }
327
328 static void
329 child_watch_func(GPid pid, gint status, gpointer data)
330 {
331     struct _PyGChildData *child_data = (struct _PyGChildData *) data;
332     PyObject *retval;
333     PyGILState_STATE gil;
334
335     gil = pyglib_gil_state_ensure();
336     if (child_data->data)
337         retval = PyObject_CallFunction(child_data->func, "iiO", pid, status,
338                                        child_data->data);
339     else
340         retval = PyObject_CallFunction(child_data->func, "ii", pid, status);
341
342     if (retval)
343         Py_DECREF(retval);
344     else
345         PyErr_Print();
346
347     pyglib_gil_state_release(gil);
348 }
349
350 static void
351 child_watch_dnotify(gpointer data)
352 {
353     struct _PyGChildData *child_data = (struct _PyGChildData *) data;
354     Py_DECREF(child_data->func);
355     Py_XDECREF(child_data->data);
356     g_slice_free(struct _PyGChildData, child_data);
357 }
358
359
360 static PyObject *
361 pyglib_child_watch_add(PyObject *unused, PyObject *args, PyObject *kwargs)
362 {
363     static char *kwlist[] = { "pid", "function", "data", "priority", NULL };
364     guint id;
365     gint priority = G_PRIORITY_DEFAULT;
366     int pid;
367     PyObject *func, *user_data = NULL;
368     struct _PyGChildData *child_data;
369
370     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
371                                      "iO|Oi:glib.child_watch_add", kwlist,
372                                      &pid, &func, &user_data, &priority))
373         return NULL;
374     if (!PyCallable_Check(func)) {
375         PyErr_SetString(PyExc_TypeError,
376                         "_glib.child_watch_add: second argument must be callable");
377         return NULL;
378     }
379
380     child_data = g_slice_new(struct _PyGChildData);
381     child_data->func = func;
382     child_data->data = user_data;
383     Py_INCREF(child_data->func);
384     if (child_data->data)
385         Py_INCREF(child_data->data);
386     id = g_child_watch_add_full(priority, pid, child_watch_func,
387                                 child_data, child_watch_dnotify);
388     return PYGLIB_PyLong_FromLong(id);
389 }
390
391 static PyObject *
392 pyglib_markup_escape_text(PyObject *unused, PyObject *args, PyObject *kwargs)
393 {
394     static char *kwlist[] = { "text", NULL };
395     char *text_in, *text_out;
396     Py_ssize_t text_size;
397     PyObject *retval;
398
399     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
400                                      "s#:glib.markup_escape_text", kwlist,
401                                      &text_in, &text_size))
402         return NULL;
403
404     text_out = g_markup_escape_text(text_in, text_size);
405     retval = PYGLIB_PyUnicode_FromString(text_out);
406     g_free(text_out);
407     return retval;
408 }
409
410 static PyObject *
411 pyglib_get_current_time(PyObject *unused)
412 {
413     GTimeVal timeval;
414
415     g_get_current_time(&timeval);
416     return pyglib_float_from_timeval(timeval);
417 }
418
419 static PyObject*
420 get_user_dir(const char *path)
421 {
422     if (path)
423         return PYGLIB_PyUnicode_FromString(path);
424     else {
425         Py_INCREF(Py_None);
426         return Py_None;
427     }
428 }
429
430 static PyObject*
431 pyglib_get_user_config_dir(PyObject *self)
432 {
433     return get_user_dir(g_get_user_config_dir());
434 }
435
436 static PyObject*
437 pyglib_get_user_cache_dir(PyObject *self)
438 {
439     return get_user_dir(g_get_user_cache_dir());
440 }
441
442 static PyObject*
443 pyglib_get_user_data_dir(PyObject *self)
444 {
445     return get_user_dir(g_get_user_data_dir());
446 }
447
448 static PyObject *
449 pyglib_get_user_special_dir(PyObject *unused, PyObject *args, PyObject *kwargs)
450 {
451     static char *kwlist[] = { "directory", NULL };
452     guint directory;
453     const char *path;
454
455     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
456                                      "i:glib.get_user_special_dir", kwlist,
457                                      &directory))
458         return NULL;
459
460     path = g_get_user_special_dir(directory);
461     if (path)
462         return PYGLIB_PyUnicode_FromString(path);
463     else {
464         Py_INCREF(Py_None);
465         return Py_None;
466     }
467 }
468
469 static PyObject *
470 pyglib_main_depth(PyObject *unused)
471 {
472     return PYGLIB_PyLong_FromLong(g_main_depth());
473 }
474
475 static PyObject *
476 pyglib_filename_display_name(PyObject *self, PyObject *args)
477 {
478     PyObject *py_display_name;
479     char *filename, *display_name;
480     
481     if (!PyArg_ParseTuple(args, "s:glib.filename_display_name",
482                           &filename))
483         return NULL;
484
485     display_name = g_filename_display_name(filename);
486     py_display_name = PyUnicode_DecodeUTF8(display_name,
487                                            strlen(display_name), NULL);
488     g_free(display_name);
489     return py_display_name;
490 }
491
492 static PyObject *
493 pyglib_filename_display_basename(PyObject *self, PyObject *args)
494 {
495     PyObject *py_display_basename;
496     char *filename, *display_basename;
497     
498     if (!PyArg_ParseTuple(args, "s:glib.filename_display_basename",
499                           &filename))
500         return NULL;
501
502     display_basename = g_filename_display_basename(filename);
503     py_display_basename = PyUnicode_DecodeUTF8(display_basename,
504                                                strlen(display_basename), NULL);
505     g_free(display_basename);
506     return py_display_basename;
507 }
508
509 static PyObject *
510 pyglib_filename_from_utf8(PyObject *self, PyObject *args)
511 {
512     char *filename, *utf8string;
513     Py_ssize_t utf8string_len;
514     gsize bytes_written;
515     GError *error = NULL;
516     PyObject *py_filename;
517     
518     if (!PyArg_ParseTuple(args, "s#:glib.filename_from_utf8",
519                           &utf8string, &utf8string_len))
520         return NULL;
521
522     filename = g_filename_from_utf8(utf8string, utf8string_len,
523                                     NULL, &bytes_written, &error);
524     if (pyglib_error_check(&error)) {
525         g_free(filename);
526         return NULL;
527     }
528     py_filename = PYGLIB_PyUnicode_FromStringAndSize(filename, bytes_written);
529     g_free(filename);
530     return py_filename;
531 }
532
533
534 static PyObject*
535 pyglib_get_application_name(PyObject *self)
536 {
537     const char *name;
538
539     name = g_get_application_name();
540     if (!name) {
541         Py_INCREF(Py_None);
542         return Py_None;
543     }
544     return PYGLIB_PyUnicode_FromString(name);
545 }
546
547 static PyObject*
548 pyglib_set_application_name(PyObject *self, PyObject *arg)
549 {
550     PyObject *repr = NULL;
551     if (!PYGLIB_PyUnicode_Check(arg)) {
552         repr = PyObject_Repr(arg);
553         PyErr_Format(PyExc_TypeError,
554                      "first argument must be a string, not '%s'",
555                      PYGLIB_PyUnicode_AsString(repr));
556         Py_DECREF(repr);
557         return NULL;
558     }
559     g_set_application_name(PYGLIB_PyUnicode_AsString(arg));
560     Py_INCREF(Py_None);
561     return Py_None;
562 }
563
564 static PyObject*
565 pyglib_get_prgname(PyObject *self)
566 {
567     char *name;
568
569     name = g_get_prgname();
570     if (!name) {
571         Py_INCREF(Py_None);
572         return Py_None;
573     }
574     return PYGLIB_PyUnicode_FromString(name);
575 }
576
577 static PyObject*
578 pyglib_set_prgname(PyObject *self, PyObject *arg)
579 {
580     PyObject *repr = NULL;
581     if (!PYGLIB_PyUnicode_Check(arg)) {
582         repr = PyObject_Repr(arg);
583         PyErr_Format(PyExc_TypeError,
584                      "first argument must be a string, not '%s'",
585                      PYGLIB_PyUnicode_AsString(repr));
586         Py_DECREF(repr);
587         return NULL;
588     }
589     g_set_prgname(PYGLIB_PyUnicode_AsString(arg));
590     Py_INCREF(Py_None);
591     return Py_None;
592 }
593
594 static PyObject *
595 pyglib_find_program_in_path(PyObject *unused, PyObject *args, PyObject *kwargs)
596 {
597     static char *kwlist[] = { "program", NULL };
598     char *program, *ret;
599     PyObject *retval;
600
601     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
602                                      "s:glib.find_program_in_path", kwlist,
603                                      &program))
604         return NULL;
605
606     ret = g_find_program_in_path(program);
607
608     if (ret != NULL) {
609         retval = PYGLIB_PyUnicode_FromString(ret);
610         g_free(ret);
611     } else {
612         Py_INCREF(Py_None);
613         retval = Py_None;
614     }
615     return retval;
616 }
617
618 static PyObject *
619 pyglib_uri_list_extract_uris(PyObject *self, PyObject *args, PyObject *kwargs)
620 {
621     static char *kwlist[] = { "uri_list", NULL };
622     char *uri_list;
623     char **uris, **tmp;
624     int i = 0, j;
625     PyObject *ret;
626
627     if (!PyArg_ParseTupleAndKeywords(args, kwargs,"s:uri_list_extract_uris", kwlist, &uri_list))
628         return NULL;
629
630     uris = (char **)g_uri_list_extract_uris(uri_list);
631     if (!uris) {
632         Py_INCREF(Py_None);
633         return Py_None;
634     }
635
636     tmp = uris;
637     while (*tmp)
638         tmp++, i++;
639
640     ret = PyTuple_New(i);
641     for (j = 0; j < i; j++)
642         PyTuple_SetItem(ret, j, PYGLIB_PyUnicode_FromString(uris[j]));
643
644     g_strfreev(uris);
645
646     return ret;
647 }
648
649 /* FIXME: we should use strv_to_pylist (in pygio-utils.h) here, but that
650  * function should be moved into pyglib first. See
651  * https://bugzilla.gnome.org/show_bug.cgi?id=630508
652  */
653 static PyObject *
654 tuple_of_strings_from_dirs(const gchar* const *dirs)
655 {
656     char **tmp;
657     int i = 0, j;
658     PyObject *ret;
659
660     if (!dirs) {
661         Py_INCREF(Py_None);
662         return Py_None;
663     }
664
665     tmp = (char **)dirs;
666     while (*tmp)
667         tmp++, i++;
668
669     ret = PyTuple_New(i);
670     for (j = 0; j < i; j++)
671         PyTuple_SetItem(ret, j, PYGLIB_PyUnicode_FromString(dirs[j]));
672
673     return ret;
674 }
675
676 static PyObject*
677 pyglib_get_system_config_dirs(PyObject *self)
678 {
679     return tuple_of_strings_from_dirs(g_get_system_config_dirs());
680 }
681
682 static PyObject*
683 pyglib_get_system_data_dirs(PyObject *self)
684 {
685     return tuple_of_strings_from_dirs(g_get_system_data_dirs());
686 }
687
688 static PyMethodDef _glib_functions[] = {
689     { "threads_init",
690       (PyCFunction) pyglib_threads_init, METH_NOARGS,
691       "threads_init()\n"
692       "Initialize GLib for use from multiple threads. If you also use GTK+\n"
693       "itself (i.e. GUI, not just PyGObject), use gtk.gdk.threads_init()\n"
694       "instead." },
695     { "idle_add",
696       (PyCFunction)pyglib_idle_add, METH_VARARGS|METH_KEYWORDS,
697       "idle_add(callable, user_data=None, priority=None) -> source id\n"
698       "  callable receives (user_data)\n"
699       "Adds a callable to be called whenever there are no higher priority\n"
700       "events pending to the default main loop." },
701     { "timeout_add",
702       (PyCFunction)pyglib_timeout_add, METH_VARARGS|METH_KEYWORDS,
703       "timeout_add(interval, callable, user_data=None,\n"
704       "            priority=None) -> source id\n"
705       "  callable receives (user_data)\n"
706       "Sets a callable be called repeatedly until it returns False." },
707     { "timeout_add_seconds",
708       (PyCFunction)pyglib_timeout_add_seconds, METH_VARARGS|METH_KEYWORDS,
709       "timeout_add(interval, callable, user_data=None,\n"
710       "            priority=None) -> source_id\n"
711       "  callable receives (user_data)\n"
712       "Sets a callable be called repeatedly until it returns False.\n"
713       "Use this if you want to have a timer in the \"seconds\" range\n"
714       "and do not care about the exact time of the first call of the\n"
715       "timer, use this for more efficient system power usage." },
716     { "io_add_watch",
717       (PyCFunction)pyglib_io_add_watch, METH_VARARGS|METH_KEYWORDS,
718       "io_add_watch(fd, condition, callback, user_data=None) -> source id\n"
719       "  callable receives (fd, condition, user_data)\n"
720       "Arranges for the fd to be monitored by the main loop for the\n"
721       "specified condition. Condition is a combination of glib.IO_IN,\n"
722       "glib.IO_OUT, glib.IO_PRI, gio.IO_ERR and gio.IO_HUB.\n" },
723     { "child_watch_add",
724       (PyCFunction)pyglib_child_watch_add, METH_VARARGS|METH_KEYWORDS,
725       "child_watch_add(pid, callable, user_data=None,\n"
726                        "priority=None) -> source id\n"
727       "  callable receives (pid, condition, user_data)\n"
728       "Sets the function specified by function to be called with the user\n"
729       "data specified by data when the child indicated by pid exits.\n"
730       "Condition is a combination of glib.IO_IN, glib.IO_OUT, glib.IO_PRI,\n"
731       "gio.IO_ERR and gio.IO_HUB." },
732     { "source_remove",
733       (PyCFunction)pyglib_source_remove, METH_VARARGS,
734       "source_remove(source_id) -> True if removed\n"
735       "Removes the event source specified by source id as returned by the\n"
736       "glib.idle_add(), glib.timeout_add() or glib.io_add_watch()\n"
737       "functions." },
738     { "spawn_async",
739       (PyCFunction)pyglib_spawn_async, METH_VARARGS|METH_KEYWORDS,
740       "spawn_async(argv, envp=None, working_directory=None,\n"
741       "            flags=0, child_setup=None, user_data=None,\n"
742       "            standard_input=None, standard_output=None,\n"
743       "            standard_error=None) -> (pid, stdin, stdout, stderr)\n"
744       "Execute a child program asynchronously within a glib.MainLoop()\n"
745       "See the reference manual for a complete reference." },
746     { "main_context_default",
747       (PyCFunction)pyglib_main_context_default, METH_NOARGS,
748       "main_context_default() -> a main context\n"
749       "Returns the default main context. This is the main context used\n"
750       "for main loop functions when a main loop is not explicitly specified." },
751     { "main_depth",
752       (PyCFunction)pyglib_main_depth, METH_NOARGS,
753       "main_depth() -> stack depth\n"
754       "Returns the depth of the stack of calls in the main context." },
755     { "filename_display_name",
756       (PyCFunction)pyglib_filename_display_name, METH_VARARGS },
757     { "filename_display_basename",
758       (PyCFunction)pyglib_filename_display_basename, METH_VARARGS },
759     { "filename_from_utf8",
760       (PyCFunction)pyglib_filename_from_utf8, METH_VARARGS },
761     { "get_application_name",
762       (PyCFunction)pyglib_get_application_name, METH_NOARGS },
763     { "set_application_name",
764       (PyCFunction)pyglib_set_application_name, METH_O },
765     { "get_prgname",
766       (PyCFunction)pyglib_get_prgname, METH_NOARGS },
767     { "set_prgname",
768       (PyCFunction)pyglib_set_prgname, METH_O },
769     { "get_current_time",
770       (PyCFunction)pyglib_get_current_time, METH_NOARGS },
771     { "get_user_cache_dir",
772       (PyCFunction)pyglib_get_user_cache_dir, METH_NOARGS },
773     { "get_user_config_dir",
774       (PyCFunction)pyglib_get_user_config_dir, METH_NOARGS },
775     { "get_user_data_dir",
776       (PyCFunction)pyglib_get_user_data_dir, METH_NOARGS },
777     { "get_user_special_dir",
778       (PyCFunction)pyglib_get_user_special_dir, METH_VARARGS|METH_KEYWORDS },
779     { "markup_escape_text",
780       (PyCFunction)pyglib_markup_escape_text, METH_VARARGS|METH_KEYWORDS },
781     { "find_program_in_path",
782       (PyCFunction)pyglib_find_program_in_path, METH_VARARGS|METH_KEYWORDS },
783     { "uri_list_extract_uris",
784       (PyCFunction)pyglib_uri_list_extract_uris, METH_VARARGS|METH_KEYWORDS,
785       "uri_list_extract_uris(uri_list) -> tuple of strings holding URIs\n"
786       "Splits an string containing an URI list conforming to the \n"
787       "text/uri-list mime type defined in RFC 2483 into individual URIs, \n"
788       "discarding any comments. The URIs are not validated." },
789     { "get_system_config_dirs",
790       (PyCFunction)pyglib_get_system_config_dirs, METH_NOARGS },
791     { "get_system_data_dirs",
792       (PyCFunction)pyglib_get_system_data_dirs, METH_NOARGS },
793     { NULL, NULL, 0 }
794 };
795
796 /* ----------------- glib module initialisation -------------- */
797
798 static struct _PyGLib_Functions pyglib_api = {
799     FALSE, /* threads_enabled */
800     NULL,  /* gerror_exception */
801     NULL,  /* block_threads */
802     NULL,  /* unblock_threads */
803     pyg_main_context_new,
804     pyg_option_context_new,
805     pyg_option_group_new,
806 };
807
808 static void
809 pyglib_register_api(PyObject *d)
810 {
811     PyObject *o;
812
813     /* for addon libraries ... */
814     PyDict_SetItemString(d, "_PyGLib_API",
815                          o=PYGLIB_CPointer_WrapPointer(&pyglib_api,"gi._glib._PyGLib_API"));
816     Py_DECREF(o);
817     
818     pyglib_init_internal(o);
819 }
820
821 static void
822 pyglib_register_error(PyObject *d)
823 {
824     PyObject *dict;
825     PyObject *gerror_class;
826     dict = PyDict_New();
827     /* This is a hack to work around the deprecation warning of
828      * BaseException.message in Python 2.6+.
829      * GError has also an "message" attribute.
830      */
831     PyDict_SetItemString(dict, "message", Py_None);
832     gerror_class = PyErr_NewException("gi._glib.GError", PyExc_RuntimeError, dict);
833     Py_DECREF(dict);
834
835     PyDict_SetItemString(d, "GError", gerror_class);
836     pyglib_api.gerror_exception = gerror_class;
837 }
838
839 static void
840 pyglib_register_version_tuples(PyObject *d)
841 {
842     PyObject *o;
843
844     /* glib version */
845     o = Py_BuildValue("(iii)", glib_major_version, glib_minor_version,
846                       glib_micro_version);
847     PyDict_SetItemString(d, "glib_version", o);
848     Py_DECREF(o);
849
850     /* pyglib version */
851     o = Py_BuildValue("(iii)",
852                       PYGLIB_MAJOR_VERSION,
853                       PYGLIB_MINOR_VERSION,
854                       PYGLIB_MICRO_VERSION);
855     PyDict_SetItemString(d, "pyglib_version", o);
856     Py_DECREF(o);
857 }
858
859 static void
860 pyglib_register_constants(PyObject *m)
861 {
862     PyModule_AddIntConstant(m, "SPAWN_LEAVE_DESCRIPTORS_OPEN",
863                             G_SPAWN_LEAVE_DESCRIPTORS_OPEN);
864     PyModule_AddIntConstant(m, "SPAWN_DO_NOT_REAP_CHILD",
865                             G_SPAWN_DO_NOT_REAP_CHILD);
866     PyModule_AddIntConstant(m, "SPAWN_SEARCH_PATH",
867                             G_SPAWN_SEARCH_PATH);
868     PyModule_AddIntConstant(m, "SPAWN_STDOUT_TO_DEV_NULL",
869                             G_SPAWN_STDOUT_TO_DEV_NULL);
870     PyModule_AddIntConstant(m, "SPAWN_STDERR_TO_DEV_NULL",
871                             G_SPAWN_STDERR_TO_DEV_NULL);
872     PyModule_AddIntConstant(m, "SPAWN_CHILD_INHERITS_STDIN",
873                             G_SPAWN_CHILD_INHERITS_STDIN);
874     PyModule_AddIntConstant(m, "SPAWN_FILE_AND_ARGV_ZERO",
875                             G_SPAWN_FILE_AND_ARGV_ZERO);
876
877     PyModule_AddIntConstant(m, "PRIORITY_HIGH",
878                             G_PRIORITY_HIGH);
879     PyModule_AddIntConstant(m, "PRIORITY_DEFAULT",
880                             G_PRIORITY_DEFAULT);
881     PyModule_AddIntConstant(m, "PRIORITY_HIGH_IDLE",
882                             G_PRIORITY_HIGH_IDLE);
883     PyModule_AddIntConstant(m, "PRIORITY_DEFAULT_IDLE",
884                             G_PRIORITY_DEFAULT_IDLE);
885     PyModule_AddIntConstant(m, "PRIORITY_LOW",
886                             G_PRIORITY_LOW);
887
888     PyModule_AddIntConstant(m, "IO_IN",   G_IO_IN);
889     PyModule_AddIntConstant(m, "IO_OUT",  G_IO_OUT);
890     PyModule_AddIntConstant(m, "IO_PRI",  G_IO_PRI);
891     PyModule_AddIntConstant(m, "IO_ERR",  G_IO_ERR);
892     PyModule_AddIntConstant(m, "IO_HUP",  G_IO_HUP);
893     PyModule_AddIntConstant(m, "IO_NVAL", G_IO_NVAL);
894
895     PyModule_AddIntConstant(m, "IO_STATUS_ERROR",
896                             G_IO_STATUS_ERROR);
897     PyModule_AddIntConstant(m, "IO_STATUS_NORMAL",
898                             G_IO_STATUS_NORMAL);
899     PyModule_AddIntConstant(m, "IO_STATUS_EOF",
900                             G_IO_STATUS_EOF);
901     PyModule_AddIntConstant(m, "IO_STATUS_AGAIN",
902                             G_IO_STATUS_AGAIN);
903     PyModule_AddIntConstant(m, "IO_FLAG_APPEND",
904                             G_IO_FLAG_APPEND);
905     PyModule_AddIntConstant(m, "IO_FLAG_NONBLOCK",
906                             G_IO_FLAG_NONBLOCK);
907     PyModule_AddIntConstant(m, "IO_FLAG_IS_READABLE",
908                             G_IO_FLAG_IS_READABLE);
909     PyModule_AddIntConstant(m, "IO_FLAG_IS_WRITEABLE",
910                             G_IO_FLAG_IS_WRITEABLE);
911     PyModule_AddIntConstant(m, "IO_FLAG_IS_SEEKABLE",
912                             G_IO_FLAG_IS_SEEKABLE);
913     PyModule_AddIntConstant(m, "IO_FLAG_MASK",
914                             G_IO_FLAG_MASK);
915     PyModule_AddIntConstant(m, "IO_FLAG_GET_MASK",
916                             G_IO_FLAG_GET_MASK);
917     PyModule_AddIntConstant(m, "IO_FLAG_SET_MASK",
918                             G_IO_FLAG_SET_MASK);
919
920     PyModule_AddIntConstant(m, "OPTION_FLAG_HIDDEN",
921                             G_OPTION_FLAG_HIDDEN);
922     PyModule_AddIntConstant(m, "OPTION_FLAG_IN_MAIN",
923                             G_OPTION_FLAG_IN_MAIN);
924     PyModule_AddIntConstant(m, "OPTION_FLAG_REVERSE",
925                             G_OPTION_FLAG_REVERSE);
926     PyModule_AddIntConstant(m, "OPTION_FLAG_NO_ARG",
927                             G_OPTION_FLAG_NO_ARG);
928     PyModule_AddIntConstant(m, "OPTION_FLAG_FILENAME",
929                             G_OPTION_FLAG_FILENAME);
930     PyModule_AddIntConstant(m, "OPTION_FLAG_OPTIONAL_ARG",
931                             G_OPTION_FLAG_OPTIONAL_ARG);
932     PyModule_AddIntConstant(m, "OPTION_FLAG_NOALIAS",
933                             G_OPTION_FLAG_NOALIAS); 
934
935     PyModule_AddIntConstant(m, "OPTION_ERROR_UNKNOWN_OPTION",
936                             G_OPTION_ERROR_UNKNOWN_OPTION);
937     PyModule_AddIntConstant(m, "OPTION_ERROR_BAD_VALUE",
938                             G_OPTION_ERROR_BAD_VALUE);
939     PyModule_AddIntConstant(m, "OPTION_ERROR_FAILED",
940                             G_OPTION_ERROR_FAILED);
941  
942     PyModule_AddIntConstant(m, "USER_DIRECTORY_DESKTOP",
943                             G_USER_DIRECTORY_DESKTOP);
944     PyModule_AddIntConstant(m, "USER_DIRECTORY_DOCUMENTS",
945                             G_USER_DIRECTORY_DOCUMENTS);
946     PyModule_AddIntConstant(m, "USER_DIRECTORY_DOWNLOAD",
947                             G_USER_DIRECTORY_DOWNLOAD);
948     PyModule_AddIntConstant(m, "USER_DIRECTORY_MUSIC",
949                             G_USER_DIRECTORY_MUSIC);
950     PyModule_AddIntConstant(m, "USER_DIRECTORY_PICTURES",
951                             G_USER_DIRECTORY_PICTURES);
952     PyModule_AddIntConstant(m, "USER_DIRECTORY_PUBLIC_SHARE",
953                             G_USER_DIRECTORY_PUBLIC_SHARE);
954     PyModule_AddIntConstant(m, "USER_DIRECTORY_TEMPLATES",
955                             G_USER_DIRECTORY_TEMPLATES);
956     PyModule_AddIntConstant(m, "USER_DIRECTORY_VIDEOS",
957                             G_USER_DIRECTORY_VIDEOS);
958
959     PyModule_AddStringConstant(m, "OPTION_REMAINING",
960                                G_OPTION_REMAINING);
961     PyModule_AddStringConstant(m, "OPTION_ERROR",
962                                (char*) g_quark_to_string(G_OPTION_ERROR));
963 }
964
965 PYGLIB_MODULE_START(_glib, "_glib")
966 {
967     PyObject *d = PyModule_GetDict(module);
968
969     pyglib_register_constants(module);
970     pyglib_register_api(d);
971     pyglib_register_error(d);
972     pyglib_register_version_tuples(d);
973     pyglib_iochannel_register_types(d);
974     pyglib_mainloop_register_types(d);
975     pyglib_maincontext_register_types(d);
976     pyglib_source_register_types(d);
977     pyglib_spawn_register_types(d);
978     pyglib_option_context_register_types(d);
979     pyglib_option_group_register_types(d);
980 }
981 PYGLIB_MODULE_END