[gtk+] image: Add the ability to set textures



commit 2d959553e9de3dd11778c7fc22b8d759de90b729
Author: Benjamin Otte <otte redhat com>
Date:   Sat Nov 4 19:05:52 2017 +0100

    image: Add the ability to set textures
    
    This also adds it to all other places that use the same infrastructure:
    GtkEntry and GtkCellRendererPixbuf

 docs/reference/gtk/gtk4-sections.txt |    5 +
 gtk/a11y/gtkimageaccessible.c        |    9 ++
 gtk/gtkcellrendererpixbuf.c          |   23 +++++
 gtk/gtkentry.c                       |  163 ++++++++++++++++++++++++++++++++-
 gtk/gtkentry.h                       |    9 ++-
 gtk/gtkiconhelper.c                  |   42 +++++++++
 gtk/gtkiconhelperprivate.h           |    3 +
 gtk/gtkimage.c                       |   82 +++++++++++++++++-
 gtk/gtkimage.h                       |   12 +++-
 gtk/gtkimagedefinition.c             |   39 ++++++++-
 gtk/gtkimagedefinitionprivate.h      |    2 +
 11 files changed, 379 insertions(+), 10 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index fdbf953..0c5003c 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -915,10 +915,12 @@ gtk_entry_set_tabs
 gtk_entry_get_tabs
 GtkEntryIconPosition
 gtk_entry_set_icon_from_surface
+gtk_entry_set_icon_from_texture
 gtk_entry_set_icon_from_icon_name
 gtk_entry_set_icon_from_gicon
 gtk_entry_get_icon_storage_type
 gtk_entry_get_icon_surface
+gtk_entry_get_icon_texture
 gtk_entry_get_icon_name
 gtk_entry_get_icon_gicon
 gtk_entry_set_icon_activatable
@@ -1487,6 +1489,7 @@ GtkIconViewPrivate
 GtkImage
 GtkImageType
 gtk_image_get_surface
+gtk_image_get_texture
 gtk_image_get_icon_name
 gtk_image_get_gicon
 gtk_image_get_storage_type
@@ -1496,12 +1499,14 @@ gtk_image_new_from_icon_name
 gtk_image_new_from_gicon
 gtk_image_new_from_resource
 gtk_image_new_from_surface
+gtk_image_new_from_texture
 gtk_image_set_from_file
 gtk_image_set_from_pixbuf
 gtk_image_set_from_icon_name
 gtk_image_set_from_gicon
 gtk_image_set_from_resource
 gtk_image_set_from_surface
+gtk_image_set_from_texture
 gtk_image_clear
 gtk_image_new
 gtk_image_set_pixel_size
diff --git a/gtk/a11y/gtkimageaccessible.c b/gtk/a11y/gtkimageaccessible.c
index be2a3c5..338d894 100644
--- a/gtk/a11y/gtkimageaccessible.c
+++ b/gtk/a11y/gtkimageaccessible.c
@@ -279,6 +279,15 @@ gtk_image_accessible_get_image_size (AtkImage *image,
         *width = cairo_image_surface_get_width (surface);
         break;
       }
+    case GTK_IMAGE_TEXTURE:
+      {
+        GdkTexture *texture;
+
+        texture = gtk_image_get_texture (gtk_image);
+        *height = gdk_texture_get_height (texture);
+        *width = gdk_texture_get_width (texture);
+        break;
+      }
     case GTK_IMAGE_ICON_NAME:
     case GTK_IMAGE_GICON:
       {
diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c
index b53fe04..2c7fb0a 100644
--- a/gtk/gtkcellrendererpixbuf.c
+++ b/gtk/gtkcellrendererpixbuf.c
@@ -76,6 +76,7 @@ enum {
   PROP_PIXBUF_EXPANDER_OPEN,
   PROP_PIXBUF_EXPANDER_CLOSED,
   PROP_SURFACE,
+  PROP_TEXTURE,
   PROP_STOCK_SIZE,
   PROP_STOCK_DETAIL,
   PROP_ICON_NAME,
@@ -176,6 +177,19 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
                                                       CAIRO_GOBJECT_TYPE_SURFACE,
                                                       GTK_PARAM_READWRITE));
 
+  /**
+   * GtkCellRendererPixbuf:texture:
+   *
+   * Since: 3.94
+   */
+  g_object_class_install_property (object_class,
+                                  PROP_TEXTURE,
+                                  g_param_spec_object ("texture",
+                                                       P_("Texture"),
+                                                       P_("The texture to render"),
+                                                        GDK_TYPE_TEXTURE,
+                                                       GTK_PARAM_READWRITE));
+
   g_object_class_install_property (object_class,
                                   PROP_STOCK_SIZE,
                                   g_param_spec_uint ("stock-size",
@@ -268,6 +282,9 @@ gtk_cell_renderer_pixbuf_get_property (GObject        *object,
     case PROP_SURFACE:
       g_value_set_boxed (value, gtk_image_definition_get_surface (priv->image_def));
       break;
+    case PROP_TEXTURE:
+      g_value_set_object (value, gtk_image_definition_get_texture (priv->image_def));
+      break;
     case PROP_STOCK_SIZE:
       g_value_set_uint (value, priv->icon_size);
       break;
@@ -295,6 +312,9 @@ notify_storage_type (GtkCellRendererPixbuf *cellpixbuf,
     case GTK_IMAGE_SURFACE:
       g_object_notify (G_OBJECT (cellpixbuf), "surface");
       break;
+    case GTK_IMAGE_TEXTURE:
+      g_object_notify (G_OBJECT (cellpixbuf), "texture");
+      break;
     case GTK_IMAGE_ICON_NAME:
       g_object_notify (G_OBJECT (cellpixbuf), "icon-name");
       break;
@@ -362,6 +382,9 @@ gtk_cell_renderer_pixbuf_set_property (GObject      *object,
     case PROP_SURFACE:
       take_image_definition (cellpixbuf, gtk_image_definition_new_surface (g_value_get_boxed (value)));
       break;
+    case PROP_TEXTURE:
+      take_image_definition (cellpixbuf, gtk_image_definition_new_texture (g_value_get_object (value)));
+      break;
     case PROP_STOCK_SIZE:
       priv->icon_size = g_value_get_uint (value);
       break;
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 941c87d..afecb31 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -106,7 +106,7 @@
  * icons can be activatable by clicking, can be set up as drag source and
  * can have tooltips. To add an icon, use gtk_entry_set_icon_from_gicon() or
  * one of the various other functions that set an icon from a stock id, an
- * icon name, or a surface. To trigger an action when the user clicks an icon,
+ * icon name, or a texture. To trigger an action when the user clicks an icon,
  * connect to the #GtkEntry::icon-press signal. To allow DND operations
  * from an icon, use gtk_entry_set_icon_drag_source(). To set a tooltip on
  * an icon, use gtk_entry_set_icon_tooltip_text() or the corresponding function
@@ -341,6 +341,8 @@ enum {
   PROP_PROGRESS_PULSE_STEP,
   PROP_SURFACE_PRIMARY,
   PROP_SURFACE_SECONDARY,
+  PROP_TEXTURE_PRIMARY,
+  PROP_TEXTURE_SECONDARY,
   PROP_ICON_NAME_PRIMARY,
   PROP_ICON_NAME_SECONDARY,
   PROP_GICON_PRIMARY,
@@ -1034,6 +1036,34 @@ gtk_entry_class_init (GtkEntryClass *class)
                           CAIRO_GOBJECT_TYPE_SURFACE,
                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
 
+   /**
+   * GtkEntry:primary-icon-texture:
+   *
+   * A #GdkTexture to use as the primary icon for the entry.
+   *
+   * Since: 3.94
+   */
+  entry_props[PROP_TEXTURE_PRIMARY] =
+      g_param_spec_object ("primary-icon-texture",
+                           P_("Primary texture"),
+                           P_("Primary texture for the entry"),
+                           GDK_TYPE_TEXTURE,
+                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * GtkEntry:secondary-icon-texture:
+   *
+   * A #GtkTexture to use as the secondary icon for the entry.
+   *
+   * Since: 3.94
+   */
+  entry_props[PROP_TEXTURE_SECONDARY] =
+      g_param_spec_object ("secondary-icon-texture",
+                           P_("Secondary texture"),
+                           P_("Secondary texture for the entry"),
+                           GDK_TYPE_TEXTURE,
+                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
   /**
    * GtkEntry:primary-icon-name:
    *
@@ -2041,6 +2071,18 @@ gtk_entry_set_property (GObject         *object,
                                        g_value_get_boxed (value));
       break;
 
+    case PROP_TEXTURE_PRIMARY:
+      gtk_entry_set_icon_from_texture (entry,
+                                       GTK_ENTRY_ICON_PRIMARY,
+                                       g_value_get_boxed (value));
+      break;
+
+    case PROP_TEXTURE_SECONDARY:
+      gtk_entry_set_icon_from_texture (entry,
+                                       GTK_ENTRY_ICON_SECONDARY,
+                                       g_value_get_boxed (value));
+      break;
+
     case PROP_ICON_NAME_PRIMARY:
       gtk_entry_set_icon_from_icon_name (entry,
                                          GTK_ENTRY_ICON_PRIMARY,
@@ -2284,6 +2326,18 @@ gtk_entry_get_property (GObject         *object,
                                                      GTK_ENTRY_ICON_SECONDARY));
       break;
 
+    case PROP_TEXTURE_PRIMARY:
+      g_value_set_boxed (value,
+                         gtk_entry_get_icon_texture (entry,
+                                                     GTK_ENTRY_ICON_PRIMARY));
+      break;
+
+    case PROP_TEXTURE_SECONDARY:
+      g_value_set_boxed (value,
+                         gtk_entry_get_icon_texture (entry,
+                                                     GTK_ENTRY_ICON_SECONDARY));
+      break;
+
     case PROP_ICON_NAME_PRIMARY:
       g_value_set_string (value,
                           gtk_entry_get_icon_name (entry,
@@ -2641,9 +2695,9 @@ gtk_entry_dispose (GObject *object)
   GtkEntryPrivate *priv = entry->priv;
   GdkKeymap *keymap;
 
-  gtk_entry_set_icon_from_surface (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
+  gtk_entry_set_icon_from_texture (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
   gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
-  gtk_entry_set_icon_from_surface (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
+  gtk_entry_set_icon_from_texture (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
   gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
   gtk_entry_set_completion (entry, NULL);
 
@@ -6614,6 +6668,13 @@ gtk_entry_clear_icon (GtkEntry             *entry,
                                             : PROP_SURFACE_SECONDARY]);
       break;
 
+    case GTK_IMAGE_TEXTURE:
+      g_object_notify_by_pspec (G_OBJECT (entry),
+                                entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
+                                            ? PROP_TEXTURE_PRIMARY
+                                            : PROP_TEXTURE_SECONDARY]);
+      break;
+
     case GTK_IMAGE_ICON_NAME:
       g_object_notify_by_pspec (G_OBJECT (entry),
                                 entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
@@ -7554,6 +7615,64 @@ gtk_entry_set_icon_from_surface (GtkEntry             *entry,
 }
 
 /**
+ * gtk_entry_set_icon_from_texture:
+ * @entry: a #GtkEntry
+ * @icon_pos: Icon position
+ * @texture: (allow-none): A #GdkTexture, or %NULL
+ *
+ * Sets the icon shown in the specified position using a #GdkTexture
+ *
+ * If @texture is %NULL, no icon will be shown in the specified position.
+ *
+ * Since: 3.94
+ */
+void
+gtk_entry_set_icon_from_texture (GtkEntry             *entry,
+                                 GtkEntryIconPosition  icon_pos,
+                                 GdkTexture           *texture)
+{
+  GtkEntryPrivate *priv;
+  EntryIconInfo *icon_info;
+
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+  g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
+
+  priv = entry->priv;
+
+  if ((icon_info = priv->icons[icon_pos]) == NULL)
+    icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
+
+  g_object_freeze_notify (G_OBJECT (entry));
+
+  if (texture)
+    {
+      g_object_ref (texture);
+
+      gtk_image_set_from_texture (GTK_IMAGE (icon_info->widget), texture);
+
+      if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
+        {
+          g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_TEXTURE_PRIMARY]);
+          g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_PRIMARY]);
+        }
+      else
+        {
+          g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_TEXTURE_SECONDARY]);
+          g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_SECONDARY]);
+        }
+
+      g_object_unref (texture);
+    }
+  else
+    gtk_entry_clear_icon (entry, icon_pos);
+
+  if (gtk_widget_get_visible (GTK_WIDGET (entry)))
+    gtk_widget_queue_resize (GTK_WIDGET (entry));
+
+  g_object_thaw_notify (G_OBJECT (entry));
+}
+
+/**
  * gtk_entry_set_icon_from_icon_name:
  * @entry: A #GtkEntry
  * @icon_pos: The position at which to set the icon
@@ -7775,13 +7894,47 @@ gtk_entry_get_icon_surface (GtkEntry             *entry,
 }
 
 /**
+ * gtk_entry_get_icon_texture:
+ * @entry: A #GtkEntry
+ * @icon_pos: Icon position
+ *
+ * Retrieves the #GdkTexture used for the icon.
+ *
+ * If no #GdkTexture was used for the icon, %NULL is returned.
+ *
+ * Returns: (transfer none) (nullable): A #GdkTexture, or %NULL if no icon is
+ *     set for this position or the icon set is not a #GdkTexture.
+ *
+ * Since: 3.94
+ */
+GdkTexture *
+gtk_entry_get_icon_texture (GtkEntry             *entry,
+                            GtkEntryIconPosition  icon_pos)
+{
+  GtkEntryPrivate *priv;
+  EntryIconInfo *icon_info;
+
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+  g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
+
+  priv = entry->priv;
+
+  icon_info = priv->icons[icon_pos];
+
+  if (!icon_info)
+    return NULL;
+
+  return gtk_image_get_texture (GTK_IMAGE (icon_info->widget));
+}
+
+/**
  * gtk_entry_get_icon_gicon:
  * @entry: A #GtkEntry
  * @icon_pos: Icon position
  *
  * Retrieves the #GIcon used for the icon, or %NULL if there is
  * no icon or if the icon was set by some other method (e.g., by
- * stock, surface, or icon name).
+ * stock, texture, or icon name).
  *
  * Returns: (transfer none) (nullable): A #GIcon, or %NULL if no icon is set
  *     or if the icon is not a #GIcon
@@ -7818,7 +7971,7 @@ gtk_entry_get_icon_gicon (GtkEntry             *entry,
  *
  * Retrieves the icon name used for the icon, or %NULL if there is
  * no icon or if the icon was set by some other method (e.g., by
- * surface, stock or gicon).
+ * texture, stock or gicon).
  *
  * Returns: (nullable): An icon name, or %NULL if no icon is set or if the icon
  *          wasn’t set from an icon name
diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
index d0d4775..e2cbd7d 100644
--- a/gtk/gtkentry.h
+++ b/gtk/gtkentry.h
@@ -287,6 +287,10 @@ GDK_AVAILABLE_IN_3_94
 void           gtk_entry_set_icon_from_surface           (GtkEntry             *entry,
                                                          GtkEntryIconPosition  icon_pos,
                                                          cairo_surface_t      *surface);
+GDK_AVAILABLE_IN_3_94
+void           gtk_entry_set_icon_from_texture           (GtkEntry             *entry,
+                                                         GtkEntryIconPosition  icon_pos,
+                                                         GdkTexture           *texture);
 GDK_AVAILABLE_IN_ALL
 void           gtk_entry_set_icon_from_icon_name         (GtkEntry             *entry,
                                                          GtkEntryIconPosition  icon_pos,
@@ -296,11 +300,14 @@ void           gtk_entry_set_icon_from_gicon             (GtkEntry             *
                                                          GtkEntryIconPosition  icon_pos,
                                                          GIcon                *icon);
 GDK_AVAILABLE_IN_ALL
-GtkImageType gtk_entry_get_icon_storage_type             (GtkEntry             *entry,
+GtkImageType   gtk_entry_get_icon_storage_type           (GtkEntry             *entry,
                                                          GtkEntryIconPosition  icon_pos);
 GDK_AVAILABLE_IN_3_94
 cairo_surface_t*gtk_entry_get_icon_surface               (GtkEntry             *entry,
                                                          GtkEntryIconPosition  icon_pos);
+GDK_AVAILABLE_IN_3_94
+GdkTexture *   gtk_entry_get_icon_texture                (GtkEntry             *entry,
+                                                         GtkEntryIconPosition  icon_pos);
 GDK_AVAILABLE_IN_ALL
 const gchar* gtk_entry_get_icon_name                     (GtkEntry             *entry,
                                                          GtkEntryIconPosition  icon_pos);
diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c
index 4836103..776cbfb 100644
--- a/gtk/gtkiconhelper.c
+++ b/gtk/gtkiconhelper.c
@@ -235,6 +235,23 @@ ensure_surface_from_surface (GtkIconHelper   *self,
 }
 
 static cairo_surface_t *
+ensure_surface_from_texture (GtkIconHelper *self,
+                             GdkTexture    *texture)
+{
+  cairo_surface_t *surface;
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                        gdk_texture_get_width (texture),
+                                        gdk_texture_get_height (texture));
+  gdk_texture_download (texture,
+                        cairo_image_surface_get_data (surface),
+                        cairo_image_surface_get_stride (surface));
+  cairo_surface_mark_dirty (surface);
+
+  return surface;
+}
+
+static cairo_surface_t *
 ensure_surface_for_gicon (GtkIconHelper    *self,
                           GtkCssStyle      *style,
                           GtkTextDirection  dir,
@@ -327,6 +344,10 @@ gtk_icon_helper_load_surface (GtkIconHelper   *self,
       surface = ensure_surface_from_surface (self, gtk_image_definition_get_surface (self->def));
       break;
 
+    case GTK_IMAGE_TEXTURE:
+      surface = ensure_surface_from_texture (self, gtk_image_definition_get_texture (self->def));
+      break;
+
     case GTK_IMAGE_ICON_NAME:
       if (self->use_fallback)
         gicon = g_themed_icon_new_with_default_fallbacks (gtk_image_definition_get_icon_name (self->def));
@@ -405,6 +426,7 @@ find_cached_texture (GtkIconHelper *self)
       break;
     case GTK_IMAGE_EMPTY:
     case GTK_IMAGE_SURFACE:
+    case GTK_IMAGE_TEXTURE:
     default:
       return NULL;
     }
@@ -496,7 +518,14 @@ _gtk_icon_helper_get_size (GtkIconHelper *self,
     case GTK_IMAGE_GICON:
       if (self->pixel_size != -1 || self->force_scale_pixbuf)
         ensure_icon_size (self, &width, &height);
+      break;
 
+    case GTK_IMAGE_TEXTURE:
+      {
+        GdkTexture *texture = gtk_image_definition_get_texture (self->def);
+        width = gdk_texture_get_width (texture);
+        height = gdk_texture_get_height (texture);
+      }
       break;
 
     case GTK_IMAGE_EMPTY:
@@ -560,6 +589,13 @@ _gtk_icon_helper_set_surface (GtkIconHelper *self,
   gtk_icon_helper_take_definition (self, gtk_image_definition_new_surface (surface));
 }
 
+void
+_gtk_icon_helper_set_texture (GtkIconHelper *self,
+                             GdkTexture *texture)
+{
+  gtk_icon_helper_take_definition (self, gtk_image_definition_new_texture (texture));
+}
+
 gboolean
 _gtk_icon_helper_set_icon_size (GtkIconHelper *self,
                                 GtkIconSize    icon_size)
@@ -641,6 +677,12 @@ _gtk_icon_helper_peek_surface (GtkIconHelper *self)
   return gtk_image_definition_get_surface (self->def);
 }
 
+GdkTexture *
+_gtk_icon_helper_peek_texture (GtkIconHelper *self)
+{
+  return gtk_image_definition_get_texture (self->def);
+}
+
 const gchar *
 _gtk_icon_helper_get_icon_name (GtkIconHelper *self)
 {
diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h
index 5c28643..dbe3def 100644
--- a/gtk/gtkiconhelperprivate.h
+++ b/gtk/gtkiconhelperprivate.h
@@ -70,6 +70,8 @@ void _gtk_icon_helper_set_icon_name (GtkIconHelper *self,
                                      GtkIconSize icon_size);
 void _gtk_icon_helper_set_surface (GtkIconHelper *self,
                                   cairo_surface_t *surface);
+void _gtk_icon_helper_set_texture (GtkIconHelper *self,
+                                  GdkTexture *texture);
 
 gboolean _gtk_icon_helper_set_icon_size    (GtkIconHelper *self,
                                             GtkIconSize    icon_size);
@@ -85,6 +87,7 @@ gboolean _gtk_icon_helper_get_use_fallback (GtkIconHelper *self);
 
 GIcon *_gtk_icon_helper_peek_gicon (GtkIconHelper *self);
 cairo_surface_t *_gtk_icon_helper_peek_surface (GtkIconHelper *self);
+GdkTexture *_gtk_icon_helper_peek_texture (GtkIconHelper *self);
 
 GtkImageDefinition *gtk_icon_helper_get_definition (GtkIconHelper *self);
 const gchar *_gtk_icon_helper_get_icon_name (GtkIconHelper *self);
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index c76bcb9..29947e9 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -115,6 +115,7 @@ enum
 {
   PROP_0,
   PROP_SURFACE,
+  PROP_TEXTURE,
   PROP_FILE,
   PROP_ICON_SIZE,
   PROP_PIXEL_SIZE,
@@ -156,6 +157,13 @@ gtk_image_class_init (GtkImageClass *class)
                           CAIRO_GOBJECT_TYPE_SURFACE,
                           GTK_PARAM_READWRITE);
 
+  image_props[PROP_TEXTURE] =
+      g_param_spec_object ("texture",
+                           P_("Texture"),
+                           P_("A GdkTexture to display"),
+                           GDK_TYPE_TEXTURE,
+                           GTK_PARAM_READWRITE);
+
   image_props[PROP_FILE] =
       g_param_spec_string ("file",
                            P_("Filename"),
@@ -309,6 +317,9 @@ gtk_image_set_property (GObject      *object,
     case PROP_SURFACE:
       gtk_image_set_from_surface (image, g_value_get_boxed (value));
       break;
+    case PROP_TEXTURE:
+      gtk_image_set_from_texture (image, g_value_get_object (value));
+      break;
     case PROP_FILE:
       gtk_image_set_from_file (image, g_value_get_string (value));
       break;
@@ -357,6 +368,9 @@ gtk_image_get_property (GObject     *object,
     case PROP_SURFACE:
       g_value_set_boxed (value, _gtk_icon_helper_peek_surface (&priv->icon_helper));
       break;
+    case PROP_TEXTURE:
+      g_value_set_object (value, _gtk_icon_helper_peek_texture (&priv->icon_helper));
+      break;
     case PROP_FILE:
       g_value_set_string (value, priv->filename);
       break;
@@ -398,8 +412,8 @@ gtk_image_get_property (GObject     *object,
  * it always returns a valid #GtkImage widget.
  *
  * If you need to detect failures to load the file, use
- * gdk_pixbuf_new_from_file() to load the file yourself, then create
- * the #GtkImage from the surface.
+ * gdk_texture_new_from_file() to load the file yourself, then create
+ * the #GtkImage from the texture.
  *
  * The storage type (gtk_image_get_storage_type()) of the returned
  * image is not defined, it will be whatever is appropriate for
@@ -932,6 +946,42 @@ gtk_image_set_from_surface (GtkImage       *image,
 }
 
 /**
+ * gtk_image_set_from_texture:
+ * @image: a #GtkImage
+ * @surface: (nullable): a #GdkTexture or %NULL
+ *
+ * See gtk_image_new_from_texture() for details.
+ * 
+ * Since: 3.94
+ **/
+void
+gtk_image_set_from_texture (GtkImage   *image,
+                           GdkTexture *texture)
+{
+  GtkImagePrivate *priv = gtk_image_get_instance_private (image);
+
+  g_return_if_fail (GTK_IS_IMAGE (image));
+  g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture));
+
+  g_object_freeze_notify (G_OBJECT (image));
+
+  if (texture)
+    g_object_ref (texture);
+
+  gtk_image_clear (image);
+
+  if (texture)
+    {
+      _gtk_icon_helper_set_texture (&priv->icon_helper, texture);
+      g_object_unref (texture);
+    }
+
+  g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_TEXTURE]);
+  
+  g_object_thaw_notify (G_OBJECT (image));
+}
+
+/**
  * gtk_image_get_storage_type:
  * @image: a #GtkImage
  * 
@@ -976,6 +1026,31 @@ gtk_image_get_surface (GtkImage *image)
 }
 
 /**
+ * gtk_image_get_texture:
+ * @image: a #GtkImage
+ *
+ * Gets the image #GdkTexture being displayed by the #GtkImage.
+ * The storage type of the image must be %GTK_IMAGE_EMPTY or
+ * %GTK_IMAGE_TEXTURE (see gtk_image_get_storage_type()).
+ * The caller of this function does not own a reference to the
+ * returned texture.
+ * 
+ * Returns: (nullable) (transfer none): the displayed texture, or %NULL if
+ *   the image is empty
+ *
+ * Since: 3.94
+ **/
+GdkTexture *
+gtk_image_get_texture (GtkImage *image)
+{
+  GtkImagePrivate *priv = gtk_image_get_instance_private (image);
+
+  g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
+
+  return _gtk_icon_helper_peek_texture (&priv->icon_helper);
+}
+
+/**
  * gtk_image_get_icon_name:
  * @image: a #GtkImage
  * @icon_name: (out) (transfer none) (allow-none): place to store an
@@ -1145,6 +1220,9 @@ gtk_image_notify_for_storage_type (GtkImage     *image,
     case GTK_IMAGE_SURFACE:
       g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_SURFACE]);
       break;
+    case GTK_IMAGE_TEXTURE:
+      g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_TEXTURE]);
+      break;
     case GTK_IMAGE_EMPTY:
     default:
       break;
diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h
index de270b1..f7dbd3d 100644
--- a/gtk/gtkimage.h
+++ b/gtk/gtkimage.h
@@ -57,6 +57,8 @@ typedef struct _GtkImageClass         GtkImageClass;
  *  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
+ * @GTK_IMAGE_TEXTURE: the widget contains a #GdkTexture.
+ *  This image type was added in GTK+ 3.94
  *
  * Describes the image data representation used by a #GtkImage. If you
  * want to get the image from the widget, you can only get the
@@ -71,7 +73,8 @@ typedef enum
   GTK_IMAGE_EMPTY,
   GTK_IMAGE_ICON_NAME,
   GTK_IMAGE_GICON,
-  GTK_IMAGE_SURFACE
+  GTK_IMAGE_SURFACE,
+  GTK_IMAGE_TEXTURE
 } GtkImageType;
 
 /**
@@ -107,6 +110,8 @@ GDK_AVAILABLE_IN_ALL
 GtkWidget* gtk_image_new_from_resource  (const gchar     *resource_path);
 GDK_AVAILABLE_IN_ALL
 GtkWidget* gtk_image_new_from_pixbuf    (GdkPixbuf       *pixbuf);
+GDK_AVAILABLE_IN_3_94
+GtkWidget* gtk_image_new_from_texture   (GdkTexture      *texture);
 GDK_AVAILABLE_IN_ALL
 GtkWidget* gtk_image_new_from_icon_name (const gchar     *icon_name,
                                         GtkIconSize      size);
@@ -127,6 +132,9 @@ void gtk_image_set_from_resource  (GtkImage        *image,
 GDK_AVAILABLE_IN_ALL
 void gtk_image_set_from_pixbuf    (GtkImage        *image,
                                    GdkPixbuf       *pixbuf);
+GDK_AVAILABLE_IN_3_94
+void gtk_image_set_from_texture   (GtkImage        *image,
+                                   GdkTexture      *texture);
 GDK_AVAILABLE_IN_ALL
 void gtk_image_set_from_icon_name (GtkImage        *image,
                                   const gchar     *icon_name,
@@ -147,6 +155,8 @@ GtkImageType gtk_image_get_storage_type (GtkImage   *image);
 
 GDK_AVAILABLE_IN_3_94
 cairo_surface_t *gtk_image_get_surface (GtkImage *image);
+GDK_AVAILABLE_IN_3_94
+GdkTexture *gtk_image_get_texture  (GtkImage       *image);
 
 GDK_AVAILABLE_IN_ALL
 void       gtk_image_get_icon_name (GtkImage     *image,
diff --git a/gtk/gtkimagedefinition.c b/gtk/gtkimagedefinition.c
index f16006c..d1a1c99 100644
--- a/gtk/gtkimagedefinition.c
+++ b/gtk/gtkimagedefinition.c
@@ -24,6 +24,7 @@ typedef struct _GtkImageDefinitionStock GtkImageDefinitionStock;
 typedef struct _GtkImageDefinitionIconName GtkImageDefinitionIconName;
 typedef struct _GtkImageDefinitionGIcon GtkImageDefinitionGIcon;
 typedef struct _GtkImageDefinitionSurface GtkImageDefinitionSurface;
+typedef struct _GtkImageDefinitionTexture GtkImageDefinitionTexture;
 
 struct _GtkImageDefinitionEmpty {
   GtkImageType type;
@@ -58,6 +59,13 @@ struct _GtkImageDefinitionSurface {
   cairo_surface_t *surface;
 };
 
+struct _GtkImageDefinitionTexture {
+  GtkImageType type;
+  gint ref_count;
+
+  GdkTexture *texture;
+};
+
 union _GtkImageDefinition
 {
   GtkImageType type;
@@ -66,6 +74,7 @@ union _GtkImageDefinition
   GtkImageDefinitionIconName icon_name;
   GtkImageDefinitionGIcon gicon;
   GtkImageDefinitionSurface surface;
+  GtkImageDefinitionTexture texture;
 };
 
 GtkImageDefinition *
@@ -84,7 +93,8 @@ gtk_image_definition_alloc (GtkImageType type)
     sizeof (GtkImageDefinitionStock),
     sizeof (GtkImageDefinitionIconName),
     sizeof (GtkImageDefinitionGIcon),
-    sizeof (GtkImageDefinitionSurface)
+    sizeof (GtkImageDefinitionSurface),
+    sizeof (GtkImageDefinitionTexture)
   };
   GtkImageDefinition *def;
 
@@ -140,6 +150,20 @@ gtk_image_definition_new_surface (cairo_surface_t *surface)
 }
 
 GtkImageDefinition *
+gtk_image_definition_new_texture (GdkTexture *texture)
+{
+  GtkImageDefinition *def;
+
+  if (texture == NULL)
+    return NULL;
+
+  def = gtk_image_definition_alloc (GTK_IMAGE_TEXTURE);
+  def->texture.texture = g_object_ref (texture);
+
+  return def;
+}
+
+GtkImageDefinition *
 gtk_image_definition_ref (GtkImageDefinition *def)
 {
   def->empty.ref_count++;
@@ -164,6 +188,9 @@ gtk_image_definition_unref (GtkImageDefinition *def)
     case GTK_IMAGE_SURFACE:
       cairo_surface_destroy (def->surface.surface);
       break;
+    case GTK_IMAGE_TEXTURE:
+      g_object_unref (def->texture.texture);
+      break;
     case GTK_IMAGE_ICON_NAME:
       g_free (def->icon_name.icon_name);
       break;
@@ -190,6 +217,7 @@ gtk_image_definition_get_scale (const GtkImageDefinition *def)
       g_assert_not_reached ();
     case GTK_IMAGE_EMPTY:
     case GTK_IMAGE_SURFACE:
+    case GTK_IMAGE_TEXTURE:
     case GTK_IMAGE_ICON_NAME:
     case GTK_IMAGE_GICON:
       return 1;
@@ -222,3 +250,12 @@ gtk_image_definition_get_surface (const GtkImageDefinition *def)
 
   return def->surface.surface;
 }
+
+GdkTexture *
+gtk_image_definition_get_texture (const GtkImageDefinition *def)
+{
+  if (def->type != GTK_IMAGE_TEXTURE)
+    return NULL;
+
+  return def->texture.texture;
+}
diff --git a/gtk/gtkimagedefinitionprivate.h b/gtk/gtkimagedefinitionprivate.h
index 9acf7ce..2dac974 100644
--- a/gtk/gtkimagedefinitionprivate.h
+++ b/gtk/gtkimagedefinitionprivate.h
@@ -29,6 +29,7 @@ GtkImageDefinition *    gtk_image_definition_new_empty          (void);
 GtkImageDefinition *    gtk_image_definition_new_icon_name      (const char                     *icon_name);
 GtkImageDefinition *    gtk_image_definition_new_gicon          (GIcon                          *gicon);
 GtkImageDefinition *    gtk_image_definition_new_surface        (cairo_surface_t                *surface);
+GtkImageDefinition *    gtk_image_definition_new_texture        (GdkTexture                     *texture);
 
 GtkImageDefinition *    gtk_image_definition_ref                (GtkImageDefinition             *def);
 void                    gtk_image_definition_unref              (GtkImageDefinition             *def);
@@ -38,6 +39,7 @@ gint                    gtk_image_definition_get_scale          (const GtkImageD
 const gchar *           gtk_image_definition_get_icon_name      (const GtkImageDefinition       *def);
 GIcon *                 gtk_image_definition_get_gicon          (const GtkImageDefinition       *def);
 cairo_surface_t *       gtk_image_definition_get_surface        (const GtkImageDefinition       *def);
+GdkTexture *            gtk_image_definition_get_texture        (const GtkImageDefinition       *def);
 
 
 G_END_DECLS


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