static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback; GIArgInfo *arg_info; GIArgument *callback_argument; arg_info = &(metadata->arg_info); callback = find_callback_function(arg_info); if (!callback) { GITypeInfo type_info; GIBaseInfo *interface_info; VALUE rb_type_name; g_arg_info_load_type(arg_info, &type_info); interface_info = g_type_info_get_interface(&type_info); rb_type_name = CSTR2RVAL(g_base_info_get_name(interface_info)); g_base_info_unref(interface_info); rb_raise(rb_eNotImpError, "TODO: <%s>(%s) callback is not supported yet.", RVAL2CSTR(rb_type_name), g_base_info_get_name(arg_info)); } callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); callback_argument->v_pointer = callback; if (metadata->closure_in_arg_index != -1) { RBGICallbackData *callback_data; GIArgument *closure_argument; callback_data = ALLOC(RBGICallbackData); callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); closure_argument->v_pointer = callback_data; } if (metadata->destroy_in_arg_index != -1) { GIArgument *destroy_argument; destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); destroy_argument->v_pointer = destroy_notify; } }
static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback_function; GIArgInfo *arg_info; GIArgument *callback_argument; GIArgument *closure_argument = NULL; GIArgument *destroy_argument = NULL; RBGICallback *callback = NULL; arg_info = &(metadata->arg_info); callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); if (metadata->closure_in_arg_index != -1) { closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); } if (metadata->destroy_in_arg_index != -1) { destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); } if (!rb_block_given_p() && g_arg_info_may_be_null(arg_info)) { callback_argument->v_pointer = NULL; if (closure_argument) { closure_argument->v_pointer = NULL; } if (destroy_argument) { destroy_argument->v_pointer = NULL; } return; } callback_function = find_callback_function(arg_info); if (callback_function) { callback_argument->v_pointer = callback_function; } else { callback = RB_ZALLOC(RBGICallback); callback->type_info = g_arg_info_get_type(arg_info); callback->callback_info = g_type_info_get_interface(callback->type_info); callback->closure = g_callable_info_prepare_closure(callback->callback_info, &(callback->cif), ffi_closure_callback, callback); callback_argument->v_pointer = callback->closure; } if (closure_argument) { RBGICallbackData *callback_data; callback_data = ALLOC(RBGICallbackData); callback_data->callback = callback; callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument->v_pointer = callback_data; } if (destroy_argument) { destroy_argument->v_pointer = destroy_notify; } }