Common subdirectories: gtk+.orig/gtk/CVS and gtk+/gtk/CVS
Common subdirectories: gtk+.orig/gtk/.deps and gtk+/gtk/.deps
diff -u gtk+.orig/gtk/gtkbindings.c gtk+/gtk/gtkbindings.c
--- gtk+.orig/gtk/gtkbindings.c	2005-09-14 15:17:17.000000000 +0200
+++ gtk+/gtk/gtkbindings.c	2005-09-25 17:36:37.000000000 +0200
@@ -44,7 +44,9 @@
 
 /* --- structures --- */
 typedef struct {
+  GtkPathType type;
   GPatternSpec *pspec;
+  GSList *widget_class_pspecs;
   gpointer user_data;
   guint seq_id;
 } PatternSpec;
@@ -59,6 +61,14 @@
 
 
 /* --- functions --- */
+static void
+pattern_spec_free (PatternSpec * pspec)
+{
+  g_pattern_spec_free (pspec->pspec);
+  _gtk_rc_free_widget_class_pspec_list (pspec->widget_class_pspecs);
+  g_free (pspec);
+}
+
 static GtkBindingSignal*
 binding_signal_new (const gchar *signal_name,
 		    guint	 n_args)
@@ -870,7 +880,18 @@
     }
   
   pspec = g_new (PatternSpec, 1);
-  pspec->pspec = g_pattern_spec_new (path_pattern);
+  pspec->type = path_type;
+  if (path_type != GTK_PATH_WIDGET_CLASS)
+    {
+      pspec->pspec = g_pattern_spec_new (path_pattern);
+      pspec->widget_class_pspecs = NULL;
+    }
+  else
+    {
+      pspec->pspec = NULL;
+      pspec->widget_class_pspecs = _gtk_rc_create_widget_class_pspec_list (path_pattern);
+    }
+    
   pspec->seq_id = priority << 28;
   pspec->user_data = binding_set;
   
@@ -886,8 +907,7 @@
 	{
 	  GtkPathPriorityType lprio = tmp_pspec->seq_id >> 28;
 
-	  g_pattern_spec_free (pspec->pspec);
-	  g_free (pspec);
+	  pattern_spec_free (pspec);
 	  pspec = NULL;
 	  if (lprio < priority)
 	    {
@@ -916,17 +936,49 @@
   for (slist = pspec_list; slist; slist = slist->next)
     {
       PatternSpec *pspec;
+      gchar *tmp_path = NULL;
+      gchar *tmp_path_reversed = NULL;
 
       pspec = slist->data;
-      if (g_pattern_match (pspec->pspec, path_length, path, path_reversed))
-	{
-	  GtkBindingSet *binding_set;
+      
+      if (pspec->type != GTK_PATH_WIDGET_CLASS)
+        {
+          if (g_pattern_match (pspec->pspec, path_length, path, path_reversed))
+	    {
+              GtkBindingSet *binding_set;
 
-	  binding_set = pspec->user_data;
+	      binding_set = pspec->user_data;
 
-	  if (gtk_binding_entry_activate (binding_set->current, object))
-	    return TRUE;
-	}
+	      if (gtk_binding_entry_activate (binding_set->current, object))
+	        return TRUE;
+	    }
+        }
+      else
+        {
+          if (tmp_path == NULL)
+            tmp_path = g_strdup (path);
+          if (tmp_path_reversed == NULL)
+            {
+              if (path_reversed != NULL)
+                tmp_path_reversed = g_strdup (path_reversed);
+              else
+                tmp_path_reversed = g_strreverse (g_strdup (path));
+            }
+          
+          if (_gtk_rc_match_widget_class (pspec->widget_class_pspecs, path_length, tmp_path, tmp_path_reversed))
+	    {
+              GtkBindingSet *binding_set;
+
+	      binding_set = pspec->user_data;
+
+	      if (gtk_binding_entry_activate (binding_set->current, object))
+	        return TRUE;
+	    }
+        }
+      if (tmp_path != NULL)
+        g_free (tmp_path);
+      if (tmp_path_reversed != NULL)
+        g_free (tmp_path_reversed);
     }
 
   return FALSE;
@@ -1418,8 +1470,7 @@
 
       pspec = slist->data;
 
-      g_pattern_spec_free (pspec->pspec);
-      g_free (pspec);
+      pattern_spec_free (pspec);
     }
 
   g_slist_free (pattern_specs);
Only in gtk+.orig/gtk: gtkiconfactory.c~
diff -u gtk+.orig/gtk/gtkrc.c gtk+/gtk/gtkrc.c
--- gtk+.orig/gtk/gtkrc.c	2005-09-14 15:17:17.000000000 +0200
+++ gtk+/gtk/gtkrc.c	2005-09-25 17:59:58.000000000 +0200
@@ -66,9 +66,28 @@
 typedef struct _GtkRcNode   GtkRcNode;
 typedef struct _GtkRcFile   GtkRcFile;
 
+typedef struct
+{
+  enum
+  {
+    CLASS_PSPEC,
+    CLASS_TYPE_UNRESOLVED,
+    CLASS_TYPE,
+    PSPEC
+  } type;
+  
+  GType class_type;
+  gchar * class_name;
+  GPatternSpec * pspec;
+} GtkRcSetPSpecList;
+
 struct _GtkRcSet
 {
+  GtkPathType type;
+  
   GPatternSpec *pspec;
+  GSList * widget_class_pspecs;
+
   GtkRcStyle *rc_style;
   gint priority;
 };
@@ -195,6 +214,7 @@
 static GtkStyle*   gtk_rc_style_real_create_style    (GtkRcStyle      *rc_style);
 static gint	   gtk_rc_properties_cmp	     (gconstpointer    bsearch_node1,
 						      gconstpointer    bsearch_node2);
+static void        gtk_rc_set_free                   (GtkRcSet        *rc_set);
 
 static gpointer parent_class = NULL;
 
@@ -1274,8 +1294,7 @@
       GtkRcSet *rc_set;
 
       rc_set = slist->data;
-      g_pattern_spec_free (rc_set->pspec);
-      g_free (rc_set);
+      gtk_rc_set_free (rc_set);
 
       slist = slist->next;
     }
@@ -1572,11 +1591,36 @@
 
   while (sets)
     {
+      gchar *tmp_path = NULL;
+      gchar *tmp_path_reversed = NULL;
+      
       rc_set = sets->data;
       sets = sets->next;
 
-      if (g_pattern_match (rc_set->pspec, path_length, path, path_reversed))
-	rc_styles = g_slist_append (rc_styles, rc_set);
+      if (rc_set->type != GTK_PATH_WIDGET_CLASS)
+        {
+          if (g_pattern_match (rc_set->pspec, path_length, path, path_reversed))
+	    rc_styles = g_slist_append (rc_styles, rc_set);
+	}
+      else
+        {
+          if (tmp_path == NULL)
+            tmp_path = g_strdup (path);
+          if (tmp_path_reversed == NULL)
+            {
+              if (path_reversed != NULL)
+                tmp_path_reversed = g_strdup (path_reversed);
+              else
+                tmp_path_reversed = g_strreverse (g_strdup (path));
+            }
+          
+          if (_gtk_rc_match_widget_class (rc_set->widget_class_pspecs, path_length, tmp_path, tmp_path_reversed))
+	    rc_styles = g_slist_append (rc_styles, rc_set);
+        }
+      if (tmp_path != NULL)
+        g_free (tmp_path);
+      if (tmp_path_reversed != NULL)
+        g_free (tmp_path_reversed);
     }
   
   return rc_styles;
@@ -1828,7 +1872,8 @@
 static GSList *
 gtk_rc_add_rc_sets (GSList      *slist,
 		    GtkRcStyle  *rc_style,
-		    const gchar *pattern)
+		    const gchar *pattern,
+		    GtkPathType  path_type)
 {
   GtkRcStyle *new_style;
   GtkRcSet *rc_set;
@@ -1844,7 +1889,19 @@
     new_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
   
   rc_set = g_new (GtkRcSet, 1);
-  rc_set->pspec = g_pattern_spec_new (pattern);
+  rc_set->type = path_type;
+  
+  if (path_type == GTK_PATH_WIDGET_CLASS)
+    {
+      rc_set->pspec = NULL;
+      rc_set->widget_class_pspecs = _gtk_rc_create_widget_class_pspec_list (pattern);
+    }
+  else
+    {
+      rc_set->pspec = g_pattern_spec_new (pattern);
+      rc_set->widget_class_pspecs = NULL;
+    }
+  
   rc_set->rc_style = rc_style;
   
   return g_slist_prepend (slist, rc_set);
@@ -1861,7 +1918,7 @@
 
   context = gtk_rc_context_get (gtk_settings_get_default ());
   
-  context->rc_sets_widget = gtk_rc_add_rc_sets (context->rc_sets_widget, rc_style, pattern);
+  context->rc_sets_widget = gtk_rc_add_rc_sets (context->rc_sets_widget, rc_style, pattern, GTK_PATH_WIDGET);
 }
 
 void
@@ -1875,7 +1932,7 @@
 
   context = gtk_rc_context_get (gtk_settings_get_default ());
   
-  context->rc_sets_widget_class = gtk_rc_add_rc_sets (context->rc_sets_widget_class, rc_style, pattern);
+  context->rc_sets_widget_class = gtk_rc_add_rc_sets (context->rc_sets_widget_class, rc_style, pattern, GTK_PATH_WIDGET_CLASS);
 }
 
 void
@@ -1889,7 +1946,7 @@
 
   context = gtk_rc_context_get (gtk_settings_get_default ());
   
-  context->rc_sets_class = gtk_rc_add_rc_sets (context->rc_sets_class, rc_style, pattern);
+  context->rc_sets_class = gtk_rc_add_rc_sets (context->rc_sets_class, rc_style, pattern, GTK_PATH_CLASS);
 }
 
 GScanner*
@@ -3612,7 +3669,19 @@
 	}
 
       rc_set = g_new (GtkRcSet, 1);
-      rc_set->pspec = g_pattern_spec_new (pattern);
+      rc_set->type = path_type;
+      
+      if (path_type == GTK_PATH_WIDGET_CLASS)
+        {
+          rc_set->pspec = NULL;
+          rc_set->widget_class_pspecs = _gtk_rc_create_widget_class_pspec_list (pattern);
+        }
+      else
+        {
+          rc_set->pspec = g_pattern_spec_new (pattern);
+          rc_set->widget_class_pspecs = NULL;
+        }
+      
       rc_set->rc_style = rc_style;
       rc_set->priority = priority;
 
@@ -3917,6 +3986,315 @@
   return G_TOKEN_NONE;
 }
 
+
+GSList *
+_gtk_rc_create_widget_class_pspec_list (const gchar * pattern)
+{
+  GSList * result = NULL;
+  GtkRcSetPSpecList * list_pspec;
+  const gchar * current = pattern;
+  const gchar * class_start;
+  const gchar * class_end;
+  gchar * sub_pattern;
+  
+  class_start = strchr (pattern, '<');
+  
+  while ((class_start = strchr (current, '<')) && (class_end = strchr (class_start, '>')))
+    {
+      /* If the class is not at the beggining, there is a pattern in front of it which needs to be added. */
+      if (class_start != current)
+        {
+          const gchar * pattern_end = class_start - 1;
+          const gchar * pattern_start = current;
+          
+          list_pspec = g_new (GtkRcSetPSpecList, 1);
+          
+          sub_pattern = g_strndup (pattern_start, pattern_end - pattern_start + 1);
+          list_pspec->type = PSPEC;
+          list_pspec->pspec = g_pattern_spec_new (sub_pattern);
+          g_free (sub_pattern);
+          
+          result = g_slist_append (result, list_pspec);
+        }
+      
+      list_pspec = g_new (GtkRcSetPSpecList, 1);
+      
+      /* The < > need to be removed from the string. */
+      sub_pattern = g_strndup (class_start + 1, class_end - class_start - 1);
+      
+      if ((strchr (sub_pattern, '?') == NULL) && (strchr (sub_pattern, '*') == NULL))
+        {
+          /* we speed up the matching, by running g_type_from_name later and then checking whether the type can be casted.
+             This needs to be done lazy, because at this point the classes are may not yet be registered. */
+          list_pspec->type = CLASS_TYPE_UNRESOLVED;
+          list_pspec->class_type = 0;
+          list_pspec->class_name = g_strdup (sub_pattern);
+          list_pspec->pspec = NULL;
+        }
+      else
+        {
+          list_pspec->type = CLASS_PSPEC;
+          list_pspec->class_name = NULL;
+          list_pspec->pspec = g_pattern_spec_new (sub_pattern);
+        }
+      
+      g_free (sub_pattern);
+      
+      result = g_slist_append (result, list_pspec);
+      
+      current = class_end + 1;
+    }
+  
+  /* Add the rest, if anything is left */
+  if (strlen (current) > 0)
+    {
+      list_pspec = g_new (GtkRcSetPSpecList, 1);
+      list_pspec->type = PSPEC;
+      list_pspec->pspec = g_pattern_spec_new (current);
+      list_pspec->class_name = NULL;
+      
+      result = g_slist_append (result, list_pspec);
+    }
+  
+  return result;
+}
+
+static void
+free_widget_class_pspec (gpointer data, gpointer user_data)
+{
+  GtkRcSetPSpecList * pspec_list = data;
+  
+  g_pattern_spec_free (pspec_list->pspec);
+  if (pspec_list->class_name)
+    g_free (pspec_list->class_name);
+  
+  g_free(pspec_list);
+}
+
+void
+_gtk_rc_free_widget_class_pspec_list (GSList * pspecs)
+{
+  g_slist_foreach (pspecs, free_widget_class_pspec, NULL);
+  g_slist_free (pspecs);
+}
+
+static void
+gtk_rc_set_free (GtkRcSet * rc_set)
+{
+  g_assert (rc_set != NULL);
+  
+  if (rc_set->pspec)
+    g_pattern_spec_free (rc_set->pspec);
+  _gtk_rc_free_widget_class_pspec_list (rc_set->widget_class_pspecs);
+  
+  g_free (rc_set);
+}
+
+static gboolean
+match_class (GtkRcSetPSpecList * rc_set, gint type_name_length, gchar *type_name, gchar *type_name_reversed)
+{
+  GType type;
+  
+  if (rc_set->type == CLASS_TYPE_UNRESOLVED)
+    {
+      type = g_type_from_name (rc_set->class_name);
+      if (type != 0)
+        {
+          rc_set->type = CLASS_TYPE;
+          rc_set->class_type = type;
+          g_free (rc_set->class_name);
+          rc_set->class_name = NULL;
+        }
+      else
+        {
+          /* Just compare the two strings we got, cannot do any better in this case. */
+          return g_str_equal (type_name, rc_set->class_name);
+        }
+    }
+  
+  if (type_name_length == -1)
+    type_name_length = strlen (type_name);
+  
+  if (rc_set->type == CLASS_TYPE)
+    {
+      return g_type_is_a (g_type_from_name (type_name), rc_set->class_type);
+    }
+  else
+    {
+      /* first match against the found name */
+      if (g_pattern_match(rc_set->pspec, strlen (type_name), type_name, type_name_reversed))
+        return TRUE;
+      
+      type = g_type_from_name (type_name);
+      type = g_type_parent (type);
+      
+      while (type)
+        {
+          const gchar *path;
+          guint path_length;
+    
+          path = g_type_name (type);
+          path_length = strlen (path);
+          
+          if (g_pattern_match (rc_set->pspec, path_length, path, type_name_reversed))
+            return TRUE;
+          
+          type = g_type_parent (type);
+        }
+    }
+  
+  return FALSE;
+}
+
+static gboolean
+match_widget_class_recursive (GSList * list, guint length, gchar * path, gchar * path_reversed)
+{
+  GtkRcSetPSpecList * pspec_list;
+  
+  /* break out if we cannot match anymore. */
+  if (list == NULL)
+    {
+      if (length > 0)
+        return FALSE;
+      else
+        return TRUE;
+    }
+  
+  /* there are two possibilities:
+      1. The next pattern should match the class.
+      2. First normal matching, and then maybe a class */
+  
+  pspec_list = list->data;
+  
+  if (pspec_list->type != PSPEC)
+    {
+      gchar * class_start = path;
+      gchar * class_end = strchr (path, '.');
+      
+      if (class_end == path)
+        {
+          class_start = path + 1;
+          class_end = strchr (class_start, '.');
+        }
+      
+      if (class_end == NULL)
+        {
+          if (!match_class (pspec_list, class_end - class_start, class_start, NULL))
+            return FALSE;
+          else
+            return match_widget_class_recursive (g_slist_next (list), 0, "", "");
+        }
+      else
+        {
+          *class_end = '\0';
+          if (!match_class (pspec_list, class_end - class_start, class_start, NULL))
+            {
+              *class_end = '.';
+              return FALSE;
+            }
+          else
+            {
+              gboolean result;
+              gint new_length = length - (class_end - path);
+              gchar old_char = path_reversed[new_length];
+              
+              *class_end = '.';
+              
+              path_reversed[new_length] = '\0';
+              result = match_widget_class_recursive (g_slist_next (list), new_length, class_end, path_reversed);
+              path_reversed[new_length] = old_char;
+              
+              return result;
+            }
+        }
+    }
+  else
+    {
+      GtkRcSetPSpecList * class_pspec_list;
+      gchar * class_start;
+      gchar * class_end;
+      gboolean result = FALSE;
+      
+      /* If there is nothing after this (ie. no class match), we just need to compare the param spec. */
+      if (g_slist_next (list) == NULL)
+        return g_pattern_match (pspec_list->pspec, length, path, path_reversed);
+      
+      class_pspec_list = (g_slist_next (list))->data;
+      
+      g_assert (class_pspec_list->type != PSPEC);
+      
+      /* jump over a leading dot */
+      if (*path != '.')
+        class_start = path;
+      else
+        class_start = path + 1;
+      
+      while (TRUE)
+        {
+          class_end = strchr (class_start, '.');
+          
+          if (class_end != NULL)
+            {
+              *class_end = '\0';
+              result = match_class (class_pspec_list, class_end - class_start, class_start, NULL);
+              *class_end = '.';
+            }
+          else
+            {
+              result = match_class (class_pspec_list, class_end - class_start, class_start, NULL);
+            }
+          
+          if (result)
+            {
+              gchar old_char = *class_start;
+              result = FALSE;
+              
+              /* terminate the string in front of the class. It does not matter that the class becomes
+                 unusable, because it is not needed inside the recursion */
+              *class_start = '\0';
+              
+              if (g_pattern_match (pspec_list->pspec, class_start - path, path, path_reversed + length - (class_start - path)))
+                {
+                  /* pattern matches, yay so go on recursive, and hope ... */
+                  if (class_end != NULL)
+                    {
+                      gint new_length = length - (class_end - path);
+                      gchar old_char = path_reversed[new_length];
+                      
+                      path_reversed[new_length] = '\0';
+                      
+                      result = match_widget_class_recursive (g_slist_next(g_slist_next (list)), new_length, class_end, path_reversed);
+                      
+                      path_reversed[new_length] = old_char;
+                    }
+                  else
+                    result = match_widget_class_recursive (g_slist_next(g_slist_next (list)), 0, "", "");
+                }
+                
+              *class_start = old_char;
+            }
+          
+          if (result)
+            return TRUE;
+          
+          /* get next class in path, or break out */
+          if (class_end != NULL)
+            class_start = class_end + 1;
+          else
+            return FALSE;
+        }
+    }
+}
+
+gboolean
+_gtk_rc_match_widget_class (GSList      *pspecs,
+                            gint         length,
+                            gchar *path,
+                            gchar *path_reversed)
+{
+  return match_widget_class_recursive (pspecs, length, path, path_reversed);
+}
+
 #ifdef G_OS_WIN32
 
 /* DLL ABI stability backward compatibility versions */
diff -u gtk+.orig/gtk/gtkrc.h gtk+/gtk/gtkrc.h
--- gtk+.orig/gtk/gtkrc.h	2005-09-14 15:17:17.000000000 +0200
+++ gtk+/gtk/gtkrc.h	2005-09-24 21:13:32.000000000 +0200
@@ -127,6 +127,13 @@
 #endif
 
 void	  _gtk_rc_init			(void);
+GSList*   _gtk_rc_create_widget_class_pspec_list (const gchar  *pattern);
+void      _gtk_rc_free_widget_class_pspec_list   (GSList       *pspecs);
+gboolean  _gtk_rc_match_widget_class    (GSList      *pspecs,
+                                         gint         length,
+                                         gchar       *path,
+                                         gchar       *path_reversed);
+
 void      gtk_rc_add_default_file	(const gchar *filename);
 void      gtk_rc_set_default_files      (gchar **filenames);
 gchar**   gtk_rc_get_default_files      (void);
Only in gtk+.orig/gtk: gtkwidget.c~
Common subdirectories: gtk+.orig/gtk/.libs and gtk+/gtk/.libs
Binary files gtk+.orig/gtk/queryimmodules.o and gtk+/gtk/queryimmodules.o differ
Common subdirectories: gtk+.orig/gtk/stock-icons and gtk+/gtk/stock-icons
Common subdirectories: gtk+.orig/gtk/theme-bits and gtk+/gtk/theme-bits
Binary files gtk+.orig/gtk/updateiconcache.o and gtk+/gtk/updateiconcache.o differ
Common subdirectories: gtk+.orig/gtk/xdgmime and gtk+/gtk/xdgmime
