diff options
author | Johan Dahlin <johan@src.gnome.org> | 2005-07-07 18:44:12 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2005-07-07 18:44:12 +0000 |
commit | 302a0be1855356577a8869c34fa90bface8d4f00 (patch) | |
tree | 87b8d571e2257c31ca4200020b01428d34cc08e4 | |
parent | 8914f109dc0515d8927c76b29ec5b46317965b68 (diff) | |
download | pygobject-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.c | 4 | ||||
-rw-r--r-- | gobject/pygobject-private.h | 6 | ||||
-rw-r--r-- | gobject/pygobject.h | 11 | ||||
-rw-r--r-- | gobject/pygtype.c | 72 |
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))); |