summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Dahlin <johan@src.gnome.org>2005-07-07 18:44:12 +0000
committerJohan Dahlin <johan@src.gnome.org>2005-07-07 18:44:12 +0000
commit302a0be1855356577a8869c34fa90bface8d4f00 (patch)
tree87b8d571e2257c31ca4200020b01428d34cc08e4
parent8914f109dc0515d8927c76b29ec5b46317965b68 (diff)
downloadpygobject-302a0be1855356577a8869c34fa90bface8d4f00.tar.gz
pygobject-302a0be1855356577a8869c34fa90bface8d4f00.tar.xz
pygobject-302a0be1855356577a8869c34fa90bface8d4f00.zip
Rename pyg_register_boxed_custom to pyg_register_gtype_custom. Add note
* gobject/gobjectmodule.c: (initgobject): * gobject/pygobject-private.h: * gobject/pygobject.h: * gobject/pygtype.c: (pyg_type_lookup), (pyg_register_gtype_custom), (pyg_value_from_pyobject), (pyg_value_as_pyobject): Rename pyg_register_boxed_custom to pyg_register_gtype_custom. Add note about private fields in exported API structure. Based on patch by Edward Hervey, fixes #309625
-rw-r--r--gobject/gobjectmodule.c4
-rw-r--r--gobject/pygobject-private.h6
-rw-r--r--gobject/pygobject.h11
-rw-r--r--gobject/pygtype.c72
4 files changed, 61 insertions, 32 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index d054635..ad00845 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -2472,7 +2472,7 @@ struct _PyGObject_Functions pygobject_api_functions = {
pyg_type_wrapper_new,
pyg_enum_get_value,
pyg_flags_get_value,
- pyg_register_boxed_custom,
+ pyg_register_gtype_custom,
pyg_value_from_pyobject,
pyg_value_as_pyobject,
@@ -2697,7 +2697,7 @@ initgobject(void)
PyModule_AddObject(m, "TYPE_OBJECT", pyg_type_wrapper_new(G_TYPE_OBJECT));
PyModule_AddObject(m, "TYPE_PYOBJECT", pyg_type_wrapper_new(PY_TYPE_OBJECT));
- pyg_register_boxed_custom(G_TYPE_STRV,
+ pyg_register_gtype_custom(G_TYPE_STRV,
_pyg_strv_from_gvalue,
_pyg_strv_to_gvalue);
}
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index 50264ff..205d255 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -68,9 +68,9 @@ int pyg_pyobj_to_unichar_conv (PyObject* py_obj, void* ptr);
typedef PyObject *(* fromvaluefunc)(const GValue *value);
typedef int (*tovaluefunc)(GValue *value, PyObject *obj);
-void pyg_register_boxed_custom(GType boxed_type,
- fromvaluefunc from_func,
- tovaluefunc to_func);
+void pyg_register_gtype_custom(GType gtype,
+ fromvaluefunc from_func,
+ tovaluefunc to_func);
int pyg_value_from_pyobject(GValue *value, PyObject *obj);
PyObject *pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed);
int pyg_param_gvalue_from_pyobject(GValue* value,
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index 7ed40b9..18c50c0 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -70,8 +70,11 @@ typedef struct {
typedef int (*PyGClassInitFunc) (gpointer gclass, PyTypeObject *pyclass);
-
struct _PyGObject_Functions {
+ /*
+ * All field names in here are considered private,
+ * use the macros below instead, which provides stability
+ */
void (* register_class)(PyObject *dict, const gchar *class_name,
GType gtype, PyTypeObject *type, PyObject *bases);
void (* register_wrapper)(PyObject *self);
@@ -90,7 +93,7 @@ struct _PyGObject_Functions {
gint (* enum_get_value)(GType enum_type, PyObject *obj, gint *val);
gint (* flags_get_value)(GType flag_type, PyObject *obj, gint *val);
- void (* register_boxed_custom)(GType boxed_type,
+ void (* register_gtype_custom)(GType gtype,
PyObject *(* from_func)(const GValue *value),
int (* to_func)(GValue *value, PyObject *obj));
int (* value_from_pyobject)(GValue *value, PyObject *obj);
@@ -186,7 +189,9 @@ struct _PyGObject_Functions *_PyGObject_API;
#define pyg_type_wrapper_new (_PyGObject_API->type_wrapper_new)
#define pyg_enum_get_value (_PyGObject_API->enum_get_value)
#define pyg_flags_get_value (_PyGObject_API->flags_get_value)
-#define pyg_register_boxed_custom (_PyGObject_API->register_boxed_custom)
+/* This is deprecated, call pyg_register_gtype_custom directly instead */
+#define pyg_register_boxed_custom pyg_register_gtype_custom
+#define pyg_register_gtype_custom (_PyGObject_API->register_gtype_custom)
#define pyg_value_from_pyobject (_PyGObject_API->value_from_pyobject)
#define pyg_value_as_pyobject (_PyGObject_API->value_as_pyobject)
#define pyg_register_interface (_PyGObject_API->register_interface)
diff --git a/gobject/pygtype.c b/gobject/pygtype.c
index 843060f..827c8a5 100644
--- a/gobject/pygtype.c
+++ b/gobject/pygtype.c
@@ -543,35 +543,49 @@ pyg_flags_get_value(GType flag_type, PyObject *obj, gint *val)
typedef struct {
fromvaluefunc fromvalue;
tovaluefunc tovalue;
-} PyGBoxedMarshal;
+} PyGTypeMarshal;
+static GQuark pyg_type_marshal_key = 0;
-#define pyg_boxed_lookup(boxed_type) \
- ((PyGBoxedMarshal *)g_type_get_qdata((boxed_type), pygboxed_marshal_key))
+static PyGTypeMarshal *
+pyg_type_lookup(GType type)
+{
+ GType ptype = type;
+ PyGTypeMarshal *tm = NULL;
+ /* recursively lookup types */
+ while (ptype) {
+ if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
+ break;
+ ptype = g_type_parent(ptype);
+ }
+ return tm;
+}
/**
- * pyg_register_boxed_custom:
- * @boxed_type: the GType for boxed type
+ * pyg_register_gtype_custom:
+ * @gtype: the GType for the new type
* @from_func: a function to convert GValues to Python objects
* @to_func: a function to convert Python objects to GValues
*
- * The standard way of wrapping boxed types in PyGTK is to create a
- * subclass of gobject.GBoxed and register it with
- * pyg_register_boxed(). In some cases however, it is useful to have
- * fine grained control over how a particular type is represented in
- * Python. This function allows you to register such a handler.
+ * In order to handle specific conversion of gboxed types or new
+ * fundamental types, you may use this function to register conversion
+ * handlers.
*/
+
void
-pyg_register_boxed_custom(GType boxed_type,
- fromvaluefunc from_func,
- tovaluefunc to_func)
+pyg_register_gtype_custom(GType gtype,
+ fromvaluefunc from_func,
+ tovaluefunc to_func)
{
- PyGBoxedMarshal *bm;
+ PyGTypeMarshal *tm;
+
+ if (!pyg_type_marshal_key)
+ pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
- bm = g_new(PyGBoxedMarshal, 1);
- bm->fromvalue = from_func;
- bm->tovalue = to_func;
- g_type_set_qdata(boxed_type, pygboxed_marshal_key, bm);
+ tm = g_new(PyGTypeMarshal, 1);
+ tm->fromvalue = from_func;
+ tm->tovalue = to_func;
+ g_type_set_qdata(gtype, pyg_type_marshal_key, tm);
}
static int
@@ -823,7 +837,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
return -1;
break;
case G_TYPE_BOXED: {
- PyGBoxedMarshal *bm;
+ PyGTypeMarshal *bm;
if (obj == Py_None)
g_value_set_boxed(value, NULL);
@@ -835,7 +849,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
else if (PySequence_Check(obj) &&
G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY))
return pyg_value_array_from_pyobject(value, obj, NULL);
- else if ((bm = pyg_boxed_lookup(G_VALUE_TYPE(value))) != NULL)
+ else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
return bm->tovalue(value, obj);
else if (PyCObject_Check(obj))
g_value_set_boxed(value, PyCObject_AsVoidPtr(obj));
@@ -860,7 +874,12 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
return -1;
break;
default:
- break;
+ {
+ PyGTypeMarshal *bm;
+ if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
+ return bm->tovalue(value, obj);
+ break;
+ }
}
return 0;
}
@@ -961,7 +980,7 @@ pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed)
return pyg_pointer_new(G_VALUE_TYPE(value),
g_value_get_pointer(value));
case G_TYPE_BOXED: {
- PyGBoxedMarshal *bm;
+ PyGTypeMarshal *bm;
if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) {
PyObject *ret = (PyObject *)g_value_dup_boxed(value);
@@ -979,7 +998,7 @@ pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed)
(array->values + i, copy_boxed));
return ret;
}
- bm = pyg_boxed_lookup(G_VALUE_TYPE(value));
+ bm = pyg_type_lookup(G_VALUE_TYPE(value));
if (bm) {
return bm->fromvalue(value);
} else {
@@ -996,7 +1015,12 @@ pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed)
case G_TYPE_OBJECT:
return pygobject_new(g_value_get_object(value));
default:
- break;
+ {
+ PyGTypeMarshal *bm;
+ if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))))
+ return bm->fromvalue(value);
+ break;
+ }
}
g_snprintf(buf, sizeof(buf), "unknown type %s",
g_type_name(G_VALUE_TYPE(value)));