1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
3 * Copyright (c) 2010 litl, LLC
4 * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29 #include "pygi-foreign.h"
30 #include "pygi-foreign-gvariant.h"
32 #include <girepository.h>
35 const char *namespace;
37 PyGIArgOverrideToGIArgumentFunc to_func;
38 PyGIArgOverrideFromGIArgumentFunc from_func;
39 PyGIArgOverrideReleaseFunc release_func;
42 static GPtrArray *foreign_structs = NULL;
45 init_foreign_structs ()
47 foreign_structs = g_ptr_array_new ();
49 pygi_register_foreign_struct ("GLib",
53 g_variant_release_foreign);
56 static PyGIForeignStruct *
57 do_lookup (const gchar *namespace, const gchar *name)
60 for (i = 0; i < foreign_structs->len; i++) {
61 PyGIForeignStruct *foreign_struct = \
62 g_ptr_array_index (foreign_structs, i);
64 if ( (strcmp (namespace, foreign_struct->namespace) == 0) &&
65 (strcmp (name, foreign_struct->name) == 0)) {
66 return foreign_struct;
72 static PyGIForeignStruct *
73 pygi_struct_foreign_lookup (GIBaseInfo *base_info)
75 PyGIForeignStruct *result;
76 const gchar *namespace = g_base_info_get_namespace (base_info);
77 const gchar *name = g_base_info_get_name (base_info);
79 if (foreign_structs == NULL) {
80 init_foreign_structs ();
83 result = do_lookup (namespace, name);
86 gchar *module_name = g_strconcat ("gi._gi_", namespace, NULL);
87 PyObject *module = PyImport_ImportModule (module_name);
95 result = do_lookup (namespace, name);
100 PyErr_Format (PyExc_TypeError,
101 "Couldn't find conversion for foreign struct '%s.%s'",
110 pygi_struct_foreign_convert_to_g_argument (PyObject *value,
111 GIInterfaceInfo *iface_info,
115 GIBaseInfo *base_info = (GIBaseInfo *) iface_info;
116 PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
118 if (foreign_struct == NULL)
121 if (!foreign_struct->to_func (value, iface_info, transfer, arg))
128 pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *iface_info,
131 GIBaseInfo *base_info = (GIBaseInfo *) iface_info;
132 PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
134 if (foreign_struct == NULL)
137 return foreign_struct->from_func (iface_info, arg);
141 pygi_struct_foreign_release (GIBaseInfo *base_info,
144 PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
146 if (foreign_struct == NULL)
149 if (!foreign_struct->release_func)
152 if (!foreign_struct->release_func (base_info, struct_))
159 pygi_register_foreign_struct_real (const char* namespace_,
161 PyGIArgOverrideToGIArgumentFunc to_func,
162 PyGIArgOverrideFromGIArgumentFunc from_func,
163 PyGIArgOverrideReleaseFunc release_func)
165 PyGIForeignStruct *new_struct = g_slice_new (PyGIForeignStruct);
166 new_struct->namespace = namespace_;
167 new_struct->name = name;
168 new_struct->to_func = to_func;
169 new_struct->from_func = from_func;
170 new_struct->release_func = release_func;
172 g_ptr_array_add (foreign_structs, new_struct);