summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo J. A. M. Carneiro <gjc@src.gnome.org>2005-01-09 14:49:57 +0000
committerGustavo J. A. M. Carneiro <gjc@src.gnome.org>2005-01-09 14:49:57 +0000
commitd953b545f6fa8f0e24b265044bc52ab5896702eb (patch)
tree0f49bc5dc293e8896c17cecb7033386a1364c8e9
parentb3ca96724b71162b93011736b2cca5f00802dae1 (diff)
downloadpygobject-d953b545f6fa8f0e24b265044bc52ab5896702eb.tar.gz
pygobject-d953b545f6fa8f0e24b265044bc52ab5896702eb.tar.xz
pygobject-d953b545f6fa8f0e24b265044bc52ab5896702eb.zip
#154974: Interface implementation support
-rw-r--r--gobject/gobjectmodule.c41
-rw-r--r--gobject/pygobject.h2
2 files changed, 43 insertions, 0 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index bbd152e..5ed9d64 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -32,6 +32,9 @@ static const gchar *pyginterface_type_id = "PyGInterface::type";
GQuark pyginterface_type_key = 0;
static const gchar *pygobject_class_init_id = "PyGObject::class-init";
GQuark pygobject_class_init_key = 0;
+static const gchar *pyginterface_info_id = "PyGInterface::info";
+GQuark pyginterface_info_key = 0;
+
static void pyg_flags_add_constants(PyObject *module, GType flags_type,
const gchar *strip_prefix);
@@ -207,6 +210,18 @@ pyg_register_interface(PyObject *dict, const gchar *class_name,
}
+static void
+pyg_register_interface_info(GType gtype, const GInterfaceInfo *info)
+{
+ g_type_set_qdata(gtype, pyginterface_info_key, (gpointer) info);
+}
+
+static const GInterfaceInfo *
+pyg_lookup_interface_info(GType gtype)
+{
+ return g_type_get_qdata(gtype, pyginterface_info_key);
+}
+
/* -------------- GMainContext objects ---------------------------- */
@@ -1016,6 +1031,30 @@ pyg_type_register(PyObject *self, PyObject *args)
return NULL;
}
g_type_class_unref(gclass);
+
+ /* Register interface implementations */
+ if (class->tp_bases) {
+ for (i = 0; i < PyTuple_GET_SIZE(class->tp_bases); ++i)
+ {
+ PyTypeObject *base = (PyTypeObject *) PyTuple_GET_ITEM(class->tp_bases, i);
+ GType itype;
+ const GInterfaceInfo *iinfo;
+
+ if (PyObject_IsSubclass((PyObject *) base,
+ (PyObject *) &PyGInterface_Type) != 1)
+ continue;
+ itype = pyg_type_from_object((PyObject *) base);
+ iinfo = pyg_lookup_interface_info(itype);
+ if (!iinfo) {
+ PyErr_Format(PyExc_NotImplementedError, "Interface type %s "
+ "has no python implementation support", base->tp_name);
+ return NULL;
+ }
+ g_type_add_interface_static(instance_type, itype, iinfo);
+ }
+ } else
+ g_warning("type has no tp_bases");
+
Py_INCREF(Py_None);
return Py_None;
}
@@ -2110,6 +2149,7 @@ struct _PyGObject_Functions pygobject_api_functions = {
pyg_gil_state_ensure_py23,
pyg_gil_state_release_py23,
pyg_register_class_init,
+ pyg_register_interface_info
};
#define REGISTER_TYPE(d, type, name) \
@@ -2159,6 +2199,7 @@ initgobject(void)
PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gdoc__",
pyg_object_descr_doc_get());
pyginterface_type_key = g_quark_from_static_string(pyginterface_type_id);
+ pyginterface_info_key = g_quark_from_static_string(pyginterface_info_id);
pygobject_class_init_key = g_quark_from_static_string(pygobject_class_init_id);
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index ae399d1..22e488c 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -159,6 +159,7 @@ struct _PyGObject_Functions {
int (*gil_state_ensure) (void);
void (*gil_state_release) (int flag);
void (*register_class_init) (GType gtype, PyGClassInitFunc class_init);
+ void (*register_interface_info) (GType gtype, const GInterfaceInfo *info);
};
#ifndef _INSIDE_PYGOBJECT_
@@ -211,6 +212,7 @@ struct _PyGObject_Functions *_PyGObject_API;
#define pyg_flags_from_gtype (_PyGObject_API->flags_from_gtype)
#define pyg_enable_threads (_PyGObject_API->enable_threads)
#define pyg_register_class_init (_PyGObject_API->register_class_init)
+#define pyg_register_interface_info (_PyGObject_API->register_interface_info)
#define pyg_block_threads() G_STMT_START { \
if (_PyGObject_API->block_threads != NULL) \