Index: gtk+/gtk/gtkiconfactory.h
===================================================================
RCS file: /cvs/GNOME-RE/gtk+/gtk/gtkiconfactory.h,v
retrieving revision 1.9
diff -u -p -r1.9 gtkiconfactory.h
--- gtk+/gtk/gtkiconfactory.h	2002/03/02 19:11:38	1.9
+++ gtk+/gtk/gtkiconfactory.h	2002/08/28 10:34:43
@@ -164,6 +164,8 @@ GtkIconSize      gtk_icon_source_get_siz
 /* ignore this */
 void _gtk_icon_set_invalidate_caches (void);
 GSList* _gtk_icon_factory_list_ids (void);
+void    _gtk_restyle_icon_dimensions (void);
+void    _gtk_reset_icon_theme (void);
 
 #ifdef __cplusplus
 }
Index: gtk+/gtk/gtkiconfactory.c
===================================================================
RCS file: /cvs/GNOME-RE/gtk+/gtk/gtkiconfactory.c,v
retrieving revision 1.41
diff -u -p -r1.41 gtkiconfactory.c
--- gtk+/gtk/gtkiconfactory.c	2002/08/10 09:55:37	1.41
+++ gtk+/gtk/gtkiconfactory.c	2002/08/28 10:34:43
@@ -28,6 +28,7 @@
 #include "stock-icons/gtkstockpixbufs.h"
 #include "gtkstock.h"
 #include "gtkintl.h"
+#include "gtksettings.h"
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
@@ -808,8 +809,13 @@ struct _IconSize
   gint size;
   gchar *name;
   
+  /* Size for icon */
   gint width;
   gint height;
+
+  /* Size in theme for icon, which will override if not -1 */
+  gint prop_width;
+  gint prop_height;
 };
 
 typedef struct _IconAlias IconAlias;
@@ -825,60 +831,133 @@ static IconSize *icon_sizes = NULL;
 static gint      icon_sizes_allocated = 0;
 static gint      icon_sizes_used = 0;
 
+/**
+ * This method reads the gtk-icon-sizes property and
+ *    parses it to determine the default sizes to use for
+ *    gtk icons, both predefined named sizes, and new
+ *    named sizes.  If an icon size name does not appear
+ *    in the style property, the dimensions of that named
+ *    icon size are unchanged.
+ **/
 static void
+restyle_icon_dimensions_from_property (IconSize *sizes)
+{
+#define MAX_ICON_SIZES 24
+  gint i;
+  gint n = icon_sizes_used;
+  gchar *icon_size_prop = NULL;
+  gchar **size_strings;
+  GtkSettings *settings = gtk_settings_get_default ();
+  g_object_get (G_OBJECT (settings), "gtk-icon-sizes", &icon_size_prop, NULL);
+  if (icon_size_prop != NULL)
+    {
+      size_strings = g_strsplit (icon_size_prop, ":", MAX_ICON_SIZES);
+#undef MAX_ICON_SIZES  
+  /* parse by name */
+      i=0;
+      while (size_strings[i])
+        {
+	  gint j;
+	  gint k;
+	  gchar *name = NULL;
+	  gchar **substrings;
+	  substrings = g_strsplit (size_strings[i], " ", 2);
+	  j = 0;
+	  do
+	    {
+	      ++j;
+	      if (j == n) break;
+              if (!strncmp (sizes[j].name, "gtk-", 4))
+	        name = sizes[j].name+4;
+	      else
+	        name = sizes[j].name;
+	    } while (!name || strcmp (substrings[0], name)); 
+          if (j < n)
+            {
+	      gchar **istrings = g_strsplit (substrings[1], ",", 2);	    
+	      sizes[j].prop_width = atoi (istrings [0]);	
+	      sizes[j].prop_height = atoi (istrings [1]);
+	      g_message ("icon %s size set to %d\n", sizes[j].name,
+			 sizes[j].width);
+	      if (istrings[0]) g_free (istrings[0]);
+	      if (istrings[1]) g_free (istrings[1]);
+	      if (istrings) g_free (istrings);
+            }
+          k = 0;
+	  while (substrings[k])
+	    {
+              g_free (substrings[k]);
+	      ++k;
+	    }
+	  g_free (substrings);
+	  ++i;
+	}
+      i = 0;
+      while (size_strings[i])
+        {
+          g_free (size_strings[i]);
+	  ++i;
+	}
+      g_free (size_strings);
+      _gtk_icon_set_invalidate_caches ();
+    }
+}
+
+static void
 init_icon_sizes (void)
 {
   if (icon_sizes == NULL)
     {
-#define NUM_BUILTIN_SIZES 7
       gint i;
-
+#define NUM_BUILTIN_SIZES 7
       icon_aliases = g_hash_table_new (g_str_hash, g_str_equal);
       
       icon_sizes = g_new (IconSize, NUM_BUILTIN_SIZES);
+
       icon_sizes_allocated = NUM_BUILTIN_SIZES;
       icon_sizes_used = NUM_BUILTIN_SIZES;
 
-      icon_sizes[GTK_ICON_SIZE_INVALID].size = 0;
-      icon_sizes[GTK_ICON_SIZE_INVALID].name = NULL;
-      icon_sizes[GTK_ICON_SIZE_INVALID].width = 0;
-      icon_sizes[GTK_ICON_SIZE_INVALID].height = 0;
+      icon_sizes[GTK_ICON_SIZE_INVALID].size         = 0;
+      icon_sizes[GTK_ICON_SIZE_INVALID].name         = NULL;
+      icon_sizes[GTK_ICON_SIZE_INVALID].width        = 0;
+      icon_sizes[GTK_ICON_SIZE_INVALID].height       = 0;
 
       /* the name strings aren't copied since we don't ever remove
        * icon sizes, so we don't need to know whether they're static.
        * Even if we did I suppose removing the builtin sizes would be
        * disallowed.
        */
-      
-      icon_sizes[GTK_ICON_SIZE_MENU].size = GTK_ICON_SIZE_MENU;
-      icon_sizes[GTK_ICON_SIZE_MENU].name = "gtk-menu";
-      icon_sizes[GTK_ICON_SIZE_MENU].width = 16;
-      icon_sizes[GTK_ICON_SIZE_MENU].height = 16;
-
-      icon_sizes[GTK_ICON_SIZE_BUTTON].size = GTK_ICON_SIZE_BUTTON;
-      icon_sizes[GTK_ICON_SIZE_BUTTON].name = "gtk-button";
-      icon_sizes[GTK_ICON_SIZE_BUTTON].width = 20;
-      icon_sizes[GTK_ICON_SIZE_BUTTON].height = 20;
-
-      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].size = GTK_ICON_SIZE_SMALL_TOOLBAR;
-      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].name = "gtk-small-toolbar";
-      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].width = 18;
+      icon_sizes[GTK_ICON_SIZE_MENU].size            = GTK_ICON_SIZE_MENU;
+      icon_sizes[GTK_ICON_SIZE_MENU].name            = "gtk-menu";
+      icon_sizes[GTK_ICON_SIZE_MENU].width           = 16;
+      icon_sizes[GTK_ICON_SIZE_MENU].height          = 16;
+
+      icon_sizes[GTK_ICON_SIZE_BUTTON].size          = GTK_ICON_SIZE_BUTTON;
+      icon_sizes[GTK_ICON_SIZE_BUTTON].name          = "gtk-button";
+      icon_sizes[GTK_ICON_SIZE_BUTTON].width         = 20;
+      icon_sizes[GTK_ICON_SIZE_BUTTON].height        = 20;
+
+      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].size   = GTK_ICON_SIZE_SMALL_TOOLBAR;
+      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].name   = "gtk-small-toolbar";
+      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].width  = 18;
       icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].height = 18;
       
-      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].size = GTK_ICON_SIZE_LARGE_TOOLBAR;
-      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].name = "gtk-large-toolbar";
-      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].width = 24;
+      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].size   = GTK_ICON_SIZE_LARGE_TOOLBAR;
+      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].name   = "gtk-large-toolbar";
+      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].width  = 24;
       icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].height = 24;
+
+      icon_sizes[GTK_ICON_SIZE_DND].size             = GTK_ICON_SIZE_DND;
+      icon_sizes[GTK_ICON_SIZE_DND].name             = "gtk-dnd";
+      icon_sizes[GTK_ICON_SIZE_DND].width            = 32;
+      icon_sizes[GTK_ICON_SIZE_DND].height           = 32;
+
+      icon_sizes[GTK_ICON_SIZE_DIALOG].size          = GTK_ICON_SIZE_DIALOG;
+      icon_sizes[GTK_ICON_SIZE_DIALOG].name          = "gtk-dialog";
+      icon_sizes[GTK_ICON_SIZE_DIALOG].width         = 48;
+      icon_sizes[GTK_ICON_SIZE_DIALOG].height        = 48;
 
-      icon_sizes[GTK_ICON_SIZE_DND].size = GTK_ICON_SIZE_DND;
-      icon_sizes[GTK_ICON_SIZE_DND].name = "gtk-dnd";
-      icon_sizes[GTK_ICON_SIZE_DND].width = 32;
-      icon_sizes[GTK_ICON_SIZE_DND].height = 32;
-
-      icon_sizes[GTK_ICON_SIZE_DIALOG].size = GTK_ICON_SIZE_DIALOG;
-      icon_sizes[GTK_ICON_SIZE_DIALOG].name = "gtk-dialog";
-      icon_sizes[GTK_ICON_SIZE_DIALOG].width = 48;
-      icon_sizes[GTK_ICON_SIZE_DIALOG].height = 48;
+      _gtk_reset_icon_theme();
 
       g_assert ((GTK_ICON_SIZE_DIALOG + 1) == NUM_BUILTIN_SIZES);
 
@@ -890,12 +969,45 @@ init_icon_sizes (void)
           
           ++i;
         }
-      
 #undef NUM_BUILTIN_SIZES
+      restyle_icon_dimensions_from_property (icon_sizes);
+    }
+}
+
+/**
+ * _gtk_restyle_icon_dimensions:
+ *
+ * Restyles icon dimensions.  Called when properties change indicating
+ * that the icons need to be redisplayed.
+ */
+void
+_gtk_restyle_icon_dimensions (void)
+{
+    if (icon_sizes == NULL) {
+      init_icon_sizes();
+    } else {
+       restyle_icon_dimensions_from_property (icon_sizes);
     }
 }
 
 /**
+ * _gtk_reset_icon_theme
+ *
+ * Resets height/width values read from the property.
+ */
+void
+_gtk_reset_icon_theme (void)
+{
+    int i = 0;      
+    while (i < icon_sizes_used)
+      {
+        icon_sizes[i].prop_height = -1;
+        icon_sizes[i].prop_width  = -1;
+        ++i;
+      }
+}
+
+/**
  * gtk_icon_size_lookup:
  * @size: an icon size
  * @width: location to store icon width
@@ -925,11 +1037,26 @@ gtk_icon_size_lookup (GtkIconSize  size,
   if (size == GTK_ICON_SIZE_INVALID)
     return FALSE;
   
+  /*
+   * Use prop_height and prop_width if not -1.  This
+   * indicates the theme is overriding the size for this
+   * icon type.
+   */
   if (widthp)
-    *widthp = icon_sizes[size].width;
+  {
+    if (icon_sizes[size].prop_width != -1)
+      *widthp = icon_sizes[size].prop_width;
+    else
+      *widthp = icon_sizes[size].width;
+  }
 
   if (heightp)
-    *heightp = icon_sizes[size].height;
+  {
+    if (icon_sizes[size].prop_height != -1)
+      *heightp = icon_sizes[size].prop_height;
+    else
+      *heightp = icon_sizes[size].height;
+  }
 
   return TRUE;
 }
@@ -963,10 +1090,12 @@ gtk_icon_size_register (const gchar *nam
       icon_sizes = g_renew (IconSize, icon_sizes, icon_sizes_allocated);
     }
   
-  icon_sizes[icon_sizes_used].size = icon_sizes_used;
-  icon_sizes[icon_sizes_used].name = g_strdup (name);
-  icon_sizes[icon_sizes_used].width = width;
-  icon_sizes[icon_sizes_used].height = height;
+  icon_sizes[icon_sizes_used].size        = icon_sizes_used;
+  icon_sizes[icon_sizes_used].name        = g_strdup (name);
+  icon_sizes[icon_sizes_used].width       = width;
+  icon_sizes[icon_sizes_used].height      = height;
+  icon_sizes[icon_sizes_used].prop_width  = -1;
+  icon_sizes[icon_sizes_used].prop_height = -1;
 
   ++icon_sizes_used;
 
Index: gtk+/gtk/gtkrc.c
===================================================================
RCS file: /cvs/GNOME-RE/gtk+/gtk/gtkrc.c,v
retrieving revision 1.128
diff -u -p -r1.128 gtkrc.c
--- gtk+/gtk/gtkrc.c	2002/08/01 23:43:13	1.128
+++ gtk+/gtk/gtkrc.c	2002/08/28 10:34:43
@@ -517,6 +517,8 @@ gtk_rc_settings_changed (GtkSettings  *s
   gchar *new_theme_name;
   gchar *new_key_theme_name;
 
+  _gtk_reset_icon_theme();
+
   g_object_get (settings,
 		"gtk-theme-name", &new_theme_name,
 		"gtk-key-theme-name", &new_key_theme_name,
@@ -535,6 +537,14 @@ gtk_rc_settings_changed (GtkSettings  *s
 }
 
 static void
+gtk_rc_icon_changed (GtkSettings  *settings,
+			 GParamSpec   *pspec,
+			 GtkRcContext *context)
+{
+   _gtk_restyle_icon_dimensions();
+}
+
+static void
 gtk_rc_font_name_changed (GtkSettings  *settings,
                           GParamSpec   *pspec,
                           GtkRcContext *context)
@@ -575,6 +585,10 @@ gtk_rc_context_get (GtkSettings *setting
 			"notify::gtk-font-name",
 			G_CALLBACK (gtk_rc_font_name_changed),
 			context);
+      g_signal_connect (settings,
+			"notify::gtk-icon-sizes",
+			G_CALLBACK (gtk_rc_icon_changed),
+			context);
 
       
       context->pixmap_path[0] = NULL;
@@ -1730,7 +1744,6 @@ gtk_rc_get_style_by_paths (GtkSettings *
 	  const gchar *path;
           gchar *path_reversed;
 	  guint path_length;
-
 	  path = g_type_name (type);
 	  path_length = strlen (path);
 	  path_reversed = g_strdup (path);
Index: gtk+/gtk/gtksettings.c
===================================================================
RCS file: /cvs/GNOME-RE/gtk+/gtk/gtksettings.c,v
retrieving revision 1.30
diff -u -p -r1.30 gtksettings.c
--- gtk+/gtk/gtksettings.c	2002/08/01 23:43:13	1.30
+++ gtk+/gtk/gtksettings.c	2002/08/28 10:34:43
@@ -31,7 +31,8 @@ enum {
   PROP_KEY_THEME_NAME,
   PROP_MENU_BAR_ACCEL,
   PROP_DND_DRAG_THRESHOLD,
-  PROP_FONT_NAME
+  PROP_FONT_NAME,
+  PROP_ICON_SIZES
 };
 
 
@@ -213,6 +214,15 @@ gtk_settings_class_init (GtkSettingsClas
 								  G_PARAM_READWRITE),
                                              NULL);
   g_assert (result == PROP_FONT_NAME);
+ 
+  result = settings_install_property_parser (class,
+                                             g_param_spec_string ("gtk-icon-sizes",
+								   _("Icon Sized"),
+								   _("Size in pixels of Standard Icon Types (semicolon delimited list)"),
+								  "x",
+								  G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_ICON_SIZES);
  
 }
 
Index: gtk+/gtk/gtkstyle.c
===================================================================
RCS file: /cvs/GNOME-RE/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.123
diff -u -p -r1.123 gtkstyle.c
--- gtk+/gtk/gtkstyle.c	2002/08/05 18:52:26	1.123
+++ gtk+/gtk/gtkstyle.c	2002/08/28 10:34:43
@@ -2004,7 +2004,7 @@ gtk_default_render_icon (GtkStyle       
       return NULL;
     }
 
-  /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+  /* If we're allowed to scale, then scale; otherwise,
    * leave it alone.
    */
   if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
Index: gtk+/tests/testgtkrc2
===================================================================
RCS file: /cvs/GNOME-RE/gtk+/tests/testgtkrc2,v
retrieving revision 1.4
diff -u -p -r1.4 testgtkrc2
--- gtk+/tests/testgtkrc2	2000/06/02 03:14:07	1.4
+++ gtk+/tests/testgtkrc2	2002/08/28 10:34:43
@@ -1,21 +1,6 @@
-# pixmap_path "<dir 1>:<dir 2>:<dir 3>:..."
-#
-# include "rc-file"
-#
-# style <name> [= <name>]
-# {
-#   <option>
-# }
-#
-# widget <widget_set> style <style_name>
-# widget_class <widget_class_set> style <style_name>
-
-# this file gets included from testgtkrc
-
-style 'main_buttons' = 'button'
+style 'panel'
 {
-  font_name = "Monospace 10"
-  bg[PRELIGHT] = { 0, 0, 0.75 }
+  bg[SELECTED] = { 0xe000, 0xe000,  0xe000}
 }
 
-widget "main window.*GtkButton*" style "main_buttons"
+widget "*GtkWidget*" style "panel"
