diff --git a/gdump.c b/gdump.c index 5cb10b045..328f07521 100644 --- a/gdump.c +++ b/gdump.c @@ -270,6 +270,56 @@ dump_enum_type (GType type, const char *symbol, GOutputStream *out) goutput_write (out, " "); } +static void +dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) +{ + guint n_interfaces; + guint i; + GType *interfaces; + GString *parent_str; + GType parent; + gboolean first = TRUE; + + + escaped_printf (out, " len > 0) + escaped_printf (out, " parents=\"%s\"", parent_str->str); + g_string_free (parent_str, TRUE); + + goutput_write (out, ">\n"); + + interfaces = g_type_interfaces (type, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + { + GType itype = interfaces[i]; + escaped_printf (out, " \n", + g_type_name (itype)); + } + goutput_write (out, " \n"); +} + static void dump_type (GType type, const char *symbol, GOutputStream *out) { @@ -294,10 +344,7 @@ dump_type (GType type, const char *symbol, GOutputStream *out) /* GValue, etc. Just skip them. */ break; default: - /* Other fundamental types such as the once GStreamer and Clutter registers - * are not yet interesting from an introspection perspective and should be - * ignored - */ + dump_fundamental_type (type, symbol, out); break; } } diff --git a/giobjectinfo.c b/giobjectinfo.c index ace8d5d4b..bc2ddcd0f 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -96,6 +96,29 @@ g_object_info_get_abstract (GIObjectInfo *info) return blob->abstract != 0; } +/** + * g_object_info_get_fundamental: + * @info: a #GIObjectInfo + * + * Obtain if the object type is of a fundamental type which is not + * G_TYPE_OBJECT. This is mostly for supporting GstMiniObject. + * + * Returns: %TRUE if the object type is a fundamental type + */ +gboolean +g_object_info_get_fundamental (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->fundamental != 0; +} + /** * g_object_info_get_type_name: * @info: a #GIObjectInfo @@ -636,3 +659,229 @@ g_object_info_get_class_struct (GIObjectInfo *info) return NULL; } +typedef const char* (*SymbolGetter) (GIObjectInfo *info); + +static void * +_get_func(GIObjectInfo *info, + SymbolGetter getter) +{ + const char* symbol; + GSList *parents = NULL, *l; + GIObjectInfo *parent_info; + + parent_info = info; + while (parent_info != NULL) { + parents = g_slist_prepend(parents, parent_info); + parent_info = g_object_info_get_parent(parent_info); + } + + for (l = parents; l; l = l->next) { + GIObjectInfoRefFunction func; + parent_info = l->data; + symbol = getter(parent_info); + if (symbol == NULL) + continue; + if (g_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (void**) &func)) { + g_slist_free(parents); + return func; + } + } + + g_slist_free(parents); + return NULL; + +} + +/** + * g_object_info_get_ref_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to ref this + * object type. It's mainly used fundamental types. The type signature for + * the symbol is %GIObjectInfoRefFunction, to fetch the function pointer + * see g_object_info_get_ref_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_ref_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->ref_func) + return g_typelib_get_string (rinfo->typelib, blob->ref_func); + + return NULL; +} + +/** + * g_object_info_get_ref_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * increase the reference count an instance of this object type. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoRefFunction +g_object_info_get_ref_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoRefFunction)_get_func(info, (SymbolGetter)g_object_info_get_ref_function); +} + +/** + * g_object_info_get_unref_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to unref this + * object type. It's mainly used fundamental types. The type signature for + * the symbol is %GIObjectInfoUnrefFunction, to fetch the function pointer + * see g_object_info_get_unref_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_unref_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->unref_func) + return g_typelib_get_string (rinfo->typelib, blob->unref_func); + + return NULL; +} + +/** + * g_object_info_get_unref_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * decrease the reference count an instance of this object type. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoUnrefFunction +g_object_info_get_unref_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoUnrefFunction)_get_func(info, (SymbolGetter)g_object_info_get_unref_function); +} + +/** + * g_object_info_get_set_value_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to convert + * set a GValue giving an object instance pointer of this object type. + * I's mainly used fundamental types. The type signature for the symbol + * is %GIObjectInfoSetValueFunction, to fetch the function pointer + * see g_object_info_get_set_value_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_set_value_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->set_value_func) + return g_typelib_get_string (rinfo->typelib, blob->set_value_func); + + return NULL; +} + +/** + * g_object_info_get_set_value_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * set a GValue given an instance of this object type. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoSetValueFunction +g_object_info_get_set_value_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoSetValueFunction)_get_func(info, (SymbolGetter)g_object_info_get_set_value_function); +} + +/** + * g_object_info_get_get_value_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to convert + * an object instance pointer of this object type to a GValue. + * I's mainly used fundamental types. The type signature for the symbol + * is %GIObjectInfoGetValueFunction, to fetch the function pointer + * see g_object_info_get_get_value_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_get_value_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->get_value_func) + return g_typelib_get_string (rinfo->typelib, blob->get_value_func); + + return NULL; +} + +/** + * g_object_info_get_get_value_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * extract an instance of this object type out of a GValue. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoGetValueFunction +g_object_info_get_get_value_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoGetValueFunction)_get_func(info, (SymbolGetter)g_object_info_get_get_value_function); +} diff --git a/giobjectinfo.h b/giobjectinfo.h index 27ec71411..630def618 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -30,12 +30,52 @@ G_BEGIN_DECLS +/** + * GIObjectInfoRefFunction: + * @object: object instance pointer + * + * Increases the reference count of an object instance. + * + * Returns: the object instance + */ +typedef void * (*GIObjectInfoRefFunction) (void *object); + +/** + * GIObjectInfoUnrefFunction: + * @object: object instance pointer + * + * Decreases the reference count of an object instance. + * + */ +typedef void (*GIObjectInfoUnrefFunction) (void *object); + +/** + * GIObjectInfoSetValueFunction: + * @value: a #GValue + * @object: object instance pointer + * + * Update @value and attach the object instance pointer @object to it. + * + */ +typedef void (*GIObjectInfoSetValueFunction) (GValue *value, void *object); + +/** + * GIObjectInfoGetValueFunction: + * @value: a #GValue + * + * Extract an object instance out of @value + * + * Returns: the object instance + */ +typedef void * (*GIObjectInfoGetValueFunction) (const GValue *value); + #define GI_IS_OBJECT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) const gchar * g_object_info_get_type_name (GIObjectInfo *info); const gchar * g_object_info_get_type_init (GIObjectInfo *info); gboolean g_object_info_get_abstract (GIObjectInfo *info); +gboolean g_object_info_get_fundamental (GIObjectInfo *info); GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); gint g_object_info_get_n_interfaces (GIObjectInfo *info); GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, @@ -64,6 +104,18 @@ GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n); GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); +const char * g_object_info_get_ref_function (GIObjectInfo *info); +GIObjectInfoRefFunction g_object_info_get_ref_function_pointer (GIObjectInfo *info); + +const char * g_object_info_get_unref_function (GIObjectInfo *info); +GIObjectInfoUnrefFunction g_object_info_get_unref_function_pointer (GIObjectInfo *info); + +const char * g_object_info_get_set_value_function (GIObjectInfo *info); +GIObjectInfoSetValueFunction g_object_info_get_set_value_function_pointer (GIObjectInfo *info); + +const char * g_object_info_get_get_value_function (GIObjectInfo *info); +GIObjectInfoGetValueFunction g_object_info_get_get_value_function_pointer (GIObjectInfo *info); + G_END_DECLS diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index f3c20fdde..76a1ee22d 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -38,7 +38,8 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION)) + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_BOXED)) const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); diff --git a/girnode.c b/girnode.c index 576ac1006..af24161d2 100644 --- a/girnode.c +++ b/girnode.c @@ -298,6 +298,10 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_free (iface->gtype_name); g_free (iface->gtype_init); + g_free (iface->ref_func); + g_free (iface->unref_func); + g_free (iface->set_value_func); + g_free (iface->get_value_func); g_free (iface->glib_type_struct); @@ -692,6 +696,14 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); if (iface->gtype_init) size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + if (iface->ref_func) + size += ALIGN_VALUE (strlen (iface->ref_func) + 1, 4); + if (iface->unref_func) + size += ALIGN_VALUE (strlen (iface->unref_func) + 1, 4); + if (iface->set_value_func) + size += ALIGN_VALUE (strlen (iface->set_value_func) + 1, 4); + if (iface->get_value_func) + size += ALIGN_VALUE (strlen (iface->get_value_func) + 1, 4); size += 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) @@ -2094,11 +2106,20 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_OBJECT; blob->abstract = object->abstract; + blob->fundamental = object->fundamental; blob->deprecated = object->deprecated; blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); blob->gtype_name = write_string (object->gtype_name, strings, data, offset2); blob->gtype_init = write_string (object->gtype_init, strings, data, offset2); + if (object->ref_func) + blob->ref_func = write_string (object->ref_func, strings, data, offset2); + if (object->unref_func) + blob->unref_func = write_string (object->unref_func, strings, data, offset2); + if (object->set_value_func) + blob->set_value_func = write_string (object->set_value_func, strings, data, offset2); + if (object->get_value_func) + blob->get_value_func = write_string (object->get_value_func, strings, data, offset2); if (object->parent) blob->parent = find_entry (module, modules, object->parent); else diff --git a/girnode.h b/girnode.h index bd9acd068..dcd8fa494 100644 --- a/girnode.h +++ b/girnode.h @@ -244,10 +244,16 @@ struct _GIrNodeInterface gboolean abstract; gboolean deprecated; + gboolean fundamental; gchar *gtype_name; gchar *gtype_init; + gchar *ref_func; + gchar *unref_func; + gchar *set_value_func; + gchar *get_value_func; + gchar *parent; gchar *glib_type_struct; diff --git a/girparser.c b/girparser.c index 678edcc35..7796bea28 100644 --- a/girparser.c +++ b/girparser.c @@ -1640,6 +1640,11 @@ start_class (GMarkupParseContext *context, const gchar *typeinit; const gchar *deprecated; const gchar *abstract; + const gchar *fundamental; + const gchar *ref_func; + const gchar *unref_func; + const gchar *set_value_func; + const gchar *get_value_func; GIrNodeInterface *iface; if (!(strcmp (element_name, "class") == 0 && @@ -1656,6 +1661,11 @@ start_class (GMarkupParseContext *context, typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); abstract = find_attribute ("abstract", attribute_names, attribute_values); + fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values); + ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values); + unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values); + set_value_func = find_attribute ("glib:set-value-func", attribute_names, attribute_values); + get_value_func = find_attribute ("glib:get-value-func", attribute_names, attribute_values); if (name == NULL) { @@ -1686,6 +1696,15 @@ start_class (GMarkupParseContext *context, iface->abstract = abstract && strcmp (abstract, "1") == 0; + if (ref_func) + iface->ref_func = g_strdup (ref_func); + if (unref_func) + iface->unref_func = g_strdup (unref_func); + if (set_value_func) + iface->set_value_func = g_strdup (set_value_func); + if (get_value_func) + iface->get_value_func = g_strdup (get_value_func); + push_node (ctx, (GIrNode *) iface); ctx->current_module->entries = g_list_append (ctx->current_module->entries, iface); diff --git a/girwriter.c b/girwriter.c index 19862b0da..56d61b239 100644 --- a/girwriter.c +++ b/girwriter.c @@ -999,8 +999,10 @@ write_object_info (const gchar *namespace, const gchar *name; const gchar *type_name; const gchar *type_init; + const gchar *func; gboolean deprecated; gboolean is_abstract; + gboolean is_fundamental; GIObjectInfo *pnode; GIStructInfo *class_struct; gint i; @@ -1008,6 +1010,7 @@ write_object_info (const gchar *namespace, name = g_base_info_get_name ((GIBaseInfo *)info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); is_abstract = g_object_info_get_abstract (info); + is_fundamental = g_object_info_get_fundamental (info); type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); @@ -1033,6 +1036,25 @@ write_object_info (const gchar *namespace, xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + if (is_fundamental) + xml_printf (file, " glib:fundamental=\"1\""); + + func = g_object_info_get_unref_function (info); + if (func) + xml_printf (file, " glib:unref-function=\"%s\"", func); + + func = g_object_info_get_ref_function (info); + if (func) + xml_printf (file, " glib:ref-function=\"%s\"", func); + + func = g_object_info_get_set_value_function (info); + if (func) + xml_printf (file, " glib:set-value-function=\"%s\"", func); + + func = g_object_info_get_get_value_function (info); + if (func) + xml_printf (file, " glib:get-value-function=\"%s\"", func); + if (deprecated) xml_printf (file, " deprecated=\"1\""); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index d4577acc7..981f7b480 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -72,6 +72,11 @@ G_BEGIN_DECLS /* TYPELIB HISTORY ----- + +Version 1.1 +- Add ref/unref/set-value/get-value functions to Object, to be able + to support instantiatable fundamental types which are not GObject based. + Version 1.0 - Rename class_struct to gtype_struct, add to interfaces @@ -918,6 +923,8 @@ typedef struct { /** * ObjectBlob: * @blob_type: #BLOB_TYPE_OBJECT + * @fundamental: this object is not a GObject derived type, instead it's + * an additional fundamental type. * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType * @parent: The directory index of the parent type. This is only set for @@ -938,12 +945,21 @@ typedef struct { * @signals: Describes the signals. * @vfuncs: Describes the virtual functions. * @constants: Describes the constants. + * @ref_func: String pointing to a function which can be called to increase + * the reference count for an instance of this object type. + * @unref_func: String pointing to a function which can be called to decrease + * the reference count for an instance of this object type. + * @set_value_func: String pointing to a function which can be called to + * convert a pointer of this object to a GValue + * @get_value_func: String pointing to a function which can be called to + * convert extract a pointer to this object from a GValue */ typedef struct { guint16 blob_type; /* 7 */ guint16 deprecated : 1; guint16 abstract : 1; - guint16 reserved :14; + guint16 fundamental : 1; + guint16 reserved :13; guint32 name; guint32 gtype_name; @@ -961,6 +977,11 @@ typedef struct { guint16 n_constants; guint16 reserved2; + guint32 ref_func; + guint32 unref_func; + guint32 set_value_func; + guint32 get_value_func; + guint32 reserved3; guint32 reserved4; diff --git a/gitypelib.c b/gitypelib.c index 6aa3077c4..74aa7edd8 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -183,7 +183,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (PropertyBlob, 16); CHECK_SIZE (SignalBlob, 16); CHECK_SIZE (VFuncBlob, 20); - CHECK_SIZE (ObjectBlob, 44); + CHECK_SIZE (ObjectBlob, 60); CHECK_SIZE (InterfaceBlob, 40); CHECK_SIZE (ConstantBlob, 24); CHECK_SIZE (AttributeBlob, 12);