initial stock implementation



Hi,

I did an initial implementation of the stock and stock icon stuff,
excluding the RcStyle and rc file parsing portion of the task (because
that part scares me ;-).  However this should contain all the changes
to Style, along with GtkIconSet, GtkIconFactory, and GtkStockItem.

This isn't a candidate patch, just a snapshot for commentary. It
compiles but I don't know if it works or not.

I'm going to need a list of stock items GTK includes by default. An
initial proposal:

 - The 5 message box types: Warning, Error, Info, Question, Generic
 - Buttons: OK, Cancel, Close
 - Menu/toolbar (?): Exit, New, Open, Save, Cut, Copy, Paste 

Proposal is to use the GNOME icons for all of these.

Making message boxes part of the stock system is somewhat different
from GNOME. The idea is that the image in the dialog and the title of
the dialog come from the stock icon and label. I'm not sure about
this; if we do it, I'll need to add another icon size to
GtkIconSizeType for message boxes.

Havoc

Index: gtk/Makefile.am
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/Makefile.am,v
retrieving revision 1.114
diff -u -r1.114 Makefile.am
--- gtk/Makefile.am	2000/06/21 20:47:20	1.114
+++ gtk/Makefile.am	2000/06/22 23:06:14
@@ -96,6 +96,7 @@
 	gtkhscrollbar.h		\
 	gtkhseparator.h		\
 	gtkhsv.h		\
+	gtkiconfactory.h	\
 	gtkimage.h		\
 	gtkimcontext.h		\
 	gtkimmulticontext.h	\
@@ -141,6 +142,7 @@
 	gtkspinbutton.h		\
 	gtkstyle.h		\
 	gtkstatusbar.h		\
+	gtkstock.h		\
 	gtktable.h		\
 	gtktearoffmenuitem.h    \
 	gtktextbuffer.h		\
@@ -235,6 +237,7 @@
 	gtkhscrollbar.c		\
 	gtkhseparator.c		\
 	gtkhsv.c		\
+	gtkiconfactory.c	\
 	gtkimage.c		\
 	gtkimcontext.c		\
 	gtkimcontextsimple.c	\
@@ -280,6 +283,7 @@
 	gtksignal.c		\
 	gtksocket.c             \
 	gtkspinbutton.c		\
+	gtkstock.c		\
 	gtkstyle.c		\
 	gtkstatusbar.c		\
 	gtktable.c		\
Index: gtk/gtkiconfactory.c
===================================================================
RCS file: gtkiconfactory.c
diff -N gtkiconfactory.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkiconfactory.c	Thu Jun 22 19:06:14 2000
@@ -0,0 +1,761 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "gtkiconfactory.h"
+
+static gpointer parent_class = NULL;
+
+static void gtk_icon_factory_init       (GtkIconFactory      *icon_factory);
+static void gtk_icon_factory_class_init (GtkIconFactoryClass *klass);
+static void gtk_icon_factory_finalize   (GObject             *object);
+
+GType
+gtk_icon_factory_get_type (void)
+{
+  static GType object_type = 0;
+
+  if (!object_type)
+    {
+      static const GTypeInfo object_info =
+      {
+        sizeof (GtkIconFactoryClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gtk_icon_factory_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data */
+        sizeof (GtkIconFactory),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) gtk_icon_factory_init,
+      };
+      
+      object_type = g_type_register_static (G_TYPE_OBJECT,
+                                            "GtkIconFactory",
+                                            &object_info);
+    }
+  
+  return object_type;
+}
+
+static void
+gtk_icon_factory_init (GtkIconFactory *factory)
+{
+  factory->icons = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+static void
+gtk_icon_factory_class_init (GtkIconFactoryClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = gtk_icon_factory_finalize;
+}
+
+static void
+free_icon_set (gpointer key, gpointer value, gpointer data)
+{
+  g_free (key);
+  gtk_icon_set_unref (value);
+}
+
+static void
+gtk_icon_factory_finalize (GObject *object)
+{
+  GtkIconFactory *factory = GTK_ICON_FACTORY (object);
+
+  g_hash_table_foreach (factory->icons, free_icon_set, NULL);
+  
+  g_hash_table_destroy (factory->icons);
+  
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+GtkIconFactory*
+gtk_icon_factory_new (void)
+{
+  return GTK_ICON_FACTORY (g_type_create_instance (GTK_TYPE_ICON_FACTORY));
+}
+
+void
+gtk_icon_factory_add (GtkIconFactory *factory,
+                      const gchar    *stock_id,
+                      GtkIconSet     *icon_set)
+{
+  gpointer old_key = NULL;
+  gpointer old_value = NULL;
+
+  g_return_if_fail (GTK_IS_ICON_FACTORY (factory));
+  g_return_if_fail (stock_id != NULL);
+  g_return_if_fail (icon_set != NULL);
+  
+  g_hash_table_lookup_extended (factory->icons, stock_id,
+                                &old_key, &old_value);
+
+  if (old_value == icon_set)
+    return;
+
+  gtk_icon_set_ref (icon_set);
+  
+  g_hash_table_insert (factory->icons, g_strdup (stock_id), icon_set);
+
+  if (old_key)
+    g_free (old_key);
+
+  if (old_value)
+    gtk_icon_set_unref (old_value);
+}
+
+GtkIconSet *
+gtk_icon_factory_lookup (GtkIconFactory *factory,
+                         const gchar    *stock_id)
+{
+  g_return_val_if_fail (GTK_IS_ICON_FACTORY (factory), NULL);
+  g_return_val_if_fail (stock_id != NULL, NULL);
+  
+  return g_hash_table_lookup (factory->icons, stock_id);
+}
+
+static GtkIconFactory *gtk_default_icons = NULL;
+static GSList *default_factories = NULL;
+
+void
+gtk_push_default_icon_factory (GtkIconFactory *factory)
+{
+  g_return_if_fail (GTK_IS_ICON_FACTORY (factory));
+
+  g_object_ref (G_OBJECT (factory));
+  
+  default_factories = g_slist_prepend (default_factories, factory);
+}
+
+GtkIconSet *
+gtk_default_icon_lookup (const gchar *stock_id)
+{
+  GSList *iter;
+
+  g_return_val_if_fail (stock_id != NULL, NULL);
+  
+  iter = default_factories;
+  while (iter != NULL)
+    {
+      GtkIconSet *icon_set =
+        gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
+                                 stock_id);
+
+      if (icon_set)
+        return icon_set;
+
+      iter = g_slist_next (iter);
+    }
+
+  if (gtk_default_icons == NULL)
+    {
+      /* FIXME create our default icons, should be kept
+       * in sync with the default stock items.
+       */
+      gtk_default_icons = gtk_icon_factory_new ();
+      
+    }
+  
+  return gtk_icon_factory_lookup (gtk_default_icons, stock_id);
+}
+
+/* Sizes */
+
+
+/* FIXME this shouldn't be hard-coded forever. Eventually
+ * it will somehow be user-configurable.
+ */
+
+static gint widths[] =
+{
+  16, /* menu */
+  24, /* button */
+  18, /* small toolbar */
+  24  /* large toolbar */
+};
+
+static gint heights[] =
+{
+  16, /* menu */
+  24, /* button */
+  18, /* small toolbar */
+  24  /* large toolbar */
+};
+
+void
+gtk_get_icon_size (GtkIconSizeType semantic_size,
+                   gint *width,
+                   gint *height)
+{
+  g_return_if_fail (semantic_size < G_N_ELEMENTS (widths));
+
+  if (width)
+    *width = widths[semantic_size];
+
+  if (height)
+    *height = heights[semantic_size];
+}
+
+
+/* Icon Set */
+
+static GdkPixbuf *find_in_cache (GtkIconSet      *icon_set,
+                                 GtkStyle        *style,
+                                 GtkTextDirection   direction,
+                                 GtkStateType     state,
+                                 GtkIconSizeType  size);
+static void       add_to_cache  (GtkIconSet      *icon_set,
+                                 GtkStyle        *style,
+                                 GtkTextDirection   direction,
+                                 GtkStateType     state,
+                                 GtkIconSizeType  size,
+                                 GdkPixbuf       *pixbuf);
+static void       clear_cache   (GtkIconSet      *icon_set);
+static GSList*    copy_cache    (GtkIconSet      *icon_set);
+
+static GSList* direction_state_size_matches (GSList           *sources,
+                                             GtkTextDirection  direction,
+                                             GtkStateType      state,
+                                             GtkIconSizeType   size);
+static GSList* state_size_matches           (GSList           *sources,
+                                             GtkStateType      state,
+                                             GtkIconSizeType   size);
+static GSList* size_matches                 (GSList           *sources,
+                                             GtkIconSizeType   size);
+
+struct _GtkIconSet
+{
+  guint ref_count;
+
+  GSList *sources;
+
+  /* Cache of the last few rendered versions of the icon. */
+  GSList *cache;
+
+  guint cache_size;
+};
+
+GtkIconSet*
+gtk_icon_set_new (void)
+{
+  GtkIconSet *icon_set;
+
+  icon_set = g_new (GtkIconSet, 1);
+
+  icon_set->ref_count = 1;
+  icon_set->sources = NULL;
+  icon_set->cache = NULL;
+  icon_set->cache_size = 0;
+  
+  return icon_set;
+}
+
+GtkIconSet*
+gtk_icon_set_ref (GtkIconSet *icon_set)
+{
+  g_return_val_if_fail (icon_set != NULL, NULL);
+  g_return_val_if_fail (icon_set->ref_count > 0, NULL);
+
+  icon_set->ref_count += 1;
+
+  return icon_set;
+}
+
+void
+gtk_icon_set_unref (GtkIconSet *icon_set)
+{
+  g_return_if_fail (icon_set != NULL);
+  g_return_if_fail (icon_set->ref_count > 0);
+
+  icon_set->ref_count -= 1;
+
+  if (icon_set->ref_count == 0)
+    {
+      GSList *iter = icon_set->sources;
+      while (iter != NULL)
+        {
+          gtk_icon_source_free (iter->data);
+
+          iter = g_slist_next (iter);
+        }
+
+      clear_cache (icon_set);
+
+      g_free (icon_set);
+    }
+}
+
+GtkIconSet*
+gtk_icon_set_copy (GtkIconSet *icon_set)
+{
+  GtkIconSet *copy;
+  GSList *iter;
+  
+  copy = gtk_icon_set_new ();
+
+  iter = icon_set->sources;
+  while (iter != NULL)
+    {
+      copy->sources = g_slist_prepend (copy->sources,
+                                       gtk_icon_source_copy (iter->data));
+
+      iter = g_slist_next (iter);
+    }
+
+  copy->sources = g_slist_reverse (copy->sources);
+
+  copy->cache = copy_cache (icon_set);
+  copy->cache_size = icon_set->cache_size;
+
+  return copy;
+}
+
+GdkPixbuf*
+gtk_icon_set_get_icon (GtkIconSet      *icon_set,
+                       GtkStyle        *style,
+                       GtkTextDirection   direction,
+                       GtkStateType     state,
+                       GtkIconSizeType  size,
+                       GtkWidget       *widget,
+                       const char      *detail)
+{
+  GdkPixbuf *icon;
+
+  GSList *candidates = NULL;
+  GtkIconSource *source;
+  
+  /* FIXME conceivably, everywhere this function
+   * returns NULL, we should return some default
+   * dummy icon like a question mark or the image icon
+   * from netscape
+   */
+  
+  g_return_val_if_fail (icon_set != NULL, NULL);
+
+  if (icon_set->sources == NULL)
+    return NULL;
+  
+  icon = find_in_cache (icon_set, style, direction,
+                        state, size);
+
+  if (icon)
+    {
+      g_object_ref (G_OBJECT (icon));
+      add_to_cache (icon_set, style, direction, state, size, icon);
+      return icon;
+    }
+
+  /* We need to find the best icon source.  Direction matters more
+   * than state, state matters more than size.
+   */
+  candidates = direction_state_size_matches (icon_set->sources,
+                                             direction,
+                                             state,
+                                             size);
+
+
+  if (candidates == NULL)
+    return NULL; /* No sources were found. */
+  
+  /* If multiple candidates were returned, it basically means the
+   * RC file contained stupidness. We just pick one at random.
+   */
+  source = candidates->data;
+  g_slist_free (candidates);
+
+  if (source->pixbuf == NULL)
+    {
+      if (source->filename == NULL)
+        {
+          g_warning ("Useless GtkIconSource contains NULL filename and pixbuf");
+          return NULL;
+        }
+
+      source->pixbuf = gdk_pixbuf_new_from_file (source->filename);
+
+      /* This needs to fail silently and do something sane.
+       * A good argument for returning a default icon.
+       */
+      if (source->pixbuf == NULL)
+        return NULL;
+    }
+
+  g_assert (source->pixbuf != NULL);
+  
+  if (style)
+    {
+      icon = gtk_style_render_icon (style,
+                                    source,
+                                    direction,
+                                    state,
+                                    size,
+                                    widget,
+                                    detail);
+    }
+  else
+    {
+      /* Internal function used here and in the default theme. */
+      icon = _gtk_default_render_icon (style,
+                                       source,
+                                       direction,
+                                       state,
+                                       size,
+                                       widget,
+                                       detail);
+    }
+
+  g_assert (icon != NULL);
+
+  add_to_cache (icon_set, style, direction, state, size, icon);
+  
+  return icon;
+}
+
+void
+gtk_icon_set_add_source (GtkIconSet *icon_set,
+                         const GtkIconSource *source)
+{
+  g_return_if_fail (icon_set != NULL);
+  g_return_if_fail (source != NULL);
+  
+  icon_set->sources = g_slist_prepend (icon_set->sources,
+                                       gtk_icon_source_copy (source));
+}
+
+GtkIconSource *
+gtk_icon_source_copy (const GtkIconSource *source)
+{
+  GtkIconSource *copy;
+  
+  g_return_val_if_fail (source != NULL, NULL);
+
+  copy = g_new (GtkIconSource, 1);
+
+  *copy = *source;
+  
+  copy->filename = g_strdup (source->filename);
+  if (copy->pixbuf)
+    g_object_ref (G_OBJECT (copy->pixbuf));
+
+  return copy;
+}
+
+void
+gtk_icon_source_free (GtkIconSource *source)
+{
+  g_return_if_fail (source != NULL);
+
+  g_free ((char*) source->filename);
+  if (source->pixbuf)
+    g_object_unref (G_OBJECT (source->pixbuf));
+
+  g_free (source);
+}
+
+void
+gtk_icon_set_clear (GtkIconSet *icon_set)
+{
+  GSList *iter;
+
+  g_return_if_fail (icon_set != NULL);
+  
+  iter = icon_set->sources;
+  while (iter != NULL)
+    {
+      gtk_icon_source_free (iter->data);
+
+      iter = g_slist_next (iter);
+    }
+
+  clear_cache (icon_set);
+}
+
+/* Note that the logical maximum is 20 per GtkTextDirection, so we could
+ * eventually set this to >20 to never throw anything out.
+ */
+#define NUM_CACHED_ICONS 8
+
+typedef struct _CachedIcon CachedIcon;
+
+struct _CachedIcon
+{
+  /* These must all match to use the cached pixbuf.
+   * If any don't match, we must re-render the pixbuf.  */
+  GtkStyle *style;
+  GtkTextDirection direction;
+  GtkStateType state;
+  GtkIconSizeType size;
+
+  GdkPixbuf *pixbuf;
+};
+
+static GdkPixbuf *
+find_in_cache (GtkIconSet      *icon_set,
+               GtkStyle        *style,
+               GtkTextDirection   direction,
+               GtkStateType     state,
+               GtkIconSizeType  size)
+{
+  GSList *iter;
+
+  iter = icon_set->cache;
+  while (iter != NULL)
+    {
+      CachedIcon *icon = iter->data;
+
+      if (icon->style == style &&
+          icon->direction == direction &&
+          icon->state == state &&
+          icon->size == size)
+        return icon->pixbuf;
+
+      iter = g_slist_next (iter);
+    }
+
+  return NULL;
+}
+
+static void
+add_to_cache (GtkIconSet      *icon_set,
+              GtkStyle        *style,
+              GtkTextDirection   direction,
+              GtkStateType     state,
+              GtkIconSizeType  size,
+              GdkPixbuf       *pixbuf)
+{
+  CachedIcon *icon;
+
+  g_object_ref (G_OBJECT (pixbuf));
+
+  /* We have to ref the style, since if the style was finalized
+   * its address could be reused by another style, creating a
+   * really weird bug
+   */
+  
+  if (style)
+    g_object_ref (G_OBJECT (style));
+  
+
+  icon = g_new (CachedIcon, 1);
+  icon_set->cache = g_slist_prepend (icon_set->cache, icon);
+
+  icon->style = style;
+  icon->direction = direction;
+  icon->state = state;
+  icon->size = size;
+  icon->pixbuf = pixbuf;
+
+  if (icon_set->cache_size >= NUM_CACHED_ICONS)
+    {
+      /* Remove oldest item in the cache */
+      
+      GSList *iter;
+      
+      iter = icon_set->cache;
+
+      /* Find next-to-last link */
+      g_assert (NUM_CACHED_ICONS > 2);
+      while (iter->next->next)
+        iter = iter->next;
+
+      g_assert (iter != NULL);
+      g_assert (iter->next != NULL);
+      g_assert (iter->next->next == NULL);
+
+      icon = iter->next->data;
+
+      g_slist_free (iter->next);
+      iter->next = NULL;
+      
+      g_object_unref (G_OBJECT (icon->pixbuf));
+      if (icon->style)
+        g_object_unref (G_OBJECT (icon->style));
+    }
+}
+
+static void
+clear_cache (GtkIconSet *icon_set)
+{
+  GSList *iter;
+
+  iter = icon_set->cache;
+  while (iter != NULL)
+    {
+      CachedIcon *icon = iter->data;
+
+      g_object_unref (G_OBJECT (icon->pixbuf));
+      if (icon->style)
+        g_object_unref (G_OBJECT (icon->style));
+
+      g_free (icon);
+      
+      iter = g_slist_next (iter);
+    }
+
+  g_slist_free (icon_set->cache);
+  icon_set->cache = NULL;
+  icon_set->cache_size = 0;
+}
+
+static GSList*
+copy_cache (GtkIconSet *icon_set)
+{
+  GSList *iter;
+  GSList *copy = NULL;
+  
+  iter = icon_set->cache;
+  while (iter != NULL)
+    {
+      CachedIcon *icon = iter->data;
+      CachedIcon *icon_copy = g_new (CachedIcon, 1);
+
+      *icon_copy = *icon;
+
+      if (icon_copy->style)
+        g_object_ref (G_OBJECT (icon_copy->style));
+      g_object_ref (G_OBJECT (icon_copy->pixbuf));
+          
+      copy = g_slist_prepend (copy, icon_copy);      
+      
+      iter = g_slist_next (iter);
+    }
+
+  return g_slist_reverse (copy);
+}
+
+static GSList*
+direction_state_size_matches (GSList *sources,
+                              GtkTextDirection direction,
+                              GtkStateType state,
+                              GtkIconSizeType size)
+{
+  GSList *direction_matches = NULL;
+  GSList *direction_wild = NULL;
+  GSList *candidates;
+  GSList *iter;
+  
+  iter = sources;
+  while (iter != NULL)
+    {
+      GtkIconSource *source = iter->data;
+
+      if (!source->any_direction &&
+          source->direction == direction)
+        direction_matches = g_slist_prepend (direction_matches, source);
+      else if (source->any_direction)
+        direction_wild = g_slist_prepend (direction_wild, source);
+      
+      iter = g_slist_next (iter);
+    }
+
+  /* First look for a matching source among exact direction matches,
+   * then look for a matching source among wildcard direction sources
+   */
+  candidates = state_size_matches (direction_matches, state, size);
+  if (candidates == NULL)
+    candidates = state_size_matches (direction_wild, state, size);
+
+  g_slist_free (direction_wild);
+  g_slist_free (direction_matches);
+
+  return candidates;
+}
+
+
+static GSList*
+state_size_matches (GSList *sources,
+                    GtkStateType state,
+                    GtkIconSizeType size)
+{
+  GSList *state_matches = NULL;
+  GSList *state_wild = NULL;
+  GSList *candidates;
+  GSList *iter;
+  
+  iter = sources;
+  while (iter != NULL)
+    {
+      GtkIconSource *source = iter->data;
+
+      if (!source->any_state &&
+          source->state == state)
+        state_matches = g_slist_prepend (state_matches, source);
+      else if (source->any_state)
+        state_wild = g_slist_prepend (state_wild, source);
+      
+      iter = g_slist_next (iter);
+    }
+
+  /* First look for a matching source among exact state matches,
+   * then look for a matching source among wildcard state sources
+   */
+  candidates = size_matches (state_matches, size);
+  if (candidates == NULL)
+    candidates = size_matches (state_wild, size);
+
+  g_slist_free (state_wild);
+  g_slist_free (state_matches);
+
+  return candidates;
+}
+
+static GSList*
+size_matches (GSList *sources,
+              GtkIconSizeType size)
+{
+  GSList *size_matches = NULL;
+  GSList *size_wild = NULL;
+  GSList *iter;
+  
+  iter = sources;
+  while (iter != NULL)
+    {
+      GtkIconSource *source = iter->data;
+
+      if (!source->any_size &&
+          source->size == size)
+        size_matches = g_slist_prepend (size_matches, source);
+      else if (source->any_size)
+        size_wild = g_slist_prepend (size_wild, source);
+      
+      iter = g_slist_next (iter);
+    }
+
+  /* Prefer exact size matches, return wildcard sizes otherwise. */
+  if (size_matches)
+    {
+      g_slist_free (size_wild);
+      return size_matches;
+    }
+  else
+    {
+      return size_wild;
+    }
+}
+
Index: gtk/gtkiconfactory.h
===================================================================
RCS file: gtkiconfactory.h
diff -N gtkiconfactory.h
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkiconfactory.h	Thu Jun 22 19:06:14 2000
@@ -0,0 +1,137 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GTK_ICON_FACTORY_H__
+#define __GTK_ICON_FACTORY_H__
+
+#include <gdk/gdk.h>
+#include <gtk/gtkstyle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkIconFactory      GtkIconFactory;
+typedef struct _GtkIconFactoryClass GtkIconFactoryClass;
+
+#define GTK_TYPE_ICON_FACTORY              (gtk_icon_factory_get_type ())
+#define GTK_ICON_FACTORY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_ICON_FACTORY, GtkIconFactory))
+#define GTK_ICON_FACTORY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ICON_FACTORY, GtkIconFactoryClass))
+#define GTK_IS_ICON_FACTORY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_ICON_FACTORY))
+#define GTK_IS_ICON_FACTORY_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ICON_FACTORY))
+#define GTK_ICON_FACTORY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON_FACTORY, GtkIconFactoryClass))
+
+struct _GtkIconFactory
+{
+  GObject parent_instance;
+
+  GHashTable *icons;
+};
+
+struct _GtkIconFactoryClass
+{
+  GObjectClass parent_class;
+
+  
+};
+
+GType           gtk_icon_factory_get_type (void);
+GtkIconFactory* gtk_icon_factory_new      (void);
+void            gtk_icon_factory_add      (GtkIconFactory *factory,
+                                           const gchar    *stock_id,
+                                           GtkIconSet     *icon_set);
+GtkIconSet *    gtk_icon_factory_lookup   (GtkIconFactory *factory,
+                                           const gchar    *stock_id);
+
+/* Manage the default icon factory stack */
+
+void        gtk_push_default_icon_factory (GtkIconFactory  *factory);
+GtkIconSet *gtk_default_icon_lookup       (const gchar     *stock_id);
+
+/* Get real size from semantic size (eventually user-configurable) */
+void        gtk_get_icon_size             (GtkIconSizeType  semantic_size,
+                                           gint            *width,
+                                           gint            *height);
+
+
+/* Icon sets */
+
+GtkIconSet* gtk_icon_set_ref             (GtkIconSet      *icon_set);
+void        gtk_icon_set_unref           (GtkIconSet      *icon_set);
+GtkIconSet* gtk_icon_set_copy            (GtkIconSet      *icon_set);
+
+/* Get one of the icon variants in the set, creating the variant if
+ * necessary.
+ */
+GdkPixbuf*  gtk_icon_set_get_icon        (GtkIconSet      *icon_set,
+                                          GtkStyle        *style,
+                                          GtkTextDirection direction,
+                                          GtkStateType     state,
+                                          GtkIconSizeType  size,
+                                          GtkWidget       *widget,
+                                          const char      *detail);
+
+GtkIconSet* gtk_icon_set_new             (void);
+
+struct _GtkIconSource
+{
+  /* Either filename or pixbuf can be NULL. If both are non-NULL,
+   * the filename gets ignored.
+   */
+  const char *filename;
+  GdkPixbuf *pixbuf;
+
+  GtkTextDirection direction;
+  GtkStateType state;
+  GtkIconSizeType size;
+
+  /* If TRUE, then the parameter is wildcarded, and the above
+   * fields should be ignored. If FALSE, the parameter is
+   * specified, and the above fields should be valid.
+   */
+  guint any_direction : 1;
+  guint any_state : 1;
+  guint any_size : 1;
+};
+
+void gtk_icon_set_add_source (GtkIconSet *icon_set,
+                              const GtkIconSource *source);
+
+GtkIconSource *gtk_icon_source_copy (const GtkIconSource *source);
+void           gtk_icon_source_free (GtkIconSource *source);
+
+/* Clear icon set contents, drop references to all contained
+ * GdkPixbuf objects and forget all GtkIconSources. Used to
+ * recycle an icon set.
+ */
+void        gtk_icon_set_clear           (GtkIconSet      *icon_set);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GTK_ICON_FACTORY_H__ */
Index: gtk/gtkstock.c
===================================================================
RCS file: gtkstock.c
diff -N gtkstock.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkstock.c	Thu Jun 22 19:06:14 2000
@@ -0,0 +1,145 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "gtkstock.h"
+#include "gtkintl.h"
+#include <gdk/gdkkeysyms.h>
+
+static GHashTable *stock_hash = NULL;
+static void init_stock_hash (void);
+
+static void
+real_add (const GtkStockItem *items,
+          guint               n_items,
+          gboolean            copy)
+{
+  int i;
+  
+  init_stock_hash ();
+
+  if (n_items == 0)
+    return;
+  
+  i = 0;
+  while (i < n_items)
+    {
+      const GtkStockItem * item = &items[i];
+      if (copy)
+        item = gtk_stock_item_copy (item);
+      
+      g_hash_table_insert (stock_hash,
+                           (gchar*)item->stock_id, (GtkStockItem*)item);
+      
+      ++i;
+    }
+}
+
+void
+gtk_stock_add (const GtkStockItem *items,
+               guint               n_items)
+{
+  g_return_if_fail (items != NULL);
+
+  real_add (items, n_items, TRUE);
+}
+
+void
+gtk_stock_add_static (const GtkStockItem *items,
+                      guint               n_items)
+{
+  g_return_if_fail (items != NULL);
+  
+  real_add (items, n_items, FALSE);
+}
+
+gboolean
+gtk_stock_lookup (const gchar  *stock_id,
+                  GtkStockItem *item)
+{
+  const GtkStockItem *found;
+
+  g_return_val_if_fail (stock_id != NULL, FALSE);
+  g_return_val_if_fail (item != NULL, FALSE);
+  
+  init_stock_hash ();
+  
+  found = g_hash_table_lookup (stock_hash, stock_id);
+
+  if (found)
+    *item = *found;
+
+  return found != NULL;
+}
+
+GtkStockItem *
+gtk_stock_item_copy (const GtkStockItem *item)
+{
+  GtkStockItem *copy;
+
+  g_return_val_if_fail (item != NULL, NULL);
+  
+  copy = g_new (GtkStockItem, 1);
+
+  *copy = *item;
+  
+  copy->stock_id = g_strdup (item->stock_id);
+  copy->label = g_strdup (item->label);
+  copy->translation_domain = g_strdup (item->translation_domain);
+
+  return copy;
+}
+
+void
+gtk_stock_item_free (GtkStockItem *item)
+{
+  g_return_if_fail (item != NULL);
+
+  g_free ((gchar*)item->stock_id);
+  g_free ((gchar*)item->label);
+  g_free ((gchar*)item->translation_domain);
+
+  g_free (item);
+}
+
+static GtkStockItem builtin_items [] =
+{
+  /* FIXME these are just examples */
+  /* and the OK accelerator is wrong, Return means default button,
+     OK should have its own accelerator */
+  { GTK_STOCK_OK, N_("OK"), 0, GDK_Return, "gtk+" }, 
+  { GTK_STOCK_EXIT, N_("Exit"), GDK_CONTROL_MASK, GDK_x, "gtk+" }
+};
+  
+static void
+init_stock_hash (void)
+{
+  if (stock_hash == NULL)
+    {
+      stock_hash = g_hash_table_new (g_str_hash, g_str_equal);
+      
+      gtk_stock_add_static (builtin_items, G_N_ELEMENTS (builtin_items));
+    }
+}
Index: gtk/gtkstock.h
===================================================================
RCS file: gtkstock.h
diff -N gtkstock.h
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkstock.h	Thu Jun 22 19:06:14 2000
@@ -0,0 +1,71 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GTK_STOCK_H__
+#define __GTK_STOCK_H__
+
+
+#include <gdk/gdk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkStockItem GtkStockItem;
+
+struct _GtkStockItem
+{
+  const char *stock_id;
+  const char *label;
+  GdkModifierType modifier;
+  guint keyval;
+  const char *translation_domain;
+};
+
+void     gtk_stock_add        (const GtkStockItem *item,
+                               guint               n_items);
+void     gtk_stock_add_static (const GtkStockItem *item,
+                               guint               n_items);
+gboolean gtk_stock_lookup     (const gchar        *stock_id,
+                               GtkStockItem       *item);
+
+
+
+GtkStockItem *gtk_stock_item_copy (const GtkStockItem *item);
+void          gtk_stock_item_free (GtkStockItem       *item);
+
+
+/* Stock IDs */
+#define GTK_STOCK_OK "OK"
+#define GTK_STOCK_CANCEL "Cancel"
+#define GTK_STOCK_EXIT "Exit"
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_STOCK_H__ */
Index: gtk/gtkstyle.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.39
diff -u -r1.39 gtkstyle.c
--- gtk/gtkstyle.c	2000/06/20 21:04:38	1.39
+++ gtk/gtkstyle.c	2000/06/22 23:06:14
@@ -31,8 +31,8 @@
 #include "gtkstyle.h"
 #include "gtkwidget.h"
 #include "gtkthemes.h"
+#include "gtkiconfactory.h"
 
-
 #define LIGHTNESS_MULT  1.3
 #define DARKNESS_MULT   0.7
 
@@ -432,6 +432,7 @@
 
   object_class->finalize = gtk_style_finalize;
 
+  klass->render_icon = _gtk_default_render_icon;
   klass->draw_hline = gtk_default_draw_hline;
   klass->draw_vline = gtk_default_draw_vline;
   klass->draw_shadow = gtk_default_draw_shadow;
@@ -795,6 +796,28 @@
     style->engine->realize_style (style);
 }
 
+GtkIconSet*
+gtk_style_lookup_icon (GtkStyle   *style,
+                       const char *stock_id)
+{
+  GSList *iter;
+
+  iter = style->icon_factories;
+  while (iter != NULL)
+    {
+      GtkIconSet *icon_set =
+        gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
+                                 stock_id);
+
+      if (icon_set)
+        return icon_set;
+      
+      iter = g_slist_next (iter);
+    }
+
+  return gtk_default_icon_lookup (stock_id);
+}
+
 void
 gtk_draw_hline (GtkStyle     *style,
                 GdkWindow    *window,
@@ -1176,6 +1199,22 @@
 }
 
 
+GdkPixbuf *
+gtk_style_render_icon (GtkStyle            *style,
+                       const GtkIconSource *source,
+                       GtkTextDirection     direction,
+                       GtkStateType         state,
+                       GtkIconSizeType      size,
+                       GtkWidget           *widget,
+                       const gchar         *detail)
+{
+  g_return_val_if_fail (style != NULL, NULL);
+  g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
+  
+  return GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
+                                                   size, widget, detail);
+}
+
 /* Default functions */
 void
 gtk_style_apply_default_background (GtkStyle     *style,
@@ -1239,6 +1278,157 @@
                              new_rect.x, new_rect.y, 
                              new_rect.width, new_rect.height);
     }
+}
+
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+
+static void
+gdk_pixbuf_saturate_and_pixelate(const GdkPixbuf *src,
+                                 GdkPixbuf *dest,
+                                 gfloat saturation,
+                                 gboolean pixelate)
+{
+  /* NOTE that src and dest MAY be the same pixbuf! */
+  
+  g_return_if_fail (src != NULL);
+  g_return_if_fail (dest != NULL);
+  g_return_if_fail (gdk_pixbuf_get_height (src) == gdk_pixbuf_get_height (dest));
+  g_return_if_fail (gdk_pixbuf_get_width (src) == gdk_pixbuf_get_width (dest));
+  g_return_if_fail (gdk_pixbuf_get_rowstride (src) == gdk_pixbuf_get_rowstride (dest));
+  g_return_if_fail (gdk_pixbuf_get_colorspace (src) == gdk_pixbuf_get_colorspace (dest));
+  
+  if (saturation == 1.0 && !pixelate)
+    {
+      if (dest != src)
+        memcpy (gdk_pixbuf_get_pixels (dest),
+                gdk_pixbuf_get_pixels (src),
+                gdk_pixbuf_get_height (src) * gdk_pixbuf_get_rowstride (src));
+
+      return;
+    }
+  else
+    {
+      gint i, j;
+      gint width, height, has_alpha, rowstride;
+      guchar *target_pixels;
+      guchar *original_pixels;
+      guchar *current_pixel;
+      guchar intensity;
+
+      has_alpha = gdk_pixbuf_get_has_alpha (src);
+      width = gdk_pixbuf_get_width (src);
+      height = gdk_pixbuf_get_height (src);
+      rowstride = gdk_pixbuf_get_rowstride (src);
+                
+      target_pixels = gdk_pixbuf_get_pixels (dest);
+      original_pixels = gdk_pixbuf_get_pixels (src);
+
+      for (i = 0; i < height; i++)
+        {
+          for (j = 0; j < width; j++)
+            {
+              current_pixel = original_pixels + i*rowstride + j*(has_alpha?4:3);
+              intensity = INTENSITY (*(current_pixel), *(current_pixel + 1), *(current_pixel + 2));
+              if (pixelate && (i+j)%2 == 0)
+                {
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3)) = intensity/2 + 127;
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) = intensity/2 + 127;
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) = intensity/2 + 127;
+                }
+              else if (pixelate)
+                {
+#define DARK_FACTOR 0.7
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3)) =
+                    (guchar) (((1.0 - saturation) * intensity
+                               + saturation * (*(current_pixel)))) * DARK_FACTOR;
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) =
+                    (guchar) (((1.0 - saturation) * intensity
+                               + saturation * (*(current_pixel + 1)))) * DARK_FACTOR;
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) =
+                    (guchar) (((1.0 - saturation) * intensity
+                               + saturation * (*(current_pixel + 2)))) * DARK_FACTOR;
+                }
+              else
+                {
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3)) =
+                    (guchar) ((1.0 - saturation) * intensity
+                              + saturation * (*(current_pixel)));
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) =
+                    (guchar) ((1.0 - saturation) * intensity
+                              + saturation * (*(current_pixel + 1)));
+                  *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) =
+                    (guchar) ((1.0 - saturation) * intensity
+                              + saturation * (*(current_pixel + 2)));
+                }
+              
+              if (has_alpha)
+                *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 3) = *(current_pixel + 3);
+            }
+        }
+
+      return;
+    }
+}
+
+static GdkPixbuf*
+scale_or_ref (GdkPixbuf *src,
+              gint width,
+              gint height)
+{
+  if (width == gdk_pixbuf_get_width (src) &&
+      height == gdk_pixbuf_get_height (src))
+    {
+      gdk_pixbuf_ref (src);
+      return src;
+    }
+  else
+    {
+      return gdk_pixbuf_scale_simple (src,
+                                      width, height,
+                                      GDK_INTERP_BILINEAR);
+    }
+}
+
+GdkPixbuf *
+_gtk_default_render_icon (GtkStyle            *style,
+                          const GtkIconSource *source,
+                          GtkTextDirection     direction,
+                          GtkStateType         state,
+                          GtkIconSizeType      size,
+                          GtkWidget           *widget,
+                          const gchar         *detail)
+{
+  gint width = 1;
+  gint height = 1;
+  GdkPixbuf *scaled;
+  GdkPixbuf *stated;
+
+  /* Oddly, style can be NULL in this function, because
+   * GtkIconSet can be used without a style and if so
+   * it uses this function.
+   */
+  
+  g_return_val_if_fail (source->pixbuf != NULL, NULL);
+  
+  gtk_get_icon_size (size, &width, &height);
+  
+  scaled = scale_or_ref (source->pixbuf, width, height);
+
+  if (state == GTK_STATE_INSENSITIVE)
+    {
+      stated = gdk_pixbuf_copy (scaled);      
+
+      gdk_pixbuf_saturate_and_pixelate (scaled, stated,
+                                        0.8, TRUE);
+
+      gdk_pixbuf_unref (scaled);
+    }
+  else
+    {
+      stated = scaled;
+    }
+  
+  return stated;
 }
 
 static void
Index: gtk/gtkstyle.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.h,v
retrieving revision 1.15
diff -u -r1.15 gtkstyle.h
--- gtk/gtkstyle.h	2000/06/20 21:04:38	1.15
+++ gtk/gtkstyle.h	2000/06/22 23:06:14
@@ -51,7 +51,16 @@
  */
 typedef struct _GtkThemeEngine GtkThemeEngine;
 typedef struct _GtkRcStyle     GtkRcStyle;
+typedef struct _GtkIconSet     GtkIconSet;
+typedef struct _GtkIconSource  GtkIconSource;
 
+typedef enum
+{
+  GTK_ICON_MENU,
+  GTK_ICON_BUTTON,
+  GTK_ICON_SMALL_TOOLBAR,
+  GTK_ICON_LARGE_TOOLBAR
+} GtkIconSizeType;
 
 /* We make this forward declaration here, since we pass
  * GtkWidgt's to the draw functions.
@@ -114,11 +123,21 @@
 				 * was created
 				 */
   GSList	 *styles;
+
+  GSList         *icon_factories;
 };
 
 struct _GtkStyleClass
 {
   GObjectClass parent_class;
+
+  GdkPixbuf * (* render_icon)   (GtkStyle               *style,
+                                 const GtkIconSource    *source,
+                                 GtkTextDirection        direction,
+                                 GtkStateType            state,
+                                 GtkIconSizeType         size,
+                                 GtkWidget              *widget,
+                                 const gchar            *detail);
   
   void (*draw_hline)		(GtkStyle		*style,
 				 GdkWindow		*window,
@@ -377,6 +396,16 @@
 					      gint	    width, 
 					      gint	    height);
 
+GtkIconSet* gtk_style_lookup_icon (GtkStyle            *style,
+                                   const char          *stock_id);
+GdkPixbuf * gtk_style_render_icon (GtkStyle            *style,
+                                   const GtkIconSource *source,
+                                   GtkTextDirection     direction,
+                                   GtkStateType         state,
+                                   GtkIconSizeType      size,
+                                   GtkWidget           *widget,
+                                   const gchar         *detail);
+
 void gtk_draw_hline      (GtkStyle        *style,
 			  GdkWindow       *window,
 			  GtkStateType     state_type,
@@ -783,6 +812,17 @@
 			   gint             width,
 			   gint             height,
 			   GtkOrientation   orientation);
+
+/* Internal */
+
+GdkPixbuf * _gtk_default_render_icon (GtkStyle            *style,
+                                      const GtkIconSource *source,
+                                      GtkTextDirection     direction,
+                                      GtkStateType         state,
+                                      GtkIconSizeType      size,
+                                      GtkWidget           *widget,
+                                      const gchar         *detail);
+
 
 #ifdef __cplusplus
 }
Index: gtk/gtkwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.c,v
retrieving revision 1.166
diff -u -r1.166 gtkwidget.c
--- gtk/gtkwidget.c	2000/06/21 20:41:15	1.166
+++ gtk/gtkwidget.c	2000/06/22 23:06:14
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <locale.h>
 #include "gtkcontainer.h"
+#include "gtkiconfactory.h"
 #include "gtkmain.h"
 #include "gtkrc.h"
 #include "gtkselection.h"
@@ -3188,6 +3189,35 @@
       gtk_style_unref ((GtkStyle*) tmp->data);
       g_slist_free_1 (tmp);
     }
+}
+
+GdkPixbuf*
+gtk_widget_get_icon (GtkWidget      *widget,
+                     const gchar    *stock_id,
+                     GtkIconSizeType size,
+                     const gchar    *detail)
+{
+  GtkIconSet *icon_set;
+  GdkPixbuf *retval;
+  
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+  
+  gtk_widget_ensure_style (widget);
+  
+  icon_set = gtk_style_lookup_icon (widget->style, stock_id);
+
+  if (icon_set == NULL)
+    return NULL;
+
+  retval = gtk_icon_set_get_icon (icon_set,
+                                  widget->style,
+                                  gtk_widget_get_direction (widget),
+                                  GTK_WIDGET_STATE (widget),
+                                  size,
+                                  widget,
+                                  detail);
+
+  return retval;
 }
 
 /**
Index: gtk/gtkwidget.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.h,v
retrieving revision 1.73
diff -u -r1.73 gtkwidget.h
--- gtk/gtkwidget.h	2000/06/02 17:02:16	1.73
+++ gtk/gtkwidget.h	2000/06/22 23:06:14
@@ -576,6 +576,11 @@
 void       gtk_widget_modify_style      (GtkWidget      *widget,
 					 GtkRcStyle     *style);
 
+GdkPixbuf* gtk_widget_get_icon          (GtkWidget      *widget,
+                                         const gchar    *stock_id,
+                                         GtkIconSizeType size,
+                                         const gchar    *detail);
+
 PangoContext *gtk_widget_create_pango_context (GtkWidget *widget);
 PangoLayout  *gtk_widget_create_pango_layout  (GtkWidget *widget);
 




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