diff options
author | Ryan Lortie <desrt@desrt.ca> | 2013-04-20 18:50:21 -0400 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2013-04-21 16:31:14 -0400 |
commit | c16f914b40c749b938490a4e10a3c54ec1855c42 (patch) | |
tree | 6f1e76d356c717105a87119bd9835d4dd80d9601 /gio/gemblemedicon.c | |
parent | 9cc222c0bfc65034143753a64b081b7811ee48f1 (diff) |
GIcon: add g_icon_[de]serialize()
Add support for serialising a GIcon to a GVariant and deserialising the
result back to a GIcon.
This solves a number of problems suffered by the existing to_string()
API, primarily these:
- not forcing the icon to be a utf8 string means that we can
efficiently encode a PNG (ie: just give the array of bytes)
- there is no need to ensure that proper types are loaded before using
the deserialisation interface. 'Foreign' icon types will probably
emit a serialised format the deserialises to a GBytesIcon.
We additionally clearly document what is required for being a consumer
or implementation of #GIcon.
Further patches will be required to GdkPixbuf and GVfsIcon to bring
their implementations in line with the new rules (essentially: introduce
implementations of the new serialize() API).
https://bugzilla.gnome.org/show_bug.cgi?id=688820
Diffstat (limited to 'gio/gemblemedicon.c')
-rw-r--r-- | gio/gemblemedicon.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/gio/gemblemedicon.c b/gio/gemblemedicon.c index c10dc9bc1..32e734104 100644 --- a/gio/gemblemedicon.c +++ b/gio/gemblemedicon.c @@ -413,6 +413,54 @@ g_emblemed_icon_from_tokens (gchar **tokens, return NULL; } +static GVariant * +g_emblemed_icon_serialize (GIcon *icon) +{ + GEmblemedIcon *emblemed_icon = G_EMBLEMED_ICON (icon); + GVariantBuilder builder; + GVariant *icon_data; + GList *node; + + icon_data = g_icon_serialize (emblemed_icon->priv->icon); + if (!icon_data) + return NULL; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(va(va{sv}))")); + + g_variant_builder_add (&builder, "v", icon_data); + g_variant_unref (icon_data); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(va{sv})")); + for (node = emblemed_icon->priv->emblems; node != NULL; node = node->next) + { + icon_data = g_icon_serialize (node->data); + if (icon_data) + { + /* We know how emblems serialise, so do a tweak here to + * reduce some of the variant wrapping and redundant storage + * of 'emblem' over and again... + */ + if (g_variant_is_of_type (icon_data, G_VARIANT_TYPE ("(sv)"))) + { + const gchar *name; + GVariant *content; + + g_variant_get (icon_data, "(&sv)", &name, &content); + + if (g_str_equal (name, "emblem") && g_variant_is_of_type (content, G_VARIANT_TYPE ("(va{sv})"))) + g_variant_builder_add (&builder, "@(va{sv})", content); + + g_variant_unref (content); + } + + g_variant_unref (icon_data); + } + } + g_variant_builder_close (&builder); + + return g_variant_new ("(sv)", "emblemed", g_variant_builder_end (&builder)); +} + static void g_emblemed_icon_icon_iface_init (GIconIface *iface) { @@ -420,4 +468,5 @@ g_emblemed_icon_icon_iface_init (GIconIface *iface) iface->equal = g_emblemed_icon_equal; iface->to_tokens = g_emblemed_icon_to_tokens; iface->from_tokens = g_emblemed_icon_from_tokens; + iface->serialize = g_emblemed_icon_serialize; } |