diff options
Diffstat (limited to 'gobject/pygobject.c')
-rw-r--r-- | gobject/pygobject.c | 1019 |
1 files changed, 0 insertions, 1019 deletions
diff --git a/gobject/pygobject.c b/gobject/pygobject.c deleted file mode 100644 index b0e85b0..0000000 --- a/gobject/pygobject.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- */ -#include "pygobject-private.h" - -static const gchar *pygobject_class_id = "PyGObject::class"; -static GQuark pygobject_class_key = 0; -static const gchar *pygobject_wrapper_id = "PyGObject::wrapper"; -static GQuark pygobject_wrapper_key = 0; -static const gchar *pygobject_ownedref_id = "PyGObject::ownedref"; -static GQuark pygobject_ownedref_key = 0; - -static void pygobject_dealloc(PyGObject *self); -static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg); - -/* -------------- class <-> wrapper manipulation --------------- */ - -typedef struct { - GType type; - void (* sinkfunc)(GObject *object); -} SinkFunc; -static GArray *sink_funcs = NULL; - -static inline void -sink_object(GObject *obj) -{ - if (sink_funcs) { - gint i; - - for (i = 0; i < sink_funcs->len; i++) { - if (g_type_is_a(G_OBJECT_TYPE(obj), - g_array_index(sink_funcs, SinkFunc, i).type)) { - g_array_index(sink_funcs, SinkFunc, i).sinkfunc(obj); - break; - } - } - } -} - -void -pygobject_register_sinkfunc(GType type, void (* sinkfunc)(GObject *object)) -{ - SinkFunc sf; - - if (!sink_funcs) - sink_funcs = g_array_new(FALSE, FALSE, sizeof(SinkFunc)); - - sf.type = type; - sf.sinkfunc = sinkfunc; - g_array_append_val(sink_funcs, sf); -} - -void -pygobject_register_class(PyObject *dict, const gchar *type_name, - GType gtype, PyTypeObject *type, - PyObject *bases) -{ - PyObject *o; - const char *class_name, *s; - - if (!pygobject_class_key) - pygobject_class_key = g_quark_from_static_string(pygobject_class_id); - - class_name = type->tp_name; - s = strrchr(class_name, '.'); - if (s != NULL) - class_name = s + 1; - - type->ob_type = &PyType_Type; - if (bases) { - type->tp_bases = bases; - type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0); - } - - type->tp_dealloc = (destructor)pygobject_dealloc; - type->tp_traverse = (traverseproc)pygobject_traverse; - type->tp_flags |= Py_TPFLAGS_HAVE_GC; - type->tp_weaklistoffset = offsetof(PyGObject, weakreflist); - type->tp_dictoffset = offsetof(PyGObject, inst_dict); - - if (PyType_Ready(type) < 0) { - g_warning ("couldn't make the type `%s' ready", type->tp_name); - return; - } - - if (gtype) { - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(type->tp_dict, "__gtype__", o); - Py_DECREF(o); - - /* stash a pointer to the python class with the GType */ - Py_INCREF(type); - g_type_set_qdata(gtype, pygobject_class_key, type); - } - - /* set up __doc__ descriptor on type */ - PyDict_SetItemString(type->tp_dict, "__doc__", - pyg_object_descr_doc_get()); - - PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); -} - -void -pygobject_register_wrapper(PyObject *self) -{ - GObject *obj = ((PyGObject *)self)->obj; - - if (!pygobject_wrapper_key) - pygobject_wrapper_key=g_quark_from_static_string(pygobject_wrapper_id); - - sink_object(obj); - g_object_set_qdata(obj, pygobject_wrapper_key, self); -} - -PyTypeObject * -pygobject_lookup_class(GType gtype) -{ - PyTypeObject *type = NULL; - - /* find the python type for this object. If not found, use parent. */ - while (gtype != G_TYPE_INVALID && - (type = g_type_get_qdata(gtype, pygobject_class_key)) == NULL) - gtype = g_type_parent(gtype); - g_assert(type != NULL); - return type; -} - -PyObject * -pygobject_new(GObject *obj) -{ - PyGObject *self; - PyTypeObject *tp; - - if (!pygobject_wrapper_key) - pygobject_wrapper_key=g_quark_from_static_string(pygobject_wrapper_id); - if (!pygobject_ownedref_key) - pygobject_ownedref_key = - g_quark_from_static_string(pygobject_ownedref_id); - - if (obj == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - - /* we already have a wrapper for this object -- return it. */ - if ((self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key))) { - /* if the GObject currently owns the wrapper reference ... */ - if (self->hasref) { - self->hasref = FALSE; - g_object_steal_qdata(obj, pygobject_ownedref_key); - g_object_ref(obj); - } else - Py_INCREF(self); - return (PyObject *)self; - } - - tp = pygobject_lookup_class(G_OBJECT_TYPE(obj)); - self = PyObject_GC_New(PyGObject, tp); - - if (self == NULL) - return NULL; - self->obj = g_object_ref(obj); - sink_object(self->obj); - - self->hasref = FALSE; - self->inst_dict = NULL; - self->weakreflist = NULL; - self->closures = NULL; - /* save wrapper pointer so we can access it later */ - g_object_set_qdata(obj, pygobject_wrapper_key, self); - - PyObject_GC_Track((PyObject *)self); - - return (PyObject *)self; -} - -static void -pygobject_unwatch_closure(gpointer data, GClosure *closure) -{ - PyGObject *self = (PyGObject *)data; - - self->closures = g_slist_remove (self->closures, closure); -} - -void -pygobject_watch_closure(PyObject *self, GClosure *closure) -{ - PyGObject *gself; - - g_return_if_fail(self != NULL); - g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type)); - g_return_if_fail(closure != NULL); - g_return_if_fail(g_slist_find(((PyGObject *)self)->closures, closure) == NULL); - - gself = (PyGObject *)self; - gself->closures = g_slist_prepend(gself->closures, closure); - g_closure_add_invalidate_notifier(closure,self, pygobject_unwatch_closure); -} - -/* -------------- PyGObject behaviour ----------------- */ - -static void -pygobject_dealloc(PyGObject *self) -{ - GObject *obj = self->obj; - GSList *tmp; - - if (!pygobject_ownedref_key) - pygobject_ownedref_key = - g_quark_from_static_string(pygobject_ownedref_id); - - /* save reference to python wrapper if there are still - * references to the GObject in such a way that it will be - * freed when the GObject is destroyed, so is the python - * wrapper, but if a python wrapper can be */ - if (obj && obj->ref_count > 1) { - Py_INCREF(self); /* grab a reference on the wrapper */ - self->hasref = TRUE; - g_object_set_qdata_full(obj, pygobject_ownedref_key, - self, pyg_destroy_notify); - g_object_unref(obj); - - /* we ref the type, so subtype_dealloc() doesn't kill off our - * instance's type. */ - if (self->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(self->ob_type); - -#ifdef Py_TRACE_REFS - /* if we're tracing refs, set up the reflist again, as it was just - * torn down */ - _Py_NewReference((PyObject *) self); -#endif - - return; - } - if (obj && !self->hasref) /* don't unref the GObject if it owns us */ - g_object_unref(obj); - - PyObject_ClearWeakRefs((PyObject *)self); - - PyObject_GC_UnTrack((PyObject *)self); - - if (self->inst_dict) { - Py_DECREF(self->inst_dict); - } - self->inst_dict = NULL; - - tmp = self->closures; - while (tmp) { - GClosure *closure = tmp->data; - - /* we get next item first, because the current link gets - * invalidated by pygobject_unwatch_closure */ - tmp = tmp->next; - g_closure_invalidate(closure); - } - self->closures = NULL; - - /* the following causes problems with subclassed types */ - /*self->ob_type->tp_free((PyObject *)self); */ - PyObject_GC_Del(self); -} - -static int -pygobject_compare(PyGObject *self, PyGObject *v) -{ - if (self->obj == v->obj) return 0; - if (self->obj > v->obj) return -1; - return 1; -} - -static long -pygobject_hash(PyGObject *self) -{ - return (long)self->obj; -} - -static PyObject * -pygobject_repr(PyGObject *self) -{ - gchar buf[256]; - - g_snprintf(buf, sizeof(buf), - "<%s object (%s) at 0x%lx>", - self->ob_type->tp_name, - self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized", - (long)self); - return PyString_FromString(buf); -} - -static int -pygobject_traverse(PyGObject *self, visitproc visit, void *arg) -{ - int ret = 0; - GSList *tmp; - - if (self->inst_dict) ret = visit(self->inst_dict, arg); - if (ret != 0) return ret; - - for (tmp = self->closures; tmp != NULL; tmp = tmp->next) { - PyGClosure *closure = tmp->data; - - if (closure->callback) ret = visit(closure->callback, arg); - if (ret != 0) return ret; - - if (closure->extra_args) ret = visit(closure->extra_args, arg); - if (ret != 0) return ret; - - if (closure->swap_data) ret = visit(closure->swap_data, arg); - if (ret != 0) return ret; - } - return 0; -} - -static int -pygobject_clear(PyGObject *self) -{ - GSList *tmp; - - tmp = self->closures; - while (tmp) { - GClosure *closure = tmp->data; - - /* we get next item first, because the current link gets - * invalidated by pygobject_unwatch_closure */ - tmp = tmp->next; - g_closure_invalidate(closure); - } - if (self->closures != NULL) - g_message("invalidated all closures, but self->closures != NULL !"); - - return 0; -} - -static void -pygobject_free(PyObject *op) -{ - PyObject_GC_Del(op); -} - - -/* ---------------- PyGObject methods ----------------- */ - -static void -parameter_list_free (GParameter *parameters, guint n_parameters) -{ - gint i; - for (i = 0; i < n_parameters; i ++){ - g_free ((char *)parameters[i].name); - g_value_unset (&(parameters[i].value)); - } - g_free (parameters); -} - -static int -pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - GType object_type; - guint n_parameters = 0; - GParameter *parameters = NULL; - PyObject *key, *item; - gint pos = 0; - GObjectClass *class; - - if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type)) - return -1; - - object_type = pyg_type_from_object((PyObject *)self); - if (!object_type) - return -1; - - if ((class = g_type_class_ref (object_type)) == NULL) { - PyErr_SetString(PyExc_TypeError, - "could not get a reference to type class"); - return -1; - } - - - while (kwargs && PyDict_Next(kwargs, &pos, &key, &item)) { - gchar *param_name; - GParamSpec *pspec; - GValue value = { 0, }; - - param_name = PyString_AsString(key); - pspec = g_object_class_find_property(class, param_name); - - if (pspec == NULL) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), - "Unknown parameter '%s' used in type initialization arguments", - param_name); - PyErr_SetString(PyExc_AttributeError, buf); - parameter_list_free (parameters, n_parameters); - g_type_class_unref(class); - return -1; - } - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - if (pyg_value_from_pyobject(&value, item) < 0) { - PyErr_SetString(PyExc_TypeError, - "could not convert argument to correct param type"); - parameter_list_free (parameters, n_parameters); - g_type_class_unref(class); - return -1; - } - - n_parameters ++; - if (parameters == NULL) { - parameters = g_new (GParameter, 1); - } else { - parameters = g_renew (GParameter, parameters, n_parameters); - } - parameters[n_parameters - 1].name = g_strdup (param_name); - parameters[n_parameters - 1].value = value; - } - - self->obj = g_object_newv(object_type, n_parameters, parameters); - parameter_list_free (parameters, n_parameters); - - g_type_class_unref(class); - - if (!self->obj) { - PyErr_SetString(PyExc_RuntimeError, "could not create object"); - return -1; - } - pygobject_register_wrapper((PyObject *)self); - - return 0; -} - -static PyObject * -pygobject__gobject_init__(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - if (pygobject_init(self, args, kwargs) < 0) - return NULL; - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_get_property(PyGObject *self, PyObject *args) -{ - gchar *param_name; - GParamSpec *pspec; - GValue value = { 0, }; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name)) - return NULL; - pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), - param_name); - if (!pspec) { - PyErr_SetString(PyExc_TypeError, - "the object does not support the given parameter"); - return NULL; - } - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - g_object_get_property(self->obj, param_name, &value); - ret = pyg_value_as_pyobject(&value, TRUE); - g_value_unset(&value); - return ret; -} - -static PyObject * -pygobject_set_property(PyGObject *self, PyObject *args) -{ - gchar *param_name; - GParamSpec *pspec; - GValue value = { 0, }; - PyObject *pvalue; - - if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name, - &pvalue)) - return NULL; - pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), - param_name); - if (!pspec) { - PyErr_SetString(PyExc_TypeError, - "the object does not support the given parameter"); - return NULL; - } - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - if (pyg_value_from_pyobject(&value, pvalue) < 0) { - PyErr_SetString(PyExc_TypeError, - "could not convert argument to correct param type"); - return NULL; - } - g_object_set_property(self->obj, param_name, &value); - g_value_unset(&value); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_freeze_notify(PyGObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":GObject.freeze_notify")) - return NULL; - g_object_freeze_notify(self->obj); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_notify(PyGObject *self, PyObject *args) -{ - char *property_name; - - if (!PyArg_ParseTuple(args, "s:GObject.notify", &property_name)) - return NULL; - g_object_notify(self->obj, property_name); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_thaw_notify(PyGObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":GObject.thaw_notify")) - return NULL; - g_object_thaw_notify(self->obj); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_get_data(PyGObject *self, PyObject *args) -{ - char *key; - GQuark quark; - PyObject *data; - - if (!PyArg_ParseTuple(args, "s:GObject.get_data", &key)) - return NULL; - quark = g_quark_from_string(key); - data = g_object_get_qdata(self->obj, quark); - if (!data) data = Py_None; - Py_INCREF(data); - return data; -} - -static PyObject * -pygobject_set_data(PyGObject *self, PyObject *args) -{ - char *key; - GQuark quark; - PyObject *data; - - if (!PyArg_ParseTuple(args, "sO:GObject.get_data", &key, &data)) - return NULL; - quark = g_quark_from_string(key); - Py_INCREF(data); - g_object_set_qdata_full(self->obj, quark, data, pyg_destroy_notify); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_connect(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args; - gchar *name; - guint handlerid, sigid, len; - GQuark detail = 0; - GClosure *closure; - - len = PyTuple_Size(args); - if (len < 2) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect requires at least 2 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 2); - if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &sigid, &detail, TRUE)) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - extra_args = PySequence_GetSlice(args, 2, len); - if (extra_args == NULL) - return NULL; - closure = pyg_closure_new(callback, extra_args, NULL); - pygobject_watch_closure((PyObject *)self, closure); - handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail, - closure, FALSE); - Py_DECREF(extra_args); - return PyInt_FromLong(handlerid); -} - -static PyObject * -pygobject_connect_after(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args; - gchar *name; - guint handlerid, sigid, len; - GQuark detail; - GClosure *closure; - - len = PyTuple_Size(args); - if (len < 2) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect_after requires at least 2 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 2); - if (!PyArg_ParseTuple(first, "sO:GObject.connect_after", - &name, &callback)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &sigid, &detail, TRUE)) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - extra_args = PySequence_GetSlice(args, 2, len); - if (extra_args == NULL) - return NULL; - closure = pyg_closure_new(callback, extra_args, NULL); - pygobject_watch_closure((PyObject *)self, closure); - handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail, - closure, TRUE); - Py_DECREF(extra_args); - return PyInt_FromLong(handlerid); -} - -static PyObject * -pygobject_connect_object(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *object; - gchar *name; - guint handlerid, sigid, len; - GQuark detail; - GClosure *closure; - - len = PyTuple_Size(args); - if (len < 3) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect_object requires at least 3 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 3); - if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object", - &name, &callback, &object)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &sigid, &detail, TRUE)) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - extra_args = PySequence_GetSlice(args, 3, len); - if (extra_args == NULL) - return NULL; - closure = pyg_closure_new(callback, extra_args, NULL); - pygobject_watch_closure((PyObject *)self, closure); - handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail, - closure, FALSE); - Py_DECREF(extra_args); - return PyInt_FromLong(handlerid); -} - -static PyObject * -pygobject_connect_object_after(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *object; - gchar *name; - guint handlerid, sigid, len; - GQuark detail; - GClosure *closure; - - len = PyTuple_Size(args); - if (len < 3) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect_object_after requires at least 3 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 3); - if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after", - &name, &callback, &object)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &sigid, &detail, TRUE)) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - extra_args = PySequence_GetSlice(args, 3, len); - if (extra_args == NULL) - return NULL; - closure = pyg_closure_new(callback, extra_args, NULL); - pygobject_watch_closure((PyObject *)self, closure); - handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail, - closure, TRUE); - Py_DECREF(extra_args); - return PyInt_FromLong(handlerid); -} - -static PyObject * -pygobject_disconnect(PyGObject *self, PyObject *args) -{ - guint handler_id; - - if (!PyArg_ParseTuple(args, "i:GObject.disconnect", &handler_id)) - return NULL; - g_signal_handler_disconnect(self->obj, handler_id); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_handler_block(PyGObject *self, PyObject *args) -{ - guint handler_id; - - if (!PyArg_ParseTuple(args, "i:GObject.handler_block", &handler_id)) - return NULL; - g_signal_handler_block(self->obj, handler_id); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_handler_unblock(PyGObject *self, PyObject *args) -{ - guint handler_id; - - if (!PyArg_ParseTuple(args, "i:GObject.handler_unblock", &handler_id)) - return NULL; - g_signal_handler_unblock(self->obj, handler_id); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_emit(PyGObject *self, PyObject *args) -{ - guint signal_id, i, len; - GQuark detail; - PyObject *first, *py_ret; - gchar *name; - GSignalQuery query; - GValue *params, ret = { 0, }; - - len = PyTuple_Size(args); - if (len < 1) { - PyErr_SetString(PyExc_TypeError,"GObject.emit 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); - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &signal_id, &detail, TRUE)) { - 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_emitv(params, signal_id, detail, &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, TRUE); - g_value_unset(&ret); - } else { - Py_INCREF(Py_None); - py_ret = Py_None; - } - return py_ret; -} - -static PyObject * -pygobject_stop_emission(PyGObject *self, PyObject *args) -{ - gchar *signal; - guint signal_id; - GQuark detail; - - if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal)) - return NULL; - if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj), - &signal_id, &detail, TRUE)) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - g_signal_stop_emission(self->obj, signal_id, detail); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_chain_from_overridden(PyGObject *self, PyObject *args) -{ - GSignalInvocationHint *ihint; - guint signal_id, i, len; - PyObject *py_ret; - const gchar *name; - GSignalQuery query; - GValue *params, ret = { 0, }; - - ihint = g_signal_get_invocation_hint(self->obj); - signal_id = ihint->signal_id; - name = g_signal_name(signal_id); - - len = PyTuple_Size(args); - if (signal_id == 0) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - g_signal_query(signal_id, &query); - if (len != query.n_params) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), - "%d parameters needed for signal %s; %d given", - query.n_params, name, len); - 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); - - 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, &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, TRUE); - 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 }, - { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS }, - { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS }, - { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS }, - { "notify", (PyCFunction)pygobject_notify, METH_VARARGS }, - { "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS }, - { "get_data", (PyCFunction)pygobject_get_data, METH_VARARGS }, - { "set_data", (PyCFunction)pygobject_set_data, METH_VARARGS }, - { "connect", (PyCFunction)pygobject_connect, METH_VARARGS }, - { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS }, - { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS }, - { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS }, - { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS }, - { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS }, - { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS }, - { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS }, - { "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", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS }, - { NULL, NULL, 0 } -}; - -static PyObject * -pygobject_get_dict(PyGObject *self, void *closure) -{ - if (self->inst_dict == NULL) { - self->inst_dict = PyDict_New(); - if (self->inst_dict == NULL) - return NULL; - } - Py_INCREF(self->inst_dict); - return self->inst_dict; -} - -static PyObject * -pygobject_get_refcount(PyGObject *self, void *closure) -{ - return PyInt_FromLong(self->obj->ref_count); -} - -static PyGetSetDef pygobject_getsets[] = { - { "__dict__", (getter)pygobject_get_dict, (setter)0 }, - { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, }, - { NULL, 0, 0 } -}; - -PyTypeObject PyGObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "gobject.GObject", /* tp_name */ - sizeof(PyGObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)pygobject_dealloc, /* tp_dealloc */ - (printfunc)0, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)pygobject_compare, /* tp_compare */ - (reprfunc)pygobject_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pygobject_hash, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)0, /* tp_str */ - (getattrofunc)0, /* tp_getattro */ - (setattrofunc)0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /* tp_flags */ - NULL, /* Documentation string */ - (traverseproc)pygobject_traverse, /* tp_traverse */ - (inquiry)pygobject_clear, /* tp_clear */ - (richcmpfunc)0, /* tp_richcompare */ - offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ - (getiterfunc)0, /* tp_iter */ - (iternextfunc)0, /* tp_iternext */ - pygobject_methods, /* tp_methods */ - 0, /* tp_members */ - pygobject_getsets, /* tp_getset */ - (PyTypeObject *)0, /* tp_base */ - (PyObject *)0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(PyGObject, inst_dict), /* tp_dictoffset */ - (initproc)pygobject_init, /* tp_init */ - (allocfunc)0, /* tp_alloc */ - (newfunc)0, /* tp_new */ - pygobject_free, /* tp_free */ - (inquiry)0, /* tp_is_gc */ - (PyObject *)0, /* tp_bases */ -}; - |