/* -*- Mode: C; c-basic-offset: 4 -*- * pygtk- Python bindings for the GTK toolkit. * Copyright (C) 2008 Johan Dahlin * * gio.override: module wrapping the GIO library * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ %% modulename gio %% import gobject.GObject as PyGObject_Type import glib.PollFD as PyGPollFD_Type %% headers #define NO_IMPORT_PYGOBJECT #include #include #include "pygio-utils.h" #include "pyglib.h" #include "pygsource.h" #define BUFSIZE 8192 typedef struct _PyGIONotify PyGIONotify; struct _PyGIONotify { gboolean referenced; PyObject *callback; PyObject *data; gboolean attach_self; gpointer buffer; gsize buffer_size; /* If a structure has any 'slaves', those will reference their * callbacks and be freed together with the 'master'. */ PyGIONotify *slaves; }; static GQuark pygio_notify_get_internal_quark(void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_string("pygio::notify"); return quark; } static PyGIONotify * pygio_notify_new(void) { return g_slice_new0(PyGIONotify); } static PyGIONotify * pygio_notify_new_slave(PyGIONotify* master) { PyGIONotify *slave = pygio_notify_new(); while (master->slaves) master = master->slaves; master->slaves = slave; return slave; } static gboolean pygio_notify_using_optional_callback(PyGIONotify *notify) { if (notify->callback) return TRUE; else { notify->data = NULL; return FALSE; } } static gboolean pygio_notify_callback_is_valid_full(PyGIONotify *notify, const gchar *name) { if (!notify->callback) { PyErr_SetString(PyExc_RuntimeError, "internal error: callback is not set"); return FALSE; } if (!PyCallable_Check(notify->callback)) { gchar *error_message = g_strdup_printf("%s argument not callable", name); PyErr_SetString(PyExc_TypeError, error_message); g_free(error_message); return FALSE; } return TRUE; } static gboolean pygio_notify_callback_is_valid(PyGIONotify *notify) { return pygio_notify_callback_is_valid_full(notify, "callback"); } static void pygio_notify_reference_callback(PyGIONotify *notify) { if (!notify->referenced) { notify->referenced = TRUE; Py_XINCREF(notify->callback); Py_XINCREF(notify->data); if (notify->slaves) pygio_notify_reference_callback(notify->slaves); } } static void pygio_notify_copy_buffer(PyGIONotify *notify, gpointer buffer, gsize buffer_size) { if (buffer_size > 0) { notify->buffer = g_slice_copy(buffer_size, buffer); notify->buffer_size = buffer_size; } } static gboolean pygio_notify_allocate_buffer(PyGIONotify *notify, gsize buffer_size) { if (buffer_size > 0) { notify->buffer = g_slice_alloc(buffer_size); if (!notify->buffer) { PyErr_Format(PyExc_MemoryError, "failed to allocate %d bytes", buffer_size); return FALSE; } notify->buffer_size = buffer_size; } return TRUE; } static void pygio_notify_attach_to_result(PyGIONotify *notify) { notify->attach_self = TRUE; } static PyGIONotify * pygio_notify_get_attached(PyGObject *result) { return g_object_get_qdata(G_OBJECT(result->obj), pygio_notify_get_internal_quark()); } static void pygio_notify_free(PyGIONotify *notify) { if (notify) { if (notify->slaves) pygio_notify_free(notify->slaves); if (notify->referenced) { PyGILState_STATE state; state = pyg_gil_state_ensure(); Py_XDECREF(notify->callback); Py_XDECREF(notify->data); pyg_gil_state_release(state); } if (notify->buffer) g_slice_free1(notify->buffer_size, notify->buffer); g_slice_free(PyGIONotify, notify); } } static void async_result_callback_marshal(GObject *source_object, GAsyncResult *result, PyGIONotify *notify) { PyObject *ret; PyGILState_STATE state; state = pyg_gil_state_ensure(); if (!notify->referenced) g_warning("pygio_notify_reference_callback() hasn't been called before using the structure"); if (notify->attach_self) { g_object_set_qdata_full(G_OBJECT(result), pygio_notify_get_internal_quark(), notify, (GDestroyNotify) pygio_notify_free); } if (notify->data) ret = PyEval_CallFunction(notify->callback, "NNO", pygobject_new(source_object), pygobject_new((GObject *)result), notify->data); else ret = PyObject_CallFunction(notify->callback, "NN", pygobject_new(source_object), pygobject_new((GObject *)result)); if (ret == NULL) { PyErr_Print(); PyErr_Clear(); } Py_XDECREF(ret); /* Otherwise the structure is attached to 'result' and will be * freed when that object dies. */ if (!notify->attach_self) pygio_notify_free(notify); pyg_gil_state_release(state); } %% include gappinfo.override gapplaunchcontext.override gbufferedinputstream.override gcancellable.override gdatainputstream.override gdrive.override gfile.override gfileattribute.override gfileenumerator.override gfileinfo.override gfileinputstream.override gfileiostream.override gfileoutputstream.override gicon.override giostream.override gmemoryinputstream.override gmemoryoutputstream.override gmount.override ginputstream.override goutputstream.override gresolver.override gsocket.override gvolume.override gvolumemonitor.override %% ignore-glob *_get_type *free *_ref *_unref g_async_result_get_user_data g_file_new_from_commandline_arg g_file_new_from_path g_file_new_from_uri g_file_hash g_io_error_quark g_simple_async_result_new_error g_simple_async_report_error_in_idle g_simple_async_result_set_op_res_gpointer g_simple_async_result_get_op_res_gpointer g_simple_async_result_get_source_tag g_simple_async_result_run_in_thread g_simple_async_result_set_from_error g_simple_async_result_set_error g_simple_async_result_set_error_va g_io_module* g_io_scheduler_* %% override g_app_info_get_all noargs static PyObject * _wrap_g_app_info_get_all (PyGObject *self) { GList *list, *l; PyObject *ret; list = g_app_info_get_all (); ret = PyList_New(0); for (l = list; l; l = l->next) { GObject *obj = l->data; PyObject *item = pygobject_new(obj); PyList_Append(ret, item); Py_DECREF(item); } g_list_free(list); return ret; } %% override g_app_info_get_all_for_type args static PyObject * _wrap_g_app_info_get_all_for_type (PyGObject *self, PyObject *args) { GList *list, *l; PyObject *ret; gchar *type; if (!PyArg_ParseTuple (args, "s:app_info_get_all_for_type", &type)) return NULL; list = g_app_info_get_all_for_type (type); ret = PyList_New(0); for (l = list; l; l = l->next) { GObject *obj = l->data; PyObject *item = pygobject_new(obj); PyList_Append(ret, item); Py_DECREF(item); } g_list_free(list); return ret; } %% override g_content_type_guess kwargs static PyObject * _wrap_g_content_type_guess(PyGObject *self, PyObject *args, PyObject *kwargs) { char *kwlist[] = {"filename", "data", "want_uncertain", NULL}; char *filename = NULL, *data = NULL, *type; Py_ssize_t data_size = 0; gboolean result_uncertain, want_uncertain = FALSE; PyObject *ret; if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|zz#i:content_type_guess", kwlist, &filename, &data, &data_size, &want_uncertain)) return NULL; if (!filename && !data) { PyErr_SetString(PyExc_TypeError, "need at least one argument"); return NULL; } type = g_content_type_guess(filename, (guchar *) data, data_size, &result_uncertain); if (want_uncertain) { ret = Py_BuildValue("zN", type, PyBool_FromLong(result_uncertain)); } else { ret = _PyUnicode_FromString(type); } g_free(type); return ret; } %% override g_vfs_get_supported_uri_schemes noargs static PyObject * _wrap_g_vfs_get_supported_uri_schemes(PyGObject *self) { const char * const *names; PyObject *ret; names = g_vfs_get_supported_uri_schemes(G_VFS(self->obj)); ret = PyList_New(0); while (names && *names) { PyObject *item = _PyUnicode_FromString(names[0]); PyList_Append(ret, item); Py_DECREF(item); names++; } return ret; } %% override g_content_types_get_registered noargs static PyObject * _wrap_g_content_types_get_registered(PyObject *self) { GList *list, *l; PyObject *ret; list = g_content_types_get_registered(); ret = PyList_New(0); for (l = list; l; l = l->next) { char *content_type = l->data; PyObject *string = _PyUnicode_FromString(content_type); PyList_Append(ret, string); Py_DECREF(string); g_free(content_type); } g_list_free(list); return ret; }