 gtk/Makefile.am       |    2 
 gtk/Makefile.in       |   72 +++++++------
 gtk/gtkhashtable.c    |   99 ++++++++++++++++++
 gtk/gtkhashtable.h    |   61 +++++++++++
 gtk/gtkrc.c           |  266 +++++++++++++++++++++++++++++++++++++++-----------
 gtk/gtkrc.h           |    3 
 gtk/gtkstyle.c        |  127 +++++++++++++++++++----
 gtk/gtkstyle.h        |    4 
 gtk/gtktypebuiltins.c |    1 
 9 files changed, 521 insertions(+), 114 deletions(-)

Index: gtk+-2.6.4/gtk/gtkrc.c
===================================================================
--- gtk+-2.6.4.orig/gtk/gtkrc.c	2005-09-11 02:00:33.000000000 +0300
+++ gtk+-2.6.4/gtk/gtkrc.c	2005-09-11 02:01:02.000000000 +0300
@@ -56,6 +56,7 @@
 #include "gtkprivate.h"
 #include "gtksettings.h"
 #include "gtkwindow.h"
+#include "gtkhashtable.h"
 
 #ifdef G_OS_WIN32
 #include <io.h>
@@ -105,6 +106,14 @@ struct _GtkRcContext
   GtkStyle *default_style;
 };
 
+#define GTK_RC_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RC_STYLE, GtkRcStylePrivate))
+
+typedef struct _GtkRcStylePrivate GtkRcStylePrivate;
+
+struct _GtkRcStylePrivate {
+  GSList *logical_color_hashes;
+};
+
 static GtkRcContext *gtk_rc_context_get              (GtkSettings     *settings);
 
 static guint       gtk_rc_style_hash                 (const gchar     *name);
@@ -179,6 +188,13 @@ static guint       gtk_rc_parse_stock   
 						      GScanner        *scanner,
                                                       GtkRcStyle      *rc_style,
                                                       GtkIconFactory  *factory);
+static guint       gtk_rc_parse_logical_color        (GScanner        *scanner,
+                                                              GtkRcStyle      *rc_style,
+                                                             GtkHashTable    *hash);
+static guint       gtk_rc_parse_color_full           (GScanner        *scanner,
+                                                             GdkColor        *color,
+                                                             GtkRcStyle      *style);
+
 static void        gtk_rc_clear_hash_node            (gpointer         key,
                                                       gpointer         data,
                                                       gpointer         user_data);
@@ -277,7 +293,8 @@ static const struct
   { "stock", GTK_RC_TOKEN_STOCK },
   { "im_module_file", GTK_RC_TOKEN_IM_MODULE_FILE },
   { "LTR", GTK_RC_TOKEN_LTR },
-  { "RTL", GTK_RC_TOKEN_RTL }
+  { "RTL", GTK_RC_TOKEN_RTL },
+  { "logical_color", GTK_RC_TOKEN_LOGICAL_COLOR }
 };
 
 static GHashTable *realized_style_ht = NULL;
@@ -954,6 +971,7 @@ gtk_rc_style_get_type (void)
 static void
 gtk_rc_style_init (GtkRcStyle *style)
 {
+  GtkRcStylePrivate *priv = GTK_RC_STYLE_GET_PRIVATE (style);
   guint i;
 
   style->name = NULL;
@@ -976,6 +994,7 @@ gtk_rc_style_init (GtkRcStyle *style)
 
   style->rc_style_lists = NULL;
   style->icon_factories = NULL;
+  priv->logical_color_hashes = NULL;
 }
 
 static void
@@ -991,6 +1010,21 @@ gtk_rc_style_class_init (GtkRcStyleClass
   klass->create_rc_style = gtk_rc_style_real_create_rc_style;
   klass->merge = gtk_rc_style_real_merge;
   klass->create_style = gtk_rc_style_real_create_style;
+
+  g_type_class_add_private (object_class, sizeof (GtkRcStylePrivate));
+}
+
+static void
+free_object_list (GSList *list)
+{
+  GSList *tmp_list = list;
+  while (tmp_list)
+    {
+      g_object_unref (tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+  g_slist_free (list);
+  
 }
 
 static void
@@ -998,9 +1032,11 @@ gtk_rc_style_finalize (GObject *object)
 {
   GSList *tmp_list1, *tmp_list2;
   GtkRcStyle *rc_style;
+  GtkRcStylePrivate *rc_priv;
   gint i;
 
   rc_style = GTK_RC_STYLE (object);
+  rc_priv = GTK_RC_STYLE_GET_PRIVATE (rc_style);
   
   if (rc_style->name)
     g_free (rc_style->name);
@@ -1059,13 +1095,8 @@ gtk_rc_style_finalize (GObject *object)
       rc_style->rc_properties = NULL;
     }
 
-  tmp_list1 = rc_style->icon_factories;
-  while (tmp_list1)
-    {
-      g_object_unref (tmp_list1->data);
-      tmp_list1 = tmp_list1->next;
-    }
-  g_slist_free (rc_style->icon_factories);
+  free_object_list (rc_style->icon_factories);
+  free_object_list (rc_priv->logical_color_hashes);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -1125,6 +1156,14 @@ gtk_rc_style_real_create_rc_style (GtkRc
   return g_object_new (G_OBJECT_TYPE (style), NULL);
 }
 
+GSList *
+_gtk_rc_style_get_logical_color_hashes (GtkRcStyle *rc_style)
+{
+  GtkRcStylePrivate *priv = GTK_RC_STYLE_GET_PRIVATE (rc_style);
+
+  return priv->logical_color_hashes;
+}
+
 static gint
 gtk_rc_properties_cmp (gconstpointer bsearch_node1,
 		       gconstpointer bsearch_node2)
@@ -2062,6 +2101,29 @@ gtk_rc_style_to_style (GtkRcContext *con
   return style;
 }
 
+static GSList *
+concat_object_lists (GSList *list_a, GSList *list_b)
+{
+  GSList *copy;
+  
+  copy = g_slist_copy (list_b);
+  if (copy)
+    {
+      GSList *iter;
+              
+      iter = copy;
+      while (iter != NULL)
+        {
+          g_object_ref (iter->data);
+          iter = g_slist_next (iter);
+        }
+
+      return g_slist_concat (list_a, copy);
+    }
+  else
+    return list_a;
+}
+
 /* Reuses or frees rc_styles */
 static GtkStyle *
 gtk_rc_init_style (GtkRcContext *context,
@@ -2083,6 +2145,7 @@ gtk_rc_init_style (GtkRcContext *context
       GtkRcStyle *base_style = NULL;
       GtkRcStyle *proto_style;
       GtkRcStyleClass *proto_style_class;
+      GtkRcStylePrivate *proto_priv;
       GSList *tmp_styles;
       GType rc_style_type = GTK_TYPE_RC_STYLE;
 
@@ -2109,12 +2172,13 @@ gtk_rc_init_style (GtkRcContext *context
       
       proto_style_class = GTK_RC_STYLE_GET_CLASS (base_style);
       proto_style = proto_style_class->create_rc_style (base_style);
+      proto_priv = GTK_RC_STYLE_GET_PRIVATE (proto_style);
       
       tmp_styles = rc_styles;
       while (tmp_styles)
 	{
 	  GtkRcStyle *rc_style = tmp_styles->data;
-          GSList *factories;
+	  GtkRcStylePrivate *rc_priv = GTK_RC_STYLE_GET_PRIVATE (rc_style);
           
 	  proto_style_class->merge (proto_style, rc_style);	  
           
@@ -2122,22 +2186,12 @@ gtk_rc_init_style (GtkRcContext *context
 	  if (!g_slist_find (rc_style->rc_style_lists, rc_styles))
 	    rc_style->rc_style_lists = g_slist_prepend (rc_style->rc_style_lists, rc_styles);
 
-          factories = g_slist_copy (rc_style->icon_factories);
-          if (factories)
-            {
-              GSList *iter;
-              
-              iter = factories;
-              while (iter != NULL)
-                {
-                  g_object_ref (iter->data);
-                  iter = g_slist_next (iter);
-                }
-
-              proto_style->icon_factories = g_slist_concat (proto_style->icon_factories,
-                                                            factories);
-
-            }
+          proto_style->icon_factories =
+                concat_object_lists (proto_style->icon_factories,
+                                     rc_style->icon_factories);
+	  proto_priv->logical_color_hashes =
+                concat_object_lists (proto_priv->logical_color_hashes,
+                                     rc_priv->logical_color_hashes);
           
 	  tmp_styles = tmp_styles->next;
 	}
@@ -2515,9 +2569,11 @@ gtk_rc_parse_style (GtkRcContext *contex
   GtkRcStyle *rc_style;
   GtkRcStyle *orig_style;
   GtkRcStyle *parent_style;
+  GtkRcStylePrivate *rc_priv = NULL;
   guint token;
   gint i;
   GtkIconFactory *our_factory = NULL;
+  GtkHashTable *our_hash = NULL;
   
   token = g_scanner_get_next_token (scanner);
   if (token != GTK_RC_TOKEN_STYLE)
@@ -2533,12 +2589,6 @@ gtk_rc_parse_style (GtkRcContext *contex
   else
     orig_style = NULL;
 
-  /* If there's a list, its first member is always the factory belonging
-   * to this RcStyle
-   */
-  if (rc_style && rc_style->icon_factories)
-    our_factory = rc_style->icon_factories->data;
-  
   if (!rc_style)
     {
       rc_style = gtk_rc_style_new ();
@@ -2550,6 +2600,16 @@ gtk_rc_parse_style (GtkRcContext *contex
       for (i = 0; i < 5; i++)
 	rc_style->color_flags[i] = 0;
     }
+  
+  rc_priv = GTK_RC_STYLE_GET_PRIVATE (rc_style);
+
+  /* If there's a list, its first member is always the factory belonging
+   * to this RcStyle
+   */
+  if (rc_style->icon_factories)
+    our_factory = rc_style->icon_factories->data;
+  if (rc_priv->logical_color_hashes)
+    our_hash = rc_priv->logical_color_hashes->data;
 
   token = g_scanner_peek_next_token (scanner);
   if (token == G_TOKEN_EQUAL_SIGN)
@@ -2566,8 +2626,8 @@ gtk_rc_parse_style (GtkRcContext *contex
       parent_style = gtk_rc_style_find (context, scanner->value.v_string);
       if (parent_style)
 	{
-          GSList *factories;
-          
+	  GtkRcStylePrivate *parent_priv = GTK_RC_STYLE_GET_PRIVATE (parent_style); 
+
 	  for (i = 0; i < 5; i++)
 	    {
 	      rc_style->color_flags[i] = parent_style->color_flags[i];
@@ -2621,17 +2681,24 @@ gtk_rc_parse_style (GtkRcContext *contex
                   rc_style->icon_factories = g_slist_prepend (rc_style->icon_factories,
                                                               our_factory);
                 }
-              
-              rc_style->icon_factories = g_slist_concat (rc_style->icon_factories,
-                                                         g_slist_copy (parent_style->icon_factories));
-              
-              factories = parent_style->icon_factories;
-              while (factories != NULL)
+              rc_style->icon_factories = concat_object_lists (rc_style->icon_factories,
+                                                              parent_style->icon_factories);
+            }
+
+	  /* Also append parent's color hashes, adding a ref to them */
+          if (parent_priv->logical_color_hashes != NULL)
+            {
+	      /* See comment above .. */
+              if (our_hash == NULL)
                 {
-                  g_object_ref (factories->data);
-                  factories = factories->next;
+                  our_hash = _gtk_hash_table_new ();
+                  rc_priv->logical_color_hashes = g_slist_prepend (rc_priv->logical_color_hashes,
+                                                                    our_hash);
                 }
-            }
+               
+              rc_priv->logical_color_hashes = concat_object_lists (rc_priv->logical_color_hashes,
+                                                                    parent_priv->logical_color_hashes);           
+          }
 	}
     }
   
@@ -2689,6 +2756,15 @@ gtk_rc_parse_style (GtkRcContext *contex
             }
           token = gtk_rc_parse_stock (context, scanner, rc_style, our_factory);
           break;
+    case GTK_RC_TOKEN_LOGICAL_COLOR:
+	  if (our_hash == NULL)
+	    {
+	      our_hash = _gtk_hash_table_new ();
+	      rc_priv->logical_color_hashes = g_slist_prepend (rc_priv->logical_color_hashes,
+								our_hash);
+	    }
+	  token = gtk_rc_parse_logical_color (scanner, rc_style, our_hash);
+	  break;
 	case G_TOKEN_IDENTIFIER:
 	  if (is_c_identifier (scanner->next_value.v_identifier) &&
 	      scanner->next_value.v_identifier[0] >= 'A' &&
@@ -2828,7 +2904,7 @@ gtk_rc_parse_bg (GScanner   *scanner,
     return G_TOKEN_EQUAL_SIGN;
 
   style->color_flags[state] |= GTK_RC_BG;
-  return gtk_rc_parse_color (scanner, &style->bg[state]);
+  return gtk_rc_parse_color_full (scanner, &style->bg[state], style);
 }
 
 static guint
@@ -2851,7 +2927,7 @@ gtk_rc_parse_fg (GScanner   *scanner,
     return G_TOKEN_EQUAL_SIGN;
   
   style->color_flags[state] |= GTK_RC_FG;
-  return gtk_rc_parse_color (scanner, &style->fg[state]);
+  return gtk_rc_parse_color_full (scanner, &style->fg[state], style);
 }
 
 static guint
@@ -2874,7 +2950,7 @@ gtk_rc_parse_text (GScanner   *scanner,
     return G_TOKEN_EQUAL_SIGN;
   
   style->color_flags[state] |= GTK_RC_TEXT;
-  return gtk_rc_parse_color (scanner, &style->text[state]);
+  return gtk_rc_parse_color_full (scanner, &style->text[state], style);
 }
 
 static guint
@@ -2897,7 +2973,7 @@ gtk_rc_parse_base (GScanner   *scanner,
     return G_TOKEN_EQUAL_SIGN;
 
   style->color_flags[state] |= GTK_RC_BASE;
-  return gtk_rc_parse_color (scanner, &style->base[state]);
+  return gtk_rc_parse_color_full (scanner, &style->base[state], style);
 }
 
 static guint
@@ -3348,11 +3424,45 @@ gtk_rc_parse_priority (GScanner	        
 
   return G_TOKEN_NONE;
 }
+static gboolean
+lookup_logical_color (GtkRcStyle *style,
+		      const char *color_name,
+		      GdkColor   *color)
+{
+  GtkRcStylePrivate *priv = GTK_RC_STYLE_GET_PRIVATE (style);
+  GSList *iter;
+
+  iter = priv->logical_color_hashes;
+  while (iter != NULL)
+    {
+      GdkColor *match = g_hash_table_lookup (GTK_HASH_TABLE (iter->data)->hash,
+					     color_name);
+      if (match)
+	{
+	  color->red = match->red;
+	  color->green = match->green;
+	  color->blue = match->blue;
+	  return TRUE;
+        }
+
+      iter = g_slist_next (iter);
+    }
+
+  return FALSE;
+}
 
 guint
 gtk_rc_parse_color (GScanner *scanner,
 		    GdkColor *color)
 {
+    return gtk_rc_parse_color_full (scanner, color, NULL);
+}
+
+static guint
+gtk_rc_parse_color_full (GScanner *scanner,
+		         GdkColor *color,
+		         GtkRcStyle *style)
+{
   guint token;
 
   g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
@@ -3410,11 +3520,14 @@ gtk_rc_parse_color (GScanner *scanner,
     case G_TOKEN_STRING:
       if (!gdk_color_parse (scanner->value.v_string, color))
 	{
-	  g_scanner_warn (scanner, "Invalid color constant '%s'",
-			  scanner->value.v_string);
-	  return G_TOKEN_STRING;
+	  if (!(style && lookup_logical_color (style, scanner->value.v_string, color)))
+	    {
+	      g_scanner_warn (scanner, "Invalid color constant '%s'",
+			      scanner->value.v_string);
+	      return G_TOKEN_STRING;
+	    }
 	}
-      else
+
 	return G_TOKEN_NONE;
       
     default:
@@ -3628,8 +3741,8 @@ gtk_rc_parse_path_pattern (GtkRcContext 
 }
 
 static guint
-gtk_rc_parse_stock_id (GScanner	 *scanner,
-                       gchar    **stock_id)
+gtk_rc_parse_hash_key (GScanner *scanner,
+                       gchar    **hash_key)
 {
   guint token;
   
@@ -3642,12 +3755,12 @@ gtk_rc_parse_stock_id (GScanner	 *scanne
   if (token != G_TOKEN_STRING)
     return G_TOKEN_STRING;
   
-  *stock_id = g_strdup (scanner->value.v_string);
+  *hash_key = g_strdup (scanner->value.v_string);
   
   token = g_scanner_get_next_token (scanner);
   if (token != G_TOKEN_RIGHT_BRACE)
     {
-      g_free (*stock_id);
+      g_free (*hash_key);
       return G_TOKEN_RIGHT_BRACE;
     }
   
@@ -3857,7 +3970,7 @@ gtk_rc_parse_stock (GtkRcContext   *cont
   if (token != GTK_RC_TOKEN_STOCK)
     return GTK_RC_TOKEN_STOCK;
   
-  token = gtk_rc_parse_stock_id (scanner, &stock_id);
+  token = gtk_rc_parse_hash_key (scanner, &stock_id);
   if (token != G_TOKEN_NONE)
     return token;
   
@@ -3968,3 +4081,46 @@ gtk_rc_parse (const gchar *filename)
 }
 
 #endif
+
+static guint
+gtk_rc_parse_logical_color (GScanner     *scanner,
+		GtkRcStyle   *rc_style,
+		GtkHashTable *hash)
+{
+	gchar *color_id = NULL;
+	guint token;
+	GdkColor *color;
+
+	token = g_scanner_get_next_token (scanner);
+	if (token != GTK_RC_TOKEN_LOGICAL_COLOR)
+		return GTK_RC_TOKEN_LOGICAL_COLOR;
+
+	token = gtk_rc_parse_hash_key (scanner, &color_id);
+	if (token != G_TOKEN_NONE)
+		return token;
+
+	token = g_scanner_get_next_token (scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+	{
+		g_free (color_id);
+		return G_TOKEN_EQUAL_SIGN;
+	}
+
+	color = g_new (GdkColor, 1);
+	token = gtk_rc_parse_color_full (scanner, color, rc_style);
+	if (token != G_TOKEN_NONE)
+	{
+		g_free (color_id);
+		g_free (color);
+		return token;
+	}
+
+	/* Because the hash is created with destroy functions,
+	 * g_hash_table_insert will free any old values for us,
+	 * if a mapping with the specified key already exists. */
+	g_hash_table_insert (hash->hash, color_id, color);
+
+	return G_TOKEN_NONE;
+}
+
+
Index: gtk+-2.6.4/gtk/gtkrc.h
===================================================================
--- gtk+-2.6.4.orig/gtk/gtkrc.h	2005-09-11 01:52:25.000000000 +0300
+++ gtk+-2.6.4/gtk/gtkrc.h	2005-09-11 02:01:02.000000000 +0300
@@ -211,6 +211,7 @@ typedef enum {
   GTK_RC_TOKEN_STOCK,
   GTK_RC_TOKEN_LTR,
   GTK_RC_TOKEN_RTL,
+  GTK_RC_TOKEN_LOGICAL_COLOR,
   GTK_RC_TOKEN_LAST
 } GtkRcTokenType;
 
@@ -241,6 +242,8 @@ const GtkRcProperty* _gtk_rc_style_looku
 
 const gchar* _gtk_rc_context_get_default_font_name (GtkSettings *settings);
 
+GSList *_gtk_rc_style_get_logical_color_hashes (GtkRcStyle *rc_style);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
Index: gtk+-2.6.4/gtk/gtkstyle.c
===================================================================
--- gtk+-2.6.4.orig/gtk/gtkstyle.c	2005-09-11 02:00:31.000000000 +0300
+++ gtk+-2.6.4/gtk/gtkstyle.c	2005-09-11 02:01:02.000000000 +0300
@@ -38,6 +38,7 @@
 #include "gtkthemes.h"
 #include "gtkiconfactory.h"
 #include "gtksettings.h"	/* _gtk_settings_parse_convert() */
+#include "gtkhashtable.h"
 
 #define LIGHTNESS_MULT  1.3
 #define DARKNESS_MULT   0.7
@@ -49,6 +50,14 @@ typedef struct {
   GValue      value;
 } PropertyValue;
 
+#define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
+
+typedef struct _GtkStylePrivate GtkStylePrivate;
+
+struct _GtkStylePrivate {
+  GSList *logical_color_hashes;
+};
+
 /* --- prototypes --- */
 static void	 gtk_style_init			(GtkStyle	*style);
 static void	 gtk_style_class_init		(GtkStyleClass	*klass);
@@ -655,6 +664,7 @@ gtk_style_class_init (GtkStyleClass *kla
   klass->draw_layout = gtk_default_draw_layout;
   klass->draw_resize_grip = gtk_default_draw_resize_grip;
 
+  g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
   
   /**
    * GtkStyle::realize:
@@ -714,9 +724,28 @@ clear_property_cache (GtkStyle *style)
 }
 
 static void
+free_object_list (GSList *list)
+{
+  if (list)
+    {
+      GSList *tmp_list = list;
+
+      while (tmp_list)
+	{
+	  g_object_unref (tmp_list->data);
+	  tmp_list = tmp_list->next;
+	}
+
+      g_slist_free (list);
+    }
+    
+}
+
+static void
 gtk_style_finalize (GObject *object)
 {
   GtkStyle *style = GTK_STYLE (object);
+  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
 
   g_return_if_fail (style->attach_count == 0);
 
@@ -745,19 +774,9 @@ gtk_style_finalize (GObject *object)
           g_slist_free_1 (style->styles);
         }
     }
-
-  if (style->icon_factories)
-    {
-      GSList *tmp_list = style->icon_factories;
-
-      while (tmp_list)
-	{
-	  g_object_unref (tmp_list->data);
-	  tmp_list = tmp_list->next;
-	}
-
-      g_slist_free (style->icon_factories);
-    }
+  
+  free_object_list (style->icon_factories);
+  free_object_list (priv->logical_color_hashes);
 
   pango_font_description_free (style->font_desc);
   
@@ -1003,6 +1022,51 @@ gtk_style_lookup_icon_set (GtkStyle   *s
   return gtk_icon_factory_lookup_default (stock_id);
 }
 
+ /**
+ * gtk_style_lookup_logical_color:
+ * @style: a #GtkStyle
+ * @color_name: the name of the logical color to look up
+ * @color: the #GdkColor to fill in
+ *
+ * Looks up @color_name in the style's logical color mappings,
+ * filling in @color and returning %TRUE if found, otherwise
+ * returning %FALSE. Do not cache the found mapping, because
+ * it depends on the #GtkStyle and might change when a theme
+ * switch occurs.
+ *
+ * Return value: %TRUE if the mapping was found.
+ */
+gboolean
+gtk_style_lookup_logical_color (GtkStyle   *style,
+				const char *color_name,
+				GdkColor   *color)
+{
+  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
+  GSList *iter;
+
+  g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
+  g_return_val_if_fail (color_name != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+  
+  iter = priv->logical_color_hashes;
+  while (iter != NULL)
+    {
+      GdkColor *mapping = g_hash_table_lookup (GTK_HASH_TABLE (iter->data)->hash,
+					       color_name);
+      if (mapping)
+        {
+          color->red = mapping->red;
+          color->green = mapping->green;
+          color->blue = mapping->blue;
+          return TRUE;
+        }
+      
+      iter = g_slist_next (iter);
+    }
+
+  return FALSE;
+}
+
 /**
  * gtk_draw_hline:
  * @style: a #GtkStyle
@@ -1717,10 +1781,32 @@ gtk_style_real_copy (GtkStyle *style,
   clear_property_cache (style);
 }
 
+static GSList *
+copy_object_list (GSList *list)
+{
+  if (list)
+    {
+      GSList *iter;
+
+      iter = list;
+      while (iter != NULL)
+        {
+          g_object_ref (iter->data);
+          iter = g_slist_next (iter);
+        }
+      
+      return g_slist_copy (list);
+    }
+  else
+    return NULL;
+}
+
 static void
 gtk_style_real_init_from_rc (GtkStyle   *style,
 			     GtkRcStyle *rc_style)
 {
+  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
+  GSList *logical_color_hashes;
   gint i;
 
   /* cache _should_ be still empty */
@@ -1746,19 +1832,10 @@ gtk_style_real_init_from_rc (GtkStyle   
   if (rc_style->ythickness >= 0)
     style->ythickness = rc_style->ythickness;
 
-  if (rc_style->icon_factories)
-    {
-      GSList *iter;
+  style->icon_factories = copy_object_list (rc_style->icon_factories);
 
-      style->icon_factories = g_slist_copy (rc_style->icon_factories);
-      
-      iter = style->icon_factories;
-      while (iter != NULL)
-        {
-          g_object_ref (iter->data);
-          iter = g_slist_next (iter);
-        }
-    }
+  logical_color_hashes = _gtk_rc_style_get_logical_color_hashes (rc_style);
+  priv->logical_color_hashes = copy_object_list (logical_color_hashes);
 }
 
 static gint
Index: gtk+-2.6.4/gtk/gtkstyle.h
===================================================================
--- gtk+-2.6.4.orig/gtk/gtkstyle.h	2005-09-11 01:52:25.000000000 +0300
+++ gtk+-2.6.4/gtk/gtkstyle.h	2005-09-11 02:01:02.000000000 +0300
@@ -454,6 +454,10 @@ void	  gtk_style_apply_default_backgroun
 					      gint	    width, 
 					      gint	    height);
 
+gboolean  gtk_style_lookup_logical_color     (GtkStyle     *style,
+                                              const gchar  *color_name,
+                                              GdkColor     *color);
+                          
 GtkIconSet* gtk_style_lookup_icon_set (GtkStyle            *style,
                                        const gchar         *stock_id);
 GdkPixbuf*  gtk_style_render_icon     (GtkStyle            *style,
Index: gtk+-2.6.4/gtk/gtktypebuiltins.c
===================================================================
--- gtk+-2.6.4.orig/gtk/gtktypebuiltins.c	2005-09-11 02:00:37.000000000 +0300
+++ gtk+-2.6.4/gtk/gtktypebuiltins.c	2005-09-11 02:01:02.000000000 +0300
@@ -1405,6 +1405,7 @@ gtk_rc_token_type_get_type (void)
       { GTK_RC_TOKEN_STOCK, "GTK_RC_TOKEN_STOCK", "stock" },
       { GTK_RC_TOKEN_LTR, "GTK_RC_TOKEN_LTR", "ltr" },
       { GTK_RC_TOKEN_RTL, "GTK_RC_TOKEN_RTL", "rtl" },
+      { GTK_RC_TOKEN_LOGICAL_COLOR, "GTK_RC_TOKEN_LOGICAL_COLOR", "logical-color" },
       { GTK_RC_TOKEN_LAST, "GTK_RC_TOKEN_LAST", "last" },
       { 0, NULL, NULL }
     };
Index: gtk+-2.6.4/gtk/gtkhashtable.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gtk+-2.6.4/gtk/gtkhashtable.c	2005-09-11 02:01:02.000000000 +0300
@@ -0,0 +1,99 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Jorn Baayen <jbaayen@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#include <config.h>
+#include "gtkhashtable.h"
+
+static gpointer parent_class = NULL;
+
+static void _gtk_hash_table_init       (GtkHashTable      *hash_table);
+static void _gtk_hash_table_class_init (GtkHashTableClass *klass);
+static void _gtk_hash_table_finalize   (GObject           *object);
+
+GType
+_gtk_hash_table_get_type (void)
+{
+  static GType hash_table_type = 0;
+
+  if (!hash_table_type)
+    {
+      static const GTypeInfo hash_table_info =
+      {
+        sizeof (GtkHashTableClass),
+        NULL,		/* base_init */
+        NULL,		/* base_finalize */
+        (GClassInitFunc) _gtk_hash_table_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data */
+        sizeof (GtkHashTable),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) _gtk_hash_table_init,
+      };
+      
+      hash_table_type =
+	g_type_register_static (G_TYPE_OBJECT, "GtkHashTable",
+				&hash_table_info, 0);
+    }
+  
+  return hash_table_type;
+}
+
+static void
+_gtk_hash_table_init (GtkHashTable *hash_table)
+{
+  hash_table->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+				            g_free, g_free);
+}
+
+static void
+_gtk_hash_table_class_init (GtkHashTableClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = _gtk_hash_table_finalize;
+}
+
+static void
+_gtk_hash_table_finalize (GObject *object)
+{
+  GtkHashTable *hash_table = GTK_HASH_TABLE (object);
+
+  g_hash_table_destroy (hash_table->hash);
+  
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * _gtk_hash_table_new:
+ *
+ * Creates a new #GtkHashTable. This is a #GHashTable wrapped in a GObject,
+ * thereby supporting refcounting.
+ * 
+ * Return value: a new #GtkHashTable
+ **/
+GtkHashTable*
+_gtk_hash_table_new (void)
+{
+  return g_object_new (GTK_TYPE_HASH_TABLE, NULL);
+}
+
+
Index: gtk+-2.6.4/gtk/gtkhashtable.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gtk+-2.6.4/gtk/gtkhashtable.h	2005-09-11 02:01:02.000000000 +0300
@@ -0,0 +1,61 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2005 Nokia Corporation.
+ * Author: Jorn Baayen <jbaayen@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#ifndef __GTK_HASH_TABLE_H__
+#define __GTK_HASH_TABLE_H__
+
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkHashTable GtkHashTable;
+typedef struct _GtkHashTableClass GtkHashTableClass;
+
+#define GTK_TYPE_HASH_TABLE              (_gtk_hash_table_get_type ())
+#define GTK_HASH_TABLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_HASH_TABLE, GtkHashTable))
+#define GTK_HASH_TABLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_HASH_TABLE, GtkHashTableClass))
+#define GTK_IS_HASH_TABLE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_HASH_TABLE))
+#define GTK_IS_HASH_TABLE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_HASH_TABLE))
+#define GTK_HASH_TABLE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_HASH_TABLE, GtkHashTableClass))
+
+struct _GtkHashTable
+{
+  GObject parent_instance;
+
+  GHashTable *hash;
+};
+
+struct _GtkHashTableClass
+{
+  GObjectClass parent_class;
+};
+
+GType         _gtk_hash_table_get_type (void) G_GNUC_CONST;
+GtkHashTable* _gtk_hash_table_new      (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GTK_HASH_TABLE_H__ */
+
+
Index: gtk+-2.6.4/gtk/Makefile.am
===================================================================
--- gtk+-2.6.4.orig/gtk/Makefile.am	2005-09-11 02:00:50.000000000 +0300
+++ gtk+-2.6.4/gtk/Makefile.am	2005-09-11 02:01:02.000000000 +0300
@@ -388,6 +388,8 @@ gtk_c_sources =                 \
 	gtkframe.c		\
 	gtkgamma.c		\
 	gtkgc.c			\
+	gtkhashtable.c		\
+	gtkhashtable.h		\
 	gtkhandlebox.c		\
 	gtkhbbox.c		\
 	gtkhbox.c		\
Index: gtk+-2.6.4/gtk/Makefile.in
===================================================================
--- gtk+-2.6.4.orig/gtk/Makefile.in	2005-09-11 02:00:50.000000000 +0300
+++ gtk+-2.6.4/gtk/Makefile.in	2005-09-11 02:01:02.000000000 +0300
@@ -630,6 +630,8 @@ gtk_c_sources = \
 	gtkframe.c		\
 	gtkgamma.c		\
 	gtkgc.c			\
+	gtkhashtable.c		\
+	gtkhashtable.h		\
 	gtkhandlebox.c		\
 	gtkhbbox.c		\
 	gtkhbox.c		\
@@ -933,14 +935,14 @@ am__libgtk_linux_fb_2_0_la_SOURCES_DIST 
 	gtkfilechooserdefault.c gtkfilechooserutils.c \
 	gtkfilechooserwidget.c gtkfilefilter.c gtkfilesel.c \
 	gtkfilesystem.c gtkfilesystemmodel.c gtkfixed.c gtkfontbutton.c \
-	gtkfontsel.c gtkframe.c gtkgamma.c gtkgc.c gtkhandlebox.c \
-	gtkhbbox.c gtkhbox.c gtkhpaned.c gtkhruler.c gtkhscale.c \
-	gtkhscrollbar.c gtkhseparator.c gtkhsv.c gtkhsv.h \
-	gtkiconfactory.c gtkiconcache.c gtkicontheme.c gtkiconview.c \
-	gtkimage.c gtkimagemenuitem.c gtkimcontext.c \
-	gtkimcontextsimple.c gtkimmodule.c gtkimmulticontext.c \
-	gtkinputdialog.c gtkintl.h gtkinvisible.c gtkitem.c \
-	gtkitemfactory.c gtkkeyhash.c gtkkeyhash.h gtklabel.c \
+	gtkfontsel.c gtkframe.c gtkgamma.c gtkgc.c gtkhashtable.c \
+	gtkhashtable.h gtkhandlebox.c gtkhbbox.c gtkhbox.c gtkhpaned.c \
+	gtkhruler.c gtkhscale.c gtkhscrollbar.c gtkhseparator.c \
+	gtkhsv.c gtkhsv.h gtkiconfactory.c gtkiconcache.c \
+	gtkicontheme.c gtkiconview.c gtkimage.c gtkimagemenuitem.c \
+	gtkimcontext.c gtkimcontextsimple.c gtkimmodule.c \
+	gtkimmulticontext.c gtkinputdialog.c gtkintl.h gtkinvisible.c \
+	gtkitem.c gtkitemfactory.c gtkkeyhash.c gtkkeyhash.h gtklabel.c \
 	gtklayout.c gtklist.c gtklistitem.c gtkliststore.c gtkmain.c \
 	gtkmarshal.c gtkmarshalers.c gtkmenu.c gtkmenubar.c \
 	gtkmenuitem.c gtkmenushell.c gtkmenutoolbutton.c \
@@ -992,16 +994,16 @@ am__objects_3 = fnmatch.lo gtkaboutdialo
 	gtkfilechooserutils.lo gtkfilechooserwidget.lo gtkfilefilter.lo \
 	gtkfilesel.lo gtkfilesystem.lo gtkfilesystemmodel.lo \
 	gtkfixed.lo gtkfontbutton.lo gtkfontsel.lo gtkframe.lo \
-	gtkgamma.lo gtkgc.lo gtkhandlebox.lo gtkhbbox.lo gtkhbox.lo \
-	gtkhpaned.lo gtkhruler.lo gtkhscale.lo gtkhscrollbar.lo \
-	gtkhseparator.lo gtkhsv.lo gtkiconfactory.lo gtkiconcache.lo \
-	gtkicontheme.lo gtkiconview.lo gtkimage.lo gtkimagemenuitem.lo \
-	gtkimcontext.lo gtkimcontextsimple.lo gtkimmodule.lo \
-	gtkimmulticontext.lo gtkinputdialog.lo gtkinvisible.lo \
-	gtkitem.lo gtkitemfactory.lo gtkkeyhash.lo gtklabel.lo \
-	gtklayout.lo gtklist.lo gtklistitem.lo gtkliststore.lo \
-	gtkmain.lo gtkmarshal.lo gtkmarshalers.lo gtkmenu.lo \
-	gtkmenubar.lo gtkmenuitem.lo gtkmenushell.lo \
+	gtkgamma.lo gtkgc.lo gtkhashtable.lo gtkhandlebox.lo \
+	gtkhbbox.lo gtkhbox.lo gtkhpaned.lo gtkhruler.lo gtkhscale.lo \
+	gtkhscrollbar.lo gtkhseparator.lo gtkhsv.lo gtkiconfactory.lo \
+	gtkiconcache.lo gtkicontheme.lo gtkiconview.lo gtkimage.lo \
+	gtkimagemenuitem.lo gtkimcontext.lo gtkimcontextsimple.lo \
+	gtkimmodule.lo gtkimmulticontext.lo gtkinputdialog.lo \
+	gtkinvisible.lo gtkitem.lo gtkitemfactory.lo gtkkeyhash.lo \
+	gtklabel.lo gtklayout.lo gtklist.lo gtklistitem.lo \
+	gtkliststore.lo gtkmain.lo gtkmarshal.lo gtkmarshalers.lo \
+	gtkmenu.lo gtkmenubar.lo gtkmenuitem.lo gtkmenushell.lo \
 	gtkmenutoolbutton.lo gtkmessagedialog.lo gtkmisc.lo \
 	gtkmnemonichash.lo gtkmodules.lo gtknotebook.lo gtkobject.lo \
 	gtkoldeditable.lo gtkoptionmenu.lo gtkpaned.lo gtkpathbar.lo \
@@ -1049,14 +1051,14 @@ am__libgtk_win32_2_0_la_SOURCES_DIST = f
 	gtkfilechooserdefault.c gtkfilechooserutils.c \
 	gtkfilechooserwidget.c gtkfilefilter.c gtkfilesel.c \
 	gtkfilesystem.c gtkfilesystemmodel.c gtkfixed.c gtkfontbutton.c \
-	gtkfontsel.c gtkframe.c gtkgamma.c gtkgc.c gtkhandlebox.c \
-	gtkhbbox.c gtkhbox.c gtkhpaned.c gtkhruler.c gtkhscale.c \
-	gtkhscrollbar.c gtkhseparator.c gtkhsv.c gtkhsv.h \
-	gtkiconfactory.c gtkiconcache.c gtkicontheme.c gtkiconview.c \
-	gtkimage.c gtkimagemenuitem.c gtkimcontext.c \
-	gtkimcontextsimple.c gtkimmodule.c gtkimmulticontext.c \
-	gtkinputdialog.c gtkintl.h gtkinvisible.c gtkitem.c \
-	gtkitemfactory.c gtkkeyhash.c gtkkeyhash.h gtklabel.c \
+	gtkfontsel.c gtkframe.c gtkgamma.c gtkgc.c gtkhashtable.c \
+	gtkhashtable.h gtkhandlebox.c gtkhbbox.c gtkhbox.c gtkhpaned.c \
+	gtkhruler.c gtkhscale.c gtkhscrollbar.c gtkhseparator.c \
+	gtkhsv.c gtkhsv.h gtkiconfactory.c gtkiconcache.c \
+	gtkicontheme.c gtkiconview.c gtkimage.c gtkimagemenuitem.c \
+	gtkimcontext.c gtkimcontextsimple.c gtkimmodule.c \
+	gtkimmulticontext.c gtkinputdialog.c gtkintl.h gtkinvisible.c \
+	gtkitem.c gtkitemfactory.c gtkkeyhash.c gtkkeyhash.h gtklabel.c \
 	gtklayout.c gtklist.c gtklistitem.c gtkliststore.c gtkmain.c \
 	gtkmarshal.c gtkmarshalers.c gtkmenu.c gtkmenubar.c \
 	gtkmenuitem.c gtkmenushell.c gtkmenutoolbutton.c \
@@ -1113,14 +1115,14 @@ am__libgtk_x11_2_0_la_SOURCES_DIST = fnm
 	gtkfilechooserdefault.c gtkfilechooserutils.c \
 	gtkfilechooserwidget.c gtkfilefilter.c gtkfilesel.c \
 	gtkfilesystem.c gtkfilesystemmodel.c gtkfixed.c gtkfontbutton.c \
-	gtkfontsel.c gtkframe.c gtkgamma.c gtkgc.c gtkhandlebox.c \
-	gtkhbbox.c gtkhbox.c gtkhpaned.c gtkhruler.c gtkhscale.c \
-	gtkhscrollbar.c gtkhseparator.c gtkhsv.c gtkhsv.h \
-	gtkiconfactory.c gtkiconcache.c gtkicontheme.c gtkiconview.c \
-	gtkimage.c gtkimagemenuitem.c gtkimcontext.c \
-	gtkimcontextsimple.c gtkimmodule.c gtkimmulticontext.c \
-	gtkinputdialog.c gtkintl.h gtkinvisible.c gtkitem.c \
-	gtkitemfactory.c gtkkeyhash.c gtkkeyhash.h gtklabel.c \
+	gtkfontsel.c gtkframe.c gtkgamma.c gtkgc.c gtkhashtable.c \
+	gtkhashtable.h gtkhandlebox.c gtkhbbox.c gtkhbox.c gtkhpaned.c \
+	gtkhruler.c gtkhscale.c gtkhscrollbar.c gtkhseparator.c \
+	gtkhsv.c gtkhsv.h gtkiconfactory.c gtkiconcache.c \
+	gtkicontheme.c gtkiconview.c gtkimage.c gtkimagemenuitem.c \
+	gtkimcontext.c gtkimcontextsimple.c gtkimmodule.c \
+	gtkimmulticontext.c gtkinputdialog.c gtkintl.h gtkinvisible.c \
+	gtkitem.c gtkitemfactory.c gtkkeyhash.c gtkkeyhash.h gtklabel.c \
 	gtklayout.c gtklist.c gtklistitem.c gtkliststore.c gtkmain.c \
 	gtkmarshal.c gtkmarshalers.c gtkmenu.c gtkmenubar.c \
 	gtkmenuitem.c gtkmenushell.c gtkmenutoolbutton.c \
@@ -1238,6 +1240,7 @@ am__depfiles_maybe = depfiles
 @AMDEP_TRUE@	./$(DEPDIR)/gtkfontsel.Plo ./$(DEPDIR)/gtkframe.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/gtkgamma.Plo ./$(DEPDIR)/gtkgc.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/gtkhandlebox.Plo \
+@AMDEP_TRUE@	./$(DEPDIR)/gtkhashtable.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/gtkhbbox.Plo ./$(DEPDIR)/gtkhbox.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/gtkhpaned.Plo ./$(DEPDIR)/gtkhruler.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/gtkhscale.Plo \
@@ -1543,6 +1546,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkgamma.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkgc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkhandlebox.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkhashtable.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkhbbox.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkhbox.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkhpaned.Plo@am__quote@
