summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2010-04-26 11:55:34 +0100
committerBastien Nocera <hadess@hadess.net>2010-04-28 12:02:05 +0100
commit6b939d57c762f58a9f8d529024b7171ff70b6986 (patch)
tree04bf5bcb6aeb62c01c62edb40e9c4036fc8e98e5 /gtk
parent3cc9575323b4ca8c6d82572f1bfe3eb23555fdb3 (diff)
downloadgtk+-6b939d57c762f58a9f8d529024b7171ff70b6986.tar.gz
Support 'symbolic' themed icons
Add gtk_icon_info_load_symbolic() to load symbolic icons, and theme their background/foreground colours to match the colours used in the theme. Adds the gtk_icon_info_load_symbolic() function, explicit support in GtkImage and GtkCellRendererPixbuf, and test cases for those 2 widgets. With help from Bastien Nocera <hadess@hadess.net> https://bugzilla.gnome.org/show_bug.cgi?id=614711
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtk.symbols1
-rw-r--r--gtk/gtkcellrendererpixbuf.c157
-rw-r--r--gtk/gtkicontheme.c136
-rw-r--r--gtk/gtkicontheme.h7
-rw-r--r--gtk/gtkimage.c137
5 files changed, 405 insertions, 33 deletions
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index af6ada455d..ff85c8c4dc 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -1965,6 +1965,7 @@ gtk_icon_info_get_filename_utf8
#endif
gtk_icon_info_get_type G_GNUC_CONST
gtk_icon_info_load_icon
+gtk_icon_info_load_symbolic
gtk_icon_info_set_raw_coordinates
gtk_icon_theme_add_builtin_icon
#ifndef _WIN64
diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c
index f689784bcc..bde1d809e3 100644
--- a/gtk/gtkcellrendererpixbuf.c
+++ b/gtk/gtkcellrendererpixbuf.c
@@ -497,6 +497,7 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf
GtkIconTheme *icon_theme;
GtkSettings *settings;
gint width, height;
+ GtkIconInfo *info;
priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
@@ -519,30 +520,141 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf
}
if (priv->icon_name)
- cellpixbuf->pixbuf = gtk_icon_theme_load_icon (icon_theme,
- priv->icon_name,
- MIN (width, height),
- GTK_ICON_LOOKUP_USE_BUILTIN,
- NULL);
+ info = gtk_icon_theme_lookup_icon (icon_theme,
+ priv->icon_name,
+ MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN);
else if (priv->gicon)
+ info = gtk_icon_theme_lookup_by_gicon (icon_theme,
+ priv->gicon,
+ MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN);
+ else
+ info = NULL;
+
+ if (info)
{
- GtkIconInfo *info;
+ GdkColor error_color, warning_color, success_color;
+ GdkColor *error_ptr, *warning_ptr, *success_ptr;
+ GtkStyle *style;
- info = gtk_icon_theme_lookup_by_gicon (icon_theme,
- priv->gicon,
- MIN (width, height),
- GTK_ICON_LOOKUP_USE_BUILTIN);
- if (info)
- {
- cellpixbuf->pixbuf = gtk_icon_info_load_icon (info, NULL);
- gtk_icon_info_free (info);
- }
+ style = gtk_widget_get_style (GTK_WIDGET (widget));
+ if (!gtk_style_lookup_color (style, "error_color", &error_color))
+ error_ptr = NULL;
+ else
+ error_ptr = &error_color;
+ if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
+ warning_ptr = NULL;
+ else
+ warning_ptr = &warning_color;
+ if (!gtk_style_lookup_color (style, "success_color", &success_color))
+ success_ptr = NULL;
+ else
+ success_ptr = &success_color;
+
+ cellpixbuf->pixbuf = gtk_icon_info_load_symbolic (info,
+ &style->fg[GTK_STATE_NORMAL],
+ success_ptr,
+ warning_ptr,
+ error_ptr,
+ NULL,
+ NULL);
+ gtk_icon_info_free (info);
}
g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
}
static GdkPixbuf *
+create_symbolic_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
+ GtkWidget *widget,
+ GdkColor *fg)
+{
+ GtkCellRendererPixbufPrivate *priv;
+ GdkScreen *screen;
+ GtkIconTheme *icon_theme;
+ GtkSettings *settings;
+ gint width, height;
+ GtkIconInfo *info;
+ GdkPixbuf *pixbuf;
+
+ priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
+
+ /* Not a named symbolic icon? */
+ if (priv->icon_name) {
+ if (!g_str_has_suffix (priv->icon_name, "-symbolic"))
+ return NULL;
+ } else if (priv->gicon) {
+ const gchar * const *names;
+ if (!G_IS_THEMED_ICON (priv->gicon))
+ return NULL;
+ names = g_themed_icon_get_names (G_THEMED_ICON (priv->gicon));
+ if (names == NULL || !g_str_has_suffix (names[0], "-symbolic"))
+ return NULL;
+ } else {
+ return NULL;
+ }
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (widget));
+ icon_theme = gtk_icon_theme_get_for_screen (screen);
+ settings = gtk_settings_get_for_screen (screen);
+
+ if (!gtk_icon_size_lookup_for_settings (settings,
+ priv->stock_size,
+ &width, &height))
+ {
+ g_warning ("Invalid icon size %u\n", priv->stock_size);
+ width = height = 24;
+ }
+
+
+ if (priv->icon_name)
+ info = gtk_icon_theme_lookup_icon (icon_theme,
+ priv->icon_name,
+ MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN);
+ else if (priv->gicon)
+ info = gtk_icon_theme_lookup_by_gicon (icon_theme,
+ priv->gicon,
+ MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN);
+ else
+ return NULL;
+
+ if (info)
+ {
+ GdkColor error_color, warning_color, success_color;
+ GdkColor *error_ptr, *warning_ptr, *success_ptr;
+ GtkStyle *style;
+
+ style = gtk_widget_get_style (GTK_WIDGET (widget));
+ if (!gtk_style_lookup_color (style, "error_color", &error_color))
+ error_ptr = NULL;
+ else
+ error_ptr = &error_color;
+ if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
+ warning_ptr = NULL;
+ else
+ warning_ptr = &warning_color;
+ if (!gtk_style_lookup_color (style, "success_color", &success_color))
+ success_ptr = NULL;
+ else
+ success_ptr = &success_color;
+
+ pixbuf = gtk_icon_info_load_symbolic (info,
+ fg,
+ success_ptr,
+ warning_ptr,
+ error_ptr,
+ NULL,
+ NULL);
+ gtk_icon_info_free (info);
+ return pixbuf;
+ }
+ return NULL;
+}
+
+static GdkPixbuf *
create_colorized_pixbuf (GdkPixbuf *src,
GdkColor *new_color)
{
@@ -678,6 +790,7 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
GdkPixbuf *pixbuf;
GdkPixbuf *invisible = NULL;
GdkPixbuf *colorized = NULL;
+ GdkPixbuf *symbolic = NULL;
GdkRectangle pix_rect;
GdkRectangle draw_rect;
cairo_t *cr;
@@ -755,10 +868,15 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
else
state = GTK_STATE_PRELIGHT;
- colorized = create_colorized_pixbuf (pixbuf,
- &widget->style->base[state]);
+ symbolic = create_symbolic_pixbuf (cellpixbuf, widget, &widget->style->fg[state]);
+ if (!symbolic) {
+ colorized = create_colorized_pixbuf (pixbuf,
+ &widget->style->base[state]);
- pixbuf = colorized;
+ pixbuf = colorized;
+ } else {
+ pixbuf = symbolic;
+ }
}
cr = gdk_cairo_create (window);
@@ -774,6 +892,9 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
if (colorized)
g_object_unref (colorized);
+
+ if (symbolic)
+ g_object_unref (symbolic);
}
#define __GTK_CELL_RENDERER_PIXBUF_C__
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c
index 67ed420332..0084343fbf 100644
--- a/gtk/gtkicontheme.c
+++ b/gtk/gtkicontheme.c
@@ -3079,6 +3079,142 @@ gtk_icon_info_load_icon (GtkIconInfo *icon_info,
return g_object_ref (icon_info->pixbuf);
}
+static gchar *
+gdk_color_to_css (GdkColor *color)
+{
+ return g_strdup_printf ("rgb(%d,%d,%d)",
+ color->red >> 8,
+ color->green >> 8,
+ color->blue >> 8);
+}
+
+/**
+ * gtk_icon_info_load_symbolic:
+ * @info: a #GtkIconInfo
+ * @fg: a #GdkColor representing the foreground color of the icon
+ * @success_color: (allow-none): a #GdkColor representing the warning color of the icon
+ * or %NULL to use the default color
+ * @warning_color: (allow-none): a #GdkColor representing the warning color of the icon
+ * or %NULL to use the default color
+ * @error_color: (allow-none): a #GdkColor representing the error color of the icon
+ * or %NULL to use the default color (allow-none)
+ * @was_symbolic: (allow-none): a #gboolean, returns whether the loaded icon was a symbolic
+ * one and whether the @fg color was applied to it.
+ * @error: (allow-none): location to store error information on failure, or %NULL.
+ *
+ * Loads an icon, modifying it to match the system colours for the foreground,
+ * success, warning and error colors provided. If the icon is not a symbolic one,
+ * the function will return the result from gtk_icon_info_load_icon().
+ *
+ * This allows loading symbolic icons that will match the system theme.
+ *
+ * Unless you are implementing a widget, you will want to use
+ * g_themed_icon_new_with_default_fallbacks() to load the icon.
+ *
+ * As implementation details, the icon loaded needs to be of SVG type,
+ * contain the "symbolic" term as the last chunk of the icon name,
+ * and use the fg, success, warning and error styles in the SVG file itself.
+ * See the <a ulink url="http://www.freedesktop.org/wiki/SymbolicIcons">Symbolic Icons spec</ulink>
+ * for more information about symbolic icons.
+ *
+ * Return value: a #GdkPixbuf representing the loaded icon
+ *
+ * Since: 2.22
+ **/
+GdkPixbuf *
+gtk_icon_info_load_symbolic (GtkIconInfo *info,
+ GdkColor *fg,
+ GdkColor *success_color,
+ GdkColor *warning_color,
+ GdkColor *error_color,
+ gboolean *was_symbolic,
+ GError **error)
+{
+ GdkPixbuf *pixbuf;
+ GInputStream *stream;
+ gchar *data;
+ gchar *css_fg;
+ gchar *css_success;
+ gchar *css_warning;
+ gchar *css_error;
+
+ g_return_val_if_fail (fg != NULL, NULL);
+
+ if (!info->filename || !g_str_has_suffix (info->filename, "-symbolic.svg"))
+ {
+ if (was_symbolic)
+ *was_symbolic = FALSE;
+ return gtk_icon_info_load_icon (info, error);
+ }
+
+ if (was_symbolic)
+ *was_symbolic = TRUE;
+
+ css_fg = gdk_color_to_css (fg);
+ if (!warning_color)
+ {
+ GdkColor warning_default_color = { 0, 0xf500, 0x7900, 0x3e00 };
+ css_warning = gdk_color_to_css (&warning_default_color);
+ }
+ else
+ css_warning = gdk_color_to_css (warning_color);
+ if (!error_color)
+ {
+ GdkColor error_default_color = { 0, 0xcc00, 0x0000, 0x0000 };
+ css_error = gdk_color_to_css (&error_default_color);
+ }
+ else
+ css_error = gdk_color_to_css (error_color);
+ if (!success_color)
+ {
+ GdkColor success_default_color = { 0, 0x4e00, 0x9a00, 0x0600 };
+ css_success = gdk_color_to_css (&success_default_color);
+ }
+ else
+ css_success = gdk_color_to_css (success_color);
+
+ data = g_strconcat (
+"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
+"<svg version=\"1.1\"\n"
+" xmlns=\"http://www.w3.org/2000/svg\"\n"
+" xmlns:xi=\"http://www.w3.org/2001/XInclude\"\n"
+" width=\"16\"\n"
+" height=\"16\">\n"
+" <style type=\"text/css\">\n"
+" rect,path {\n"
+" fill: ", css_fg," !important;\n"
+" }\n"
+" .warning {\n"
+" fill: ", css_warning," !important;\n"
+" }\n"
+" .error {\n"
+" fill: ", css_error," !important;\n"
+" }\n"
+" .success {\n"
+" fill: ", css_success," !important;\n"
+" }\n"
+" </style>\n"
+" <xi:include href=\"", info->filename, "\"/>\n"
+"</svg>",
+ NULL);
+ g_free (css_fg);
+ g_free (css_warning);
+ g_free (css_success);
+ g_free (css_error);
+
+ stream = g_memory_input_stream_new_from_data (data, -1, g_free);
+
+ pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
+ info->desired_size,
+ info->desired_size,
+ TRUE,
+ NULL,
+ error);
+ g_object_unref (stream);
+
+ return pixbuf;
+}
+
/**
* gtk_icon_info_set_raw_coordinates:
* @icon_info: a #GtkIconInfo
diff --git a/gtk/gtkicontheme.h b/gtk/gtkicontheme.h
index b6d7d31fe2..f8609cbc0b 100644
--- a/gtk/gtkicontheme.h
+++ b/gtk/gtkicontheme.h
@@ -179,6 +179,13 @@ G_CONST_RETURN gchar *gtk_icon_info_get_filename (GtkIconInfo *icon_info
GdkPixbuf * gtk_icon_info_get_builtin_pixbuf (GtkIconInfo *icon_info);
GdkPixbuf * gtk_icon_info_load_icon (GtkIconInfo *icon_info,
GError **error);
+GdkPixbuf * gtk_icon_info_load_symbolic (GtkIconInfo *icon_info,
+ GdkColor *fg,
+ GdkColor *success_color,
+ GdkColor *warning_color,
+ GdkColor *error_color,
+ gboolean *was_symbolic,
+ GError **error);
void gtk_icon_info_set_raw_coordinates (GtkIconInfo *icon_info,
gboolean raw_coordinates);
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index 6654f0db62..87e0b08245 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -134,6 +134,11 @@ struct _GtkImagePrivate
/* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
gchar *filename;
+ /* a GtkStateType, with -1 meaning an invalid state,
+ * only used with GTK_IMAGE_GICON, GTK_IMAGE_ICON_NAME */
+ gint last_rendered_state;
+ gboolean was_symbolic;
+
gint pixel_size;
guint need_calc_size : 1;
};
@@ -1628,6 +1633,10 @@ animation_timeout (gpointer data)
static void
icon_theme_changed (GtkImage *image)
{
+ GtkImagePrivate *priv;
+
+ priv = GTK_IMAGE_GET_PRIVATE (image);
+
if (image->storage_type == GTK_IMAGE_ICON_NAME)
{
if (image->data.name.pixbuf)
@@ -1647,7 +1656,8 @@ icon_theme_changed (GtkImage *image)
}
static void
-ensure_pixbuf_for_icon_name (GtkImage *image)
+ensure_pixbuf_for_icon_name (GtkImage *image,
+ GtkStateType state)
{
GtkImagePrivate *priv;
GdkScreen *screen;
@@ -1655,8 +1665,8 @@ ensure_pixbuf_for_icon_name (GtkImage *image)
GtkSettings *settings;
gint width, height;
gint *sizes, *s, dist;
+ GtkIconInfo *info;
GtkIconLookupFlags flags;
- GError *error = NULL;
g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_NAME);
@@ -1665,8 +1675,15 @@ ensure_pixbuf_for_icon_name (GtkImage *image)
icon_theme = gtk_icon_theme_get_for_screen (screen);
settings = gtk_settings_get_for_screen (screen);
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
- if (image->data.name.pixbuf == NULL)
+ if (image->data.name.pixbuf == NULL ||
+ (priv->was_symbolic && priv->last_rendered_state != state))
{
+ priv->last_rendered_state = state;
+ if (image->data.name.pixbuf)
+ {
+ g_object_unref (image->data.name.pixbuf);
+ image->data.name.pixbuf = NULL;
+ }
if (priv->pixel_size != -1)
{
width = height = priv->pixel_size;
@@ -1714,24 +1731,57 @@ ensure_pixbuf_for_icon_name (GtkImage *image)
width = height = 24;
}
}
- image->data.name.pixbuf =
- gtk_icon_theme_load_icon (icon_theme,
- image->data.name.icon_name,
- MIN (width, height), flags, &error);
+
+ info = gtk_icon_theme_lookup_icon (icon_theme,
+ image->data.name.icon_name,
+ MIN (width, height), flags);
+ if (info)
+ {
+ GdkColor error_color, warning_color, success_color;
+ GdkColor *error_ptr, *warning_ptr, *success_ptr;
+ GtkStyle *style;
+ gboolean was_symbolic;
+
+ style = gtk_widget_get_style (GTK_WIDGET (image));
+ if (!gtk_style_lookup_color (style, "error_color", &error_color))
+ error_ptr = NULL;
+ else
+ error_ptr = &error_color;
+ if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
+ warning_ptr = NULL;
+ else
+ warning_ptr = &warning_color;
+ if (!gtk_style_lookup_color (style, "success_color", &success_color))
+ success_ptr = NULL;
+ else
+ success_ptr = &success_color;
+
+ image->data.name.pixbuf = gtk_icon_info_load_symbolic (info,
+ &style->fg[state],
+ success_ptr,
+ warning_ptr,
+ error_ptr,
+ &was_symbolic,
+ NULL);
+ priv->was_symbolic = was_symbolic;
+ gtk_icon_info_free (info);
+ }
+
if (image->data.name.pixbuf == NULL)
{
- g_error_free (error);
image->data.name.pixbuf =
gtk_widget_render_icon (GTK_WIDGET (image),
GTK_STOCK_MISSING_IMAGE,
image->icon_size,
NULL);
+ priv->was_symbolic = FALSE;
}
}
}
static void
-ensure_pixbuf_for_gicon (GtkImage *image)
+ensure_pixbuf_for_gicon (GtkImage *image,
+ GtkStateType state)
{
GtkImagePrivate *priv;
GdkScreen *screen;
@@ -1748,8 +1798,15 @@ ensure_pixbuf_for_gicon (GtkImage *image)
icon_theme = gtk_icon_theme_get_for_screen (screen);
settings = gtk_settings_get_for_screen (screen);
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
- if (image->data.gicon.pixbuf == NULL)
+ if (image->data.gicon.pixbuf == NULL ||
+ (priv->was_symbolic && priv->last_rendered_state != state))
{
+ priv->last_rendered_state = state;
+ if (image->data.gicon.pixbuf)
+ {
+ g_object_unref (image->data.gicon.pixbuf);
+ image->data.gicon.pixbuf = NULL;
+ }
if (priv->pixel_size != -1)
{
width = height = priv->pixel_size;
@@ -1773,7 +1830,33 @@ ensure_pixbuf_for_gicon (GtkImage *image)
MIN (width, height), flags);
if (info)
{
- image->data.gicon.pixbuf = gtk_icon_info_load_icon (info, NULL);
+ GdkColor error_color, warning_color, success_color;
+ GdkColor *error_ptr, *warning_ptr, *success_ptr;
+ GtkStyle *style;
+ gboolean was_symbolic;
+
+ style = gtk_widget_get_style (GTK_WIDGET (image));
+ if (!gtk_style_lookup_color (style, "error_color", &error_color))
+ error_ptr = NULL;
+ else
+ error_ptr = &error_color;
+ if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
+ warning_ptr = NULL;
+ else
+ warning_ptr = &warning_color;
+ if (!gtk_style_lookup_color (style, "success_color", &success_color))
+ success_ptr = NULL;
+ else
+ success_ptr = &success_color;
+
+ image->data.gicon.pixbuf = gtk_icon_info_load_symbolic (info,
+ &style->fg[state],
+ success_ptr,
+ warning_ptr,
+ error_ptr,
+ &was_symbolic,
+ NULL);
+ priv->was_symbolic = was_symbolic;
gtk_icon_info_free (info);
}
@@ -1784,6 +1867,7 @@ ensure_pixbuf_for_gicon (GtkImage *image)
GTK_STOCK_MISSING_IMAGE,
image->icon_size,
NULL);
+ priv->was_symbolic = FALSE;
}
}
}
@@ -1845,6 +1929,7 @@ gtk_image_expose (GtkWidget *widget,
gint x, y, mask_x, mask_y;
GdkBitmap *mask;
GdkPixbuf *pixbuf;
+ GtkStateType state;
gboolean needs_state_transform;
image = GTK_IMAGE (widget);
@@ -2012,7 +2097,18 @@ gtk_image_expose (GtkWidget *widget,
break;
case GTK_IMAGE_ICON_NAME:
- ensure_pixbuf_for_icon_name (image);
+ state = gtk_widget_get_state (widget);
+ if (state == GTK_STATE_INSENSITIVE)
+ {
+ ensure_pixbuf_for_icon_name (image, GTK_STATE_NORMAL);
+ }
+ else
+ {
+ ensure_pixbuf_for_icon_name (image, state);
+ /* Already done by the loading function? */
+ if (priv->was_symbolic)
+ needs_state_transform = FALSE;
+ }
pixbuf = image->data.name.pixbuf;
if (pixbuf)
{
@@ -2023,7 +2119,18 @@ gtk_image_expose (GtkWidget *widget,
break;
case GTK_IMAGE_GICON:
- ensure_pixbuf_for_gicon (image);
+ state = gtk_widget_get_state (widget);
+ if (state == GTK_STATE_INSENSITIVE)
+ {
+ ensure_pixbuf_for_gicon (image, GTK_STATE_NORMAL);
+ }
+ else
+ {
+ ensure_pixbuf_for_gicon (image, state);
+ /* Already done by the loading function? */
+ if (priv->was_symbolic)
+ needs_state_transform = FALSE;
+ }
pixbuf = image->data.gicon.pixbuf;
if (pixbuf)
{
@@ -2325,12 +2432,12 @@ gtk_image_calc_size (GtkImage *image)
NULL);
break;
case GTK_IMAGE_ICON_NAME:
- ensure_pixbuf_for_icon_name (image);
+ ensure_pixbuf_for_icon_name (image, GTK_STATE_NORMAL);
pixbuf = image->data.name.pixbuf;
if (pixbuf) g_object_ref (pixbuf);
break;
case GTK_IMAGE_GICON:
- ensure_pixbuf_for_gicon (image);
+ ensure_pixbuf_for_gicon (image, GTK_STATE_NORMAL);
pixbuf = image->data.gicon.pixbuf;
if (pixbuf)
g_object_ref (pixbuf);