static PyObject * _get_vfuncs (PyGIBaseInfo *self, GIInfoType info_type) { gssize n_infos; PyObject *infos; gssize i; switch (info_type) { case GI_INFO_TYPE_INTERFACE: n_infos = g_interface_info_get_n_vfuncs ( (GIInterfaceInfo *) self->info); break; case GI_INFO_TYPE_OBJECT: n_infos = g_object_info_get_n_vfuncs ( (GIObjectInfo *) self->info); break; default: g_assert_not_reached(); } infos = PyTuple_New (n_infos); if (infos == NULL) { return NULL; } for (i = 0; i < n_infos; i++) { GIBaseInfo *info; PyObject *py_info; switch (info_type) { case GI_INFO_TYPE_INTERFACE: info = (GIBaseInfo *) g_interface_info_get_vfunc ( (GIInterfaceInfo *) self->info, i); break; case GI_INFO_TYPE_OBJECT: info = (GIBaseInfo *) g_object_info_get_vfunc ( (GIObjectInfo *) self->info, i); break; default: g_assert_not_reached(); } g_assert (info != NULL); py_info = _pygi_info_new (info); g_base_info_unref (info); if (py_info == NULL) { Py_CLEAR (infos); break; } PyTuple_SET_ITEM (infos, i, py_info); } return infos; }
/** * g_function_info_get_vfunc: * @info: a #GIFunctionInfo * * Obtain the virtual function associated with this #GIFunctionInfo. * Only #GIFunctionInfo with the flag %GI_FUNCTION_WRAPS_VFUNC has * a virtual function set. For other cases, %NULL will be returned. * * Returns: (transfer full): the virtual function or %NULL if not set. * Free it by calling g_base_info_unref() when done. */ GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info) { GIRealInfo *rinfo; FunctionBlob *blob; GIInterfaceInfo *container; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); rinfo = (GIRealInfo *)info; blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; container = (GIInterfaceInfo *)rinfo->container; return g_interface_info_get_vfunc (container, blob->index); }
/** * g_signal_info_get_class_closure: * @info: a #GISignalInfo * * Obtain the class closure for this signal if one is set. The class * closure is a virtual function on the type that the signal belongs to. * If the signal lacks a closure %NULL will be returned. * * Returns: (transfer full): the class closure or %NULL */ GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; SignalBlob *blob; g_return_val_if_fail (info != NULL, 0); g_return_val_if_fail (GI_IS_SIGNAL_INFO (info), 0); blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->has_class_closure) return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure); return NULL; }
static VALUE rg_get_vfunc(VALUE self, VALUE rb_n_or_name) { GIInterfaceInfo *info; GIVFuncInfo *vfunc_info; info = SELF(self); if (RB_TYPE_P(rb_n_or_name, T_FIXNUM)) { gint n; n = NUM2INT(rb_n_or_name); vfunc_info = g_interface_info_get_vfunc(info, n); } else { const gchar *name; name = RVAL2CSTR(rb_n_or_name); vfunc_info = g_interface_info_find_vfunc(info, name); } return GI_BASE_INFO2RVAL_WITH_UNREF(vfunc_info); }
static void generic_interface_init (gpointer iface, gpointer data) { GIInterfaceInfo *info = data; GIStructInfo *struct_info; gint n, i; struct_info = g_interface_info_get_iface_struct (info); n = g_interface_info_get_n_vfuncs (info); for (i = 0; i < n; i++) { GIVFuncInfo *vfunc_info; const gchar *vfunc_name; GIFieldInfo *field_info; gint field_offset; GITypeInfo *field_type_info; gchar *perl_method_name; GPerlI11nPerlCallbackInfo *callback_info; vfunc_info = g_interface_info_get_vfunc (info, i); vfunc_name = g_base_info_get_name (vfunc_info); /* FIXME: g_vfunc_info_get_offset does not seem to work here. */ field_info = get_field_info (struct_info, vfunc_name); g_assert (field_info); field_offset = g_field_info_get_offset (field_info); field_type_info = g_field_info_get_type (field_info); perl_method_name = g_ascii_strup (vfunc_name, -1); callback_info = create_perl_callback_closure_for_named_sub ( field_type_info, perl_method_name); dwarn ("installing vfunc %s as %s at offset %d (vs. %d) inside %p\n", vfunc_name, perl_method_name, field_offset, g_vfunc_info_get_offset (vfunc_info), iface); G_STRUCT_MEMBER (gpointer, iface, field_offset) = callback_info->closure; g_base_info_unref (field_type_info); g_base_info_unref (field_info); g_base_info_unref (vfunc_info); } g_base_info_unref (struct_info); }
static void implement_interface_methods (gpointer iface, GType proxy_type) { GType exten_type = G_TYPE_FROM_INTERFACE (iface); guint i; GArray *impls; g_debug ("Implementing interface '%s' for proxy type '%s'", g_type_name (exten_type), g_type_name (proxy_type)); impls = g_type_get_qdata (exten_type, method_impl_quark ()); if (impls == NULL) { GIInterfaceInfo *iface_info; guint n_vfuncs; iface_info = g_irepository_find_by_gtype (NULL, exten_type); g_return_if_fail (iface_info != NULL); g_return_if_fail (g_base_info_get_type (iface_info) == GI_INFO_TYPE_INTERFACE); n_vfuncs = g_interface_info_get_n_vfuncs (iface_info); impls = g_array_new (FALSE, TRUE, sizeof (MethodImpl)); g_array_set_size (impls, n_vfuncs); for (i = 0; i < n_vfuncs; i++) { GIVFuncInfo *vfunc_info; vfunc_info = g_interface_info_get_vfunc (iface_info, i); create_native_closure (exten_type, iface_info, vfunc_info, &g_array_index (impls, MethodImpl, i)); g_base_info_unref (vfunc_info); } g_type_set_qdata (exten_type, method_impl_quark (), impls); g_base_info_unref (iface_info); } for (i = 0; i < impls->len; i++) { MethodImpl *impl = &g_array_index (impls, MethodImpl, i); gpointer *method_ptr; if (impl->closure == NULL) continue; method_ptr = G_STRUCT_MEMBER_P (iface, impl->struct_offset); *method_ptr = impl->closure; g_debug ("Implemented '%s.%s' at %d (%p) with %p", g_type_name (exten_type), impl->method_name, impl->struct_offset, method_ptr, impl->closure); } g_debug ("Implemented interface '%s' for '%s' proxy", g_type_name (exten_type), g_type_name (proxy_type)); }