diff options
author | James Henstridge <james@daa.com.au> | 2001-12-17 05:55:33 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 2001-12-17 05:55:33 +0000 |
commit | 6bd8ae3492a556aed7653c7f5da2bfd6edca402f (patch) | |
tree | d07d6ef6cf4b0a0c84ad4640a673b263dbb36442 | |
parent | cab00167c3e9843c1e3bd1b20ad68997e4ee581f (diff) | |
download | pygobject-6bd8ae3492a556aed7653c7f5da2bfd6edca402f.tar.gz pygobject-6bd8ae3492a556aed7653c7f5da2bfd6edca402f.tar.xz pygobject-6bd8ae3492a556aed7653c7f5da2bfd6edca402f.zip |
add chaining function. This will need to change when Tim makes the changes
2001-12-17 James Henstridge <james@daa.com.au>
* gobjectmodule.c (pygobject_chain_from_overridden): add chaining
function. This will need to change when Tim makes the changes to
the chaining API. This was just to test that things worked
correctly (and they do). Possibly this should be renamed to just
GObject.chain() or GObject._chain().
2001-12-15 James Henstridge <james@daa.com.au>
* gobjectmodule.c (add_signals): put the class ref/unref in here,
so it is only done once. The ref/unref is really needed for
adding signals as well, so that we don't end up with dups.
-rw-r--r-- | gobject/gobjectmodule.c | 95 |
1 files changed, 88 insertions, 7 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index e965379..77e434f 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -1629,6 +1629,81 @@ pygobject_stop_emission(PyGObject *self, PyObject *args) return Py_None; } +static PyObject * +pygobject_chain_from_overridden(PyGObject *self, PyObject *args) +{ + guint signal_id, i, len; + PyObject *first, *py_ret; + gchar *name; + GSignalQuery query; + GValue *params, ret = { 0, }; + + len = PyTuple_Size(args); + if (len < 1) { + PyErr_SetString(PyExc_TypeError,"GObject.chain_from_overridden needs at least one arg"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 1); + if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + signal_id = g_signal_lookup(name, G_OBJECT_TYPE(self->obj)); + if (signal_id == 0) { + PyErr_SetString(PyExc_TypeError, "unknown signal name"); + return NULL; + } + g_signal_query(signal_id, &query); + if (len != query.n_params + 1) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), + "%d parameters needed for signal %s; %d given", + query.n_params, name, len - 1); + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + params = g_new0(GValue, query.n_params + 1); + g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj)); + g_value_set_object(¶ms[0], G_OBJECT(self->obj)); + + for (i = 0; i < query.n_params; i++) + g_value_init(¶ms[i + 1], + query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); + for (i = 0; i < query.n_params; i++) { + PyObject *item = PyTuple_GetItem(args, i+1); + + if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), + "could not convert type %s to %s required for parameter %d", + item->ob_type->tp_name, + g_type_name(G_VALUE_TYPE(¶ms[i+1])), i); + PyErr_SetString(PyExc_TypeError, buf); + for (i = 0; i < query.n_params + 1; i++) + g_value_unset(¶ms[i]); + g_free(params); + return NULL; + } + } + if (query.return_type != G_TYPE_NONE) + g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_chain_from_overridden(params, signal_id, &ret); + for (i = 0; i < query.n_params + 1; i++) + g_value_unset(¶ms[i]); + g_free(params); + if (query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE != G_TYPE_NONE) { + py_ret = pyg_value_as_pyobject(&ret); + g_value_unset(&ret); + } else { + Py_INCREF(Py_None); + py_ret = Py_None; + } + return py_ret; +} + static PyMethodDef pygobject_methods[] = { { "__gobject_init__", (PyCFunction)pygobject__gobject_init__, METH_VARARGS|METH_KEYWORDS }, @@ -1650,6 +1725,7 @@ static PyMethodDef pygobject_methods[] = { { "emit", (PyCFunction)pygobject_emit, METH_VARARGS }, { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS }, { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS }, + { "chain_from_overridden", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS }, { NULL, NULL, 0 } }; @@ -1993,12 +2069,9 @@ create_signal (GType instance_type, const gchar *signal_name, PyObject *tuple) static gboolean override_signal(GType instance_type, const gchar *signal_name) { - GObjectClass *oclass; guint signal_id; - oclass = g_type_class_ref(instance_type); signal_id = g_signal_lookup(signal_name, instance_type); - g_type_class_unref(oclass); if (!signal_id) { gchar buf[128]; @@ -2014,15 +2087,19 @@ override_signal(GType instance_type, const gchar *signal_name) static gboolean add_signals (GType instance_type, PyObject *signals) { + GObjectClass *oclass; int pos = 0; PyObject *key, *value; + oclass = g_type_class_ref(instance_type); while (PyDict_Next(signals, &pos, &key, &value)) { const gchar *signal_name; + gboolean retval = TRUE; if (!PyString_Check(key)) { PyErr_SetString(PyExc_TypeError, "__gsignals__ keys must be strings"); + g_type_class_unref(oclass); return FALSE; } signal_name = PyString_AsString (key); @@ -2030,13 +2107,17 @@ add_signals (GType instance_type, PyObject *signals) if (value == Py_None || (PyString_Check(value) && !strcmp(PyString_AsString(value), "override"))) { - if (!override_signal(instance_type, signal_name)) - return FALSE; + retval = override_signal(instance_type, signal_name); } else { - if (!create_signal(instance_type, signal_name, value)) - return FALSE; + retval = create_signal(instance_type, signal_name, value); + } + + if (!retval) { + g_type_class_unref(oclass); + return FALSE; } } + g_type_class_unref(oclass); return TRUE; } |