/** * peas_extension_set_new_valist: (skip) * @engine: A #PeasEngine, or %NULL. * @exten_type: the extension #GType. * @first_property: the name of the first property. * @var_args: the value of the first property, followed optionally by more * name/value pairs, followed by %NULL. * * Create a new #PeasExtensionSet for the @exten_type extension type. * * If @engine is %NULL, then the default engine will be used. * * See peas_extension_set_new() for more information. * * Returns: a new instance of #PeasExtensionSet. */ PeasExtensionSet * peas_extension_set_new_valist (PeasEngine *engine, GType exten_type, const gchar *first_property, va_list var_args) { gpointer type_struct; GParameter *parameters; guint n_parameters; PeasExtensionSet *set; g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL); g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL); type_struct = _g_type_struct_ref (exten_type); if (!_valist_to_parameter_list (exten_type, type_struct, first_property, var_args, ¶meters, &n_parameters)) { /* Already warned */ _g_type_struct_unref (exten_type, type_struct); return NULL; } set = peas_extension_set_newv (engine, exten_type, n_parameters, parameters); while (n_parameters-- > 0) g_value_unset (¶meters[n_parameters].value); g_free (parameters); _g_type_struct_unref (exten_type, type_struct); return set; }
static VALUE interface_s_property(VALUE self, VALUE property_name) { gpointer ginterface; const char* name; GParamSpec* prop; VALUE result; GType gtype = CLASS2GTYPE(self); if (SYMBOL_P(property_name)) name = rb_id2name(SYM2ID(property_name)); else name = StringValuePtr(property_name); if (!G_TYPE_IS_INTERFACE(gtype)) rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self)); /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */ if (gtype == G_TYPE_INTERFACE) { rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")), "No such property: %s", name); } ginterface = g_type_default_interface_ref(gtype); prop = g_object_interface_find_property(ginterface, name); if (!prop){ g_type_default_interface_unref(ginterface); rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")), "No such property: %s", name); } result = GOBJ2RVAL(prop); g_type_default_interface_unref(ginterface); return result; }
static VALUE interface_s_properties(int argc, VALUE* argv, VALUE self) { guint n_properties; GParamSpec** props; VALUE inherited_too; VALUE ary = rb_ary_new(); guint i; gpointer ginterface; GType gtype = CLASS2GTYPE(self); if (rb_scan_args(argc, argv, "01", &inherited_too) == 0) inherited_too = Qtrue; if (!G_TYPE_IS_INTERFACE(gtype)) rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self)); /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */ if (gtype == G_TYPE_INTERFACE) return ary; ginterface = g_type_default_interface_ref(gtype); props = g_object_interface_list_properties(ginterface, &n_properties); for (i = 0; i < n_properties; i++){ if (RVAL2CBOOL(inherited_too) || GTYPE2CLASS(props[i]->owner_type) == self) rb_ary_push(ary, rb_str_new2(props[i]->name)); } g_free(props); g_type_default_interface_unref(ginterface); return ary; }
static void o(GType type) { if (!G_TYPE_IS_INTERFACE (type)) { foo = g_type_class_ref (type); } }
USER_OBJECT_ toRPointer(void *val, const char *typeName) { USER_OBJECT_ ans, klass = NULL; GType type = 0; if(val == NULL) return(NULL_USER_OBJECT); PROTECT(ans = R_MakeExternalPtr(val, Rf_install(typeName), NULL_USER_OBJECT)); if (typeName) type = g_type_from_name(typeName); if(type) { if (G_TYPE_IS_INSTANTIATABLE(type) || G_TYPE_IS_INTERFACE(type)) type = G_TYPE_FROM_INSTANCE(val); if (G_TYPE_IS_DERIVED(type)) { setAttrib(ans, install("interfaces"), R_internal_getInterfaces(type)); PROTECT(klass = R_internal_getGTypeHierarchy(type)); } } if (!klass && typeName) { PROTECT(klass = asRString(typeName)); } if(klass) { SET_CLASS(ans, klass); UNPROTECT(1); } UNPROTECT(1); return(ans); }
USER_OBJECT_ toRPointerWithFinalizer(gconstpointer val, const gchar *typeName, RPointerFinalizer finalizer) { USER_OBJECT_ ans; USER_OBJECT_ r_finalizer = NULL_USER_OBJECT; USER_OBJECT_ klass = NULL, rgtk_class; int i = 0; GType type = 0; if(!val) return(NULL_USER_OBJECT); if (finalizer) { PROTECT(r_finalizer = R_MakeExternalPtr(finalizer, NULL_USER_OBJECT, NULL_USER_OBJECT)); } PROTECT(ans = R_MakeExternalPtr((gpointer)val, r_finalizer, NULL_USER_OBJECT)); if (finalizer) { R_RegisterCFinalizer(ans, RGtk_finalizer); } if (typeName) type = g_type_from_name(typeName); if(type) { if (G_TYPE_IS_INSTANTIATABLE(type) || G_TYPE_IS_INTERFACE(type)) type = G_TYPE_FROM_INSTANCE(val); if (G_TYPE_IS_DERIVED(type)) { setAttrib(ans, install("interfaces"), R_internal_getInterfaces(type)); PROTECT(klass = R_internal_getGTypeAncestors(type)); } } if (!klass && typeName) { PROTECT(klass = asRString(typeName)); } if (klass) { /* so much trouble just to add "RGtkObject" onto the end */ PROTECT(rgtk_class = NEW_CHARACTER(GET_LENGTH(klass)+1)); for (i = 0; i < GET_LENGTH(klass); i++) SET_STRING_ELT(rgtk_class, i, STRING_ELT(klass, i)); } else { PROTECT(rgtk_class = NEW_CHARACTER(1)); } SET_STRING_ELT(rgtk_class, i, COPY_TO_USER_STRING("RGtkObject")); SET_CLASS(ans, rgtk_class); if (g_type_is_a(type, S_TYPE_G_OBJECT)) { USER_OBJECT_ public_sym = install(".public"); setAttrib(ans, public_sym, findVar(public_sym, S_GOBJECT_GET_ENV(val))); } if (klass) UNPROTECT(1); if (finalizer) UNPROTECT(1); UNPROTECT(2); return(ans); }
gpointer _g_type_struct_ref (GType the_type) { if (G_TYPE_IS_INTERFACE (the_type)) return g_type_default_interface_ref (the_type); else if (G_TYPE_IS_OBJECT (the_type)) return g_type_class_ref (the_type); else g_return_val_if_reached (NULL); }
void _g_type_struct_unref (GType the_type, gpointer type_struct) { if (G_TYPE_IS_INTERFACE (the_type)) g_type_default_interface_unref (type_struct); else if (G_TYPE_IS_OBJECT (the_type)) g_type_class_unref (type_struct); else g_return_if_reached (); }
/** * thunarx_provider_plugin_add_interface: * @plugin : a #ThunarxProviderPlugin. * @instance_type : type to which to add the interface. * @interface_type : interface type to add. * @interface_info : type information structure. * * Registers an additional interface for a type, whose interface lives in the given type @plugin. * If the interface was already registered for the type in this @plugin, nothing will be done. * * As long as any instances of the type exist, the type @plugin will not be unloaded. **/ void thunarx_provider_plugin_add_interface (ThunarxProviderPlugin *plugin, GType instance_type, GType interface_type, const GInterfaceInfo *interface_info) { g_return_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin)); g_return_if_fail (G_TYPE_IS_INTERFACE (interface_type)); g_return_if_fail (interface_info != NULL); (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->add_interface) (plugin, instance_type, interface_type, interface_info); }
static GParamSpec * _g_type_struct_find_property (GType the_type, gpointer type_struct, const gchar *property_name) { if (G_TYPE_IS_INTERFACE (the_type)) return g_object_interface_find_property (type_struct, property_name); else if (G_TYPE_IS_OBJECT (the_type)) return g_object_class_find_property (type_struct, property_name); else g_return_val_if_reached (NULL); }
gboolean peas_gi_method_call (GObject *instance, GICallableInfo *func_info, GType iface_type, const gchar *method_name, GIArgument *args, GIArgument *return_value) { gint n_args; guint n_in_args, n_out_args; GIArgument *in_args, *out_args; gboolean ret = TRUE; GError *error = NULL; g_return_val_if_fail (G_IS_OBJECT (instance), FALSE); g_return_val_if_fail (func_info != NULL, FALSE); g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE); g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (instance, iface_type), FALSE); g_return_val_if_fail (method_name != NULL, FALSE); n_args = g_callable_info_get_n_args (func_info); g_return_val_if_fail (n_args >= 0, FALSE); n_in_args = 0; n_out_args = 0; in_args = g_newa (GIArgument, n_args + 1); out_args = g_newa (GIArgument, n_args); peas_gi_split_in_and_out_arguments (func_info, args, in_args+1, &n_in_args, out_args, &n_out_args); /* Set the object as the first argument for the method. */ in_args[0].v_pointer = instance; n_in_args++; g_debug ("Calling '%s.%s' on '%p'", g_type_name (iface_type), method_name, instance); ret = g_function_info_invoke (func_info, in_args, n_in_args, out_args, n_out_args, return_value, &error); if (!ret) { g_warning ("Error while calling '%s.%s': %s", g_type_name (iface_type), method_name, error->message); g_error_free (error); } return ret; }
static gboolean param_objects_validate (GParamSpec *pspec, GValue *value) { GladeParamSpecObjects *ospec = GLADE_PARAM_SPEC_OBJECTS (pspec); GList *objects, *list, *toremove = NULL; GObject *object; objects = value->data[0].v_pointer; for (list = objects; list; list = list->next) { object = list->data; if (G_TYPE_IS_INTERFACE (ospec->type) && glade_util_class_implements_interface (G_OBJECT_TYPE (object), ospec->type) == FALSE) toremove = g_list_prepend (toremove, object); else if (G_TYPE_IS_INTERFACE (ospec->type) == FALSE && g_type_is_a (G_OBJECT_TYPE (object), ospec->type) == FALSE) toremove = g_list_prepend (toremove, object); } for (list = toremove; list; list = list->next) { object = list->data; objects = g_list_remove (objects, object); } if (toremove) g_list_free (toremove); value->data[0].v_pointer = objects; return toremove != NULL; }
/* Help function to dump a GType */ void my_dump_type(GType type_id) { printf("Type id: %d\n", type_id); printf("Type name: %s\n", g_type_name(type_id)); printf("Is fundamental? %s\n", G_TYPE_IS_FUNDAMENTAL(type_id) ? "yes" : "no"); printf("Is derived? %s\n", G_TYPE_IS_DERIVED(type_id) ? "yes" : "no"); printf("Is interface? %s\n", G_TYPE_IS_INTERFACE(type_id) ? "yes" : "no"); printf("Is classed? %s\n", G_TYPE_IS_CLASSED(type_id) ? "yes" : "no"); printf("Is instantiatable? %s\n", G_TYPE_IS_INSTANTIATABLE(type_id) ? "yes" : "no"); printf("Is derivable? %s\n", G_TYPE_IS_DERIVABLE(type_id) ? "yes" : "no"); printf("Is deep derivable? %s\n", G_TYPE_IS_DEEP_DERIVABLE(type_id) ? "yes" : "no"); printf("Is abstract? %s\n", G_TYPE_IS_ABSTRACT(type_id) ? "yes" : "no"); printf("Is value abstract? %s\n", G_TYPE_IS_VALUE_ABSTRACT(type_id) ? "yes" : "no"); printf("Is value type: %s\n", G_TYPE_IS_VALUE_TYPE(type_id) ? "yes" : "no"); printf("Has value table: %s\n", G_TYPE_HAS_VALUE_TABLE(type_id) ? "yes" : "no"); }
static GVariant * serialize_pspec(GvsSerializer *self, GParamSpec *pspec, const GValue *value) { GvsPropertySerializeFunc func = NULL; GVariant *variant = NULL; GType type = pspec->value_type; /* Try to find the right serialization function */ func = g_param_spec_get_qdata(pspec, gvs_property_serialize_func_quark()); if (func == NULL) { if (G_TYPE_IS_FUNDAMENTAL(type)) { func = serialize_fundamental; } else if (G_TYPE_IS_ENUM(type)) { func = serialize_enum; } else if (G_TYPE_IS_FLAGS(type)) { func = serialize_flags; } else if (G_TYPE_IS_OBJECT(type) || G_TYPE_IS_INTERFACE (type)) { func = serialize_object_property; } else if (g_type_is_a(type, G_TYPE_BOXED)) { func = serialize_boxed_property; } } if (func) { variant = func(self, value, NULL); } else { g_warning("Could not serialize property %s of type %s\n" "Use gvs_register_property_serialize_func() in your class_init function\n", pspec->name, g_type_name(pspec->value_type)); } return variant; }
/** * peas_extension_set_newv: * @engine: (allow-none): A #PeasEngine, or %NULL. * @exten_type: the extension #GType. * @n_parameters: the length of the @parameters array. * @parameters: (array length=n_parameters): an array of #GParameter. * * Create a new #PeasExtensionSet for the @exten_type extension type. * * If @engine is %NULL, then the default engine will be used. * * See peas_extension_set_new() for more information. * * Returns: (transfer full): a new instance of #PeasExtensionSet. * * Rename to: peas_extension_set_new */ PeasExtensionSet * peas_extension_set_newv (PeasEngine *engine, GType exten_type, guint n_parameters, GParameter *parameters) { PeasParameterArray construct_properties = { n_parameters, parameters }; g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL); g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL); return PEAS_EXTENSION_SET (g_object_new (PEAS_TYPE_EXTENSION_SET, "engine", engine, "extension-type", exten_type, "construct-properties", &construct_properties, NULL)); }
/** * peas_extension_set_new: (skip) * @engine: A #PeasEngine, or %NULL. * @exten_type: the extension #GType. * @first_property: the name of the first property. * @...: the value of the first property, followed optionally by more * name/value pairs, followed by %NULL. * * Create a new #PeasExtensionSet for the @exten_type extension type. * * At any moment, the #PeasExtensionSet will contain an extension instance for * each loaded plugin which implements the @exten_type extension type. It does * so by connecting to the relevant signals from #PeasEngine. * * The property values passed to peas_extension_set_new() will be used for the * construction of new extension instances. * * If @engine is %NULL, then the default engine will be used. * * See peas_engine_create_extension() for more information. * * Returns: a new instance of #PeasExtensionSet. */ PeasExtensionSet * peas_extension_set_new (PeasEngine *engine, GType exten_type, const gchar *first_property, ...) { va_list var_args; PeasExtensionSet *set; g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL); g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL); va_start (var_args, first_property); set = peas_extension_set_new_valist (engine, exten_type, first_property, var_args); va_end (var_args); return set; }
std::string get_defs(GType gtype, GTypeIsAPointerFunc is_a_pointer_func) { std::string strObjectName = g_type_name(gtype); std::string strDefs; if (G_TYPE_IS_OBJECT(gtype) || G_TYPE_IS_INTERFACE(gtype)) { strDefs = ";; From " + strObjectName + "\n\n"; strDefs += get_signals(gtype, is_a_pointer_func); strDefs += get_properties(gtype); } else strDefs = ";; " + strObjectName + " is neither a GObject nor a GInterface. Not checked for signals and properties.\n\n"; return strDefs; }
static void add_all_interfaces (GType iface_type, GPtrArray *type_structs) { GType *prereq; guint n_prereq; guint i; g_ptr_array_add (type_structs, g_type_default_interface_ref (iface_type)); prereq = g_type_interface_prerequisites (iface_type, &n_prereq); for (i = 0; i < n_prereq; ++i) { if (G_TYPE_IS_INTERFACE (prereq[i])) add_all_interfaces (prereq[i], type_structs); } g_free (prereq); }
void rbgobj_define_property_accessors(VALUE klass) { GType gtype; GParamSpec** pspecs = NULL; guint i; GString* source; guint n_properties = 0; gtype = CLASS2GTYPE(klass); if (G_TYPE_IS_INTERFACE(gtype)){ #if GLIB_CHECK_VERSION(2,4,0) gpointer iface = g_type_default_interface_ref(gtype); pspecs = g_object_interface_list_properties(iface, &n_properties); g_type_default_interface_unref(iface); #endif } else { GObjectClass* oclass = G_OBJECT_CLASS(g_type_class_ref(gtype)); pspecs = g_object_class_list_properties(oclass, &n_properties); g_type_class_unref(oclass); } if (n_properties == 0) return; source = g_string_new(NULL); for (i = 0; i < n_properties; i++){ GParamSpec* pspec = pspecs[i]; char* buf; char* prop_name; char* p; if (pspec->owner_type != gtype) continue; buf = g_strdup(pspec->name); for (p = buf; *p; p++) if (*p == '-') *p = '_'; if (!strncmp(buf, "is_", 3)) prop_name = buf + 3; else prop_name = buf; if (g_hash_table_lookup(prop_exclude_list, prop_name)){ g_free(buf); continue; } if (pspec->flags & G_PARAM_READABLE){ g_string_append_printf( source, "def %s%s; get_property('%s'); end\n", prop_name, (G_PARAM_SPEC_VALUE_TYPE(pspec) == G_TYPE_BOOLEAN) ? "?" : "", pspec->name); } if (IS_FLAG(pspec->flags, G_PARAM_WRITABLE) && !IS_FLAG(pspec->flags, G_PARAM_CONSTRUCT_ONLY)){ g_string_append_printf(source, "def set_%s(val); set_property('%s', val); end\n", prop_name, pspec->name); #ifdef HAVE_NODE_ATTRASGN g_string_append_printf(source, "alias %s= set_%s\n", prop_name, prop_name); #else g_string_append_printf(source, "def %s=(val); set_property('%s', val); val; end\n", prop_name, pspec->name); #endif } g_free(buf); } if (source->len > 0) rb_funcall(klass, id_module_eval, 1, rb_str_new2(source->str)); g_string_free(source, TRUE); }
static PyObject* _wrap_g_type_is_interface(PyGTypeWrapper *self) { return PyBool_FromLong(G_TYPE_IS_INTERFACE(self->type)); }
static VALUE rg_interface_p(VALUE self) { return CBOOL2RVAL(G_TYPE_IS_INTERFACE(rbgobj_gtype_get(self))); }
static const RGObjClassInfo * rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent, gboolean create_class) { GType fundamental_type; RGObjClassInfo* cinfo; RGObjClassInfoDynamic* cinfod; void* gclass = NULL; VALUE c; if (gtype == G_TYPE_INVALID) return NULL; cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype)); if (cinfo) return cinfo; if (!create_class) return NULL; c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo); cinfo->gtype = gtype; cinfo->mark = NULL; cinfo->free = NULL; cinfo->flags = 0; fundamental_type = G_TYPE_FUNDAMENTAL(gtype); switch (fundamental_type) { case G_TYPE_POINTER: case G_TYPE_BOXED: case G_TYPE_PARAM: case G_TYPE_OBJECT: case G_TYPE_ENUM: case G_TYPE_FLAGS: if (NIL_P(parent)) parent = get_superclass(gtype); cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent); break; case G_TYPE_INTERFACE: cinfo->klass = rb_module_new(); break; default: if (NIL_P(parent)) parent = get_superclass(gtype); if (NIL_P(parent)) { fprintf(stderr, "%s: %s's fundamental type %s isn't supported\n", "rbgobj_lookup_class_by_gtype", g_type_name(gtype), g_type_name(fundamental_type)); return NULL; } cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent); } cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list, g_type_name(gtype)); if (cinfod) { cinfo->mark = cinfod->mark; cinfo->free = cinfod->free; rb_define_const(cinfod->module, cinfod->name, cinfo->klass); } rb_hash_aset(klass_to_cinfo, cinfo->klass, c); g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo); if (G_TYPE_IS_CLASSED(gtype)) gclass = g_type_class_ref(gtype); if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype)) rbgobj_define_action_methods(cinfo->klass); if (G_TYPE_IS_INSTANTIATABLE(gtype)) { GType* interfaces = NULL; guint n_interfaces = 0; guint i; interfaces = g_type_interfaces(gtype, &n_interfaces); for (i = 0; i < n_interfaces; i++) { const RGObjClassInfo *iface_cinfo; iface_cinfo = rbgobj_lookup_class_by_gtype_without_lock(interfaces[i], Qnil, TRUE); rb_include_module(cinfo->klass, iface_cinfo->klass); } g_free(interfaces); } if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) { switch (fundamental_type) { case G_TYPE_OBJECT: rbgobj_init_object_class(cinfo->klass); break; case G_TYPE_ENUM: rbgobj_init_enum_class(cinfo->klass); break; case G_TYPE_FLAGS: rbgobj_init_flags_class(cinfo->klass); break; case G_TYPE_INTERFACE: rbgobj_init_interface(cinfo->klass); break; default: rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass); break; } } if (gclass) g_type_class_unref(gclass); return cinfo; }
gboolean peas_utils_valist_to_parameter_list (GType iface_type, const gchar *first_property, va_list args, GParameter **params, guint *n_params) { GPtrArray *type_structs; const gchar *name; guint n_allocated_params; g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE); type_structs = g_ptr_array_new (); g_ptr_array_set_free_func (type_structs, (GDestroyNotify) g_type_default_interface_unref); add_all_interfaces (iface_type, type_structs); *n_params = 0; n_allocated_params = 16; *params = g_new0 (GParameter, n_allocated_params); name = first_property; while (name) { gchar *error_msg = NULL; GParamSpec *pspec = find_param_spec_in_interfaces (type_structs, name); if (!pspec) { g_warning ("%s: type '%s' has no property named '%s'", G_STRFUNC, g_type_name (iface_type), name); goto error; } if (*n_params >= n_allocated_params) { n_allocated_params += 16; *params = g_renew (GParameter, *params, n_allocated_params); memset (*params + (n_allocated_params - 16), 0, sizeof (GParameter) * 16); } (*params)[*n_params].name = name; G_VALUE_COLLECT_INIT (&(*params)[*n_params].value, pspec->value_type, args, 0, &error_msg); (*n_params)++; if (error_msg) { g_warning ("%s: %s", G_STRFUNC, error_msg); g_free (error_msg); goto error; } name = va_arg (args, gchar*); } g_ptr_array_unref (type_structs); return TRUE; error: for (; *n_params > 0; --(*n_params)) g_value_unset (&(*params)[*n_params].value); g_free (*params); g_ptr_array_unref (type_structs); return FALSE; }
// Until the glib bug https://bugzilla.gnome.org/show_bug.cgi?id=465631 // is fixed, get_properties() must be called for a GObject before it's // called for a GInterface. std::string get_properties(GType gtype) { std::string strResult; std::string strObjectName = g_type_name(gtype); // Get the list of properties: GParamSpec** ppParamSpec = nullptr; guint iCount = 0; if (G_TYPE_IS_OBJECT(gtype)) { GObjectClass* pGClass = G_OBJECT_CLASS(g_type_class_ref(gtype)); ppParamSpec = g_object_class_list_properties(pGClass, &iCount); g_type_class_unref(pGClass); if (!ppParamSpec) { strResult += ";; Warning: g_object_class_list_properties() returned NULL for " + std::string(g_type_name(gtype)) + "\n"; } } else if (G_TYPE_IS_INTERFACE(gtype)) { gpointer pGInterface = g_type_default_interface_ref(gtype); if (pGInterface) { ppParamSpec = g_object_interface_list_properties(pGInterface, &iCount); g_type_default_interface_unref(pGInterface); if (!ppParamSpec) { strResult += ";; Warning: g_object_interface_list_properties() returned NULL for " + std::string(g_type_name(gtype)) + "\n"; } } else strResult += ";; Warning: g_type_default_interface_ref() returned NULL for " + std::string(g_type_name(gtype)) + "\n"; } // This extra check avoids an occasional crash if (!ppParamSpec) iCount = 0; for (guint i = 0; i < iCount; i++) { GParamSpec* pParamSpec = ppParamSpec[i]; // Generate the property if the specified gtype actually owns the property. // (Generally all properties, including any base classes' properties are // retrieved by g_object_interface_list_properties() for a given gtype. // The base classes' properties should not be generated). if (pParamSpec && pParamSpec->owner_type == gtype) { strResult += get_property_with_node_name(pParamSpec, strObjectName, "define-property"); } } g_free(ppParamSpec); return strResult; }
std::string get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func) { std::string strResult; std::string strObjectName = g_type_name(gtype); gpointer gclass_ref = nullptr; gpointer ginterface_ref = nullptr; if (G_TYPE_IS_OBJECT(gtype)) gclass_ref = g_type_class_ref(gtype); // Ensures that class_init() is called. else if (G_TYPE_IS_INTERFACE(gtype)) ginterface_ref = g_type_default_interface_ref(gtype); // install signals. // Get the list of signals: guint iCount = 0; guint* pIDs = g_signal_list_ids(gtype, &iCount); // Loop through the list of signals: if (pIDs) { for (guint i = 0; i < iCount; i++) { guint signal_id = pIDs[i]; // Name: std::string strName = g_signal_name(signal_id); strResult += "(define-signal " + strName + "\n"; strResult += " (of-object \"" + strObjectName + "\")\n"; // Other information about the signal: GSignalQuery signalQuery = { 0, nullptr, 0, GSignalFlags(0), 0, 0, nullptr, }; g_signal_query(signal_id, &signalQuery); // Return type: std::string strReturnTypeName = get_type_name_signal(signalQuery.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func); // The type is mangled with a flag. Hacky. // bool bReturnTypeHasStaticScope = (signalQuery.return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == // G_SIGNAL_TYPE_STATIC_SCOPE; strResult += " (return-type \"" + strReturnTypeName + "\")\n"; // Flags: std::string strFlags; add_signal_flag_if(strFlags, "Run First", signalQuery, G_SIGNAL_RUN_FIRST); add_signal_flag_if(strFlags, "Run Last", signalQuery, G_SIGNAL_RUN_LAST); add_signal_flag_if(strFlags, "Run Cleanup", signalQuery, G_SIGNAL_RUN_CLEANUP); add_signal_flag_if(strFlags, "No Recurse", signalQuery, G_SIGNAL_NO_RECURSE); add_signal_flag_if(strFlags, "Action", signalQuery, G_SIGNAL_ACTION); add_signal_flag_if(strFlags, "No Hooks", signalQuery, G_SIGNAL_NO_HOOKS); add_signal_flag_if(strFlags, "Must Collect", signalQuery, G_SIGNAL_MUST_COLLECT); strResult += " (flags \"" + strFlags + "\")\n"; if (signalQuery.signal_flags & G_SIGNAL_DETAILED) strResult += " (detailed #t)\n"; // Default: not detailed if (signalQuery.signal_flags & G_SIGNAL_DEPRECATED) strResult += " (deprecated #t)\n"; // Default: not deprecated // Loop through the list of parameters: const GType* pParameters = signalQuery.param_types; if (pParameters) { strResult += " (parameters\n"; for (unsigned j = 0; j < signalQuery.n_params; j++) { GType typeParamMangled = pParameters[j]; // Parameter name: // We can't get the real parameter name from the GObject system. It's not registered with // g_signal_new(). gchar* pchNum = g_strdup_printf("%d", j); std::string strParamName = "p" + std::string(pchNum); g_free(pchNum); pchNum = nullptr; // Just like above, for the return type: std::string strTypeName = get_type_name_signal(typeParamMangled & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func); // The type is mangled with a flag. Hacky. // bool bTypeHasStaticScope = (typeParamMangled & G_SIGNAL_TYPE_STATIC_SCOPE) == // G_SIGNAL_TYPE_STATIC_SCOPE; strResult += " '(\"" + strTypeName + "\" \"" + strParamName + "\")\n"; } strResult += " )\n"; // close (parameters } strResult += ")\n\n"; // close (define-signal } } g_free(pIDs); if (gclass_ref) g_type_class_unref(gclass_ref); // to match the g_type_class_ref() above. else if (ginterface_ref) g_type_default_interface_unref(ginterface_ref); // for interface ref above. return strResult; }