diff options
Diffstat (limited to 'gi/pygi-foreign.c')
-rw-r--r-- | gi/pygi-foreign.c | 119 |
1 files changed, 72 insertions, 47 deletions
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c index 13a0f77..f80b43c 100644 --- a/gi/pygi-foreign.c +++ b/gi/pygi-foreign.c @@ -23,6 +23,7 @@ */ #include "pygi-foreign.h" +#include "pygi-foreign-gvariant.h" #include <config.h> #include <girepository.h> @@ -30,62 +31,87 @@ typedef struct { const char *namespace; const char *name; - PyGIArgOverrideToGArgumentFunc to_func; - PyGIArgOverrideFromGArgumentFunc from_func; - PyGIArgOverrideReleaseGArgumentFunc release_func; + PyGIArgOverrideToGIArgumentFunc to_func; + PyGIArgOverrideFromGIArgumentFunc from_func; + PyGIArgOverrideReleaseFunc release_func; } PyGIForeignStruct; static GPtrArray *foreign_structs = NULL; +void +init_foreign_structs () +{ + foreign_structs = g_ptr_array_new (); + + pygi_register_foreign_struct ("GLib", + "Variant", + g_variant_to_arg, + g_variant_from_arg, + g_variant_release_foreign); +} + static PyGIForeignStruct * -pygi_struct_foreign_lookup (GITypeInfo *type_info) +do_lookup (const gchar *namespace, const gchar *name) { gint i; - PyObject *module; - gchar *module_name; - GIBaseInfo *base_info; - const gchar *namespace; - const gchar *name; - - base_info = g_type_info_get_interface (type_info); - if (base_info == NULL) { - PyErr_Format (PyExc_ValueError, "Couldn't resolve the type of this foreign struct"); - return NULL; + for (i = 0; i < foreign_structs->len; i++) { + PyGIForeignStruct *foreign_struct = \ + g_ptr_array_index (foreign_structs, i); + + if ( (strcmp (namespace, foreign_struct->namespace) == 0) && + (strcmp (name, foreign_struct->name) == 0)) { + return foreign_struct; + } + } + return NULL; +} + +static PyGIForeignStruct * +pygi_struct_foreign_lookup (GIBaseInfo *base_info) +{ + PyGIForeignStruct *result; + const gchar *namespace = g_base_info_get_namespace (base_info); + const gchar *name = g_base_info_get_name (base_info); + + if (foreign_structs == NULL) { + init_foreign_structs (); } - namespace = g_base_info_get_namespace (base_info); - name = g_base_info_get_name (base_info); + result = do_lookup (namespace, name); - module_name = g_strconcat ("gi._gi_", g_base_info_get_namespace (base_info), NULL); - module = PyImport_ImportModule (module_name); - g_free (module_name); + if (result == NULL) { + gchar *module_name = g_strconcat ("gi._gi_", namespace, NULL); + PyObject *module = PyImport_ImportModule (module_name); - if (foreign_structs != NULL) { - for (i = 0; i < foreign_structs->len; i++) { - PyGIForeignStruct *foreign_struct = \ - g_ptr_array_index (foreign_structs, i); + g_free (module_name); - if ( (strcmp (namespace, foreign_struct->namespace) == 0) && - (strcmp (name, foreign_struct->name) == 0)) { - g_base_info_unref (base_info); - return foreign_struct; - } + if (module == NULL) + PyErr_Clear (); + else { + Py_DECREF (module); + result = do_lookup (namespace, name); } } - g_base_info_unref (base_info); + if (result == NULL) { + PyErr_Format (PyExc_TypeError, + "Couldn't find conversion for foreign struct '%s.%s'", + namespace, + name); + } - PyErr_Format (PyExc_TypeError, "Couldn't find conversion for foreign struct '%s.%s'", namespace, name); - return NULL; + return result; } PyObject * -pygi_struct_foreign_convert_to_g_argument (PyObject *value, +pygi_struct_foreign_convert_to_g_argument (PyObject *value, GITypeInfo *type_info, GITransfer transfer, - GArgument *arg) + GIArgument *arg) { - PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info); + GIBaseInfo *base_info = g_type_info_get_interface (type_info); + PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info); + g_base_info_unref (base_info); if (foreign_struct == NULL) return NULL; @@ -98,9 +124,12 @@ pygi_struct_foreign_convert_to_g_argument (PyObject *value, PyObject * pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info, - GArgument *arg) + GIArgument *arg) { - PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info); + GIBaseInfo *base_info = g_type_info_get_interface (type_info); + PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info); + g_base_info_unref (base_info); + if (foreign_struct == NULL) return NULL; @@ -109,11 +138,10 @@ pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info, } PyObject * -pygi_struct_foreign_release_g_argument (GITransfer transfer, - GITypeInfo *type_info, - GArgument *arg) +pygi_struct_foreign_release (GIBaseInfo *base_info, + gpointer struct_) { - PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info); + PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info); if (foreign_struct == NULL) return NULL; @@ -121,7 +149,7 @@ pygi_struct_foreign_release_g_argument (GITransfer transfer, if (!foreign_struct->release_func) Py_RETURN_NONE; - if (!foreign_struct->release_func (transfer, type_info, arg)) + if (!foreign_struct->release_func (base_info, struct_)) return NULL; Py_RETURN_NONE; @@ -130,9 +158,9 @@ pygi_struct_foreign_release_g_argument (GITransfer transfer, void pygi_register_foreign_struct_real (const char* namespace_, const char* name, - PyGIArgOverrideToGArgumentFunc to_func, - PyGIArgOverrideFromGArgumentFunc from_func, - PyGIArgOverrideReleaseGArgumentFunc release_func) + PyGIArgOverrideToGIArgumentFunc to_func, + PyGIArgOverrideFromGIArgumentFunc from_func, + PyGIArgOverrideReleaseFunc release_func) { PyGIForeignStruct *new_struct = g_slice_new0 (PyGIForeignStruct); new_struct->namespace = namespace_; @@ -141,8 +169,5 @@ pygi_register_foreign_struct_real (const char* namespace_, new_struct->from_func = from_func; new_struct->release_func = release_func; - if (foreign_structs == NULL) - foreign_structs = g_ptr_array_new (); - g_ptr_array_add (foreign_structs, new_struct); } |