diff options
Diffstat (limited to 'gobject/gobjectmodule.c')
-rw-r--r-- | gobject/gobjectmodule.c | 1453 |
1 files changed, 0 insertions, 1453 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c deleted file mode 100644 index 26530831..00000000 --- a/gobject/gobjectmodule.c +++ /dev/null @@ -1,1453 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "pygobject-private.h" - -static PyObject *gerror_exc = NULL; - -/* -------------- GDK threading hooks ---------------------------- */ - -static void -pyg_set_thread_block_funcs (PyGThreadBlockFunc block_threads_func, - PyGThreadBlockFunc unblock_threads_func) -{ - g_return_if_fail(pygobject_api_functions.block_threads == NULL && pygobject_api_functions.unblock_threads == NULL); - - pygobject_api_functions.block_threads = block_threads_func; - pygobject_api_functions.unblock_threads = unblock_threads_func; -} - -static void -object_free(PyObject *op) -{ - PyObject_FREE(op); -} - -void -pyg_destroy_notify(gpointer user_data) -{ - PyObject *obj = (PyObject *)user_data; - - pyg_block_threads(); - Py_DECREF(obj); - pyg_unblock_threads(); -} - -/* -------------- GParamSpec objects ---------------------------- */ - -static int -pyg_param_spec_compare(PyGParamSpec *self, PyGParamSpec *v) -{ - if (self->pspec == v->pspec) return 0; - if (self->pspec > v->pspec) return -1; - return 1; -} - -static long -pyg_param_spec_hash(PyGParamSpec *self) -{ - return (long)self->pspec; -} - -static PyObject * -pyg_param_spec_repr(PyGParamSpec *self) -{ - char buf[80]; - - g_snprintf(buf, sizeof(buf), "<%s '%s'>", - G_PARAM_SPEC_TYPE_NAME(self->pspec), - g_param_spec_get_name(self->pspec)); - return PyString_FromString(buf); -} - -static void -pyg_param_spec_dealloc(PyGParamSpec *self) -{ - g_param_spec_unref(self->pspec); - PyObject_DEL(self); -} - -static PyObject * -pyg_param_spec_getattr(PyGParamSpec *self, const gchar *attr) -{ - if (!strcmp(attr, "__members__")) { - return Py_BuildValue("[ssssssss]", "__doc__", "__gtype__", "blurb", - "flags", "name", "nick", "owner_type", - "value_type"); - } else if (!strcmp(attr, "__gtype__")) { - return pyg_type_wrapper_new(G_PARAM_SPEC_TYPE(self->pspec)); - } else if (!strcmp(attr, "name")) { - const gchar *name = g_param_spec_get_name(self->pspec); - - if (name) - return PyString_FromString(name); - Py_INCREF(Py_None); - return Py_None; - } else if (!strcmp(attr, "nick")) { - const gchar *nick = g_param_spec_get_nick(self->pspec); - - if (nick) - return PyString_FromString(nick); - Py_INCREF(Py_None); - return Py_None; - } else if (!strcmp(attr, "blurb") || !strcmp(attr, "__doc__")) { - const gchar *blurb = g_param_spec_get_blurb(self->pspec); - - if (blurb) - return PyString_FromString(blurb); - Py_INCREF(Py_None); - return Py_None; - } else if (!strcmp(attr, "flags")) { - return PyInt_FromLong(self->pspec->flags); - } else if (!strcmp(attr, "value_type")) { - return pyg_type_wrapper_new(self->pspec->value_type); - } else if (!strcmp(attr, "owner_type")) { - return pyg_type_wrapper_new(self->pspec->owner_type); - } - PyErr_SetString(PyExc_AttributeError, attr); - return NULL; -} - -PyTypeObject PyGParamSpec_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "gobject.GParamSpec", - sizeof(PyGParamSpec), - 0, - (destructor)pyg_param_spec_dealloc, - (printfunc)0, - (getattrfunc)pyg_param_spec_getattr, - (setattrfunc)0, - (cmpfunc)pyg_param_spec_compare, - (reprfunc)pyg_param_spec_repr, - 0, - 0, - 0, - (hashfunc)pyg_param_spec_hash, - (ternaryfunc)0, - (reprfunc)0, - 0L,0L,0L,0L, - NULL -}; - -PyObject * -pyg_param_spec_new(GParamSpec *pspec) -{ - PyGParamSpec *self; - - self = (PyGParamSpec *)PyObject_NEW(PyGParamSpec, - &PyGParamSpec_Type); - if (self == NULL) - return NULL; - - self->pspec = g_param_spec_ref(pspec); - return (PyObject *)self; -} - - -/* ---------------- GBoxed functions -------------------- */ - -GType PY_TYPE_OBJECT = 0; - -static gpointer -pyobject_copy(gpointer boxed) -{ - PyObject *object = boxed; - - Py_INCREF(object); - return object; -} - -static void -pyobject_free(gpointer boxed) -{ - PyObject *object = boxed; - - Py_DECREF(object); -} - - -/* ---------------- GInterface functions -------------------- */ - -static int -pyg_interface_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - gchar buf[512]; - - if (!PyArg_ParseTuple(args, ":GInterface.__init__")) - return -1; - - g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name); - PyErr_SetString(PyExc_NotImplementedError, buf); - return -1; -} - -static PyTypeObject PyGInterface_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "gobject.GInterface", /* tp_name */ - sizeof(PyObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)0, /* tp_dealloc */ - (printfunc)0, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)0, /* tp_compare */ - (reprfunc)0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* 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, /* tp_flags */ - NULL, /* Documentation string */ - (traverseproc)0, /* tp_traverse */ - (inquiry)0, /* tp_clear */ - (richcmpfunc)0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)0, /* tp_iter */ - (iternextfunc)0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - (PyTypeObject *)0, /* tp_base */ - (PyObject *)0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pyg_interface_init, /* tp_init */ - (allocfunc)0, /* tp_alloc */ - (newfunc)0, /* tp_new */ - object_free, /* tp_free */ - (inquiry)0, /* tp_is_gc */ - (PyObject *)0, /* tp_bases */ -}; - -static void -pyg_register_interface(PyObject *dict, const gchar *class_name, - GType gtype, PyTypeObject *type) -{ - PyObject *o; - - type->ob_type = &PyType_Type; - type->tp_base = &PyGInterface_Type; - - if (PyType_Ready(type) < 0) { - g_warning("could not ready `%s'", type->tp_name); - return; - } - - if (gtype) { - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(type->tp_dict, "__gtype__", o); - Py_DECREF(o); - } - - PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); -} - - -/* ---------------- gobject module functions -------------------- */ - -static PyObject * -pyg_type_name (PyObject *self, PyObject *args) -{ - PyObject *gtype; - GType type; - const gchar *name; - - if (!PyArg_ParseTuple(args, "O:gobject.type_name", >ype)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - name = g_type_name(type); - if (name) - return PyString_FromString(name); - PyErr_SetString(PyExc_RuntimeError, "unknown typecode"); - return NULL; -} - -static PyObject * -pyg_type_from_name (PyObject *self, PyObject *args) -{ - const gchar *name; - GType type; - - if (!PyArg_ParseTuple(args, "s:gobject.type_from_name", &name)) - return NULL; - type = g_type_from_name(name); - if (type != 0) - return pyg_type_wrapper_new(type); - PyErr_SetString(PyExc_RuntimeError, "unknown type name"); - return NULL; -} - -static PyObject * -pyg_type_parent (PyObject *self, PyObject *args) -{ - PyObject *gtype; - GType type, parent; - - if (!PyArg_ParseTuple(args, "O:gobject.type_parent", >ype)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - parent = g_type_parent(type); - if (parent != 0) - return pyg_type_wrapper_new(parent); - PyErr_SetString(PyExc_RuntimeError, "no parent for type"); - return NULL; -} - -static PyObject * -pyg_type_is_a (PyObject *self, PyObject *args) -{ - PyObject *gtype, *gparent; - GType type, parent; - - if (!PyArg_ParseTuple(args, "OO:gobject.type_is_a", >ype, &gparent)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - if ((parent = pyg_type_from_object(gparent)) == 0) - return NULL; - return PyInt_FromLong(g_type_is_a(type, parent)); -} - -static PyObject * -pyg_type_children (PyObject *self, PyObject *args) -{ - PyObject *gtype, *list; - GType type, *children; - guint n_children, i; - - if (!PyArg_ParseTuple(args, "O:gobject.type_children", >ype)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - children = g_type_children(type, &n_children); - if (children) { - list = PyList_New(0); - for (i = 0; i < n_children; i++) { - PyObject *o; - PyList_Append(list, o=pyg_type_wrapper_new(children[i])); - Py_DECREF(o); - } - g_free(children); - return list; - } - PyErr_SetString(PyExc_RuntimeError, "invalid type, or no children"); - return NULL; -} - -static PyObject * -pyg_type_interfaces (PyObject *self, PyObject *args) -{ - PyObject *gtype, *list; - GType type, *interfaces; - guint n_interfaces, i; - - if (!PyArg_ParseTuple(args, "O:gobject.type_interfaces", >ype)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - interfaces = g_type_interfaces(type, &n_interfaces); - if (interfaces) { - list = PyList_New(0); - for (i = 0; i < n_interfaces; i++) { - PyObject *o; - PyList_Append(list, o=pyg_type_wrapper_new(interfaces[i])); - Py_DECREF(o); - } - g_free(interfaces); - return list; - } - PyErr_SetString(PyExc_RuntimeError, "invalid type, or no interfaces"); - return NULL; -} - -static void -pyg_object_set_property (GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec) -{ - PyObject *object_wrapper, *retval; - PyObject *py_pspec, *py_value; - - object_wrapper = pygobject_new(object); - g_return_if_fail(object_wrapper != NULL); - - py_pspec = pyg_param_spec_new(pspec); - py_value = pyg_value_as_pyobject (value, TRUE); - retval = PyObject_CallMethod(object_wrapper, "do_set_property", - "OO", py_pspec, py_value); - if (retval) { - Py_DECREF(retval); - } else { - PyErr_Print(); - PyErr_Clear(); - } - Py_DECREF(object_wrapper); - Py_DECREF(py_pspec); - Py_DECREF(py_value); -} - -static void -pyg_object_get_property (GObject *object, guint property_id, - GValue *value, GParamSpec *pspec) -{ - PyObject *object_wrapper, *retval; - PyObject *py_pspec; - - object_wrapper = pygobject_new(object); - g_return_if_fail(object_wrapper != NULL); - - py_pspec = pyg_param_spec_new(pspec); - retval = PyObject_CallMethod(object_wrapper, "do_get_property", - "O", py_pspec); - if (retval == NULL || pyg_value_from_pyobject(value, retval) < 0) { - PyErr_Print(); - PyErr_Clear(); - } - Py_DECREF(object_wrapper); - Py_DECREF(py_pspec); - Py_XDECREF(retval); -} - -static void -pyg_object_class_init(GObjectClass *class, PyObject *py_class) -{ - class->set_property = pyg_object_set_property; - class->get_property = pyg_object_get_property; -} - -static gboolean -create_signal (GType instance_type, const gchar *signal_name, PyObject *tuple) -{ - GSignalFlags signal_flags; - PyObject *py_return_type, *py_param_types; - GType return_type; - guint n_params, i; - GType *param_types; - guint signal_id; - - if (!PyArg_ParseTuple(tuple, "iOO", &signal_flags, &py_return_type, - &py_param_types)) { - gchar buf[128]; - - PyErr_Clear(); - g_snprintf(buf, sizeof(buf), "value for __gsignals__['%s'] not in correct format", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - - return_type = pyg_type_from_object(py_return_type); - if (!return_type) - return FALSE; - if (!PySequence_Check(py_param_types)) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "third element of __gsignals__['%s'] tuple must be a sequence", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - n_params = PySequence_Length(py_param_types); - param_types = g_new(GType, n_params); - for (i = 0; i < n_params; i++) { - PyObject *item = PySequence_GetItem(py_param_types, i); - - param_types[i] = pyg_type_from_object(item); - if (param_types[i] == 0) { - Py_DECREF(item); - g_free(param_types); - return FALSE; - } - Py_DECREF(item); - } - - signal_id = g_signal_newv(signal_name, instance_type, signal_flags, - pyg_signal_class_closure_get(), - (GSignalAccumulator)0, NULL, - (GSignalCMarshaller)0, - return_type, n_params, param_types); - g_free(param_types); - - if (signal_id == 0) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "could not create signal for %s", - signal_name); - PyErr_SetString(PyExc_RuntimeError, buf); - return FALSE; - } - return TRUE; -} - -static gboolean -override_signal(GType instance_type, const gchar *signal_name) -{ - guint signal_id; - - signal_id = g_signal_lookup(signal_name, instance_type); - if (!signal_id) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "could not look up %s", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - g_signal_override_class_closure(signal_id, instance_type, - pyg_signal_class_closure_get()); - return TRUE; -} - -static gboolean -add_signals (GType instance_type, PyObject *signals) -{ - gboolean ret = TRUE; - 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; - - if (!PyString_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "__gsignals__ keys must be strings"); - ret = FALSE; - break; - } - signal_name = PyString_AsString (key); - - if (value == Py_None || - (PyString_Check(value) && - !strcmp(PyString_AsString(value), "override"))) { - ret = override_signal(instance_type, signal_name); - } else { - ret = create_signal(instance_type, signal_name, value); - } - - if (!ret) - break; - } - g_type_class_unref(oclass); - return ret; -} - -static gboolean -create_property (GObjectClass *oclass, const gchar *prop_name, - GType prop_type, const gchar *nick, const gchar *blurb, - PyObject *args, GParamFlags flags) -{ - GParamSpec *pspec = NULL; - - switch (G_TYPE_FUNDAMENTAL(prop_type)) { - case G_TYPE_CHAR: - { - gchar minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_char (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_UCHAR: - { - gchar minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_uchar (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_BOOLEAN: - { - gboolean default_value; - - if (!PyArg_ParseTuple(args, "i", &default_value)) - return FALSE; - pspec = g_param_spec_boolean (prop_name, nick, blurb, - default_value, flags); - } - break; - case G_TYPE_INT: - { - gint minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "iii", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_int (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_UINT: - { - guint minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "iii", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_uint (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_LONG: - { - glong minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "lll", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_long (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_ULONG: - { - gulong minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "lll", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_ulong (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_INT64: - { - gint64 minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "LLL", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_int64 (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_UINT64: - { - guint64 minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "LLL", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_uint64 (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_ENUM: - { - gint default_value; - - if (!PyArg_ParseTuple(args, "i", &default_value)) - return FALSE; - pspec = g_param_spec_enum (prop_name, nick, blurb, - prop_type, default_value, flags); - } - break; - case G_TYPE_FLAGS: - { - guint default_value; - - if (!PyArg_ParseTuple(args, "i", &default_value)) - return FALSE; - pspec = g_param_spec_flags (prop_name, nick, blurb, - prop_type, default_value, flags); - } - break; - case G_TYPE_FLOAT: - { - gfloat minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "fff", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_float (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_DOUBLE: - { - gdouble minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "ddd", &minimum, &maximum, - &default_value)) - return FALSE; - pspec = g_param_spec_double (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_STRING: - { - const gchar *default_value; - - if (!PyArg_ParseTuple(args, "z", &default_value)) - return FALSE; - pspec = g_param_spec_string (prop_name, nick, blurb, - default_value, flags); - } - break; - case G_TYPE_PARAM: - if (!PyArg_ParseTuple(args, "")) - return FALSE; - pspec = g_param_spec_param (prop_name, nick, blurb, prop_type, flags); - break; - case G_TYPE_BOXED: - if (!PyArg_ParseTuple(args, "")) - return FALSE; - pspec = g_param_spec_boxed (prop_name, nick, blurb, prop_type, flags); - break; - case G_TYPE_POINTER: - if (!PyArg_ParseTuple(args, "")) - return FALSE; - pspec = g_param_spec_pointer (prop_name, nick, blurb, flags); - break; - case G_TYPE_OBJECT: - if (!PyArg_ParseTuple(args, "")) - return FALSE; - pspec = g_param_spec_object (prop_name, nick, blurb, prop_type, flags); - break; - default: - /* unhandled pspec type ... */ - break; - } - - if (!pspec) { - char buf[128]; - - g_snprintf(buf, sizeof(buf), "could not create param spec for type %s", - g_type_name(prop_type)); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - g_object_class_install_property(oclass, 1, pspec); - return TRUE; -} - -static gboolean -add_properties (GType instance_type, PyObject *properties) -{ - gboolean ret = TRUE; - GObjectClass *oclass; - int pos = 0; - PyObject *key, *value; - - oclass = g_type_class_ref(instance_type); - while (PyDict_Next(properties, &pos, &key, &value)) { - const gchar *prop_name; - GType prop_type; - const gchar *nick, *blurb; - GParamFlags flags; - gint val_length; - PyObject *slice, *item, *py_prop_type; - /* values are of format (type,nick,blurb, type_specific_args, flags) */ - - if (!PyString_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ keys must be strings"); - ret = FALSE; - break; - } - prop_name = PyString_AsString (key); - - if (!PyTuple_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ values must be tuples"); - ret = FALSE; - break; - } - val_length = PyTuple_Size(value); - if (val_length < 4) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ values must be at least 4 elements long"); - ret = FALSE; - break; - } - - slice = PySequence_GetSlice(value, 0, 3); - if (!slice) { - ret = FALSE; - break; - } - if (!PyArg_ParseTuple(slice, "Ozz", &py_prop_type, &nick, &blurb)) { - Py_DECREF(slice); - ret = FALSE; - break; - } - Py_DECREF(slice); - prop_type = pyg_type_from_object(py_prop_type); - if (!prop_type) { - ret = FALSE; - break; - } - item = PyTuple_GetItem(value, val_length-1); - if (!PyInt_Check(item)) { - PyErr_SetString(PyExc_TypeError, - "last element in __gproperties__ value tuple must be an int"); - ret = FALSE; - break; - } - flags = PyInt_AsLong(item); - - /* slice is the extra items in the tuple */ - slice = PySequence_GetSlice(value, 3, val_length-1); - ret = create_property(oclass, prop_name, prop_type, nick, blurb, - slice, flags); - Py_DECREF(slice); - - if (!ret) - break; - } - g_type_class_unref(oclass); - return ret; -} - -static PyObject * -pyg_type_register(PyObject *self, PyObject *args) -{ - PyObject *gtype, *module, *gsignals, *gproperties; - PyTypeObject *class; - GType parent_type, instance_type; - gchar *type_name = NULL; - gint i; - GTypeQuery query; - GTypeInfo type_info = { - 0, /* class_size */ - - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - - (GClassInitFunc) pyg_object_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - - 0, /* instance_size */ - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL - }; - - if (!PyArg_ParseTuple(args, "O:gobject.type_register", &class)) - return NULL; - if (!PyType_IsSubtype(class, &PyGObject_Type)) { - PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass"); - return NULL; - } - - /* find the GType of the parent */ - parent_type = pyg_type_from_object((PyObject *)class); - if (!parent_type) { - return NULL; - } - - /* make name for new widget */ - module = PyObject_GetAttrString((PyObject *)class, "__module__"); - if (module && PyString_Check(module)) { - type_name = g_strconcat(PyString_AsString(module), ".", - class->tp_name, NULL); - } else { - if (module) - Py_DECREF(module); - else - PyErr_Clear(); - type_name = g_strdup(class->tp_name); - } - /* convert '.' in type name to '+', which isn't banned (grumble) */ - for (i = 0; type_name[i] != '\0'; i++) - if (type_name[i] == '.') - type_name[i] = '+'; - - /* set class_data that will be passed to the class_init function. */ - type_info.class_data = class; - - /* fill in missing values of GTypeInfo struct */ - g_type_query(parent_type, &query); - type_info.class_size = query.class_size; - type_info.instance_size = query.instance_size; - - /* create new typecode */ - instance_type = g_type_register_static(parent_type, type_name, - &type_info, 0); - g_free(type_name); - if (instance_type == 0) { - PyErr_SetString(PyExc_RuntimeError, "could not create new GType"); - return NULL; - } - - /* store pointer to the class with the GType */ - Py_INCREF(class); - g_type_set_qdata(instance_type, g_quark_from_string("PyGObject::class"), - class); - - /* set new value of __gtype__ on class */ - gtype = pyg_type_wrapper_new(instance_type); - PyDict_SetItemString(class->tp_dict, "__gtype__", gtype); - Py_DECREF(gtype); - - /* if no __doc__, set it to the auto doc descriptor */ - if (PyDict_GetItemString(class->tp_dict, "__doc__") == NULL) { - PyDict_SetItemString(class->tp_dict, "__doc__", - pyg_object_descr_doc_get()); - } - - /* we look this up in the instance dictionary, so we don't - * accidentally get a parent type's __gsignals__ attribute. */ - gsignals = PyDict_GetItemString(class->tp_dict, "__gsignals__"); - if (gsignals) { - if (!PyDict_Check(gsignals)) { - PyErr_SetString(PyExc_TypeError, - "__gsignals__ attribute not a dict!"); - Py_DECREF(gsignals); - return NULL; - } - if (!add_signals(instance_type, gsignals)) { - Py_DECREF(gsignals); - return NULL; - } - PyDict_DelItemString(class->tp_dict, "__gsignals__"); - Py_DECREF(gsignals); - } else { - PyErr_Clear(); - } - - /* we look this up in the instance dictionary, so we don't - * accidentally get a parent type's __gsignals__ attribute. */ - gproperties = PyDict_GetItemString(class->tp_dict, "__gproperties__"); - if (gproperties) { - if (!PyDict_Check(gproperties)) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ attribute not a dict!"); - Py_DECREF(gproperties); - return NULL; - } - if (!add_properties(instance_type, gproperties)) { - Py_DECREF(gproperties); - return NULL; - } - PyDict_DelItemString(class->tp_dict, "__gproperties__"); - Py_DECREF(gproperties); - } else { - PyErr_Clear(); - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pyg_signal_new(PyObject *self, PyObject *args) -{ - gchar *signal_name; - PyObject *py_type; - GSignalFlags signal_flags; - GType return_type; - PyObject *py_return_type, *py_param_types; - - GType instance_type = 0; - guint n_params, i; - GType *param_types; - - guint signal_id; - - if (!PyArg_ParseTuple(args, "sOiOO:gobject.signal_new", &signal_name, - &py_type, &signal_flags, &py_return_type, - &py_param_types)) - return NULL; - instance_type = pyg_type_from_object(py_type); - if (!instance_type) - return NULL; - return_type = pyg_type_from_object(py_return_type); - if (!return_type) - return NULL; - if (!PySequence_Check(py_param_types)) { - PyErr_SetString(PyExc_TypeError, - "argument 5 must be a sequence of GType codes"); - return NULL; - } - n_params = PySequence_Length(py_param_types); - param_types = g_new(GType, n_params); - for (i = 0; i < n_params; i++) { - PyObject *item = PySequence_GetItem(py_param_types, i); - - param_types[i] = pyg_type_from_object(item); - if (param_types[i] == 0) { - PyErr_Clear(); - Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "argument 5 must be a sequence of GType codes"); - return NULL; - } - Py_DECREF(item); - } - - signal_id = g_signal_newv(signal_name, instance_type, signal_flags, - pyg_signal_class_closure_get(), - (GSignalAccumulator)0, NULL, - (GSignalCMarshaller)0, - return_type, n_params, param_types); - g_free(param_types); - if (signal_id != 0) - return PyInt_FromLong(signal_id); - PyErr_SetString(PyExc_RuntimeError, "could not create signal"); - return NULL; -} - -static PyObject * -pyg_signal_list_names (PyObject *self, PyObject *args) -{ - PyObject *py_itype, *list; - GObjectClass *class; - GType itype; - guint n; - guint *ids; - guint i; - - if (!PyArg_ParseTuple(args, "O:gobject.signal_list_names", &py_itype)) - return NULL; - if ((itype = pyg_type_from_object(py_itype)) == 0) - return NULL; - - if (!G_TYPE_IS_INSTANTIATABLE(itype) && !G_TYPE_IS_INTERFACE(itype)) { - PyErr_SetString(PyExc_TypeError, - "type must be instantiable or an interface"); - return NULL; - } - - class = g_type_class_ref(itype); - if (!class) { - PyErr_SetString(PyExc_RuntimeError, - "could not get a reference to type class"); - return NULL; - } - ids = g_signal_list_ids(itype, &n); - - list = PyTuple_New((gint)n); - if (list == NULL) { - g_free(ids); - g_type_class_unref(class); - return NULL; - } - - for (i = 0; i < n; i++) - PyTuple_SetItem(list, i, PyString_FromString(g_signal_name(ids[i]))); - g_free(ids); - g_type_class_unref(class); - return list; -} - -static PyObject * -pyg_object_class_list_properties (PyObject *self, PyObject *args) -{ - GParamSpec **specs; - PyObject *py_itype, *list; - GType itype; - GObjectClass *class; - guint nprops; - guint i; - - if (!PyArg_ParseTuple(args, "O:gobject.list_properties", - &py_itype)) - return NULL; - if ((itype = pyg_type_from_object(py_itype)) == 0) - return NULL; - - if (!g_type_is_a(itype, G_TYPE_OBJECT)) { - PyErr_SetString(PyExc_TypeError, "type must be derived from GObject"); - return NULL; - } - - class = g_type_class_ref(itype); - if (!class) { - PyErr_SetString(PyExc_RuntimeError, - "could not get a reference to type class"); - return NULL; - } - - specs = g_object_class_list_properties(class, &nprops); - list = PyTuple_New(nprops); - if (list == NULL) { - g_free(specs); - g_type_class_unref(class); - return NULL; - } - for (i = 0; i < nprops; i++) { - PyTuple_SetItem(list, i, pyg_param_spec_new(specs[i])); - } - g_free(specs); - g_type_class_unref(class); - - return list; -} - -static PyObject * -pyg_object_new (PyGObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *pytype; - GType type; - GObject *obj = NULL; - GObjectClass *class; - PyObject *value; - PyObject *key; - int pos=0, num_params=0, i; - GParameter *params; - - if (!PyArg_ParseTuple (args, "O:gobject.new", &pytype)) { - return NULL; - } - - if ((type = pyg_type_from_object (pytype)) == 0) - return NULL; - - if ((class = g_type_class_ref (type)) == NULL) { - PyErr_SetString(PyExc_TypeError, - "could not get a reference to type class"); - return NULL; - } - - params = g_new0(GParameter, PyDict_Size(kwargs)); - - while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) { - GParamSpec *pspec; - gchar *key_str = g_strdup(PyString_AsString (key)); - pspec = g_object_class_find_property (class, key_str); - if (!pspec) { - gchar buf[512]; - - g_snprintf(buf, sizeof(buf), - "gobject `%s' doesn't support property `%s'", - g_type_name(type), key_str); - PyErr_SetString(PyExc_TypeError, buf); - goto cleanup; - } - g_value_init(¶ms[num_params].value, - G_PARAM_SPEC_VALUE_TYPE(pspec)); - if (pyg_value_from_pyobject(¶ms[num_params].value, value)) { - gchar buf[512]; - - g_snprintf(buf, sizeof(buf), - "could not convert value for property `%s'", key_str); - PyErr_SetString(PyExc_TypeError, buf); - goto cleanup; - } - params[num_params].name = key_str; - num_params++; - } - - obj = g_object_newv(type, num_params, params); - if (!obj) - PyErr_SetString (PyExc_RuntimeError, "could not create object"); - - cleanup: - for (i = 0; i < num_params; i++) { - g_free((gchar *) params[i].name); - g_value_unset(¶ms[i].value); - } - g_free(params); - g_type_class_unref(class); - - if (obj) - return pygobject_new ((GObject *)obj); - return NULL; -} - -static PyMethodDef pygobject_functions[] = { - { "type_name", pyg_type_name, METH_VARARGS }, - { "type_from_name", pyg_type_from_name, METH_VARARGS }, - { "type_parent", pyg_type_parent, METH_VARARGS }, - { "type_is_a", pyg_type_is_a, METH_VARARGS }, - { "type_children", pyg_type_children, METH_VARARGS }, - { "type_interfaces", pyg_type_interfaces, METH_VARARGS }, - { "type_register", pyg_type_register, METH_VARARGS }, - { "signal_new", pyg_signal_new, METH_VARARGS }, - { "signal_list_names", pyg_signal_list_names, METH_VARARGS }, - { "list_properties", pyg_object_class_list_properties, METH_VARARGS }, - { "new", (PyCFunction)pyg_object_new, METH_VARARGS|METH_KEYWORDS }, - { NULL, NULL, 0 } -}; - - -/* ----------------- Constant extraction ------------------------ */ - -static char * -pyg_constant_strip_prefix(gchar *name, const gchar *strip_prefix) -{ - gint prefix_len; - guint j; - - prefix_len = strlen(strip_prefix); - - /* strip off prefix from value name, while keeping it a valid - * identifier */ - for (j = prefix_len; j >= 0; j--) { - if (g_ascii_isalpha(name[j]) || name[j] == '_') { - return &name[j]; - } - } - return name; -} - -static void -pyg_enum_add_constants(PyObject *module, GType enum_type, - const gchar *strip_prefix) -{ - GEnumClass *eclass; - guint i; - - /* a more useful warning */ - if (!G_TYPE_IS_ENUM(enum_type)) { - g_warning("`%s' is not an enum type", g_type_name(enum_type)); - return; - } - g_return_if_fail (strip_prefix != NULL); - - eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); - - for (i = 0; i < eclass->n_values; i++) { - gchar *name = eclass->values[i].value_name; - gint value = eclass->values[i].value; - - PyModule_AddIntConstant(module, - pyg_constant_strip_prefix(name, strip_prefix), - (long) value); - } - - g_type_class_unref(eclass); -} - -static void -pyg_flags_add_constants(PyObject *module, GType flags_type, - const gchar *strip_prefix) -{ - GFlagsClass *fclass; - guint i; - - /* a more useful warning */ - if (!G_TYPE_IS_FLAGS(flags_type)) { - g_warning("`%s' is not an flags type", g_type_name(flags_type)); - return; - } - g_return_if_fail (strip_prefix != NULL); - - fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); - - for (i = 0; i < fclass->n_values; i++) { - gchar *name = fclass->values[i].value_name; - guint value = fclass->values[i].value; - - PyModule_AddIntConstant(module, - pyg_constant_strip_prefix(name, strip_prefix), - (long) value); - } - - g_type_class_unref(fclass); -} - -static gboolean -pyg_error_check(GError **error) -{ - g_return_val_if_fail(error != NULL, FALSE); - - if (*error != NULL) { - PyObject *exc_instance; - PyObject *d; - - exc_instance = PyObject_CallFunction(gerror_exc, "z", - (*error)->message); - PyObject_SetAttrString(exc_instance, "domain", - d=PyString_FromString(g_quark_to_string((*error)->domain))); - Py_DECREF(d); - PyObject_SetAttrString(exc_instance, "code", - d=PyInt_FromLong((*error)->code)); - Py_DECREF(d); - if ((*error)->message) { - PyObject_SetAttrString(exc_instance, "message", - d=PyString_FromString((*error)->message)); - Py_DECREF(d); - } else { - PyObject_SetAttrString(exc_instance, "message", Py_None); - } - - PyErr_SetObject(gerror_exc, exc_instance); - Py_DECREF(exc_instance); - g_clear_error(error); - return TRUE; - } - return FALSE; -} - -/* ----------------- gobject module initialisation -------------- */ - -struct _PyGObject_Functions pygobject_api_functions = { - pygobject_register_class, - pygobject_register_wrapper, - pygobject_register_sinkfunc, - pygobject_lookup_class, - pygobject_new, - - pyg_closure_new, - pygobject_watch_closure, - pyg_destroy_notify, - - pyg_type_from_object, - pyg_type_wrapper_new, - pyg_enum_get_value, - pyg_flags_get_value, - pyg_register_boxed_custom, - pyg_value_from_pyobject, - pyg_value_as_pyobject, - - pyg_register_interface, - - &PyGBoxed_Type, - pyg_register_boxed, - pyg_boxed_new, - - &PyGPointer_Type, - pyg_register_pointer, - pyg_pointer_new, - - pyg_enum_add_constants, - pyg_flags_add_constants, - - pyg_constant_strip_prefix, - - pyg_error_check, - - pyg_set_thread_block_funcs, - (PyGThreadBlockFunc)0, /* block_threads */ - (PyGThreadBlockFunc)0, /* unblock_threads */ -}; - -DL_EXPORT(void) -initgobject(void) -{ - PyObject *m, *d, *o, *tuple; - - PyGTypeWrapper_Type.ob_type = &PyType_Type; - PyGParamSpec_Type.ob_type = &PyType_Type; - - m = Py_InitModule("gobject", pygobject_functions); - d = PyModule_GetDict(m); - -#ifdef ENABLE_PYGTK_THREADING - if (!g_threads_got_initialized) - g_thread_init(NULL); -#endif - - g_type_init(); - - PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject", - pyobject_copy, - pyobject_free); - - gerror_exc = PyErr_NewException("gobject.GError", PyExc_RuntimeError,NULL); - PyDict_SetItemString(d, "GError", gerror_exc); - - PyGObject_Type.tp_alloc = PyType_GenericAlloc; - PyGObject_Type.tp_new = PyType_GenericNew; - pygobject_register_class(d, "GObject", G_TYPE_OBJECT, - &PyGObject_Type, NULL); - PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__", - pyg_object_descr_doc_get()); - - PyGInterface_Type.ob_type = &PyType_Type; - PyGInterface_Type.tp_alloc = PyType_GenericAlloc; - PyGInterface_Type.tp_new = PyType_GenericNew; - if (PyType_Ready(&PyGInterface_Type)) - return; - PyDict_SetItemString(d, "GInterface", (PyObject *)&PyGInterface_Type); - PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gtype__", - o=pyg_type_wrapper_new(G_TYPE_INTERFACE)); - Py_DECREF(o); - PyDict_SetItemString(PyGInterface_Type.tp_dict, "__doc__", - pyg_object_descr_doc_get()); - PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gdoc__", - pyg_object_descr_doc_get()); - - PyGBoxed_Type.ob_type = &PyType_Type; - PyGBoxed_Type.tp_alloc = PyType_GenericAlloc; - PyGBoxed_Type.tp_new = PyType_GenericNew; - if (PyType_Ready(&PyGBoxed_Type)) - return; - PyDict_SetItemString(d, "GBoxed", (PyObject *)&PyGBoxed_Type); - PyDict_SetItemString(PyGBoxed_Type.tp_dict, "__gtype__", - o=pyg_type_wrapper_new(G_TYPE_BOXED)); - Py_DECREF(o); - - PyGPointer_Type.ob_type = &PyType_Type; - PyGPointer_Type.tp_alloc = PyType_GenericAlloc; - PyGPointer_Type.tp_new = PyType_GenericNew; - if (PyType_Ready(&PyGPointer_Type)) - return; - PyDict_SetItemString(d, "GPointer", (PyObject *)&PyGPointer_Type); - PyDict_SetItemString(PyGPointer_Type.tp_dict, "__gtype__", - o=pyg_type_wrapper_new(G_TYPE_POINTER)); - Py_DECREF(o); - - tuple = Py_BuildValue ("(iii)", glib_major_version, glib_minor_version, - glib_micro_version); - PyDict_SetItemString(d, "glib_version", tuple); - Py_DECREF(tuple); - - /* for addon libraries ... */ - PyDict_SetItemString(d, "_PyGObject_API", - o=PyCObject_FromVoidPtr(&pygobject_api_functions,NULL)); - Py_DECREF(o); - - /* some constants */ - PyModule_AddIntConstant(m, "SIGNAL_RUN_FIRST", G_SIGNAL_RUN_FIRST); - PyModule_AddIntConstant(m, "SIGNAL_RUN_LAST", G_SIGNAL_RUN_LAST); - PyModule_AddIntConstant(m, "SIGNAL_RUN_CLEANUP", G_SIGNAL_RUN_CLEANUP); - PyModule_AddIntConstant(m, "SIGNAL_NO_RECURSE", G_SIGNAL_NO_RECURSE); - PyModule_AddIntConstant(m, "SIGNAL_DETAILED", G_SIGNAL_DETAILED); - PyModule_AddIntConstant(m, "SIGNAL_ACTION", G_SIGNAL_ACTION); - PyModule_AddIntConstant(m, "SIGNAL_NO_HOOKS", G_SIGNAL_NO_HOOKS); - - PyModule_AddIntConstant(m, "PARAM_READABLE", G_PARAM_READABLE); - PyModule_AddIntConstant(m, "PARAM_WRITABLE", G_PARAM_WRITABLE); - PyModule_AddIntConstant(m, "PARAM_CONSTRUCT", G_PARAM_CONSTRUCT); - PyModule_AddIntConstant(m, "PARAM_CONSTRUCT_ONLY", G_PARAM_CONSTRUCT_ONLY); - PyModule_AddIntConstant(m, "PARAM_LAX_VALIDATION", G_PARAM_LAX_VALIDATION); - PyModule_AddIntConstant(m, "PARAM_READWRITE", G_PARAM_READWRITE); - - PyModule_AddObject(m, "TYPE_INVALID", pyg_type_wrapper_new(G_TYPE_INVALID)); - PyModule_AddObject(m, "TYPE_NONE", pyg_type_wrapper_new(G_TYPE_NONE)); - PyModule_AddObject(m, "TYPE_INTERFACE", pyg_type_wrapper_new(G_TYPE_INTERFACE)); - PyModule_AddObject(m, "TYPE_CHAR", pyg_type_wrapper_new(G_TYPE_CHAR)); - PyModule_AddObject(m, "TYPE_UCHAR", pyg_type_wrapper_new(G_TYPE_UCHAR)); - PyModule_AddObject(m, "TYPE_BOOLEAN", pyg_type_wrapper_new(G_TYPE_BOOLEAN)); - PyModule_AddObject(m, "TYPE_INT", pyg_type_wrapper_new(G_TYPE_INT)); - PyModule_AddObject(m, "TYPE_UINT", pyg_type_wrapper_new(G_TYPE_UINT)); - PyModule_AddObject(m, "TYPE_LONG", pyg_type_wrapper_new(G_TYPE_LONG)); - PyModule_AddObject(m, "TYPE_ULONG", pyg_type_wrapper_new(G_TYPE_ULONG)); - PyModule_AddObject(m, "TYPE_INT64", pyg_type_wrapper_new(G_TYPE_INT64)); - PyModule_AddObject(m, "TYPE_UINT64", pyg_type_wrapper_new(G_TYPE_UINT64)); - PyModule_AddObject(m, "TYPE_ENUM", pyg_type_wrapper_new(G_TYPE_ENUM)); - PyModule_AddObject(m, "TYPE_FLAGS", pyg_type_wrapper_new(G_TYPE_FLAGS)); - PyModule_AddObject(m, "TYPE_FLOAT", pyg_type_wrapper_new(G_TYPE_FLOAT)); - PyModule_AddObject(m, "TYPE_DOUBLE", pyg_type_wrapper_new(G_TYPE_DOUBLE)); - PyModule_AddObject(m, "TYPE_STRING", pyg_type_wrapper_new(G_TYPE_STRING)); - PyModule_AddObject(m, "TYPE_POINTER", pyg_type_wrapper_new(G_TYPE_POINTER)); - PyModule_AddObject(m, "TYPE_BOXED", pyg_type_wrapper_new(G_TYPE_BOXED)); - PyModule_AddObject(m, "TYPE_PARAM", pyg_type_wrapper_new(G_TYPE_PARAM)); - PyModule_AddObject(m, "TYPE_OBJECT", pyg_type_wrapper_new(G_TYPE_OBJECT)); - PyModule_AddObject(m, "TYPE_PYOBJECT", pyg_type_wrapper_new(PY_TYPE_OBJECT)); - - if (PyErr_Occurred()) { - PyErr_Print(); - Py_FatalError("can't initialise module gobject"); - } -} |