mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
structure: more cleanups
gst_structure_get_type() -> _gst_structure_type to avoid method calls for getting the GType that initialized at the start. Hide some structure fields in private data so that we can change the implementation. Move structure equality check from caps.c to structure.c where it belongs.
This commit is contained in:
parent
a59bc0ab02
commit
9597545d23
6 changed files with 140 additions and 97 deletions
|
@ -668,6 +668,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
|||
_gst_memory_init ();
|
||||
_gst_format_initialize ();
|
||||
_gst_query_initialize ();
|
||||
_gst_structure_initialize ();
|
||||
_gst_caps_initialize ();
|
||||
_gst_meta_init ();
|
||||
|
||||
|
@ -755,7 +756,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
|||
g_type_class_ref (gst_map_flags_get_type ());
|
||||
g_type_class_ref (gst_caps_intersect_mode_get_type ());
|
||||
|
||||
gst_structure_get_type ();
|
||||
_gst_event_initialize ();
|
||||
_gst_buffer_initialize ();
|
||||
_gst_message_initialize ();
|
||||
|
|
|
@ -98,6 +98,7 @@ void _priv_gst_quarks_initialize (void);
|
|||
* we want enterprise edition packagers dancing on our heads) */
|
||||
void _gst_buffer_initialize (void);
|
||||
void _gst_buffer_list_initialize (void);
|
||||
void _gst_structure_initialize (void);
|
||||
void _gst_caps_initialize (void);
|
||||
void _gst_event_initialize (void);
|
||||
void _gst_format_initialize (void);
|
||||
|
@ -115,7 +116,7 @@ gboolean _gst_plugin_loader_client_run (void);
|
|||
void _priv_gst_pad_invalidate_cache (GstPad *pad);
|
||||
|
||||
/* used in both gststructure.c and gstcaps.c; numbers are completely made up */
|
||||
#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + (s)->fields->len * 22)
|
||||
#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + gst_structure_n_fields(s) * 22)
|
||||
|
||||
gboolean priv_gst_structure_append_to_gstring (const GstStructure * structure,
|
||||
GString * s);
|
||||
|
|
|
@ -464,22 +464,6 @@ gst_caps_steal_structure (GstCaps * caps, guint index)
|
|||
return gst_caps_remove_and_get_structure (caps, index);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
|
||||
gpointer data)
|
||||
{
|
||||
GstStructure *struct1 = (GstStructure *) data;
|
||||
const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
|
||||
|
||||
if (G_UNLIKELY (val1 == NULL))
|
||||
return FALSE;
|
||||
if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
|
||||
gpointer user_data)
|
||||
|
@ -530,8 +514,8 @@ static gboolean
|
|||
gst_caps_structure_is_subset (const GstStructure * minuend,
|
||||
const GstStructure * subtrahend)
|
||||
{
|
||||
if ((minuend->name != subtrahend->name) ||
|
||||
(gst_structure_n_fields (minuend) !=
|
||||
if ((minuend->name != subtrahend->name)
|
||||
|| (gst_structure_n_fields (minuend) !=
|
||||
gst_structure_n_fields (subtrahend))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -643,7 +627,6 @@ gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
|
|||
g_return_if_fail (IS_WRITABLE (caps));
|
||||
|
||||
if (G_LIKELY (structure)) {
|
||||
g_return_if_fail (structure->parent_refcount == NULL);
|
||||
gst_caps_append_structure_unchecked (caps, structure);
|
||||
}
|
||||
}
|
||||
|
@ -688,7 +671,6 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
|
|||
int i;
|
||||
gboolean unique = TRUE;
|
||||
|
||||
g_return_if_fail (structure->parent_refcount == NULL);
|
||||
/* check each structure */
|
||||
for (i = caps->structs->len - 1; i >= 0; i--) {
|
||||
structure1 = gst_caps_get_structure_unchecked (caps, i);
|
||||
|
@ -1000,15 +982,7 @@ gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
|
|||
struct1 = gst_caps_get_structure_unchecked (caps1, 0);
|
||||
struct2 = gst_caps_get_structure_unchecked (caps2, 0);
|
||||
|
||||
if (struct1->name != struct2->name) {
|
||||
return FALSE;
|
||||
}
|
||||
if (struct1->fields->len != struct2->fields->len) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gst_structure_foreach (struct1, gst_structure_is_equal_foreach,
|
||||
struct2);
|
||||
return gst_structure_is_equal (struct1, struct2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -312,15 +312,23 @@ gst_event_new_custom (GstEventType type, GstStructure * structure)
|
|||
GstEvent *event;
|
||||
|
||||
/* structure must not have a parent */
|
||||
if (structure)
|
||||
g_return_val_if_fail (structure->parent_refcount == NULL, NULL);
|
||||
|
||||
event = gst_event_new (type);
|
||||
if (structure) {
|
||||
gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
|
||||
if (!gst_structure_set_parent_refcount (structure,
|
||||
&event->mini_object.refcount))
|
||||
goto had_parent;
|
||||
|
||||
GST_EVENT_STRUCTURE (event) = structure;
|
||||
}
|
||||
return event;
|
||||
|
||||
/* ERRORS */
|
||||
had_parent:
|
||||
{
|
||||
gst_event_unref (event);
|
||||
g_warning ("structure is already owned by another object");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline GstStructure *
|
||||
|
|
|
@ -74,12 +74,25 @@ struct _GstStructureField
|
|||
GValue value;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstStructure s;
|
||||
|
||||
/* owned by parent structure, NULL if no parent */
|
||||
gint *parent_refcount;
|
||||
|
||||
GArray *fields;
|
||||
} GstStructureImpl;
|
||||
|
||||
#define GST_STRUCTURE_REFCOUNT(s) (((GstStructureImpl*)(s))->parent_refcount)
|
||||
#define GST_STRUCTURE_FIELDS(s) (((GstStructureImpl*)(s))->fields)
|
||||
|
||||
#define GST_STRUCTURE_FIELD(structure, index) \
|
||||
&g_array_index((structure)->fields, GstStructureField, (index))
|
||||
&g_array_index(GST_STRUCTURE_FIELDS(structure), GstStructureField, (index))
|
||||
|
||||
#define IS_MUTABLE(structure) \
|
||||
(!(structure)->parent_refcount || \
|
||||
g_atomic_int_get ((structure)->parent_refcount) == 1)
|
||||
(!GST_STRUCTURE_REFCOUNT(structure) || \
|
||||
g_atomic_int_get (GST_STRUCTURE_REFCOUNT(structure)) == 1)
|
||||
|
||||
#define IS_TAGLIST(structure) \
|
||||
(structure->name == GST_QUARK (TAGLIST))
|
||||
|
@ -98,36 +111,32 @@ static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
|
|||
GValue * value, GType default_type);
|
||||
static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
|
||||
|
||||
GType
|
||||
gst_structure_get_type (void)
|
||||
GType _gst_structure_type = 0;
|
||||
|
||||
void
|
||||
_gst_structure_initialize (void)
|
||||
{
|
||||
static GType gst_structure_type = 0;
|
||||
_gst_structure_type = g_boxed_type_register_static ("GstStructure",
|
||||
(GBoxedCopyFunc) gst_structure_copy_conditional,
|
||||
(GBoxedFreeFunc) gst_structure_free);
|
||||
|
||||
if (G_UNLIKELY (gst_structure_type == 0)) {
|
||||
gst_structure_type = g_boxed_type_register_static ("GstStructure",
|
||||
(GBoxedCopyFunc) gst_structure_copy_conditional,
|
||||
(GBoxedFreeFunc) gst_structure_free);
|
||||
|
||||
g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
|
||||
gst_structure_transform_to_string);
|
||||
}
|
||||
|
||||
return gst_structure_type;
|
||||
g_value_register_transform_func (_gst_structure_type, G_TYPE_STRING,
|
||||
gst_structure_transform_to_string);
|
||||
}
|
||||
|
||||
static GstStructure *
|
||||
gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstStructureImpl *structure;
|
||||
|
||||
structure = g_slice_new (GstStructure);
|
||||
structure->type = gst_structure_get_type ();
|
||||
structure->name = quark;
|
||||
structure->parent_refcount = NULL;
|
||||
structure->fields =
|
||||
structure = g_slice_new (GstStructureImpl);
|
||||
((GstStructure *) structure)->type = _gst_structure_type;
|
||||
((GstStructure *) structure)->name = quark;
|
||||
GST_STRUCTURE_REFCOUNT (structure) = NULL;
|
||||
GST_STRUCTURE_FIELDS (structure) =
|
||||
g_array_sized_new (FALSE, FALSE, sizeof (GstStructureField), prealloc);
|
||||
|
||||
return structure;
|
||||
return GST_STRUCTURE_CAST (structure);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -265,20 +274,31 @@ gst_structure_new_valist (const gchar * name,
|
|||
* determine whether a structure is mutable or not. This function should only be
|
||||
* called by code implementing parent objects of #GstStructure, as described in
|
||||
* the MT Refcounting section of the design documents.
|
||||
*
|
||||
* Returns: %TRUE if the parent refcount could be set.
|
||||
*/
|
||||
void
|
||||
gboolean
|
||||
gst_structure_set_parent_refcount (GstStructure * structure, gint * refcount)
|
||||
{
|
||||
g_return_if_fail (structure != NULL);
|
||||
g_return_val_if_fail (structure != NULL, FALSE);
|
||||
|
||||
/* if we have a parent_refcount already, we can only clear
|
||||
* if with a NULL refcount */
|
||||
if (structure->parent_refcount)
|
||||
g_return_if_fail (refcount == NULL);
|
||||
else
|
||||
g_return_if_fail (refcount != NULL);
|
||||
if (GST_STRUCTURE_REFCOUNT (structure)) {
|
||||
if (refcount != NULL) {
|
||||
g_return_val_if_fail (refcount == NULL, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (refcount == NULL) {
|
||||
g_return_val_if_fail (refcount != NULL, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
structure->parent_refcount = refcount;
|
||||
GST_STRUCTURE_REFCOUNT (structure) = refcount;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,7 +320,7 @@ gst_structure_copy (const GstStructure * structure)
|
|||
|
||||
g_return_val_if_fail (structure != NULL, NULL);
|
||||
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
new_structure = gst_structure_id_empty_new_with_size (structure->name, len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -310,7 +330,7 @@ gst_structure_copy (const GstStructure * structure)
|
|||
|
||||
new_field.name = field->name;
|
||||
gst_value_init_and_copy (&new_field.value, &field->value);
|
||||
g_array_append_val (new_structure->fields, new_field);
|
||||
g_array_append_val (GST_STRUCTURE_FIELDS (new_structure), new_field);
|
||||
}
|
||||
|
||||
return new_structure;
|
||||
|
@ -330,9 +350,9 @@ gst_structure_free (GstStructure * structure)
|
|||
guint i, len;
|
||||
|
||||
g_return_if_fail (structure != NULL);
|
||||
g_return_if_fail (structure->parent_refcount == NULL);
|
||||
g_return_if_fail (GST_STRUCTURE_REFCOUNT (structure) == NULL);
|
||||
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
for (i = 0; i < len; i++) {
|
||||
field = GST_STRUCTURE_FIELD (structure, i);
|
||||
|
||||
|
@ -340,11 +360,11 @@ gst_structure_free (GstStructure * structure)
|
|||
g_value_unset (&field->value);
|
||||
}
|
||||
}
|
||||
g_array_free (structure->fields, TRUE);
|
||||
g_array_free (GST_STRUCTURE_FIELDS (structure), TRUE);
|
||||
#ifdef USE_POISONING
|
||||
memset (structure, 0xff, sizeof (GstStructure));
|
||||
#endif
|
||||
g_slice_free (GstStructure, structure);
|
||||
g_slice_free1 (sizeof (GstStructureImpl), structure);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,6 +443,46 @@ gst_structure_set_name (GstStructure * structure, const gchar * name)
|
|||
structure->name = g_quark_from_string (name);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
|
||||
gpointer data)
|
||||
{
|
||||
GstStructure *struct1 = (GstStructure *) data;
|
||||
const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
|
||||
|
||||
if (G_UNLIKELY (val1 == NULL))
|
||||
return FALSE;
|
||||
if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_structure_is_equal:
|
||||
* @struct1: a #GstStructure
|
||||
* @struct2: another #GstStructure
|
||||
*
|
||||
* Tests if two #GstStructure are equal.
|
||||
*
|
||||
* Returns: TRUE if the arguments represent the same structure
|
||||
*/
|
||||
gboolean
|
||||
gst_structure_is_equal (GstStructure * struct1, GstStructure * struct2)
|
||||
{
|
||||
if (struct1->name != struct2->name)
|
||||
return FALSE;
|
||||
|
||||
if (GST_STRUCTURE_FIELDS (struct1)->len !=
|
||||
GST_STRUCTURE_FIELDS (struct2)->len)
|
||||
return FALSE;
|
||||
|
||||
return gst_structure_foreach (struct1, gst_structure_is_equal_foreach,
|
||||
struct2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gst_structure_id_set_value_internal (GstStructure * structure, GQuark field,
|
||||
const GValue * value)
|
||||
|
@ -753,7 +813,7 @@ static void
|
|||
gst_structure_set_field (GstStructure * structure, GstStructureField * field)
|
||||
{
|
||||
GstStructureField *f;
|
||||
guint i, len = structure->fields->len;
|
||||
guint i, len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
|
||||
if (G_UNLIKELY (G_VALUE_HOLDS_STRING (&field->value))) {
|
||||
const gchar *s;
|
||||
|
@ -813,7 +873,7 @@ gst_structure_set_field (GstStructure * structure, GstStructureField * field)
|
|||
}
|
||||
}
|
||||
|
||||
g_array_append_val (structure->fields, *field);
|
||||
g_array_append_val (GST_STRUCTURE_FIELDS (structure), *field);
|
||||
}
|
||||
|
||||
/* If there is no field with the given ID, NULL is returned.
|
||||
|
@ -824,7 +884,7 @@ gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
|
|||
GstStructureField *field;
|
||||
guint i, len;
|
||||
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
field = GST_STRUCTURE_FIELD (structure, i);
|
||||
|
@ -918,7 +978,7 @@ gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
|
|||
g_return_if_fail (IS_MUTABLE (structure));
|
||||
|
||||
id = g_quark_from_string (fieldname);
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
field = GST_STRUCTURE_FIELD (structure, i);
|
||||
|
@ -927,7 +987,8 @@ gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
|
|||
if (G_IS_VALUE (&field->value)) {
|
||||
g_value_unset (&field->value);
|
||||
}
|
||||
structure->fields = g_array_remove_index (structure->fields, i);
|
||||
GST_STRUCTURE_FIELDS (structure) =
|
||||
g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -996,13 +1057,14 @@ gst_structure_remove_all_fields (GstStructure * structure)
|
|||
g_return_if_fail (structure != NULL);
|
||||
g_return_if_fail (IS_MUTABLE (structure));
|
||||
|
||||
for (i = structure->fields->len - 1; i >= 0; i--) {
|
||||
for (i = GST_STRUCTURE_FIELDS (structure)->len - 1; i >= 0; i--) {
|
||||
field = GST_STRUCTURE_FIELD (structure, i);
|
||||
|
||||
if (G_IS_VALUE (&field->value)) {
|
||||
g_value_unset (&field->value);
|
||||
}
|
||||
structure->fields = g_array_remove_index (structure->fields, i);
|
||||
GST_STRUCTURE_FIELDS (structure) =
|
||||
g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1108,7 @@ gst_structure_n_fields (const GstStructure * structure)
|
|||
{
|
||||
g_return_val_if_fail (structure != NULL, 0);
|
||||
|
||||
return structure->fields->len;
|
||||
return GST_STRUCTURE_FIELDS (structure)->len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1064,7 +1126,7 @@ gst_structure_nth_field_name (const GstStructure * structure, guint index)
|
|||
GstStructureField *field;
|
||||
|
||||
g_return_val_if_fail (structure != NULL, NULL);
|
||||
g_return_val_if_fail (index < structure->fields->len, NULL);
|
||||
g_return_val_if_fail (index < GST_STRUCTURE_FIELDS (structure)->len, NULL);
|
||||
|
||||
field = GST_STRUCTURE_FIELD (structure, index);
|
||||
|
||||
|
@ -1094,7 +1156,7 @@ gst_structure_foreach (const GstStructure * structure,
|
|||
g_return_val_if_fail (structure != NULL, FALSE);
|
||||
g_return_val_if_fail (func != NULL, FALSE);
|
||||
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
field = GST_STRUCTURE_FIELD (structure, i);
|
||||
|
@ -1131,7 +1193,7 @@ gst_structure_map_in_place (GstStructure * structure,
|
|||
g_return_val_if_fail (structure != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
|
||||
g_return_val_if_fail (func != NULL, FALSE);
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
field = GST_STRUCTURE_FIELD (structure, i);
|
||||
|
@ -1804,7 +1866,7 @@ priv_gst_structure_append_to_gstring (const GstStructure * structure,
|
|||
g_return_val_if_fail (s != NULL, FALSE);
|
||||
|
||||
g_string_append (s, g_quark_to_string (structure->name));
|
||||
len = structure->fields->len;
|
||||
len = GST_STRUCTURE_FIELDS (structure)->len;
|
||||
for (i = 0; i < len; i++) {
|
||||
char *t;
|
||||
GType type;
|
||||
|
|
|
@ -28,12 +28,16 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_STRUCTURE (gst_structure_get_type ())
|
||||
#define GST_STRUCTURE(object) ((GstStructure *)(object))
|
||||
#define GST_IS_STRUCTURE(object) ((object) && (GST_STRUCTURE(object)->type == GST_TYPE_STRUCTURE))
|
||||
extern GType _gst_structure_type;
|
||||
|
||||
typedef struct _GstStructure GstStructure;
|
||||
|
||||
#define GST_TYPE_STRUCTURE (_gst_structure_type)
|
||||
#define GST_IS_STRUCTURE(object) ((object) && (GST_STRUCTURE(object)->type == GST_TYPE_STRUCTURE))
|
||||
#define GST_STRUCTURE_CAST(object) ((GstStructure *)(object))
|
||||
#define GST_STRUCTURE(object) (GST_STRUCTURE_CAST(object))
|
||||
|
||||
|
||||
/**
|
||||
* GstStructureForeachFunc:
|
||||
* @field_id: the #GQuark of the field name
|
||||
|
@ -77,17 +81,8 @@ struct _GstStructure {
|
|||
|
||||
/*< private >*/
|
||||
GQuark name;
|
||||
|
||||
/* owned by parent structure, NULL if no parent */
|
||||
gint *parent_refcount;
|
||||
|
||||
GArray *fields;
|
||||
|
||||
gpointer _gst_reserved;
|
||||
};
|
||||
|
||||
GType gst_structure_get_type (void);
|
||||
|
||||
GstStructure * gst_structure_empty_new (const gchar * name);
|
||||
GstStructure * gst_structure_id_empty_new (GQuark quark);
|
||||
GstStructure * gst_structure_new (const gchar * name,
|
||||
|
@ -100,8 +95,8 @@ GstStructure * gst_structure_id_new (GQuark
|
|||
GQuark field_quark,
|
||||
...);
|
||||
GstStructure * gst_structure_copy (const GstStructure *structure);
|
||||
void gst_structure_set_parent_refcount (GstStructure *structure,
|
||||
gint *refcount);
|
||||
gboolean gst_structure_set_parent_refcount (GstStructure *structure,
|
||||
gint *refcount);
|
||||
void gst_structure_free (GstStructure *structure);
|
||||
|
||||
G_CONST_RETURN gchar * gst_structure_get_name (const GstStructure *structure);
|
||||
|
@ -111,6 +106,9 @@ gboolean gst_structure_has_name (const GstStructure
|
|||
void gst_structure_set_name (GstStructure *structure,
|
||||
const gchar *name);
|
||||
|
||||
gboolean gst_structure_is_equal (GstStructure *struct1,
|
||||
GstStructure *struct2);
|
||||
|
||||
void gst_structure_id_set_value (GstStructure *structure,
|
||||
GQuark field,
|
||||
const GValue *value);
|
||||
|
|
Loading…
Reference in a new issue