/* -*- Mode: C; c-basic-offset: 4 -*- * vi:si:et:sw=4:sts=4:ts=4 * * gst-python * Copyright (C) 2005 Edward Hervey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Edward Hervey */ %% headers static GstBusSyncReply bus_sync_handler (GstBus *bus, GstMessage *message, gpointer user_data) { PyGILState_STATE state; GstBusSyncReply res; PyObject *py_userdata; PyObject *py_msg; PyObject *callback, *args; PyObject *ret; gint i, len; g_return_val_if_fail (user_data != NULL, GST_BUS_PASS); state = pyg_gil_state_ensure (); py_userdata = (PyObject *) user_data; py_msg = pygstminiobject_new (GST_MINI_OBJECT (message)); callback = PyTuple_GetItem (py_userdata, 0); /* Using N we give away our references to the args tuple */ args = Py_BuildValue ("(NN)", pygstobject_new (G_OBJECT (bus)), py_msg); /* add all *args to the args tuple object */ len = PyTuple_Size (py_userdata); for (i = 1; i < len; ++i) { PyObject *tuple = args; args = PySequence_Concat (tuple, PyTuple_GetItem (py_userdata, i)); Py_DECREF (tuple); } ret = PyObject_CallObject (callback, args); if (!ret) { PyErr_Print (); res = GST_BUS_PASS; } else { if (ret == Py_None) { PyErr_SetString (PyExc_TypeError, "callback should return a BusSyncReply"); PyErr_Print (); res = GST_BUS_PASS; } else if (pyg_enum_get_value (GST_TYPE_BUS_SYNC_REPLY, ret, (gint *) &res)) res = GST_BUS_PASS; Py_DECREF (ret); } Py_DECREF (args); pyg_gil_state_release (state); return res; } static gboolean bus_func (GstBus *bus, GstMessage *message, gpointer user_data) { PyGILState_STATE state; gboolean res; PyObject *py_userdata; PyObject *py_msg; PyObject *callback, *args; PyObject *ret; gint i, len; g_return_val_if_fail (user_data != NULL, TRUE); GST_DEBUG_OBJECT (bus, "dispatching message %p", message); state = pyg_gil_state_ensure (); py_userdata = (PyObject *) user_data; g_assert (PyTuple_Check (py_userdata)); py_msg = pygstminiobject_new (GST_MINI_OBJECT (message)); callback = PyTuple_GetItem (py_userdata, 0); /* Using N we give away our references to the args tuple */ args = Py_BuildValue ("(NN)", pygstobject_new (G_OBJECT (bus)), py_msg); g_assert (args); /* add all *args to the args tuple object */ len = PyTuple_Size (py_userdata); for (i = 1; i < len; ++i) { PyObject *item; PyObject *tuple = args; item = PyTuple_GetItem (py_userdata, i); g_assert (item); args = PySequence_Concat (tuple, item); g_assert (args); Py_DECREF (tuple); } ret = PyObject_CallObject(callback, args); if (!ret) { PyErr_Print (); res = TRUE; } else { if (ret == Py_None) { PyErr_SetString (PyExc_TypeError, "callback should return True or False"); PyErr_Print (); res = TRUE; } else res = PyObject_IsTrue (ret); Py_DECREF (ret); } Py_DECREF (args); pyg_gil_state_release (state); GST_DEBUG_OBJECT (bus, "dispatched message %p", message); return res; } %% override gst_bus_set_sync_handler args static PyObject * _wrap_gst_bus_set_sync_handler (PyGObject *self, PyObject *args) { PyObject *callback, *cbargs = NULL, *data; gint len; len = PyTuple_Size(args); if (len < 1) { PyErr_SetString(PyExc_TypeError, "Bus requires at least 1 arg"); return NULL; } callback = PySequence_GetItem(args, 0); if (!PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "callback is not callable"); return NULL; } cbargs = PySequence_GetSlice(args, 1, len); if (cbargs == NULL) return NULL; data = Py_BuildValue("(ON)", callback, cbargs); if (data == NULL) return NULL; gst_bus_set_sync_handler (GST_BUS (self->obj), (GstBusSyncHandler) bus_sync_handler, data); return (PyObject*) self; } %% override gst_bus_add_watch args static PyObject * _wrap_gst_bus_add_watch (PyGObject *self, PyObject *args) { PyObject *callback, *py_events, *cbargs = NULL, *data; guint sigid; guint len; GstMessageType events; len = PyTuple_Size(args); if (len < 2) { PyErr_SetString(PyExc_TypeError, "Bus.add_watch requires at least 2 args"); return NULL; } py_events = PySequence_GetItem(args, 0); if (pyg_flags_get_value (GST_TYPE_MESSAGE_TYPE, py_events, (gint *)&events)) { PyErr_SetString(PyExc_TypeError, "message type is not a GST_TYPE_MESSAGE_TYPE"); return NULL; } callback = PySequence_GetItem(args, 1); if (!PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "callback is not callable"); return NULL; } cbargs = PySequence_GetSlice(args, 2, len); if (cbargs == NULL) return NULL; /* FIXME: thomas: I'm pretty sure the second N needs to be O */ data = Py_BuildValue("(ON)", callback, cbargs); if (data == NULL) return NULL; sigid = gst_bus_add_watch (GST_BUS (self->obj), events, (GstBusFunc) bus_func, data); return PyInt_FromLong(sigid); }