Blame gio/gthemedicon.c

Packit ae235b
/* GIO - GLib Input, Output and Streaming Library
Packit ae235b
 * 
Packit ae235b
 * Copyright (C) 2006-2007 Red Hat, Inc.
Packit ae235b
 *
Packit ae235b
 * This library is free software; you can redistribute it and/or
Packit ae235b
 * modify it under the terms of the GNU Lesser General Public
Packit ae235b
 * License as published by the Free Software Foundation; either
Packit ae235b
 * version 2.1 of the License, or (at your option) any later version.
Packit ae235b
 *
Packit ae235b
 * This library is distributed in the hope that it will be useful,
Packit ae235b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit ae235b
 * Lesser General Public License for more details.
Packit ae235b
 *
Packit ae235b
 * You should have received a copy of the GNU Lesser General
Packit ae235b
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit ae235b
 *
Packit ae235b
 * Author: Alexander Larsson <alexl@redhat.com>
Packit ae235b
 */
Packit ae235b
Packit ae235b
#include "config.h"
Packit ae235b
Packit ae235b
#include <string.h>
Packit ae235b
Packit ae235b
#include "gthemedicon.h"
Packit ae235b
#include "gicon.h"
Packit ae235b
#include "gioerror.h"
Packit ae235b
#include "glibintl.h"
Packit ae235b
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * SECTION:gthemedicon
Packit ae235b
 * @short_description: Icon theming support
Packit ae235b
 * @include: gio/gio.h
Packit ae235b
 * @see_also: #GIcon, #GLoadableIcon
Packit ae235b
 *
Packit ae235b
 * #GThemedIcon is an implementation of #GIcon that supports icon themes.
Packit ae235b
 * #GThemedIcon contains a list of all of the icons present in an icon
Packit ae235b
 * theme, so that icons can be looked up quickly. #GThemedIcon does
Packit ae235b
 * not provide actual pixmaps for icons, just the icon names.
Packit ae235b
 * Ideally something like gtk_icon_theme_choose_icon() should be used to
Packit ae235b
 * resolve the list of names so that fallback icons work nicely with
Packit ae235b
 * themes that inherit other themes.
Packit ae235b
 **/
Packit ae235b
Packit ae235b
static void g_themed_icon_icon_iface_init (GIconIface *iface);
Packit ae235b
Packit ae235b
struct _GThemedIcon
Packit ae235b
{
Packit ae235b
  GObject parent_instance;
Packit ae235b
  
Packit ae235b
  char     **names;
Packit ae235b
  gboolean   use_default_fallbacks;
Packit ae235b
};
Packit ae235b
Packit ae235b
struct _GThemedIconClass
Packit ae235b
{
Packit ae235b
  GObjectClass parent_class;
Packit ae235b
};
Packit ae235b
Packit ae235b
enum
Packit ae235b
{
Packit ae235b
  PROP_0,
Packit ae235b
  PROP_NAME,
Packit ae235b
  PROP_NAMES,
Packit ae235b
  PROP_USE_DEFAULT_FALLBACKS
Packit ae235b
};
Packit ae235b
Packit ae235b
G_DEFINE_TYPE_WITH_CODE (GThemedIcon, g_themed_icon, G_TYPE_OBJECT,
Packit ae235b
			 G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
Packit ae235b
						g_themed_icon_icon_iface_init))
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_get_property (GObject    *object,
Packit ae235b
                            guint       prop_id,
Packit ae235b
                            GValue     *value,
Packit ae235b
                            GParamSpec *pspec)
Packit ae235b
{
Packit ae235b
  GThemedIcon *icon = G_THEMED_ICON (object);
Packit ae235b
Packit ae235b
  switch (prop_id)
Packit ae235b
    {
Packit ae235b
      case PROP_NAMES:
Packit ae235b
        g_value_set_boxed (value, icon->names);
Packit ae235b
        break;
Packit ae235b
Packit ae235b
      case PROP_USE_DEFAULT_FALLBACKS:
Packit ae235b
        g_value_set_boolean (value, icon->use_default_fallbacks);
Packit ae235b
        break;
Packit ae235b
Packit ae235b
      default:
Packit ae235b
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_set_property (GObject      *object,
Packit ae235b
                            guint         prop_id,
Packit ae235b
                            const GValue *value,
Packit ae235b
                            GParamSpec   *pspec)
Packit ae235b
{
Packit ae235b
  GThemedIcon *icon = G_THEMED_ICON (object);
Packit ae235b
  gchar **names;
Packit ae235b
  const gchar *name;
Packit ae235b
Packit ae235b
  switch (prop_id)
Packit ae235b
    {
Packit ae235b
      case PROP_NAME:
Packit ae235b
        name = g_value_get_string (value);
Packit ae235b
Packit ae235b
        if (!name)
Packit ae235b
          break;
Packit ae235b
Packit ae235b
        if (icon->names)
Packit ae235b
          g_strfreev (icon->names);
Packit ae235b
Packit ae235b
        icon->names = g_new (char *, 2);
Packit ae235b
        icon->names[0] = g_strdup (name);
Packit ae235b
        icon->names[1] = NULL;
Packit ae235b
        break;
Packit ae235b
Packit ae235b
      case PROP_NAMES:
Packit ae235b
        names = g_value_dup_boxed (value);
Packit ae235b
Packit ae235b
        if (!names)
Packit ae235b
          break;
Packit ae235b
Packit ae235b
        if (icon->names)
Packit ae235b
          g_strfreev (icon->names);
Packit ae235b
Packit ae235b
        icon->names = names;
Packit ae235b
        break;
Packit ae235b
Packit ae235b
      case PROP_USE_DEFAULT_FALLBACKS:
Packit ae235b
        icon->use_default_fallbacks = g_value_get_boolean (value);
Packit ae235b
        break;
Packit ae235b
Packit ae235b
      default:
Packit ae235b
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_constructed (GObject *object)
Packit ae235b
{
Packit ae235b
  GThemedIcon *themed = G_THEMED_ICON (object);
Packit ae235b
Packit ae235b
  g_return_if_fail (themed->names != NULL && themed->names[0] != NULL);
Packit ae235b
Packit ae235b
  if (themed->use_default_fallbacks)
Packit ae235b
    {
Packit ae235b
      int i = 0, dashes = 0;
Packit ae235b
      const char *p;
Packit ae235b
      char *dashp;
Packit ae235b
      char *last;
Packit ae235b
      gboolean is_symbolic;
Packit ae235b
      char *name;
Packit ae235b
      char **names;
Packit ae235b
Packit ae235b
      is_symbolic = g_str_has_suffix (themed->names[0], "-symbolic");
Packit ae235b
      if (is_symbolic)
Packit ae235b
        name = g_strndup (themed->names[0], strlen (themed->names[0]) - 9);
Packit ae235b
      else
Packit ae235b
        name = g_strdup (themed->names[0]);
Packit ae235b
Packit ae235b
      p = name;
Packit ae235b
      while (*p)
Packit ae235b
        {
Packit ae235b
          if (*p == '-')
Packit ae235b
            dashes++;
Packit ae235b
          p++;
Packit ae235b
        }
Packit ae235b
Packit ae235b
      last = name;
Packit ae235b
Packit ae235b
      g_strfreev (themed->names);
Packit ae235b
Packit ae235b
      names = g_new (char *, dashes + 1 + 1);
Packit ae235b
      names[i++] = last;
Packit ae235b
Packit ae235b
      while ((dashp = strrchr (last, '-')) != NULL)
Packit ae235b
        names[i++] = last = g_strndup (last, dashp - last);
Packit ae235b
Packit ae235b
      names[i++] = NULL;
Packit ae235b
Packit ae235b
      if (is_symbolic)
Packit ae235b
        {
Packit ae235b
          themed->names = g_new (char *, 2 * dashes + 3);
Packit ae235b
          for (i = 0; names[i] != NULL; i++)
Packit ae235b
            {
Packit ae235b
              themed->names[i] = g_strconcat (names[i], "-symbolic", NULL);
Packit ae235b
              themed->names[dashes + 1 + i] = names[i];
Packit ae235b
            }
Packit ae235b
Packit ae235b
          themed->names[dashes + 1 + i] = NULL;
Packit ae235b
          g_free (names);
Packit ae235b
        }
Packit ae235b
      else
Packit ae235b
        {
Packit ae235b
          themed->names = names;
Packit ae235b
        }
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_finalize (GObject *object)
Packit ae235b
{
Packit ae235b
  GThemedIcon *themed;
Packit ae235b
Packit ae235b
  themed = G_THEMED_ICON (object);
Packit ae235b
Packit ae235b
  g_strfreev (themed->names);
Packit ae235b
Packit ae235b
  G_OBJECT_CLASS (g_themed_icon_parent_class)->finalize (object);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_class_init (GThemedIconClass *klass)
Packit ae235b
{
Packit ae235b
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit ae235b
  
Packit ae235b
  gobject_class->finalize = g_themed_icon_finalize;
Packit ae235b
  gobject_class->constructed = g_themed_icon_constructed;
Packit ae235b
  gobject_class->set_property = g_themed_icon_set_property;
Packit ae235b
  gobject_class->get_property = g_themed_icon_get_property;
Packit ae235b
Packit ae235b
  /**
Packit ae235b
   * GThemedIcon:name:
Packit ae235b
   *
Packit ae235b
   * The icon name.
Packit ae235b
   */
Packit ae235b
  g_object_class_install_property (gobject_class, PROP_NAME,
Packit ae235b
                                   g_param_spec_string ("name",
Packit ae235b
                                                        P_("name"),
Packit ae235b
                                                        P_("The name of the icon"),
Packit ae235b
                                                        NULL,
Packit ae235b
                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
Packit ae235b
Packit ae235b
  /**
Packit ae235b
   * GThemedIcon:names:
Packit ae235b
   *
Packit ae235b
   * A %NULL-terminated array of icon names.
Packit ae235b
   */
Packit ae235b
  g_object_class_install_property (gobject_class, PROP_NAMES,
Packit ae235b
                                   g_param_spec_boxed ("names",
Packit ae235b
                                                       P_("names"),
Packit ae235b
                                                       P_("An array containing the icon names"),
Packit ae235b
                                                       G_TYPE_STRV,
Packit ae235b
                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
Packit ae235b
Packit ae235b
  /**
Packit ae235b
   * GThemedIcon:use-default-fallbacks:
Packit ae235b
   *
Packit ae235b
   * Whether to use the default fallbacks found by shortening the icon name 
Packit ae235b
   * at '-' characters. If the "names" array has more than one element, 
Packit ae235b
   * ignores any past the first.
Packit ae235b
   *
Packit ae235b
   * For example, if the icon name was "gnome-dev-cdrom-audio", the array 
Packit ae235b
   * would become
Packit ae235b
   * |[
Packit ae235b
   * {
Packit ae235b
   *   "gnome-dev-cdrom-audio",
Packit ae235b
   *   "gnome-dev-cdrom",
Packit ae235b
   *   "gnome-dev",
Packit ae235b
   *   "gnome",
Packit ae235b
   *   NULL
Packit ae235b
   * };
Packit ae235b
   * ]|
Packit ae235b
   */
Packit ae235b
  g_object_class_install_property (gobject_class, PROP_USE_DEFAULT_FALLBACKS,
Packit ae235b
                                   g_param_spec_boolean ("use-default-fallbacks",
Packit ae235b
                                                         P_("use default fallbacks"),
Packit ae235b
                                                         P_("Whether to use default fallbacks found by shortening the name at “-” characters. Ignores names after the first if multiple names are given."),
Packit ae235b
                                                         FALSE,
Packit ae235b
                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_init (GThemedIcon *themed)
Packit ae235b
{
Packit ae235b
  themed->names = NULL;
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_themed_icon_new:
Packit ae235b
 * @iconname: a string containing an icon name.
Packit ae235b
 * 
Packit ae235b
 * Creates a new themed icon for @iconname.
Packit ae235b
 * 
Packit ae235b
 * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon.
Packit ae235b
 **/
Packit ae235b
GIcon *
Packit ae235b
g_themed_icon_new (const char *iconname)
Packit ae235b
{
Packit ae235b
  g_return_val_if_fail (iconname != NULL, NULL);
Packit ae235b
Packit ae235b
  return G_ICON (g_object_new (G_TYPE_THEMED_ICON, "name", iconname, NULL));
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_themed_icon_new_from_names:
Packit ae235b
 * @iconnames: (array length=len): an array of strings containing icon names.
Packit ae235b
 * @len: the length of the @iconnames array, or -1 if @iconnames is 
Packit ae235b
 *     %NULL-terminated
Packit ae235b
 * 
Packit ae235b
 * Creates a new themed icon for @iconnames.
Packit ae235b
 * 
Packit ae235b
 * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon
Packit ae235b
 **/
Packit ae235b
GIcon *
Packit ae235b
g_themed_icon_new_from_names (char **iconnames,
Packit ae235b
                              int    len)
Packit ae235b
{
Packit ae235b
  GIcon *icon;
Packit ae235b
Packit ae235b
  g_return_val_if_fail (iconnames != NULL, NULL);
Packit ae235b
Packit ae235b
  if (len >= 0)
Packit ae235b
    {
Packit ae235b
      char **names;
Packit ae235b
      int i;
Packit ae235b
Packit ae235b
      names = g_new (char *, len + 1);
Packit ae235b
Packit ae235b
      for (i = 0; i < len; i++)
Packit ae235b
        names[i] = iconnames[i];
Packit ae235b
Packit ae235b
      names[i] = NULL;
Packit ae235b
Packit ae235b
      icon = G_ICON (g_object_new (G_TYPE_THEMED_ICON, "names", names, NULL));
Packit ae235b
Packit ae235b
      g_free (names);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    icon = G_ICON (g_object_new (G_TYPE_THEMED_ICON, "names", iconnames, NULL));
Packit ae235b
Packit ae235b
  return icon;
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_themed_icon_new_with_default_fallbacks:
Packit ae235b
 * @iconname: a string containing an icon name
Packit ae235b
 *
Packit ae235b
 * Creates a new themed icon for @iconname, and all the names
Packit ae235b
 * that can be created by shortening @iconname at '-' characters.
Packit ae235b
 * 
Packit ae235b
 * In the following example, @icon1 and @icon2 are equivalent:
Packit ae235b
 * |[
Packit ae235b
 * const char *names[] = { 
Packit ae235b
 *   "gnome-dev-cdrom-audio",
Packit ae235b
 *   "gnome-dev-cdrom",
Packit ae235b
 *   "gnome-dev",
Packit ae235b
 *   "gnome"
Packit ae235b
 * };
Packit ae235b
 *
Packit ae235b
 * icon1 = g_themed_icon_new_from_names (names, 4);
Packit ae235b
 * icon2 = g_themed_icon_new_with_default_fallbacks ("gnome-dev-cdrom-audio");
Packit ae235b
 * ]|
Packit ae235b
 *
Packit ae235b
 * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon.
Packit ae235b
 */
Packit ae235b
GIcon *
Packit ae235b
g_themed_icon_new_with_default_fallbacks (const char *iconname)
Packit ae235b
{
Packit ae235b
  g_return_val_if_fail (iconname != NULL, NULL);
Packit ae235b
Packit ae235b
  return G_ICON (g_object_new (G_TYPE_THEMED_ICON, "name", iconname, "use-default-fallbacks", TRUE, NULL));
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_themed_icon_get_names:
Packit ae235b
 * @icon: a #GThemedIcon.
Packit ae235b
 *
Packit ae235b
 * Gets the names of icons from within @icon.
Packit ae235b
 *
Packit ae235b
 * Returns: (transfer none): a list of icon names.
Packit ae235b
 */
Packit ae235b
const char * const *
Packit ae235b
g_themed_icon_get_names (GThemedIcon *icon)
Packit ae235b
{
Packit ae235b
  g_return_val_if_fail (G_IS_THEMED_ICON (icon), NULL);
Packit ae235b
  return (const char * const *)icon->names;
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_themed_icon_append_name:
Packit ae235b
 * @icon: a #GThemedIcon
Packit ae235b
 * @iconname: name of icon to append to list of icons from within @icon.
Packit ae235b
 *
Packit ae235b
 * Append a name to the list of icons from within @icon.
Packit ae235b
 *
Packit ae235b
 * Note that doing so invalidates the hash computed by prior calls
Packit ae235b
 * to g_icon_hash().
Packit ae235b
 */
Packit ae235b
void
Packit ae235b
g_themed_icon_append_name (GThemedIcon *icon, 
Packit ae235b
                           const char  *iconname)
Packit ae235b
{
Packit ae235b
  guint num_names;
Packit ae235b
Packit ae235b
  g_return_if_fail (G_IS_THEMED_ICON (icon));
Packit ae235b
  g_return_if_fail (iconname != NULL);
Packit ae235b
Packit ae235b
  num_names = g_strv_length (icon->names);
Packit ae235b
  icon->names = g_realloc (icon->names, sizeof (char*) * (num_names + 2));
Packit ae235b
  icon->names[num_names] = g_strdup (iconname);
Packit ae235b
  icon->names[num_names + 1] = NULL;
Packit ae235b
Packit ae235b
  g_object_notify (G_OBJECT (icon), "names");
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_themed_icon_prepend_name:
Packit ae235b
 * @icon: a #GThemedIcon
Packit ae235b
 * @iconname: name of icon to prepend to list of icons from within @icon.
Packit ae235b
 *
Packit ae235b
 * Prepend a name to the list of icons from within @icon.
Packit ae235b
 *
Packit ae235b
 * Note that doing so invalidates the hash computed by prior calls
Packit ae235b
 * to g_icon_hash().
Packit ae235b
 *
Packit ae235b
 * Since: 2.18
Packit ae235b
 */
Packit ae235b
void
Packit ae235b
g_themed_icon_prepend_name (GThemedIcon *icon, 
Packit ae235b
                            const char  *iconname)
Packit ae235b
{
Packit ae235b
  guint num_names;
Packit ae235b
  gchar **names;
Packit ae235b
  gint i;
Packit ae235b
Packit ae235b
  g_return_if_fail (G_IS_THEMED_ICON (icon));
Packit ae235b
  g_return_if_fail (iconname != NULL);
Packit ae235b
Packit ae235b
  num_names = g_strv_length (icon->names);
Packit ae235b
  names = g_new (char*, num_names + 2);
Packit ae235b
  for (i = 0; icon->names[i]; i++)
Packit ae235b
    names[i + 1] = icon->names[i];
Packit ae235b
  names[0] = g_strdup (iconname);
Packit ae235b
  names[num_names + 1] = NULL;
Packit ae235b
Packit ae235b
  g_free (icon->names);
Packit ae235b
  icon->names = names;
Packit ae235b
Packit ae235b
  g_object_notify (G_OBJECT (icon), "names");
Packit ae235b
}
Packit ae235b
Packit ae235b
static guint
Packit ae235b
g_themed_icon_hash (GIcon *icon)
Packit ae235b
{
Packit ae235b
  GThemedIcon *themed = G_THEMED_ICON (icon);
Packit ae235b
  guint hash;
Packit ae235b
  int i;
Packit ae235b
Packit ae235b
  hash = 0;
Packit ae235b
Packit ae235b
  for (i = 0; themed->names[i] != NULL; i++)
Packit ae235b
    hash ^= g_str_hash (themed->names[i]);
Packit ae235b
  
Packit ae235b
  return hash;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
g_themed_icon_equal (GIcon *icon1,
Packit ae235b
                     GIcon *icon2)
Packit ae235b
{
Packit ae235b
  GThemedIcon *themed1 = G_THEMED_ICON (icon1);
Packit ae235b
  GThemedIcon *themed2 = G_THEMED_ICON (icon2);
Packit ae235b
  int i;
Packit ae235b
Packit ae235b
  for (i = 0; themed1->names[i] != NULL && themed2->names[i] != NULL; i++)
Packit ae235b
    {
Packit ae235b
      if (!g_str_equal (themed1->names[i], themed2->names[i]))
Packit ae235b
	return FALSE;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return themed1->names[i] == NULL && themed2->names[i] == NULL;
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
g_themed_icon_to_tokens (GIcon *icon,
Packit ae235b
			 GPtrArray *tokens,
Packit ae235b
                         gint  *out_version)
Packit ae235b
{
Packit ae235b
  GThemedIcon *themed_icon = G_THEMED_ICON (icon);
Packit ae235b
  int n;
Packit ae235b
Packit ae235b
  g_return_val_if_fail (out_version != NULL, FALSE);
Packit ae235b
Packit ae235b
  *out_version = 0;
Packit ae235b
Packit ae235b
  for (n = 0; themed_icon->names[n] != NULL; n++)
Packit ae235b
    g_ptr_array_add (tokens,
Packit ae235b
		     g_strdup (themed_icon->names[n]));
Packit ae235b
  
Packit ae235b
  return TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static GIcon *
Packit ae235b
g_themed_icon_from_tokens (gchar  **tokens,
Packit ae235b
                           gint     num_tokens,
Packit ae235b
                           gint     version,
Packit ae235b
                           GError **error)
Packit ae235b
{
Packit ae235b
  GIcon *icon;
Packit ae235b
  gchar **names;
Packit ae235b
  int n;
Packit ae235b
Packit ae235b
  icon = NULL;
Packit ae235b
Packit ae235b
  if (version != 0)
Packit ae235b
    {
Packit ae235b
      g_set_error (error,
Packit ae235b
                   G_IO_ERROR,
Packit ae235b
                   G_IO_ERROR_INVALID_ARGUMENT,
Packit ae235b
                   _("Can’t handle version %d of GThemedIcon encoding"),
Packit ae235b
                   version);
Packit ae235b
      goto out;
Packit ae235b
    }
Packit ae235b
  
Packit ae235b
  names = g_new0 (gchar *, num_tokens + 1);
Packit ae235b
  for (n = 0; n < num_tokens; n++)
Packit ae235b
    names[n] = tokens[n];
Packit ae235b
  names[n] = NULL;
Packit ae235b
Packit ae235b
  icon = g_themed_icon_new_from_names (names, num_tokens);
Packit ae235b
  g_free (names);
Packit ae235b
Packit ae235b
 out:
Packit ae235b
  return icon;
Packit ae235b
}
Packit ae235b
Packit ae235b
static GVariant *
Packit ae235b
g_themed_icon_serialize (GIcon *icon)
Packit ae235b
{
Packit ae235b
  GThemedIcon *themed_icon = G_THEMED_ICON (icon);
Packit ae235b
Packit ae235b
  return g_variant_new ("(sv)", "themed", g_variant_new ("^as", themed_icon->names));
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_themed_icon_icon_iface_init (GIconIface *iface)
Packit ae235b
{
Packit ae235b
  iface->hash = g_themed_icon_hash;
Packit ae235b
  iface->equal = g_themed_icon_equal;
Packit ae235b
  iface->to_tokens = g_themed_icon_to_tokens;
Packit ae235b
  iface->from_tokens = g_themed_icon_from_tokens;
Packit ae235b
  iface->serialize = g_themed_icon_serialize;
Packit ae235b
}