1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
3 * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include "pygi-private.h"
26 #include <girepository.h>
28 /* Copied from glib */
30 canonicalize_key (gchar *key)
34 for (p = key; *p != 0; p++)
39 (c < '0' || c > '9') &&
40 (c < 'A' || c > 'Z') &&
46 static GIPropertyInfo *
47 _pygi_lookup_property_from_g_type (GType g_type, const gchar *attr_name)
49 GIRepository *repository;
55 repository = g_irepository_get_default();
56 info = g_irepository_find_by_gtype (repository, g_type);
61 n_infos = g_object_info_get_n_properties ( (GIObjectInfo *) info);
62 for (i = 0; i < n_infos; i++) {
63 GIPropertyInfo *property_info;
65 property_info = g_object_info_get_property ( (GIObjectInfo *) info, i);
66 g_assert (info != NULL);
68 if (strcmp (attr_name, g_base_info_get_name (property_info)) == 0) {
69 g_base_info_unref (info);
73 g_base_info_unref (property_info);
76 g_base_info_unref (info);
78 parent = g_type_parent (g_type);
80 return _pygi_lookup_property_from_g_type (parent, attr_name);
86 pygi_get_property_value_real (PyGObject *instance,
87 const gchar *attr_name)
90 GIPropertyInfo *property_info = NULL;
91 char *property_name = g_strdup (attr_name);
92 GParamSpec *pspec = NULL;
93 GValue value = { 0, };
94 GIArgument arg = { 0, };
95 PyObject *py_value = NULL;
96 GITypeInfo *type_info = NULL;
99 canonicalize_key (property_name);
101 g_type = pyg_type_from_object ((PyObject *)instance);
102 property_info = _pygi_lookup_property_from_g_type (g_type, property_name);
104 if (property_info == NULL)
107 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (instance->obj),
112 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
113 g_object_get_property (instance->obj, attr_name, &value);
115 type_info = g_property_info_get_type (property_info);
116 transfer = g_property_info_get_ownership_transfer (property_info);
118 GITypeTag type_tag = g_type_info_get_tag (type_info);
120 case GI_TYPE_TAG_BOOLEAN:
121 arg.v_boolean = g_value_get_boolean (&value);
123 case GI_TYPE_TAG_INT8:
124 arg.v_int8 = g_value_get_schar (&value);
126 case GI_TYPE_TAG_INT16:
127 case GI_TYPE_TAG_INT32:
128 if (G_VALUE_HOLDS_LONG (&value))
129 arg.v_long = g_value_get_long (&value);
131 arg.v_int = g_value_get_int (&value);
133 case GI_TYPE_TAG_INT64:
134 if (G_VALUE_HOLDS_LONG (&value))
135 arg.v_long = g_value_get_long (&value);
137 arg.v_int64 = g_value_get_int64 (&value);
139 case GI_TYPE_TAG_UINT8:
140 arg.v_uint8 = g_value_get_uchar (&value);
142 case GI_TYPE_TAG_UINT16:
143 case GI_TYPE_TAG_UINT32:
144 if (G_VALUE_HOLDS_ULONG (&value))
145 arg.v_ulong = g_value_get_ulong (&value);
147 arg.v_uint = g_value_get_uint (&value);
149 case GI_TYPE_TAG_UINT64:
150 if (G_VALUE_HOLDS_ULONG (&value))
151 arg.v_ulong = g_value_get_ulong (&value);
153 arg.v_uint64 = g_value_get_uint64 (&value);
155 case GI_TYPE_TAG_FLOAT:
156 arg.v_float = g_value_get_float (&value);
158 case GI_TYPE_TAG_DOUBLE:
159 arg.v_double = g_value_get_double (&value);
161 case GI_TYPE_TAG_GTYPE:
162 arg.v_size = g_value_get_gtype (&value);
164 case GI_TYPE_TAG_UTF8:
165 case GI_TYPE_TAG_FILENAME:
166 arg.v_string = g_value_dup_string (&value);
168 case GI_TYPE_TAG_INTERFACE:
171 GIInfoType info_type;
174 info = g_type_info_get_interface (type_info);
175 type = g_registered_type_info_get_g_type (info);
176 info_type = g_base_info_get_type (info);
178 g_base_info_unref (info);
181 case GI_INFO_TYPE_ENUM:
182 arg.v_int32 = g_value_get_enum (&value);
184 case GI_INFO_TYPE_INTERFACE:
185 case GI_INFO_TYPE_OBJECT:
186 arg.v_pointer = g_value_get_object (&value);
188 case GI_INFO_TYPE_BOXED:
189 case GI_INFO_TYPE_STRUCT:
190 case GI_INFO_TYPE_UNION:
192 if (g_type_is_a (type, G_TYPE_BOXED)) {
193 arg.v_pointer = g_value_get_boxed (&value);
194 } else if (g_type_is_a (type, G_TYPE_POINTER)) {
195 arg.v_pointer = g_value_get_pointer (&value);
197 PyErr_Format (PyExc_NotImplementedError,
198 "Retrieving properties of type '%s' is not implemented",
203 PyErr_Format (PyExc_NotImplementedError,
204 "Retrieving properties of type '%s' is not implemented",
210 case GI_TYPE_TAG_GHASH:
211 arg.v_pointer = g_value_get_boxed (&value);
213 case GI_TYPE_TAG_GLIST:
214 arg.v_pointer = g_value_get_pointer (&value);
217 PyErr_Format (PyExc_NotImplementedError,
218 "Retrieving properties of type %s is not implemented",
219 g_type_tag_to_string (g_type_info_get_tag (type_info)));
223 py_value = _pygi_argument_to_object (&arg, type_info, transfer);
226 g_free (property_name);
227 if (property_info != NULL)
228 g_base_info_unref (property_info);
229 if (type_info != NULL)
230 g_base_info_unref (type_info);
236 pygi_set_property_value_real (PyGObject *instance,
237 const gchar *attr_name,
241 GIPropertyInfo *property_info = NULL;
242 char *property_name = g_strdup (attr_name);
243 GITypeInfo *type_info = NULL;
246 GValue value = { 0, };
247 GIArgument arg = { 0, };
248 GParamSpec *pspec = NULL;
251 canonicalize_key (property_name);
253 g_type = pyg_type_from_object ((PyObject *)instance);
254 property_info = _pygi_lookup_property_from_g_type (g_type, property_name);
256 if (property_info == NULL)
259 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (instance->obj),
264 if (! (pspec->flags & G_PARAM_WRITABLE))
267 type_info = g_property_info_get_type (property_info);
268 transfer = g_property_info_get_ownership_transfer (property_info);
269 arg = _pygi_argument_from_object (py_value, type_info, transfer);
271 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
273 // FIXME: Lots of types still unhandled
274 type_tag = g_type_info_get_tag (type_info);
276 case GI_TYPE_TAG_INTERFACE:
279 GIInfoType info_type;
282 info = g_type_info_get_interface (type_info);
283 type = g_registered_type_info_get_g_type (info);
284 info_type = g_base_info_get_type (info);
286 g_base_info_unref (info);
289 case GI_INFO_TYPE_ENUM:
290 g_value_set_enum (&value, arg.v_int32);
292 case GI_INFO_TYPE_INTERFACE:
293 case GI_INFO_TYPE_OBJECT:
294 g_value_set_object (&value, arg.v_pointer);
296 case GI_INFO_TYPE_BOXED:
297 case GI_INFO_TYPE_STRUCT:
298 case GI_INFO_TYPE_UNION:
299 if (g_type_is_a (type, G_TYPE_BOXED)) {
300 g_value_set_boxed (&value, arg.v_pointer);
302 PyErr_Format (PyExc_NotImplementedError,
303 "Setting properties of type '%s' is not implemented",
308 PyErr_Format (PyExc_NotImplementedError,
309 "Setting properties of type '%s' is not implemented",
315 case GI_TYPE_TAG_BOOLEAN:
316 g_value_set_boolean (&value, arg.v_boolean);
318 case GI_TYPE_TAG_INT8:
319 g_value_set_schar (&value, arg.v_int8);
321 case GI_TYPE_TAG_INT16:
322 case GI_TYPE_TAG_INT32:
323 if (G_VALUE_HOLDS_LONG (&value))
324 g_value_set_long (&value, arg.v_long);
326 g_value_set_int (&value, arg.v_int);
328 case GI_TYPE_TAG_INT64:
329 if (G_VALUE_HOLDS_LONG (&value))
330 g_value_set_long (&value, arg.v_long);
332 g_value_set_int64 (&value, arg.v_int64);
334 case GI_TYPE_TAG_UINT8:
335 g_value_set_uchar (&value, arg.v_uint8);
337 case GI_TYPE_TAG_UINT16:
338 case GI_TYPE_TAG_UINT32:
339 if (G_VALUE_HOLDS_ULONG (&value))
340 g_value_set_ulong (&value, arg.v_ulong);
342 g_value_set_uint (&value, arg.v_uint);
344 case GI_TYPE_TAG_UINT64:
345 if (G_VALUE_HOLDS_ULONG (&value))
346 g_value_set_ulong (&value, arg.v_ulong);
348 g_value_set_uint64 (&value, arg.v_uint64);
350 case GI_TYPE_TAG_FLOAT:
351 g_value_set_float (&value, arg.v_float);
353 case GI_TYPE_TAG_DOUBLE:
354 g_value_set_double (&value, arg.v_double);
356 case GI_TYPE_TAG_GTYPE:
357 g_value_set_gtype (&value, arg.v_size);
359 case GI_TYPE_TAG_UTF8:
360 case GI_TYPE_TAG_FILENAME:
361 g_value_set_string (&value, arg.v_string);
363 case GI_TYPE_TAG_GHASH:
364 g_value_set_boxed (&value, arg.v_pointer);
366 case GI_TYPE_TAG_GLIST:
367 g_value_set_pointer (&value, arg.v_pointer);
370 PyErr_Format (PyExc_NotImplementedError,
371 "Setting properties of type %s is not implemented",
372 g_type_tag_to_string (g_type_info_get_tag (type_info)));
376 g_object_set_property (instance->obj, attr_name, &value);
381 g_free (property_name);
382 if (property_info != NULL)
383 g_base_info_unref (property_info);
384 if (type_info != NULL)
385 g_base_info_unref (type_info);