[gtk+/wip/window-scales2: 37/40] GtkIconHelper: Convert to using cairo surfaces as base and support scales



commit 031e1a98a0d26682572906b3a3853a284412aaf1
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Jun 24 14:13:43 2013 +0200

    GtkIconHelper: Convert to using cairo surfaces as base and support scales
    
    We render the source into a cairo_surface_t so that we can render it
    with cairo directly, rather than having to convert it from a pixbuf
    every time. We also specify the target window when creating the cairo
    surface so that rendering can be faster.
    
    Using cairo surfaces also allows us to seamlessly support window scales.
    
    We also add a GTK_IMAGE_SURFACE source type.

 gtk/gtkiconhelper.c        |  479 +++++++++++++++++++++++++++++++++++++++++---
 gtk/gtkiconhelperprivate.h |    8 +-
 gtk/gtkimage.h             |    5 +-
 3 files changed, 466 insertions(+), 26 deletions(-)
---
diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c
index 629f007..56cb97c 100644
--- a/gtk/gtkiconhelper.c
+++ b/gtk/gtkiconhelper.c
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include <math.h>
 #include "gtkiconhelperprivate.h"
 
 G_DEFINE_TYPE (GtkIconHelper, _gtk_icon_helper, G_TYPE_OBJECT)
@@ -29,11 +30,13 @@ struct _GtkIconHelperPrivate {
   GdkWindow *window;
 
   GdkPixbuf *orig_pixbuf;
+  int orig_pixbuf_scale;
   GdkPixbufAnimation *animation;
   GIcon *gicon;
   GtkIconSet *icon_set;
   gchar *icon_name;
   gchar *stock_id;
+  cairo_surface_t *orig_surface;
 
   GtkIconSize icon_size;
   gint pixel_size;
@@ -43,6 +46,12 @@ struct _GtkIconHelperPrivate {
 
   GdkPixbuf *rendered_pixbuf;
   GtkStateFlags last_rendered_state;
+
+  cairo_surface_t *rendered_surface;
+  gint rendered_surface_width;
+  gint rendered_surface_height;
+  GtkStateFlags last_surface_state;
+  gint last_surface_scale;
 };
 
 void
@@ -54,6 +63,18 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
   g_clear_object (&self->priv->rendered_pixbuf);
   g_clear_object (&self->priv->window);
 
+  if (self->priv->orig_surface)
+    {
+      cairo_surface_destroy (self->priv->orig_surface);
+      self->priv->orig_surface = NULL;
+    }
+
+  if (self->priv->rendered_surface)
+    {
+      cairo_surface_destroy (self->priv->rendered_surface);
+      self->priv->rendered_surface = NULL;
+    }
+
   if (self->priv->icon_set != NULL)
     {
       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
@@ -71,6 +92,8 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
   self->priv->storage_type = GTK_IMAGE_EMPTY;
   self->priv->icon_size = GTK_ICON_SIZE_INVALID;
   self->priv->last_rendered_state = GTK_STATE_FLAG_NORMAL;
+  self->priv->last_surface_state = GTK_STATE_FLAG_NORMAL;
+  self->priv->last_surface_scale = 0;
 }
 
 void
@@ -120,6 +143,7 @@ _gtk_icon_helper_init (GtkIconHelper *self)
   self->priv->icon_size = GTK_ICON_SIZE_INVALID;
   self->priv->pixel_size = -1;
   self->priv->last_rendered_state = GTK_STATE_FLAG_NORMAL;
+  self->priv->orig_pixbuf_scale = 1;
 }
 
 static void
@@ -301,6 +325,64 @@ ensure_pixbuf_for_icon_set (GtkIconHelper *self,
 }
 
 static void
+get_surface_size (GtkIconHelper   *self,
+                 GtkStyleContext *context,
+                 cairo_surface_t *surface,
+                 int *width,
+                 int *height)
+{
+  double x_scale, y_scale;
+
+  if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE)
+    {
+      x_scale = y_scale = 1;
+
+#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
+      cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
+#endif
+
+      /* Assume any set scaling is icon scale */
+      *width =
+       ceil (cairo_image_surface_get_width (surface) / x_scale);
+      *height =
+       ceil (cairo_image_surface_get_height (surface) / y_scale);
+    }
+  else
+    ensure_icon_size (self, context, width, height);
+}
+
+static void
+ensure_pixbuf_from_surface (GtkIconHelper   *self,
+                           GtkStyleContext *context)
+{
+  cairo_surface_t *surface;
+  gint width, height;
+  cairo_t *cr;
+
+
+  if (!check_invalidate_pixbuf (self, context))
+    return;
+
+  if (self->priv->rendered_pixbuf)
+    return;
+
+  get_surface_size (self, context, self->priv->orig_surface, &width, &height);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                       width, height);
+
+  cr = cairo_create (surface);
+  cairo_set_source_surface (cr, self->priv->orig_surface, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+
+  self->priv->rendered_pixbuf =
+    gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
+
+  cairo_surface_destroy (surface);
+}
+
+static void
 ensure_pixbuf_at_size (GtkIconHelper   *self,
                        GtkStyleContext *context)
 {
@@ -312,17 +394,34 @@ ensure_pixbuf_at_size (GtkIconHelper   *self,
   if (self->priv->rendered_pixbuf)
     return;
 
-  if (self->priv->pixel_size != -1 ||
-      self->priv->icon_size != GTK_ICON_SIZE_INVALID)
+  if (self->priv->force_scale_pixbuf &&
+      (self->priv->pixel_size != -1 ||
+       self->priv->icon_size != GTK_ICON_SIZE_INVALID))
     {
       ensure_icon_size (self, context, &width, &height);
 
-      if (width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) ||
+      if (self->priv->orig_pixbuf_scale > 1 ||
+         /* These should divide the orig_pixbuf size by scale, but need not 
+            due to the above scale > 1 check */
+         width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) ||
           height < gdk_pixbuf_get_height (self->priv->orig_pixbuf))
-        self->priv->rendered_pixbuf =
-          gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
-                                   width, height,
-                                   GDK_INTERP_BILINEAR);
+       {
+         width = MIN (width, gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale);
+         height = MIN (height, gdk_pixbuf_get_height (self->priv->orig_pixbuf) / 
self->priv->orig_pixbuf_scale);
+         self->priv->rendered_pixbuf =
+           gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
+                                    width, height,
+                                    GDK_INTERP_BILINEAR);
+       }
+    }
+  else if (self->priv->orig_pixbuf_scale > 1)
+    {
+         width = gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale;
+         height =gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale;
+         self->priv->rendered_pixbuf =
+           gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
+                                    width, height,
+                                    GDK_INTERP_BILINEAR);
     }
 
   if (!self->priv->rendered_pixbuf)
@@ -338,11 +437,12 @@ _gtk_icon_helper_ensure_pixbuf (GtkIconHelper *self,
 
   switch (self->priv->storage_type)
     {
+    case GTK_IMAGE_SURFACE:
+      ensure_pixbuf_from_surface (self, context);
+      break;
+
     case GTK_IMAGE_PIXBUF:
-      if (self->priv->force_scale_pixbuf)
-        ensure_pixbuf_at_size (self, context);
-      else
-        pixbuf = g_object_ref (self->priv->orig_pixbuf);
+      ensure_pixbuf_at_size (self, context);
       break;
 
     case GTK_IMAGE_STOCK:
@@ -379,24 +479,320 @@ _gtk_icon_helper_ensure_pixbuf (GtkIconHelper *self,
   return pixbuf;
 }
 
+static gint
+get_scale_factor (GtkIconHelper *self,
+                 GtkStyleContext *context)
+{
+  GdkScreen *screen;
+
+  if (self->priv->window)
+    return gdk_window_get_scale_factor (self->priv->window);
+
+  screen = gtk_style_context_get_screen (context);
+
+  /* else fall back to something that is more likely to be right than
+   * just returning 1:
+   */
+  return gdk_screen_get_monitor_scale_factor (screen, 0);
+}
+
+static gboolean
+check_invalidate_surface (GtkIconHelper *self,
+                         GtkStyleContext *context)
+{
+  GtkStateFlags state;
+  int scale;
+
+  state = gtk_style_context_get_state (context);
+  scale = get_scale_factor (self, context);
+
+  if ((self->priv->rendered_surface != NULL) &&
+      (self->priv->last_surface_state == state) &&
+      (self->priv->last_surface_scale == scale))
+    return FALSE;
+
+  self->priv->last_surface_state = state;
+  self->priv->last_surface_scale = scale;
+
+  if (self->priv->rendered_surface)
+    cairo_surface_destroy (self->priv->rendered_surface);
+  self->priv->rendered_surface = NULL;
+
+  return TRUE;
+}
+
+static void
+ensure_surface_from_surface (GtkIconHelper   *self,
+                            GtkStyleContext *context)
+{
+  if (!check_invalidate_surface (self, context))
+    return;
+
+  if (self->priv->rendered_surface)
+    return;
+
+  self->priv->rendered_surface =
+    cairo_surface_reference (self->priv->orig_surface);
+
+  get_surface_size (self, context, self->priv->orig_surface,
+                   &self->priv->rendered_surface_width,
+                   &self->priv->rendered_surface_height);
+}
+
+static void
+ensure_surface_from_pixbuf (GtkIconHelper   *self,
+                           GtkStyleContext *context)
+{
+  gint width, height;
+  GdkPixbuf *pixbuf;
+  int scale;
+
+  if (!check_invalidate_surface (self, context))
+    return;
+
+  if (self->priv->rendered_surface)
+    return;
+
+  scale = get_scale_factor (self, context);
+
+  if (self->priv->force_scale_pixbuf &&
+      (self->priv->pixel_size != -1 ||
+       self->priv->icon_size != GTK_ICON_SIZE_INVALID))
+    {
+      ensure_icon_size (self, context, &width, &height);
+
+      if (scale != self->priv->orig_pixbuf_scale ||
+         width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale ||
+          height < gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale)
+       {
+         width = MIN (width * scale, gdk_pixbuf_get_width (self->priv->orig_pixbuf) * scale / 
self->priv->orig_pixbuf_scale);
+         height = MIN (height * scale, gdk_pixbuf_get_height (self->priv->orig_pixbuf) * scale / 
self->priv->orig_pixbuf_scale);
+
+         pixbuf = gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
+                                           width, height,
+                                           GDK_INTERP_BILINEAR);
+       }
+      else
+       {
+         pixbuf = g_object_ref (self->priv->orig_pixbuf); 
+         scale = self->priv->orig_pixbuf_scale;
+       }
+    }
+  else
+    {
+      pixbuf = g_object_ref (self->priv->orig_pixbuf);
+      scale = self->priv->orig_pixbuf_scale;
+    }
+
+  self->priv->rendered_surface_width = (gdk_pixbuf_get_width (pixbuf) + scale - 1) / scale;
+  self->priv->rendered_surface_height = (gdk_pixbuf_get_height (pixbuf) + scale - 1) / scale;
+
+  self->priv->rendered_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, self->priv->window);
+  g_object_unref (pixbuf);
+}
+
+static void
+ensure_surface_for_icon_set (GtkIconHelper *self,
+                            GtkStyleContext *context,
+                            GtkIconSet *icon_set)
+{
+  gint scale;
+
+  if (!check_invalidate_surface (self, context))
+    return;
+
+  scale = get_scale_factor (self, context);
+
+  self->priv->rendered_surface =
+    gtk_icon_set_render_icon_surface (icon_set, context, 
+                                     self->priv->icon_size,
+                                     scale, self->priv->window);
+
+  if (self->priv->rendered_surface)
+    get_surface_size (self, context, self->priv->rendered_surface, 
+                     &self->priv->rendered_surface_width, 
+                     &self->priv->rendered_surface_height);
+}
+
+static void
+ensure_stated_surface_from_info (GtkIconHelper *self,
+                                GtkStyleContext *context,
+                                GtkIconInfo *info,
+                                int scale)
+{
+  GdkPixbuf *destination = NULL;
+  cairo_surface_t *surface;
+  gboolean symbolic;
+
+  symbolic = FALSE;
+
+  if (info)
+    destination =
+      gtk_icon_info_load_symbolic_for_context (info,
+                                              context,
+                                              &symbolic,
+                                              NULL);
+
+  if (destination == NULL)
+    {
+      GtkIconSet *icon_set;
+      icon_set = gtk_style_context_lookup_icon_set (context, GTK_STOCK_MISSING_IMAGE);
+
+      destination =
+        gtk_icon_set_render_icon_pixbuf (icon_set, context, self->priv->icon_size);
+    }
+  else if (!symbolic)
+    {
+      GtkIconSource *source;
+      GdkPixbuf *rendered;
+
+      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+
+      source = gtk_icon_source_new ();
+      gtk_icon_source_set_pixbuf (source, destination);
+      /* The size here is arbitrary; since size isn't
+       * wildcarded in the source, it isn't supposed to be
+       * scaled by the engine function
+       */
+      gtk_icon_source_set_size (source,
+                               GTK_ICON_SIZE_SMALL_TOOLBAR);
+      gtk_icon_source_set_size_wildcarded (source, FALSE);
+
+      rendered = gtk_render_icon_pixbuf (context, source, (GtkIconSize) -1);
+      gtk_icon_source_free (source);
+
+      G_GNUC_END_IGNORE_DEPRECATIONS;
+
+      g_object_unref (destination);
+      destination = rendered;
+    }
+
+  surface = NULL;
+  if (destination)
+    {
+      surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, self->priv->window);
+
+      self->priv->rendered_surface_width = 
+       (gdk_pixbuf_get_width (destination) + scale - 1) / scale;
+      self->priv->rendered_surface_height = 
+       (gdk_pixbuf_get_height (destination) + scale - 1) / scale;
+    }
+
+  self->priv->rendered_surface = surface;
+}
+
+static void
+ensure_surface_for_icon_name_or_gicon (GtkIconHelper *self,
+                                      GtkStyleContext *context)
+{
+  GtkIconTheme *icon_theme;
+  gint width, height, scale;
+  GtkIconInfo *info;
+  GtkIconLookupFlags flags;
+
+  if (!check_invalidate_surface (self, context))
+    return;
+
+  icon_theme = gtk_icon_theme_get_default ();
+  flags = get_icon_lookup_flags (self);
+
+  ensure_icon_size (self, context, &width, &height);
+  scale = get_scale_factor (self, context);
+
+  if (self->priv->storage_type == GTK_IMAGE_ICON_NAME &&
+      self->priv->icon_name != NULL)
+    {
+      info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
+                                                  self->priv->icon_name,
+                                                  MIN (width, height),
+                                                  scale, flags);
+    }
+  else if (self->priv->storage_type == GTK_IMAGE_GICON &&
+           self->priv->gicon != NULL)
+    {
+      info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
+                                                      self->priv->gicon,
+                                                      MIN (width, height),
+                                                      scale, flags);
+    }
+  else
+    {
+      g_assert_not_reached ();
+      return;
+    }
+
+  ensure_stated_surface_from_info (self, context, info, scale);
+
+  if (info)
+    g_object_unref (info);
+}
+
+cairo_surface_t *
+_gtk_icon_helper_ensure_surface (GtkIconHelper *self,
+                                GtkStyleContext *context)
+{
+  cairo_surface_t *surface = NULL;
+  GtkIconSet *icon_set;
+
+  switch (self->priv->storage_type)
+    {
+    case GTK_IMAGE_SURFACE:
+      ensure_surface_from_surface (self, context);
+      break;
+
+    case GTK_IMAGE_PIXBUF:
+      ensure_surface_from_pixbuf (self, context);
+      break;
+
+    case GTK_IMAGE_STOCK:
+      icon_set = gtk_style_context_lookup_icon_set (context, self->priv->stock_id);
+      if (icon_set != NULL)
+       ensure_surface_for_icon_set (self, context, icon_set);
+      else
+       surface = NULL;
+      break;
+
+    case GTK_IMAGE_ICON_SET:
+      icon_set = self->priv->icon_set;
+      ensure_surface_for_icon_set (self, context, icon_set);
+      break;
+
+    case GTK_IMAGE_ICON_NAME:
+    case GTK_IMAGE_GICON:
+      ensure_surface_for_icon_name_or_gicon (self, context);
+      break;
+
+    case GTK_IMAGE_ANIMATION:
+    case GTK_IMAGE_EMPTY:
+    default:
+      surface = NULL;
+      break;
+    }
+
+  if (surface == NULL &&
+      self->priv->rendered_surface != NULL)
+    surface = cairo_surface_reference (self->priv->rendered_surface);
+
+  return surface;
+}
+
 void
 _gtk_icon_helper_get_size (GtkIconHelper *self,
                            GtkStyleContext *context,
                            gint *width_out,
                            gint *height_out)
 {
-  GdkPixbuf *pix;
+  cairo_surface_t *surface;
   gint width, height;
 
   width = height = 0;
-  pix = _gtk_icon_helper_ensure_pixbuf (self, context);
+  surface = _gtk_icon_helper_ensure_surface (self, context);
 
-  if (pix != NULL)
+  if (surface != NULL)
     {
-      width = gdk_pixbuf_get_width (pix);
-      height = gdk_pixbuf_get_height (pix);
-
-      g_object_unref (pix);
+      width = self->priv->rendered_surface_width;
+      height = self->priv->rendered_surface_height;
+      cairo_surface_destroy (surface);
     }
   else if (self->priv->storage_type == GTK_IMAGE_ANIMATION)
     {
@@ -489,6 +885,19 @@ _gtk_icon_helper_set_animation (GtkIconHelper *self,
 }
 
 void 
+_gtk_icon_helper_set_surface (GtkIconHelper *self,
+                             cairo_surface_t *surface)
+{
+  _gtk_icon_helper_clear (self);
+
+  if (surface != NULL)
+    {
+      self->priv->storage_type = GTK_IMAGE_SURFACE;
+      self->priv->orig_surface = cairo_surface_reference (surface);
+    }
+}
+
+void 
 _gtk_icon_helper_set_stock_id (GtkIconHelper *self,
                                const gchar *stock_id,
                                GtkIconSize icon_size)
@@ -585,6 +994,12 @@ _gtk_icon_helper_peek_icon_set (GtkIconHelper *self)
   return self->priv->icon_set;
 }
 
+cairo_surface_t *
+_gtk_icon_helper_peek_surface (GtkIconHelper *self)
+{
+  return self->priv->orig_surface;
+}
+
 const gchar *
 _gtk_icon_helper_get_stock_id (GtkIconHelper *self)
 {
@@ -610,14 +1025,13 @@ _gtk_icon_helper_draw (GtkIconHelper *self,
                        gdouble x,
                        gdouble y)
 {
-  GdkPixbuf *pixbuf;
+  cairo_surface_t *surface;
 
-  pixbuf = _gtk_icon_helper_ensure_pixbuf (self, context);
-
-  if (pixbuf != NULL)
+  surface = _gtk_icon_helper_ensure_surface (self, context);
+  if (surface != NULL)
     {
-      gtk_render_icon (context, cr, pixbuf, x, y);
-      g_object_unref (pixbuf);
+      gtk_render_icon_surface (context, cr, surface, x, y);
+      cairo_surface_destroy (surface);
     }
 }
 
@@ -643,3 +1057,20 @@ _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
       _gtk_icon_helper_invalidate (self);
     }
 }
+
+void 
+_gtk_icon_helper_set_pixbuf_scale (GtkIconHelper *self,
+                                  int scale)
+{
+  if (self->priv->orig_pixbuf_scale != scale)
+    {
+      self->priv->orig_pixbuf_scale = scale;
+      _gtk_icon_helper_invalidate (self);
+    }
+}
+
+int
+_gtk_icon_helper_get_pixbuf_scale (GtkIconHelper *self)
+{
+  return self->priv->orig_pixbuf_scale;
+}
diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h
index 10467be..e7136ac 100644
--- a/gtk/gtkiconhelperprivate.h
+++ b/gtk/gtkiconhelperprivate.h
@@ -79,7 +79,10 @@ void _gtk_icon_helper_set_gicon (GtkIconHelper *self,
                                  GIcon *gicon,
                                  GtkIconSize icon_size);
 void _gtk_icon_helper_set_pixbuf (GtkIconHelper *self,
-                                  GdkPixbuf *pixbuf);
+                                 GdkPixbuf *pixbuf);
+void _gtk_icon_helper_set_pixbuf_scale (GtkIconHelper *self,
+                                       int scale);
+int  _gtk_icon_helper_get_pixbuf_scale (GtkIconHelper *self);
 void _gtk_icon_helper_set_animation (GtkIconHelper *self,
                                      GdkPixbufAnimation *animation);
 void _gtk_icon_helper_set_icon_set (GtkIconHelper *self,
@@ -92,6 +95,8 @@ void _gtk_icon_helper_set_icon_name (GtkIconHelper *self,
 void _gtk_icon_helper_set_stock_id (GtkIconHelper *self,
                                     const gchar *stock_id,
                                     GtkIconSize icon_size);
+void _gtk_icon_helper_set_surface (GtkIconHelper *self,
+                                  cairo_surface_t *surface);
 
 void _gtk_icon_helper_set_icon_size (GtkIconHelper *self,
                                      GtkIconSize icon_size);
@@ -109,6 +114,7 @@ GdkPixbuf *_gtk_icon_helper_peek_pixbuf (GtkIconHelper *self);
 GIcon *_gtk_icon_helper_peek_gicon (GtkIconHelper *self);
 GtkIconSet *_gtk_icon_helper_peek_icon_set (GtkIconHelper *self);
 GdkPixbufAnimation *_gtk_icon_helper_peek_animation (GtkIconHelper *self);
+cairo_surface_t *_gtk_icon_helper_peek_surface (GtkIconHelper *self);
 
 const gchar *_gtk_icon_helper_get_stock_id (GtkIconHelper *self);
 const gchar *_gtk_icon_helper_get_icon_name (GtkIconHelper *self);
diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h
index 07a9375..eb5be48 100644
--- a/gtk/gtkimage.h
+++ b/gtk/gtkimage.h
@@ -60,6 +60,8 @@ typedef struct _GtkImageClass         GtkImageClass;
  *  This image type was added in GTK+ 2.6
  * @GTK_IMAGE_GICON: the widget contains a #GIcon.
  *  This image type was added in GTK+ 2.14
+ * @GTK_IMAGE_SURFACE: the widget contains a #cairo_surface_t.
+ *  This image type was added in GTK+ 3.10
  *
  * Describes the image data representation used by a #GtkImage. If you
  * want to get the image from the widget, you can only get the
@@ -77,7 +79,8 @@ typedef enum
   GTK_IMAGE_ICON_SET,
   GTK_IMAGE_ANIMATION,
   GTK_IMAGE_ICON_NAME,
-  GTK_IMAGE_GICON
+  GTK_IMAGE_GICON,
+  GTK_IMAGE_SURFACE
 } GtkImageType;
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]