1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * pygi-closure.c: PyGI C Closure functions
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "pygi-closure.h"
21 #include "pygi-error.h"
22 #include "pygi-marshal-cleanup.h"
23 #include "pygi-invoke.h"
24 #include "pygi-ccallback.h"
25 #include "pygi-info.h"
27 extern PyObject *_PyGIDefaultArgPlaceholder;
29 typedef struct _PyGICallbackCache
31 PyGIArgCache arg_cache;
32 gssize user_data_index;
33 gssize destroy_notify_index;
35 GIInterfaceInfo *interface_info;
38 /* This maintains a list of closures which can be free'd whenever
39 as they have been called. We will free them on the next
40 library function call.
42 static GSList* async_free_list;
45 _pygi_closure_assign_pyobj_to_retval (gpointer retval,
47 PyGIArgCache *arg_cache)
52 switch (arg_cache->type_tag) {
53 case GI_TYPE_TAG_BOOLEAN:
54 *((ffi_sarg *) retval) = arg->v_boolean;
56 case GI_TYPE_TAG_INT8:
57 *((ffi_sarg *) retval) = arg->v_int8;
59 case GI_TYPE_TAG_UINT8:
60 *((ffi_arg *) retval) = arg->v_uint8;
62 case GI_TYPE_TAG_INT16:
63 *((ffi_sarg *) retval) = arg->v_int16;
65 case GI_TYPE_TAG_UINT16:
66 *((ffi_arg *) retval) = arg->v_uint16;
68 case GI_TYPE_TAG_INT32:
69 *((ffi_sarg *) retval) = arg->v_int32;
71 case GI_TYPE_TAG_UINT32:
72 *((ffi_arg *) retval) = arg->v_uint32;
74 case GI_TYPE_TAG_INT64:
75 *((ffi_sarg *) retval) = arg->v_int64;
77 case GI_TYPE_TAG_UINT64:
78 *((ffi_arg *) retval) = arg->v_uint64;
80 case GI_TYPE_TAG_FLOAT:
81 *((gfloat *) retval) = arg->v_float;
83 case GI_TYPE_TAG_DOUBLE:
84 *((gdouble *) retval) = arg->v_double;
86 case GI_TYPE_TAG_GTYPE:
87 *((ffi_arg *) retval) = arg->v_ulong;
89 case GI_TYPE_TAG_UNICHAR:
90 *((ffi_arg *) retval) = arg->v_uint32;
92 case GI_TYPE_TAG_INTERFACE:
94 GIBaseInfo *interface_info;
96 interface_info = ((PyGIInterfaceCache *) arg_cache)->interface_info;
98 switch (g_base_info_get_type (interface_info)) {
99 case GI_INFO_TYPE_ENUM:
100 *(ffi_sarg *) retval = arg->v_int;
102 case GI_INFO_TYPE_FLAGS:
103 *(ffi_arg *) retval = arg->v_uint;
106 *(ffi_arg *) retval = (ffi_arg) arg->v_pointer;
113 *(ffi_arg *) retval = (ffi_arg) arg->v_pointer;
119 _pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg,
121 PyGIArgCache *arg_cache)
126 switch (arg_cache->type_tag) {
127 case GI_TYPE_TAG_BOOLEAN:
128 *((gboolean *) out_arg) = arg->v_boolean;
130 case GI_TYPE_TAG_INT8:
131 *((gint8 *) out_arg) = arg->v_int8;
133 case GI_TYPE_TAG_UINT8:
134 *((guint8 *) out_arg) = arg->v_uint8;
136 case GI_TYPE_TAG_INT16:
137 *((gint16 *) out_arg) = arg->v_int16;
139 case GI_TYPE_TAG_UINT16:
140 *((guint16 *) out_arg) = arg->v_uint16;
142 case GI_TYPE_TAG_INT32:
143 *((gint32 *) out_arg) = arg->v_int32;
145 case GI_TYPE_TAG_UINT32:
146 *((guint32 *) out_arg) = arg->v_uint32;
148 case GI_TYPE_TAG_INT64:
149 *((gint64 *) out_arg) = arg->v_int64;
151 case GI_TYPE_TAG_UINT64:
152 *((glong *) out_arg) = arg->v_uint64;
154 case GI_TYPE_TAG_FLOAT:
155 *((gfloat *) out_arg) = arg->v_float;
157 case GI_TYPE_TAG_DOUBLE:
158 *((gdouble *) out_arg) = arg->v_double;
160 case GI_TYPE_TAG_GTYPE:
161 *((gulong *) out_arg) = arg->v_ulong;
163 case GI_TYPE_TAG_UNICHAR:
164 *((guint32 *) out_arg) = arg->v_uint32;
166 case GI_TYPE_TAG_INTERFACE:
168 GIBaseInfo *interface_info;
170 interface_info = ((PyGIInterfaceCache *) arg_cache)->interface_info;
172 switch (g_base_info_get_type (interface_info)) {
173 case GI_INFO_TYPE_ENUM:
174 *(gint *) out_arg = arg->v_int;
176 case GI_INFO_TYPE_FLAGS:
177 *(guint *) out_arg = arg->v_uint;
179 case GI_INFO_TYPE_STRUCT:
180 if (!arg_cache->is_pointer) {
181 if (arg->v_pointer != NULL) {
182 gsize item_size = _pygi_g_type_info_size (arg_cache->type_info);
183 memcpy (out_arg, arg->v_pointer, item_size);
188 /* Fall through if pointer */
190 *((gpointer *) out_arg) = arg->v_pointer;
197 *((gpointer *) out_arg) = arg->v_pointer;
203 _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
204 PyGICallableCache *cache,
209 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
210 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
212 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
213 state[i].arg_value.v_pointer = * (gpointer *) args[i];
215 if (state[i].arg_value.v_pointer == NULL)
218 state[i].arg_pointer.v_pointer = state[i].arg_value.v_pointer;
219 state[i].arg_value = *(GIArgument *) state[i].arg_value.v_pointer;
223 switch (arg_cache->type_tag) {
224 case GI_TYPE_TAG_BOOLEAN:
225 state[i].arg_value.v_boolean = * (gboolean *) args[i];
227 case GI_TYPE_TAG_INT8:
228 state[i].arg_value.v_int8 = * (gint8 *) args[i];
230 case GI_TYPE_TAG_UINT8:
231 state[i].arg_value.v_uint8 = * (guint8 *) args[i];
233 case GI_TYPE_TAG_INT16:
234 state[i].arg_value.v_int16 = * (gint16 *) args[i];
236 case GI_TYPE_TAG_UINT16:
237 state[i].arg_value.v_uint16 = * (guint16 *) args[i];
239 case GI_TYPE_TAG_INT32:
240 state[i].arg_value.v_int32 = * (gint32 *) args[i];
242 case GI_TYPE_TAG_UINT32:
243 state[i].arg_value.v_uint32 = * (guint32 *) args[i];
245 case GI_TYPE_TAG_INT64:
246 state[i].arg_value.v_int64 = * (glong *) args[i];
248 case GI_TYPE_TAG_UINT64:
249 state[i].arg_value.v_uint64 = * (glong *) args[i];
251 case GI_TYPE_TAG_FLOAT:
252 state[i].arg_value.v_float = * (gfloat *) args[i];
254 case GI_TYPE_TAG_DOUBLE:
255 state[i].arg_value.v_double = * (gdouble *) args[i];
257 case GI_TYPE_TAG_UTF8:
258 state[i].arg_value.v_string = * (gchar **) args[i];
260 case GI_TYPE_TAG_INTERFACE:
262 GIBaseInfo *interface;
263 GIInfoType interface_type;
265 interface = ((PyGIInterfaceCache *) arg_cache)->interface_info;
266 interface_type = g_base_info_get_type (interface);
268 if (interface_type == GI_INFO_TYPE_ENUM) {
269 state[i].arg_value.v_int = * (gint *) args[i];
270 } else if (interface_type == GI_INFO_TYPE_FLAGS) {
271 state[i].arg_value.v_uint = * (guint *) args[i];
273 state[i].arg_value.v_pointer = * (gpointer *) args[i];
277 case GI_TYPE_TAG_ERROR:
278 case GI_TYPE_TAG_GHASH:
279 case GI_TYPE_TAG_GLIST:
280 case GI_TYPE_TAG_GSLIST:
281 case GI_TYPE_TAG_ARRAY:
282 case GI_TYPE_TAG_VOID:
283 state[i].arg_value.v_pointer = * (gpointer *) args[i];
286 g_warning ("Unhandled type tag %s",
287 g_type_tag_to_string (arg_cache->type_tag));
288 state[i].arg_value.v_pointer = 0;
293 gssize error_index = _pygi_callable_cache_args_len (cache);
295 state[error_index].arg_value.v_pointer = * (gpointer *) args[error_index];
300 _invoke_state_init_from_cache (PyGIInvokeState *state,
301 PyGIClosureCache *closure_cache,
304 PyGICallableCache *cache = (PyGICallableCache *) closure_cache;
306 state->n_args = _pygi_callable_cache_args_len (cache);
307 state->n_py_in_args = state->n_args;
309 /* Increment after setting the number of Python input args */
314 state->py_in_args = PyTuple_New (state->n_py_in_args);
315 if (state->py_in_args == NULL) {
323 if (!_pygi_invoke_arg_state_init (state)) {
327 state->ffi_args = NULL;
329 _pygi_closure_convert_ffi_arguments (state->args, cache, args);
334 _invoke_state_clear (PyGIInvokeState *state)
336 _pygi_invoke_arg_state_free (state);
337 Py_XDECREF (state->py_in_args);
341 _pygi_closure_convert_arguments (PyGIInvokeState *state,
342 PyGIClosureCache *closure_cache)
344 PyGICallableCache *cache = (PyGICallableCache *) closure_cache;
345 gssize n_in_args = 0;
348 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
349 PyGIArgCache *arg_cache;
351 arg_cache = g_ptr_array_index (cache->args_cache, i);
353 if (arg_cache->direction & PYGI_DIRECTION_TO_PYTHON) {
356 if (cache->user_data_index == i) {
357 if (state->user_data == NULL) {
358 /* user_data can be NULL for connect functions which don't accept
359 * user_data or as the default for user_data in the middle of function
365 /* Extend the callbacks args with user_data as variable args. */
366 gssize j, user_data_len;
367 PyObject *py_user_data = state->user_data;
369 if (!PyTuple_Check (py_user_data)) {
370 PyErr_SetString (PyExc_TypeError, "expected tuple for callback user_data");
374 user_data_len = PyTuple_Size (py_user_data);
375 _PyTuple_Resize (&state->py_in_args,
376 state->n_py_in_args + user_data_len - 1);
378 for (j = 0; j < user_data_len; j++, n_in_args++) {
379 value = PyTuple_GetItem (py_user_data, j);
381 PyTuple_SET_ITEM (state->py_in_args, n_in_args, value);
383 /* We can assume user_data args are never going to be inout,
384 * so just continue here.
388 } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT) {
391 value = arg_cache->to_py_marshaller (state,
394 &state->args[i].arg_value);
397 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
404 PyTuple_SET_ITEM (state->py_in_args, n_in_args, value);
409 if (_PyTuple_Resize (&state->py_in_args, n_in_args) == -1)
416 _pygi_closure_set_out_arguments (PyGIInvokeState *state,
417 PyGICallableCache *cache,
422 gssize i_py_retval = 0;
425 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
426 PyObject *item = py_retval;
428 if (PyTuple_Check (py_retval)) {
429 item = PyTuple_GET_ITEM (py_retval, 0);
432 success = cache->return_cache->from_py_marshaller (state,
437 &state->args[0].arg_cleanup_data);
440 pygi_marshal_cleanup_args_return_fail (state,
445 _pygi_closure_assign_pyobj_to_retval (resp, &state->return_arg,
446 cache->return_cache);
450 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
451 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
453 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
454 PyObject *item = py_retval;
456 if (arg_cache->type_tag == GI_TYPE_TAG_ERROR) {
457 * (GError **) state->args[i].arg_pointer.v_pointer = NULL;
461 if (PyTuple_Check (py_retval)) {
462 item = PyTuple_GET_ITEM (py_retval, i_py_retval);
463 } else if (i_py_retval != 0) {
464 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
470 success = arg_cache->from_py_marshaller (state,
474 &state->args[i].arg_value,
475 &state->args[i_py_retval].arg_cleanup_data);
478 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
484 _pygi_closure_assign_pyobj_to_out_argument (state->args[i].arg_pointer.v_pointer,
485 &state->args[i].arg_value, arg_cache);
495 _pygi_closure_clear_retvals (PyGIInvokeState *state,
496 PyGICallableCache *cache,
500 GIArgument arg = { 0, };
502 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
503 _pygi_closure_assign_pyobj_to_retval (resp, &arg,
504 cache->return_cache);
507 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
508 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
510 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
511 _pygi_closure_assign_pyobj_to_out_argument (state->args[i].arg_pointer.v_pointer,
517 gssize error_index = state->n_args - 1;
518 GError **error = (GError **) state->args[error_index].arg_value.v_pointer;
521 pygi_gerror_exception_check (error);
527 _pygi_invoke_closure_clear_py_data(PyGICClosure *invoke_closure)
529 PyGILState_STATE state = PyGILState_Ensure();
531 Py_CLEAR (invoke_closure->function);
532 Py_CLEAR (invoke_closure->user_data);
534 PyGILState_Release (state);
538 _pygi_closure_handle (ffi_cif *cif,
543 PyGILState_STATE py_state;
544 PyGICClosure *closure = data;
547 PyGIInvokeState state = { 0, };
549 /* Ignore closures when Python is not initialized. This can happen in cases
550 * where calling Python implemented vfuncs can happen at shutdown time.
551 * See: https://bugzilla.gnome.org/show_bug.cgi?id=722562 */
552 if (!Py_IsInitialized()) {
556 /* Lock the GIL as we are coming into this code without the lock and we
557 may be executing python code */
558 py_state = PyGILState_Ensure ();
560 if (closure->cache == NULL) {
561 closure->cache = pygi_closure_cache_new ((GICallableInfo *) closure->info);
563 if (closure->cache == NULL)
567 state.user_data = closure->user_data;
569 _invoke_state_init_from_cache (&state, closure->cache, args);
571 if (!_pygi_closure_convert_arguments (&state, closure->cache)) {
572 _pygi_closure_clear_retvals (&state, closure->cache, result);
576 retval = PyObject_CallObject ( (PyObject *) closure->function, state.py_in_args);
578 if (retval == NULL) {
579 _pygi_closure_clear_retvals (&state, closure->cache, result);
583 pygi_marshal_cleanup_args_to_py_marshal_success (&state, closure->cache);
584 success = _pygi_closure_set_out_arguments (&state, closure->cache, retval, result);
587 pygi_marshal_cleanup_args_from_py_marshal_success (&state, closure->cache);
588 _pygi_closure_clear_retvals (&state, closure->cache, result);
595 if (PyErr_Occurred ())
598 /* Now that the closure has finished we can make a decision about how
599 to free it. Scope call gets free'd at the end of wrap_g_function_info_invoke.
600 Scope notified will be freed when the notify is called.
601 Scope async closures free only their python data now and the closure later
602 during the next creation of a closure. This minimizes potential ref leaks
603 at least in regards to the python objects.
604 (you can't free the closure you are currently using!)
606 switch (closure->scope) {
607 case GI_SCOPE_TYPE_CALL:
608 case GI_SCOPE_TYPE_NOTIFIED:
610 case GI_SCOPE_TYPE_ASYNC:
611 /* Append this PyGICClosure to a list of closure that we will free
612 after we're done with this function invokation */
613 _pygi_invoke_closure_clear_py_data(closure);
614 async_free_list = g_slist_prepend (async_free_list, closure);
617 g_error ("Invalid scope reached inside %s. Possibly a bad annotation?",
618 g_base_info_get_name (closure->info));
621 _invoke_state_clear (&state);
622 PyGILState_Release (py_state);
625 void _pygi_invoke_closure_free (gpointer data)
627 PyGICClosure* invoke_closure = (PyGICClosure *) data;
629 g_callable_info_free_closure (invoke_closure->info,
630 invoke_closure->closure);
632 if (invoke_closure->info)
633 g_base_info_unref ( (GIBaseInfo*) invoke_closure->info);
635 if (invoke_closure->cache != NULL)
636 pygi_callable_cache_free ((PyGICallableCache *) invoke_closure->cache);
638 _pygi_invoke_closure_clear_py_data(invoke_closure);
640 g_slice_free (PyGICClosure, invoke_closure);
645 _pygi_make_native_closure (GICallableInfo* info,
647 PyObject *py_function,
648 gpointer py_user_data)
650 PyGICClosure *closure;
651 ffi_closure *fficlosure;
653 /* Begin by cleaning up old async functions */
654 g_slist_free_full (async_free_list, (GDestroyNotify) _pygi_invoke_closure_free);
655 async_free_list = NULL;
657 /* Build the closure itself */
658 closure = g_slice_new0 (PyGICClosure);
659 closure->info = (GICallableInfo *) g_base_info_ref ( (GIBaseInfo *) info);
660 closure->function = py_function;
661 closure->user_data = py_user_data;
663 Py_INCREF (py_function);
664 Py_XINCREF (closure->user_data);
667 g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle,
669 closure->closure = fficlosure;
671 /* Give the closure the information it needs to determine when
672 to free itself later */
673 closure->scope = scope;
678 /* _pygi_destroy_notify_dummy:
680 * Dummy method used in the occasion when a method has a GDestroyNotify
681 * argument without user data.
684 _pygi_destroy_notify_dummy (gpointer data) {
688 _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state,
689 PyGICallableCache *callable_cache,
690 PyGIArgCache *arg_cache,
693 gpointer *cleanup_data)
695 GICallableInfo *callable_info;
696 PyGICClosure *closure;
697 PyGIArgCache *user_data_cache = NULL;
698 PyGIArgCache *destroy_cache = NULL;
699 PyGICallbackCache *callback_cache;
700 PyObject *py_user_data = NULL;
702 callback_cache = (PyGICallbackCache *)arg_cache;
704 if (callback_cache->user_data_index > 0) {
705 user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index);
706 if (user_data_cache->py_arg_index < state->n_py_in_args) {
707 /* py_user_data is a borrowed reference. */
708 py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index);
711 /* NULL out user_data if it was not supplied and the default arg placeholder
714 if (py_user_data == _PyGIDefaultArgPlaceholder) {
716 } else if (callable_cache->user_data_varargs_index < 0) {
717 /* For non-variable length user data, place the user data in a
718 * single item tuple which is concatenated to the callbacks arguments.
719 * This allows callback input arg marshaling to always expect a
720 * tuple for user data. Note the
722 py_user_data = Py_BuildValue("(O)", py_user_data, NULL);
724 /* increment the ref borrowed from PyTuple_GetItem above */
725 Py_INCREF (py_user_data);
730 if (py_arg == Py_None) {
734 if (!PyCallable_Check (py_arg)) {
735 PyErr_Format (PyExc_TypeError,
736 "Callback needs to be a function or method not %s",
737 py_arg->ob_type->tp_name);
742 callable_info = (GICallableInfo *)callback_cache->interface_info;
744 closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data);
745 arg->v_pointer = closure->closure;
747 /* always decref the user data as _pygi_make_native_closure adds its own ref */
748 Py_XDECREF (py_user_data);
750 /* The PyGICClosure instance is used as user data passed into the C function.
751 * The return trip to python will marshal this back and pull the python user data out.
753 if (user_data_cache != NULL) {
754 state->args[user_data_cache->c_arg_index].arg_value.v_pointer = closure;
757 /* Setup a GDestroyNotify callback if this method supports it along with
758 * a user data field. The user data field is a requirement in order
759 * free resources and ref counts associated with this arguments closure.
760 * In case a user data field is not available, show a warning giving
761 * explicit information and setup a dummy notification to avoid a crash
762 * later on in _pygi_destroy_notify_callback_closure.
764 if (callback_cache->destroy_notify_index > 0) {
765 destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index);
769 if (user_data_cache != NULL) {
770 state->args[destroy_cache->c_arg_index].arg_value.v_pointer = _pygi_invoke_closure_free;
772 char *full_name = pygi_callable_cache_get_full_name (callable_cache);
773 gchar *msg = g_strdup_printf("Callables passed to %s will leak references because "
774 "the method does not support a user_data argument. "
775 "See: https://bugzilla.gnome.org/show_bug.cgi?id=685598",
778 if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) {
780 _pygi_invoke_closure_free(closure);
784 state->args[destroy_cache->c_arg_index].arg_value.v_pointer = _pygi_destroy_notify_dummy;
788 /* Use the PyGIClosure as data passed to cleanup for GI_SCOPE_TYPE_CALL. */
789 *cleanup_data = closure;
795 _pygi_marshal_to_py_interface_callback (PyGIInvokeState *state,
796 PyGICallableCache *callable_cache,
797 PyGIArgCache *arg_cache,
800 PyGICallbackCache *callback_cache = (PyGICallbackCache *) arg_cache;
801 gssize user_data_index;
802 gssize destroy_notify_index;
803 gpointer user_data = NULL;
804 GDestroyNotify destroy_notify = NULL;
806 user_data_index = callback_cache->user_data_index;
807 destroy_notify_index = callback_cache->destroy_notify_index;
809 if (user_data_index != -1)
810 user_data = state->args[user_data_index].arg_value.v_pointer;
812 if (destroy_notify_index != -1)
813 destroy_notify = state->args[destroy_notify_index].arg_value.v_pointer;
815 return _pygi_ccallback_new (arg->v_pointer,
817 callback_cache->scope,
818 (GIFunctionInfo *) callback_cache->interface_info,
823 _callback_cache_free_func (PyGICallbackCache *cache)
826 if (cache->interface_info != NULL)
827 g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
829 g_slice_free (PyGICallbackCache, cache);
834 _pygi_marshal_cleanup_from_py_interface_callback (PyGIInvokeState *state,
835 PyGIArgCache *arg_cache,
838 gboolean was_processed)
840 PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
842 if (was_processed && callback_cache->scope == GI_SCOPE_TYPE_CALL) {
843 _pygi_invoke_closure_free (data);
848 pygi_arg_callback_setup_from_info (PyGICallbackCache *arg_cache,
849 GITypeInfo *type_info,
850 GIArgInfo *arg_info, /* may be null */
852 PyGIDirection direction,
853 GIInterfaceInfo *iface_info,
854 PyGICallableCache *callable_cache)
856 PyGIArgCache *cache = (PyGIArgCache *)arg_cache;
857 gssize child_offset = 0;
859 if (!pygi_arg_base_setup ((PyGIArgCache *)arg_cache,
867 if (callable_cache != NULL)
868 child_offset = callable_cache->args_offset;
870 ( (PyGIArgCache *)arg_cache)->destroy_notify = (GDestroyNotify)_callback_cache_free_func;
872 arg_cache->user_data_index = g_arg_info_get_closure (arg_info);
873 if (arg_cache->user_data_index != -1)
874 arg_cache->user_data_index += child_offset;
876 arg_cache->destroy_notify_index = g_arg_info_get_destroy (arg_info);
877 if (arg_cache->destroy_notify_index != -1)
878 arg_cache->destroy_notify_index += child_offset;
880 if (arg_cache->user_data_index >= 0) {
881 PyGIArgCache *user_data_arg_cache = pygi_arg_cache_alloc ();
882 user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
883 user_data_arg_cache->direction = direction;
884 user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */
885 _pygi_callable_cache_set_arg (callable_cache, arg_cache->user_data_index,
886 user_data_arg_cache);
889 if (arg_cache->destroy_notify_index >= 0) {
890 PyGIArgCache *destroy_arg_cache = pygi_arg_cache_alloc ();
891 destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
892 destroy_arg_cache->direction = direction;
893 _pygi_callable_cache_set_arg (callable_cache, arg_cache->destroy_notify_index,
897 arg_cache->scope = g_arg_info_get_scope (arg_info);
898 g_base_info_ref( (GIBaseInfo *)iface_info);
899 arg_cache->interface_info = iface_info;
901 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
902 cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback;
903 cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback;
906 if (direction & PYGI_DIRECTION_TO_PYTHON) {
907 cache->to_py_marshaller = _pygi_marshal_to_py_interface_callback;
914 pygi_arg_callback_new_from_info (GITypeInfo *type_info,
915 GIArgInfo *arg_info, /* may be null */
917 PyGIDirection direction,
918 GIInterfaceInfo *iface_info,
919 PyGICallableCache *callable_cache)
921 gboolean res = FALSE;
922 PyGICallbackCache *callback_cache;
924 callback_cache = g_slice_new0 (PyGICallbackCache);
925 if (callback_cache == NULL)
928 res = pygi_arg_callback_setup_from_info (callback_cache,
936 return (PyGIArgCache *)callback_cache;
938 pygi_arg_cache_free ((PyGIArgCache *)callback_cache);