Re: Adding xsetting indirection to GtkRC parsing.



OK, I finished the first pass of implementing this. I ended up taking
a somewhat simpler approach than I planned at first -- as suggested by
Havoc, instead of worrying about getting the parsing of the GtkSetting
specified theme files and the normal RC files in a particular order, I
recyclced the priority mechanism we already had for bindings and
parsed:

 - first normal RC files
 - then theme files

There are still some things to be finished up here - mostly internal
details dealing with allowing multiple independent GtkRcContexts
within a program (not really interested until we have multihead
support.) For instance, I haven't made an attempt to make the parsing
bindings be per-rc-context.

It also has to be decided how gtk_rc_parse() and
gtk_rc_add_(widget)_style_name() interact with multiple GtkRcContexts.

Finally, there is an old bug that needs to be resolved where
information gtk_rc_parse_string() is lost if the theme changes.

Regards,
                                        Owen

? langtag.diff
? docs/reference/gdk/gdk-undocumented.txt
? docs/reference/gdk-pixbuf/gdk-pixbuf-undocumented.txt
? docs/reference/gtk/gtk-undocumented.txt
? docs/reference/gtk/gtk-docs.tex
? gdk-pixbuf/test-loaders
? tests/pango-ols
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2064
diff -u -r1.2064 ChangeLog
--- ChangeLog	2001/06/21 17:45:23	1.2064
+++ ChangeLog	2001/06/22 22:56:40
@@ -1,3 +1,42 @@
+Fri Jun 22 18:49:48 2001  Owen Taylor  <otaylor redhat com>
+
+        * gtk/gtkrc.[ch]: Add a GtkRcContext structure to hold 
+	most of the previous global variables in gtkrc.c. This is
+	in preparation for multi-head, since each screen can
+	have different GtkSettings and RC information.
+
+	* gtk/gtkrc.h (struct _GtkRcStyleClass): Add a
+	GtkRcContext parameter to GtkRcStyle::parse.
+
+	* gdk/x11/gdkevents-x11.c gtk/gtksettings.c gtk/gtkrc.c: 
+	Add two new settings gtk-theme-name, gtk-key-theme-name,
+	for RC files that are loaded by name after reading
+	the default RC files.
+	
+	* gtk/gtkrc.c: Allow priorities for styles, as wll as
+	bindings.
+
+	* gtk/gtkenums.h gtk/gtkrc.c: Add GTK_PATH_PRIO_THEME,
+	and use it by default for RC files loaded via 
+	gtk-theme-name, gtk-key-theme-naem.
+
+	* gtk/gtkiconfactory.c (gtk_icon_source_set_filename)
+        gtk/gtkrc.c (gtk_rc_parse_pixmap_path_string) 
+	tests/testgtkrc: Require pathnames to be absolute.
+
+	* gtk/gtkrc.c gtk/gtkiconfactory.c: Look up the full filename for
+	the source when parsing, since the operation of looking up a
+	pixmap from an RC file depends on the parsing context.
+
+	* gtk/gtkrc.c (gtk_rc_context_reparse_all): Automatically
+	reset RC styles on all widgets when files are reparsed.
+
+	* tests/testgtk.c (create_rc_file) gtk/gtkwindow.c (gtk_window_read_rcfiles): 
+	Simplify, now that gtk_rc_reparse_all() resets the widget heirarchy.
+
+	* gtk/gtkmain.c (gtk_get_default_language): Fix broken
+	return value.
+
 Thu Jun 21 13:42:01 2001  Owen Taylor  <otaylor redhat com>
 
 	* gdk/x11/gdkkeys-x11.c (gdk_keymap_get_direction): Handle
Index: docs/Changes-2.0.txt
===================================================================
RCS file: /cvs/gnome/gtk+/docs/Changes-2.0.txt,v
retrieving revision 1.21
diff -u -r1.21 Changes-2.0.txt
--- docs/Changes-2.0.txt	2001/06/21 17:45:24	1.21
+++ docs/Changes-2.0.txt	2001/06/22 22:56:40
@@ -366,3 +366,8 @@
  
 * gtk_rc_set_image_loader() and gtk_rc_load_image() has been removed, now 
   that GTK+ includes decent image loading capabilities itself.
+
+* gtk_rc_find_pixmap_in_path() has been replaced with 
+  gtk_rc_context_find_pixmap_in_path(), taking an extra GtkRcContext 
+  paramter. This function is only actually  useful from a theme engine
+  during parsing, at which point the GtkRcContext is provided.
Index: docs/reference/gtk/tmpl/gtk-unused.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtk-unused.sgml,v
retrieving revision 1.49
diff -u -r1.49 gtk-unused.sgml
--- docs/reference/gtk/tmpl/gtk-unused.sgml	2001/06/21 17:44:27	1.49
+++ docs/reference/gtk/tmpl/gtk-unused.sgml	2001/06/22 22:56:41
@@ -1756,6 +1756,16 @@
 @pspec: 
 @pattern: 
 
+<!-- ##### FUNCTION gtk_rc_find_pixmap_in_path ##### -->
+<para>
+</para>
+
+ scanner: a #GtkScanner. Used for printing out warning messages
+if the file is not found.
+ pixmap_file: The name of the file to search for.
+ Returns: The filename, if found. (Must be freed with g_free()),
+otherwise %NULL.
+
 <!-- ##### FUNCTION gtk_rc_init ##### -->
 <para>
 Internal function.
Index: docs/reference/gtk/tmpl/gtkenums.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtkenums.sgml,v
retrieving revision 1.12
diff -u -r1.12 gtkenums.sgml
--- docs/reference/gtk/tmpl/gtkenums.sgml	2001/06/05 14:55:53	1.12
+++ docs/reference/gtk/tmpl/gtkenums.sgml	2001/06/22 22:56:41
@@ -182,6 +182,7 @@
 @GTK_PATH_PRIO_LOWEST: 
 @GTK_PATH_PRIO_GTK: 
 @GTK_PATH_PRIO_APPLICATION: 
+ GTK_PATH_PRIO_THEME: 
 @GTK_PATH_PRIO_RC: 
 @GTK_PATH_PRIO_HIGHEST: 
 @GTK_PATH_PRIO_MASK: 
Index: docs/reference/gtk/tmpl/gtkrc.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtkrc.sgml,v
retrieving revision 1.33
diff -u -r1.33 gtkrc.sgml
--- docs/reference/gtk/tmpl/gtkrc.sgml	2001/06/21 17:44:27	1.33
+++ docs/reference/gtk/tmpl/gtkrc.sgml	2001/06/22 22:56:41
@@ -589,6 +589,7 @@
 @GTK_RC_TOKEN_LOWEST: 
 @GTK_RC_TOKEN_GTK: 
 @GTK_RC_TOKEN_APPLICATION: 
+ GTK_RC_TOKEN_THEME: 
 @GTK_RC_TOKEN_RC: 
 @GTK_RC_TOKEN_HIGHEST: 
 @GTK_RC_TOKEN_ENGINE: 
@@ -610,19 +611,10 @@
 
 <!-- ##### FUNCTION gtk_rc_get_style ##### -->
 <para>
-Finds all matching RC styles for a given widget,
-composites them together, and then creates a 
-#GtkStyle representing the composite appearance.
-(GTK+ actually keeps a cache of previously 
-created styles, so a new style may not be
-created.)
 </para>
 
- widget: a #GtkWidget
- Returns: the resulting style. The caller should
-reference the result, since GTK+ will retain the
-initial reference count itself for the cache
-of created styles.
+ widget: 
+ Returns: 
 
 
 <!-- ##### FUNCTION gtk_rc_add_widget_name_style ##### -->
@@ -686,42 +678,30 @@
 
 <!-- ##### FUNCTION gtk_rc_reparse_all ##### -->
 <para>
-If the modification time on any previously read file
-has changed, discard all style information
-and then reread all previously read RC files.
 </para>
 
- Returns: %TRUE if the files were reread.
+ Returns: 
 
 
 <!-- ##### FUNCTION gtk_rc_add_default_file ##### -->
 <para>
-Adds a file to the list of files to be parsed at the
-end of gtk_init().
 </para>
 
- filename: the pathname to the file.
+ filename: 
 
 
 <!-- ##### FUNCTION gtk_rc_get_default_files ##### -->
 <para>
-Retrieves the current list of RC files that will be parsed
-at the end of gtk_init()
 </para>
 
- Returns: A NULL terminated array of filenames. This memory
-is owned by GTK+ and must not be freed by the application.
-If you want to store this information, you should make a 
-copy.
+ Returns: 
 
 
 <!-- ##### FUNCTION gtk_rc_set_default_files ##### -->
 <para>
-Sets the list of files that GTK+ will read at the
-end of gtk_init()
 </para>
 
- filenames: A %NULL terminated list of filenames.
+ filenames: 
 
 
 <!-- ##### FUNCTION gtk_rc_parse_color ##### -->
@@ -767,20 +747,6 @@
 </para>
 
 @module_file: The name of the module to search for.
- Returns: The filename, if found. (Must be freed with g_free()),
-otherwise %NULL.
-
-
-<!-- ##### FUNCTION gtk_rc_find_pixmap_in_path ##### -->
-<para>
-Looks up a file in the current pixmap path. If the file is
-not found, it outputs a warning message using g_warning()
-and returns %NULL.
-</para>
-
- scanner: a #GtkScanner. Used for printing out warning messages
-if the file is not found.
- pixmap_file: The name of the file to search for.
 @Returns: The filename, if found. (Must be freed with g_free()),
 otherwise %NULL.
 
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.54
diff -u -r1.54 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	2001/06/08 16:06:58	1.54
+++ gdk/x11/gdkevents-x11.c	2001/06/22 22:56:41
@@ -1945,7 +1945,9 @@
   { "Gtk/ToolbarStyle", "gtk-toolbar-style" },
   { "Gtk/ToolbarIconSize", "gtk-toolbar-icon-size" },
   { "Net/CursorBlink", "gtk-cursor-blink" },
-  { "Net/CursorBlinkTime", "gtk-cursor-blink-time" }
+  { "Net/CursorBlinkTime", "gtk-cursor-blink-time" },
+  { "Net/ThemeName", "gtk-theme-name" },
+  { "Gtk/KeyThemeName", "gtk-key-theme-name" }
 };
 
 static void
Index: gtk/gtkenums.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkenums.h,v
retrieving revision 1.40
diff -u -r1.40 gtkenums.h
--- gtk/gtkenums.h	2001/06/04 02:31:11	1.40
+++ gtk/gtkenums.h	2001/06/22 22:56:41
@@ -220,6 +220,7 @@
   GTK_PATH_PRIO_LOWEST      = 0,
   GTK_PATH_PRIO_GTK	    = 4,
   GTK_PATH_PRIO_APPLICATION = 8,
+  GTK_PATH_PRIO_THEME       = 10,
   GTK_PATH_PRIO_RC          = 12,
   GTK_PATH_PRIO_HIGHEST     = 15,
   GTK_PATH_PRIO_MASK        = 0x0f
Index: gtk/gtkiconfactory.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkiconfactory.c,v
retrieving revision 1.15
diff -u -r1.15 gtkiconfactory.c
--- gtk/gtkiconfactory.c	2001/06/04 23:15:50	1.15
+++ gtk/gtkiconfactory.c	2001/06/22 22:56:41
@@ -1029,20 +1029,10 @@
   if (source->pixbuf == NULL)
     {
       GError *error;
-      gchar *full;
       
       g_assert (source->filename);
+      source->pixbuf = gdk_pixbuf_new_from_file (source->filename, &error);
 
-      if (g_path_is_absolute (source->filename))
-        full = g_strdup (source->filename);
-      else
-        full = gtk_rc_find_pixmap_in_path (NULL, source->filename);
-
-      error = NULL;
-      source->pixbuf = gdk_pixbuf_new_from_file (full, &error);
-
-      g_free (full);
-      
       if (source->pixbuf == NULL)
         {
           /* Remove this icon source so we don't keep trying to
@@ -1426,19 +1416,15 @@
  * @source: a #GtkIconSource
  * @filename: image file to use
  *
- * Sets the name of an image file to use as a base image when creating icon
- * variants for #GtkIconSet. If the filename is absolute, GTK+ will
- * attempt to open the exact file given. If the filename is relative,
- * GTK+ will search for it in the "pixmap path" which can be configured
- * by users in their gtkrc files or specified as part of a theme's gtkrc
- * file. See #GtkRcStyle for information on gtkrc files.
- * 
+ * Sets the name of an image file to use as a base image when creating
+ * icon variants for #GtkIconSet. The filename must be absolute. 
  **/
 void
-gtk_icon_source_set_filename             (GtkIconSource *source,
-                                          const gchar   *filename)
+gtk_icon_source_set_filename (GtkIconSource *source,
+			      const gchar   *filename)
 {
   g_return_if_fail (source != NULL);
+  g_return_if_fail (filename == NULL || g_path_is_absolute (filename));
 
   if (source->filename == filename)
     return;
Index: gtk/gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.164
diff -u -r1.164 gtkmain.c
--- gtk/gtkmain.c	2001/06/21 17:45:26	1.164
+++ gtk/gtkmain.c	2001/06/22 22:56:41
@@ -615,7 +615,7 @@
   result = pango_language_from_string (lang);
   g_free (lang);
   
-  return lang;
+  return result;
 }
 
 void
Index: gtk/gtkrc.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrc.c,v
retrieving revision 1.84
diff -u -r1.84 gtkrc.c
--- gtk/gtkrc.c	2001/06/21 17:45:26	1.84
+++ gtk/gtkrc.c	2001/06/22 22:56:41
@@ -54,6 +54,7 @@
 #include "gtkintl.h"
 #include "gtkiconfactory.h"
 #include "gtksettings.h"
+#include "gtkwindow.h"
 
 #ifdef G_OS_WIN32
 #include <io.h>
@@ -66,7 +67,8 @@
 struct _GtkRcSet
 {
   GPatternSpec *pspec;
-  GtkRcStyle   *rc_style;
+  GtkRcStyle *rc_style;
+  gint priority;
 };
 
 struct _GtkRcFile
@@ -74,7 +76,27 @@
   time_t mtime;
   gchar *name;
   gchar *canonical_name;
-  gboolean reload;
+  guint reload;
+};
+
+#define GTK_RC_MAX_PIXMAP_PATHS 128
+
+struct _GtkRcContext
+{
+  GHashTable *rc_style_ht;
+  GSList *rc_sets_widget;
+  GSList *rc_sets_widget_class;
+  GSList *rc_sets_class;
+
+  /* The files we have parsed, to reread later if necessary */
+  GSList *rc_files;
+
+  gchar *theme_name;
+  gchar *key_theme_name;
+  
+  gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
+
+  gint default_priority;
 };
 
 static guint       gtk_rc_style_hash                 (const gchar     *name);
@@ -83,7 +105,8 @@
 static guint       gtk_rc_styles_hash                (const GSList    *rc_styles);
 static gboolean    gtk_rc_styles_equal               (const GSList    *a,
                                                       const GSList    *b);
-static GtkRcStyle* gtk_rc_style_find                 (const gchar     *name);
+static GtkRcStyle* gtk_rc_style_find                 (GtkRcContext    *context,
+						      const gchar     *name);
 static GSList *    gtk_rc_styles_match               (GSList          *rc_styles,
                                                       GSList          *sets,
                                                       guint            path_length,
@@ -91,13 +114,22 @@
                                                       const gchar     *path_reversed);
 static GtkStyle *  gtk_rc_style_to_style             (GtkRcStyle      *rc_style);
 static GtkStyle*   gtk_rc_init_style                 (GSList          *rc_styles);
-static void        gtk_rc_parse_file                 (const gchar     *filename,
+static void        gtk_rc_parse_default_files        (GtkRcContext    *context);
+static void        gtk_rc_parse_named                (GtkRcContext    *context,
+						      const gchar     *name,
+						      const gchar     *type);
+static void        gtk_rc_parse_file                 (GtkRcContext    *context,
+						      const gchar     *filename,
+						      gint             priority,
                                                       gboolean         reload);
-static void        gtk_rc_parse_any                  (const gchar     *input_name,
+static void        gtk_rc_parse_any                  (GtkRcContext    *context,
+						      const gchar     *input_name,
                                                       gint             input_fd,
                                                       const gchar     *input_string);
-static guint       gtk_rc_parse_statement            (GScanner        *scanner);
-static guint       gtk_rc_parse_style                (GScanner        *scanner);
+static guint       gtk_rc_parse_statement            (GtkRcContext    *context,
+						      GScanner        *scanner);
+static guint       gtk_rc_parse_style                (GtkRcContext    *context,
+						      GScanner        *scanner);
 static guint       gtk_rc_parse_assignment           (GScanner        *scanner,
 						      GtkRcProperty   *prop);
 static guint       gtk_rc_parse_bg                   (GScanner        *scanner,
@@ -112,7 +144,8 @@
                                                       GtkRcStyle      *style);
 static guint       gtk_rc_parse_ythickness           (GScanner        *scanner,
                                                       GtkRcStyle      *style);
-static guint       gtk_rc_parse_bg_pixmap            (GScanner        *scanner,
+static guint       gtk_rc_parse_bg_pixmap            (GtkRcContext    *context,
+						      GScanner        *scanner,
                                                       GtkRcStyle      *rc_style);
 static guint       gtk_rc_parse_font                 (GScanner        *scanner,
                                                       GtkRcStyle      *rc_style);
@@ -120,22 +153,28 @@
                                                       GtkRcStyle      *rc_style);
 static guint       gtk_rc_parse_font_name            (GScanner        *scanner,
                                                       GtkRcStyle      *rc_style);
-static guint       gtk_rc_parse_engine               (GScanner        *scanner,
+static guint       gtk_rc_parse_engine               (GtkRcContext    *context,
+						      GScanner        *scanner,
                                                       GtkRcStyle     **rc_style);
-static guint       gtk_rc_parse_pixmap_path          (GScanner        *scanner);
-static void        gtk_rc_parse_pixmap_path_string   (gchar           *pix_path);
+static guint       gtk_rc_parse_pixmap_path          (GtkRcContext    *context,
+						      GScanner        *scanner);
+static void        gtk_rc_parse_pixmap_path_string   (GtkRcContext    *context,
+						      GScanner        *scanner,
+						      const gchar     *pix_path);
 static guint       gtk_rc_parse_module_path          (GScanner        *scanner);
-static void        gtk_rc_parse_module_path_string   (gchar           *mod_path);
+static void        gtk_rc_parse_module_path_string   (const gchar     *mod_path);
 static guint       gtk_rc_parse_im_module_path       (GScanner        *scanner);
 static guint       gtk_rc_parse_im_module_file       (GScanner        *scanner);
-static guint       gtk_rc_parse_path_pattern         (GScanner        *scanner);
-static guint       gtk_rc_parse_stock                (GScanner        *scanner,
+static guint       gtk_rc_parse_path_pattern         (GtkRcContext    *context,
+						      GScanner        *scanner);
+static guint       gtk_rc_parse_stock                (GtkRcContext    *context,
+						      GScanner        *scanner,
                                                       GtkRcStyle      *rc_style,
                                                       GtkIconFactory  *factory);
 static void        gtk_rc_clear_hash_node            (gpointer         key,
                                                       gpointer         data,
                                                       gpointer         user_data);
-static void        gtk_rc_clear_styles               (void);
+static void        gtk_rc_clear_styles               (GtkRcContext    *context);
 static void        gtk_rc_append_default_module_path (void);
 static void        gtk_rc_add_initial_default_files  (void);
 
@@ -223,6 +262,7 @@
   { "lowest", GTK_RC_TOKEN_LOWEST },
   { "gtk", GTK_RC_TOKEN_GTK },
   { "application", GTK_RC_TOKEN_APPLICATION },
+  { "theme", GTK_RC_TOKEN_THEME },
   { "rc", GTK_RC_TOKEN_RC },
   { "highest", GTK_RC_TOKEN_HIGHEST },
   { "engine", GTK_RC_TOKEN_ENGINE },
@@ -234,22 +274,14 @@
   { "RTL", GTK_RC_TOKEN_RTL }
 };
 
-static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
+static GHashTable *realized_style_ht = NULL;
 
 static gchar *im_module_path = NULL;
 static gchar *im_module_file = NULL;
 
-static GHashTable *rc_style_ht = NULL;
-static GHashTable *realized_style_ht = NULL;
-static GSList *gtk_rc_sets_widget = NULL;
-static GSList *gtk_rc_sets_widget_class = NULL;
-static GSList *gtk_rc_sets_class = NULL;
-
 #define GTK_RC_MAX_DEFAULT_FILES 128
 static gchar *gtk_rc_default_files[GTK_RC_MAX_DEFAULT_FILES];
 
-#define GTK_RC_MAX_PIXMAP_PATHS 128
-static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
 #define GTK_RC_MAX_MODULE_PATHS 128
 static gchar *module_path[GTK_RC_MAX_MODULE_PATHS];
 
@@ -258,12 +290,8 @@
  */
 static GSList *rc_dir_stack = NULL;
 
-/* The files we have parsed, to reread later if necessary */
-static GSList *rc_files = NULL;
-
 /* RC file handling */
 
-
 #ifdef G_OS_WIN32
 static gchar *
 get_gtk_dll_name (void)
@@ -459,6 +487,13 @@
     }
 }
 
+/**
+ * gtk_rc_add_default_file:
+ * @file: the pathname to the file.
+ * 
+ * Adds a file to the list of files to be parsed at the
+ * end of gtk_init().
+ **/
 void
 gtk_rc_add_default_file (const gchar *file)
 {
@@ -474,6 +509,13 @@
   gtk_rc_default_files[n] = NULL;
 }
 
+/**
+ * gtk_rc_set_default_files:
+ * @files: A %NULL terminated list of filenames.
+ * 
+ * Sets the list of files that GTK+ will read at the
+ * end of gtk_init()
+ **/
 void
 gtk_rc_set_default_files (gchar **files)
 {
@@ -498,6 +540,18 @@
     }
 }
 
+/**
+ * gtk_rc_get_default_files:
+ * @void: 
+ * 
+ * Retrieves the current list of RC files that will be parsed
+ * at the end of gtk_init()
+ * 
+ * Return value: A NULL terminated array of filenames. This memory
+ * is owned by GTK+ and must not be freed by the application.
+ *  If you want to store this information, you should make a 
+ * copy.
+ **/
 gchar **
 gtk_rc_get_default_files (void)
 {
@@ -506,126 +560,247 @@
   return gtk_rc_default_files;
 }
 
- /* The following routine is based on _nl_normalize_codeset from
-  * the GNU C library. Contributed by
-  *
-  * Contributed by Ulrich Drepper <drepper gnu ai mit edu>, 1995.
-  * Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
-  * 
-  * Normalize codeset name.  There is no standard for the codeset
-  * names.  Normalization allows the user to use any of the common
-  * names.
-  */
- static gchar *
- _gtk_normalize_codeset (const gchar *codeset, gint name_len)
- {
-   gint len = 0;
-   gint only_digit = 1;
-   gchar *retval;
-   gchar *wp;
-   gint cnt;
- 
-   for (cnt = 0; cnt < name_len; ++cnt)
-     if (isalnum (codeset[cnt]))
-       {
- 	++len;
- 
- 	if (isalpha (codeset[cnt]))
- 	  only_digit = 0;
-       }
- 
-   retval = g_malloc ((only_digit ? 3 : 0) + len + 1);
- 
-   if (only_digit)
-     {
-       memcpy (retval, "iso", 4);
-       wp = retval + 3;
-     }
-   else
-     wp = retval;
-   
-   for (cnt = 0; cnt < name_len; ++cnt)
-     if (isalpha (codeset[cnt]))
-       *wp++ = isupper(codeset[cnt]) ? tolower (codeset[cnt]) : codeset[cnt];
-     else if (isdigit (codeset[cnt]))
-       *wp++ = codeset[cnt];
-   
-   *wp = '\0';
- 
-   return retval;
- }
- 
-void
-_gtk_rc_init (void)
+/* The following routine is based on _nl_normalize_codeset from
+ * the GNU C library. Contributed by
+ *
+ * Contributed by Ulrich Drepper <drepper gnu ai mit edu>, 1995.
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ * 
+ * Normalize codeset name.  There is no standard for the codeset
+ * names.  Normalization allows the user to use any of the common
+ * names.
+ */
+static gchar *
+_gtk_normalize_codeset (const gchar *codeset, gint name_len)
 {
-  static gboolean initialized = FALSE;
-  static gchar *locale_suffixes[3];
-  static gint n_locale_suffixes = 0;
-  gint i, j;
+  gint len = 0;
+  gint only_digit = 1;
+  gchar *retval;
+  gchar *wp;
+  gint cnt;
+
+  for (cnt = 0; cnt < name_len; ++cnt)
+    if (isalnum (codeset[cnt]))
+      {
+       ++len;
 
+       if (isalpha (codeset[cnt]))
+	 only_digit = 0;
+      }
 
-  if (!initialized)
+  retval = g_malloc ((only_digit ? 3 : 0) + len + 1);
+
+  if (only_digit)
     {
-      gint length;
-      gchar *locale;
-      gchar *p;
+      memcpy (retval, "iso", 4);
+      wp = retval + 3;
+    }
+  else
+    wp = retval;
 
-#ifdef G_OS_WIN32      
-      locale = g_win32_getlocale ();
-#else      
-      locale = setlocale (LC_CTYPE, NULL);
-#endif      
-      initialized = TRUE;
+  for (cnt = 0; cnt < name_len; ++cnt)
+    if (isalpha (codeset[cnt]))
+      *wp++ = isupper(codeset[cnt]) ? tolower (codeset[cnt]) : codeset[cnt];
+    else if (isdigit (codeset[cnt]))
+      *wp++ = codeset[cnt];
 
-      pixmap_path[0] = NULL;
-      module_path[0] = NULL;
-      gtk_rc_append_default_module_path();
+  *wp = '\0';
+
+  return retval;
+}
+
+static void
+gtk_rc_settings_changed (GtkSettings  *settings,
+			 GParamSpec   *pspec,
+			 GtkRcContext *context)
+{
+  gchar *new_theme_name;
+  gchar *new_key_theme_name;
+
+  g_object_get (settings,
+		"gtk-theme-name", &new_theme_name,
+		"gtk-key-theme-name", &new_key_theme_name,
+		NULL);
+
+  if ((new_theme_name != context->theme_name && 
+       !(new_theme_name && context->theme_name && strcmp (new_theme_name, context->theme_name) == 0)) ||
+      (new_key_theme_name != context->key_theme_name &&
+       !(new_key_theme_name && context->key_theme_name && strcmp (new_key_theme_name, context->key_theme_name) == 0)))
+    {
+      gtk_rc_context_reparse_all (context, TRUE);
+    }
+
+  g_free (new_theme_name);
+  g_free (new_key_theme_name);
+}
+
+/**
+ * gtk_rc_context_get_default:
+ * 
+ * Retrieves the default #GtkRcContext, creates it if
+ * does not yet exist.
+ * 
+ * Return value: the default #GtkRcContext
+ **/
+GtkRcContext *
+gtk_rc_context_get_default (void)
+{
+  static GtkRcContext *context = NULL;
+
+  if (!context)
+    {
+      context = g_new (GtkRcContext, 1);
+
+      context->rc_style_ht = NULL;
+      context->rc_sets_widget = NULL;
+      context->rc_sets_widget_class = NULL;
+      context->rc_sets_class = NULL;
+      context->rc_files = NULL;
+
+      g_object_get (gtk_settings_get_global (),
+		    "gtk-theme-name", &context->theme_name,
+		    "gtk-key-theme-name", &context->key_theme_name,
+		    NULL);
+
+      g_signal_connect (gtk_settings_get_global (),
+			"notify::gtk-theme-name",
+			G_CALLBACK (gtk_rc_settings_changed),
+			context);
+      g_signal_connect (gtk_settings_get_global (),
+			"notify::gtk-key-theme-name",
+			G_CALLBACK (gtk_rc_settings_changed),
+			context);
       
-      gtk_rc_add_initial_default_files ();
+      context->pixmap_path[0] = NULL;
+
+      context->default_priority = GTK_PATH_PRIO_RC;
+    }
+
+  return context;
+}
+
+static void
+gtk_rc_parse_named (GtkRcContext *context,
+		    const gchar  *name,
+		    const gchar  *type)
+{
+  gchar *path = NULL;
+  gchar *home_dir;
+  gchar *subpath;
+
+  if (type)
+    subpath = g_strconcat (G_DIR_SEPARATOR_S "gtk-2.0-",
+			   type,
+			   G_DIR_SEPARATOR_S "gtkrc",
+			   NULL);
+  else
+    subpath = g_strdup (G_DIR_SEPARATOR_S "gtk-2.0" G_DIR_SEPARATOR_S "gtkrc");
+  
+  /* First look in the users home directory
+   */
+  home_dir = g_get_home_dir ();
+  if (home_dir)
+    {
+      gchar *sep;
+      /* Don't duplicate the directory separator, causes trouble at
+       * least on Windows.
+       */
+      if (home_dir[strlen (home_dir) -1] != G_DIR_SEPARATOR)
+	sep = G_DIR_SEPARATOR_S;
+      else
+	sep = "";
+      path = g_strconcat (home_dir, sep,
+			  ".themes" G_DIR_SEPARATOR_S ,
+			  name,
+			  subpath,
+			  NULL);
 
-      if (strcmp (locale, "C") && strcmp (locale, "POSIX"))
+      if (!g_file_test (path, G_FILE_TEST_EXISTS))
 	{
-	  /* Determine locale-specific suffixes for RC files
-	   *
-	   * We normalize the charset into a standard form,
-	   * which has all '-' and '_' characters removed,
-	   * and is lowercase.
-	   */
-	  gchar *normalized_locale;
+	  g_free (path);
+	  path = NULL;
+	}
+    }
 
-	  p = strchr (locale, '@');
-	  length = p ? (p -locale) : strlen (locale);
+  if (!name)
+    {
+      gchar *theme_dir = gtk_rc_get_theme_dir ();
+      gchar *path = g_strconcat (theme_dir, G_DIR_SEPARATOR_S, name, subpath);
+      g_free (theme_dir);
+      
+      if (!g_file_test (path, G_FILE_TEST_EXISTS))
+	{
+	  g_free (path);
+	  path = NULL;
+	}
+    }
 
-	  p = strchr (locale, '.');
-	  if (p)
-	    {
-	      gchar *tmp1 = g_strndup (locale, p - locale + 1);
-	      gchar *tmp2 = _gtk_normalize_codeset (p + 1, length - (p - locale + 1));
-	      
-	      normalized_locale = g_strconcat (tmp1, tmp2, NULL);
-	      g_free (tmp1);
-	      g_free (tmp2);
-						 
-	      locale_suffixes[n_locale_suffixes++] = g_strdup (normalized_locale);
-	      length = p - locale;
-	    }
-	  else
-	    normalized_locale = g_strndup (locale, length);
+  if (path)
+    {
+      gtk_rc_parse_file (context, path, GTK_PATH_PRIO_THEME, FALSE);
+      g_free (path);
+    }
+
+  g_free (subpath);
+}
+
+static void
+gtk_rc_parse_default_files (GtkRcContext *context)
+{
+  gchar *locale_suffixes[3];
+  gint n_locale_suffixes = 0;
+  gint i, j;
+  gint length;
+  gchar *locale;
+  gchar *p;
+
+#ifdef G_OS_WIN32      
+  locale = g_win32_getlocale ();
+#else      
+  locale = setlocale (LC_CTYPE, NULL);
+#endif      
+
+  if (strcmp (locale, "C") && strcmp (locale, "POSIX"))
+    {
+      /* Determine locale-specific suffixes for RC files
+       *
+       * We normalize the charset into a standard form,
+       * which has all '-' and '_' characters removed,
+       * and is lowercase.
+       */
+      gchar *normalized_locale;
+      
+      p = strchr (locale, '@');
+      length = p ? (p -locale) : strlen (locale);
+      
+      p = strchr (locale, '.');
+      if (p)
+	{
+	  gchar *tmp1 = g_strndup (locale, p - locale + 1);
+	  gchar *tmp2 = _gtk_normalize_codeset (p + 1, length - (p - locale + 1));
 	  
-	  p = strchr (normalized_locale, '_');
-	  if (p)
-	    {
-	      locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
-	      length = p - normalized_locale;
-	    }
+	  normalized_locale = g_strconcat (tmp1, tmp2, NULL);
+	  g_free (tmp1);
+	  g_free (tmp2);
 	  
+	  locale_suffixes[n_locale_suffixes++] = g_strdup (normalized_locale);
+	  length = p - locale;
+	}
+      else
+	normalized_locale = g_strndup (locale, length);
+      
+      p = strchr (normalized_locale, '_');
+      if (p)
+	{
 	  locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
-
-	  g_free (normalized_locale);
+	  length = p - normalized_locale;
 	}
+      
+      locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
+      
+      g_free (normalized_locale);
     }
   
-  g_object_freeze_notify (G_OBJECT (gtk_settings_get_global ()));
   for (i = 0; gtk_rc_default_files[i] != NULL; i++)
     {
       /* Try to find a locale specific RC file corresponding to the
@@ -637,32 +812,59 @@
 				     ".",
 				     locale_suffixes[j],
 				     NULL);
-	  gtk_rc_parse (name);
+	  gtk_rc_parse_file (context, name, GTK_PATH_PRIO_RC, FALSE);
 	  g_free (name);
 	}
-      gtk_rc_parse (gtk_rc_default_files[i]);
+      gtk_rc_parse_file (context, gtk_rc_default_files[i], GTK_PATH_PRIO_RC, FALSE);
     }
-  g_object_thaw_notify (G_OBJECT (gtk_settings_get_global ()));
+
+  for (j = 0; j < n_locale_suffixes; j++)
+    g_free (locale_suffixes[j]);
 }
 
 void
+_gtk_rc_init (void)
+{
+  static gboolean initialized = FALSE;
+
+  if (!initialized)
+    {
+      initialized = TRUE;
+      
+      module_path[0] = NULL;
+      gtk_rc_append_default_module_path();
+      
+      gtk_rc_add_initial_default_files ();
+    }
+  
+  gtk_rc_context_reparse_all (gtk_rc_context_get_default (), TRUE);
+}
+  
+void
 gtk_rc_parse_string (const gchar *rc_string)
 {
   g_return_if_fail (rc_string != NULL);
 
-  gtk_rc_parse_any ("-", -1, rc_string);
+  gtk_rc_parse_any (gtk_rc_context_get_default (), "-", -1, rc_string);	/* FIXME */
 }
 
 static void
-gtk_rc_parse_file (const gchar *filename, gboolean reload)
+gtk_rc_parse_file (GtkRcContext *context,
+		   const gchar  *filename,
+		   gint          priority,
+		   gboolean      reload)
 {
   GtkRcFile *rc_file = NULL;
   struct stat statbuf;
   GSList *tmp_list;
+  gint saved_priority;
 
   g_return_if_fail (filename != NULL);
 
-  tmp_list = rc_files;
+  saved_priority = context->default_priority;
+  context->default_priority = priority;
+  
+  tmp_list = context->rc_files;
   while (tmp_list)
     {
       rc_file = tmp_list->data;
@@ -680,7 +882,7 @@
       rc_file->mtime = 0;
       rc_file->reload = reload;
 
-      rc_files = g_slist_append (rc_files, rc_file);
+      context->rc_files = g_slist_append (context->rc_files, rc_file);
     }
 
   if (!rc_file->canonical_name)
@@ -715,7 +917,7 @@
 
       fd = open (rc_file->canonical_name, O_RDONLY);
       if (fd < 0)
-	return;
+	goto out;
 
       /* Temporarily push directory name for this file on
        * a stack of directory names while parsing it
@@ -723,7 +925,7 @@
       rc_dir_stack = 
 	g_slist_prepend (rc_dir_stack,
 			 g_path_get_dirname (rc_file->canonical_name));
-      gtk_rc_parse_any (filename, fd, NULL);
+      gtk_rc_parse_any (context, filename, fd, NULL);
  
       tmp_list = rc_dir_stack;
       rc_dir_stack = rc_dir_stack->next;
@@ -733,6 +935,9 @@
 
       close (fd);
     }
+
+ out:
+  context->default_priority = saved_priority;
 }
 
 void
@@ -740,7 +945,8 @@
 {
   g_return_if_fail (filename != NULL);
 
-  gtk_rc_parse_file (filename, TRUE);
+  gtk_rc_parse_file (gtk_rc_context_get_default (), filename,
+		     GTK_PATH_PRIO_RC, TRUE); /* FIXME */
 }
 
 /* Handling of RC styles */
@@ -1064,75 +1270,157 @@
 }
 
 static void
-gtk_rc_clear_styles (void)
+gtk_rc_clear_styles (GtkRcContext *context)
 {
   /* Clear out all old rc_styles */
 
-  if (rc_style_ht)
+  if (context->rc_style_ht)
     {
-      g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
-      g_hash_table_destroy (rc_style_ht);
-      rc_style_ht = NULL;
+      g_hash_table_foreach (context->rc_style_ht, gtk_rc_clear_hash_node, NULL);
+      g_hash_table_destroy (context->rc_style_ht);
+      context->rc_style_ht = NULL;
     }
 
-  gtk_rc_free_rc_sets (gtk_rc_sets_widget);
-  g_slist_free (gtk_rc_sets_widget);
-  gtk_rc_sets_widget = NULL;
+  gtk_rc_free_rc_sets (context->rc_sets_widget);
+  g_slist_free (context->rc_sets_widget);
+  context->rc_sets_widget = NULL;
 
-  gtk_rc_free_rc_sets (gtk_rc_sets_widget_class);
-  g_slist_free (gtk_rc_sets_widget_class);
-  gtk_rc_sets_widget_class = NULL;
+  gtk_rc_free_rc_sets (context->rc_sets_widget_class);
+  g_slist_free (context->rc_sets_widget_class);
+  context->rc_sets_widget_class = NULL;
+
+  gtk_rc_free_rc_sets (context->rc_sets_class);
+  g_slist_free (context->rc_sets_class);
+  context->rc_sets_class = NULL;
+}
 
-  gtk_rc_free_rc_sets (gtk_rc_sets_class);
-  g_slist_free (gtk_rc_sets_class);
-  gtk_rc_sets_class = NULL;
+/* Reset all our widgets. Also, we have to invalidate cached icons in
+ * icon sets so they get re-rendered.
+ */
+static void
+gtk_rc_reset_widgets (GtkRcContext *context)
+{
+  GList *list, *toplevels;
+  
+  _gtk_icon_set_invalidate_caches ();
+  
+  toplevels = gtk_window_list_toplevels ();
+  g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
+  
+  for (list = toplevels; list; list = list->next)
+    {
+      gtk_widget_reset_rc_styles (list->data);
+      gtk_widget_unref (list->data);
+    }
+  g_list_free (toplevels);
 }
 
+/**
+ * gtk_rc_context_reparse_all:
+ * @context: a #GtkRcContext
+ * @force_load: load whether or not anything changed
+ * 
+ * If the modification time on any previously read file
+ * has changed, discard all style information
+ * and then reread all previously read RC files.
+ * 
+ * Return value: %TRUE if the files were reread.
+ **/
 gboolean
-gtk_rc_reparse_all (void)
+gtk_rc_context_reparse_all (GtkRcContext *context,
+			    gboolean      force_load)
 {
-  GSList *tmp_list;
   gboolean mtime_modified = FALSE;
   GtkRcFile *rc_file;
+  GSList *tmp_list;
 
   struct stat statbuf;
 
-  /* Check through and see if any of the RC's have had their
-   * mtime modified. If so, reparse everything.
-   */
-  tmp_list = rc_files;
-  while (tmp_list)
+  if (!force_load)
     {
-      rc_file = tmp_list->data;
-      
-      if (!lstat (rc_file->name, &statbuf) && 
-	  (statbuf.st_mtime > rc_file->mtime))
+      /* Check through and see if any of the RC's have had their
+       * mtime modified. If so, reparse everything.
+       */
+      tmp_list = context->rc_files;
+      while (tmp_list)
 	{
-	  mtime_modified = TRUE;
-	  break;
+	  rc_file = tmp_list->data;
+	  
+	  if (!lstat (rc_file->name, &statbuf) && 
+	      (statbuf.st_mtime > rc_file->mtime))
+	    {
+	      mtime_modified = TRUE;
+	      break;
+	    }
+	  
+	  tmp_list = tmp_list->next;
 	}
-      
-      tmp_list = tmp_list->next;
     }
-
-  if (mtime_modified)
+      
+  if (force_load || mtime_modified)
     {
-      gtk_rc_clear_styles();
+      GSList *old_files;
+      
+      gtk_rc_clear_styles (context);
+      g_object_freeze_notify (G_OBJECT (gtk_settings_get_global ()));
+
+      old_files = context->rc_files;
+      context->rc_files = NULL;
+
+      gtk_rc_parse_default_files (context);
 
-      tmp_list = rc_files;
+      tmp_list = old_files;
       while (tmp_list)
 	{
 	  rc_file = tmp_list->data;
 	  if (rc_file->reload)
-	    gtk_rc_parse_file (rc_file->name, FALSE);
+	    gtk_rc_parse_file (context, rc_file->name, GTK_PATH_PRIO_RC, TRUE);
+
+	  if (rc_file->canonical_name != rc_file->name)
+	    g_free (rc_file->canonical_name);
+	  g_free (rc_file->name);
+	  g_free (rc_file);
 	  
 	  tmp_list = tmp_list->next;
 	}
+
+      g_slist_free (old_files);;
+
+      g_free (context->theme_name);
+      g_free (context->key_theme_name);
+      g_object_get (gtk_settings_get_global (),
+		    "gtk-theme-name", &context->theme_name,
+		    "gtk-key-theme-name", &context->key_theme_name,
+		    NULL);
+
+      if (context->theme_name && context->theme_name[0])
+	gtk_rc_parse_named (context, context->theme_name, NULL);
+      if (context->key_theme_name && context->key_theme_name[0])
+	gtk_rc_parse_named (context, context->key_theme_name, "key");
+      
+      g_object_thaw_notify (G_OBJECT (gtk_settings_get_global ()));
+
+      gtk_rc_reset_widgets (context);
     }
 
   return mtime_modified;
 }
 
+/**
+ * gtk_rc_reparse_all:
+ * 
+ * If the modification time on any previously read file for the
+ * default #GtkRcContext has changed, discard all style information
+ * and then reread all previously read RC files.
+ * 
+ * Return value:  %TRUE if the files were reread.
+ **/
+gboolean
+gtk_rc_reparse_all (void)
+{
+  return gtk_rc_context_reparse_all (gtk_rc_context_get_default (), FALSE);
+}
+
 static GSList *
 gtk_rc_styles_match (GSList       *rc_styles,
 		     GSList	  *sets,
@@ -1155,14 +1443,34 @@
   return rc_styles;
 }
 
+/**
+ * gtk_rc_get_style:
+ * @widget: a #GtkWidget
+ * 
+ * Finds all matching RC styles for a given widget,
+ * composites them together, and then creates a 
+ * #GtkStyle representing the composite appearance.
+ * (GTK+ actually keeps a cache of previously 
+ * created styles, so a new style may not be
+ * created.)
+ * 
+ * @Returns: the resulting style. No refcount is added
+ *   to the returned style, so if you want to save this
+ *   style around, you should add a reference yourself.
+ **/
 GtkStyle *
 gtk_rc_get_style (GtkWidget *widget)
 {
   GtkRcStyle *widget_rc_style;
   GSList *rc_styles = NULL;
+  GtkRcContext *context;
 
   static guint rc_style_key_id = 0;
 
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  context = gtk_rc_context_get_default (); /* FIXME */
+
   /* We allow the specification of a single rc style to be bound
    * tightly to a widget, for application modifications
    */
@@ -1175,30 +1483,29 @@
   if (widget_rc_style)
     rc_styles = g_slist_prepend (rc_styles, widget_rc_style);
   
-  if (gtk_rc_sets_widget)
+  if (context->rc_sets_widget)
     {
       gchar *path, *path_reversed;
       guint path_length;
 
       gtk_widget_path (widget, &path_length, &path, &path_reversed);
-      rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget, path_length, path, path_reversed);
+      rc_styles = gtk_rc_styles_match (rc_styles, context->rc_sets_widget, path_length, path, path_reversed);
       g_free (path);
       g_free (path_reversed);
-      
     }
   
-  if (gtk_rc_sets_widget_class)
+  if (context->rc_sets_widget_class)
     {
       gchar *path, *path_reversed;
       guint path_length;
 
       gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
-      rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget_class, path_length, path, path_reversed);
+      rc_styles = gtk_rc_styles_match (rc_styles, context->rc_sets_widget_class, path_length, path, path_reversed);
       g_free (path);
       g_free (path_reversed);
     }
 
-  if (gtk_rc_sets_class)
+  if (context->rc_sets_class)
     {
       GtkType type;
 
@@ -1214,7 +1521,7 @@
 	  path_reversed = g_strdup (path);
 	  g_strreverse (path_reversed);
 	  
-	  rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_class, path_length, path, path_reversed);
+	  rc_styles = gtk_rc_styles_match (rc_styles, context->rc_sets_class, path_length, path, path_reversed);
 	  g_free (path_reversed);
       
 	  type = gtk_type_parent (type);
@@ -1256,30 +1563,42 @@
 gtk_rc_add_widget_name_style (GtkRcStyle  *rc_style,
 			      const gchar *pattern)
 {
+  GtkRcContext *context;
+  
   g_return_if_fail (rc_style != NULL);
   g_return_if_fail (pattern != NULL);
 
-  gtk_rc_sets_widget = gtk_rc_add_rc_sets (gtk_rc_sets_widget, rc_style, pattern);
+  context = gtk_rc_context_get_default ();
+  
+  context->rc_sets_widget = gtk_rc_add_rc_sets (context->rc_sets_widget, rc_style, pattern);
 }
 
 void
 gtk_rc_add_widget_class_style (GtkRcStyle  *rc_style,
 			       const gchar *pattern)
 {
+  GtkRcContext *context;
+  
   g_return_if_fail (rc_style != NULL);
   g_return_if_fail (pattern != NULL);
 
-  gtk_rc_sets_widget_class = gtk_rc_add_rc_sets (gtk_rc_sets_widget_class, rc_style, pattern);
+  context = gtk_rc_context_get_default ();
+  
+  context->rc_sets_widget_class = gtk_rc_add_rc_sets (context->rc_sets_widget_class, rc_style, pattern);
 }
 
 void
 gtk_rc_add_class_style (GtkRcStyle  *rc_style,
 			const gchar *pattern)
 {
+  GtkRcContext *context;
+  
   g_return_if_fail (rc_style != NULL);
   g_return_if_fail (pattern != NULL);
 
-  gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
+  context = gtk_rc_context_get_default ();
+  
+  context->rc_sets_class = gtk_rc_add_rc_sets (context->rc_sets_class, rc_style, pattern);
 }
 
 GScanner*
@@ -1289,7 +1608,8 @@
 }
 
 static void
-gtk_rc_parse_any (const gchar  *input_name,
+gtk_rc_parse_any (GtkRcContext *context,
+		  const gchar  *input_name,
 		  gint		input_fd,
 		  const gchar  *input_string)
 {
@@ -1313,7 +1633,7 @@
     }
   scanner->input_name = input_name;
 
-  for (i = 0; i < n_symbols; i++)
+  for (i = 0; i < G_N_ELEMENTS (symbols); i++)
     g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
   
   done = FALSE;
@@ -1325,7 +1645,7 @@
 	{
 	  guint expected_token;
 	  
-	  expected_token = gtk_rc_parse_statement (scanner);
+	  expected_token = gtk_rc_parse_statement (context, scanner);
 
 	  if (expected_token != G_TOKEN_NONE)
 	    {
@@ -1344,7 +1664,7 @@
 		  if (expected_token > GTK_RC_TOKEN_INVALID &&
 		      expected_token < GTK_RC_TOKEN_LAST)
 		    {
-		      for (i = 0; i < n_symbols; i++)
+		      for (i = 0; i < G_N_ELEMENTS (symbols); i++)
 			if (symbols[i].token == expected_token)
 			  msg = symbols[i].name;
 		      if (msg)
@@ -1354,7 +1674,7 @@
 		      scanner->token < GTK_RC_TOKEN_LAST)
 		    {
 		      symbol_name = "???";
-		      for (i = 0; i < n_symbols; i++)
+		      for (i = 0; i < G_N_ELEMENTS (symbols); i++)
 			if (symbols[i].token == scanner->token)
 			  symbol_name = symbols[i].name;
 		    }
@@ -1425,10 +1745,11 @@
 }
 
 static GtkRcStyle*
-gtk_rc_style_find (const gchar *name)
+gtk_rc_style_find (GtkRcContext *context,
+		   const gchar  *name)
 {
-  if (rc_style_ht)
-    return g_hash_table_lookup (rc_style_ht, (gpointer) name);
+  if (context->rc_style_ht)
+    return g_hash_table_lookup (context->rc_style_ht, (gpointer) name);
   else
     return NULL;
 }
@@ -1460,7 +1781,7 @@
   
   if (!realized_style_ht)
     realized_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_styles_hash,
-					  (GEqualFunc) gtk_rc_styles_equal);
+ (GEqualFunc) gtk_rc_styles_equal);
 
   style = g_hash_table_lookup (realized_style_ht, rc_styles);
 
@@ -1734,7 +2055,8 @@
 }
 
 static guint
-gtk_rc_parse_statement (GScanner *scanner)
+gtk_rc_parse_statement (GtkRcContext *context,
+			GScanner     *scanner)
 {
   guint token;
   
@@ -1748,26 +2070,26 @@
       token = g_scanner_get_next_token (scanner);
       if (token != G_TOKEN_STRING)
 	return G_TOKEN_STRING;
-      gtk_rc_parse_file (scanner->value.v_string, FALSE);
+      gtk_rc_parse_file (context, scanner->value.v_string, context->default_priority, FALSE);
       return G_TOKEN_NONE;
       
     case GTK_RC_TOKEN_STYLE:
-      return gtk_rc_parse_style (scanner);
+      return gtk_rc_parse_style (context, scanner);
       
     case GTK_RC_TOKEN_BINDING:
       return gtk_binding_parse_binding (scanner);
       
     case GTK_RC_TOKEN_PIXMAP_PATH:
-      return gtk_rc_parse_pixmap_path (scanner);
+      return gtk_rc_parse_pixmap_path (context, scanner);
       
     case GTK_RC_TOKEN_WIDGET:
-      return gtk_rc_parse_path_pattern (scanner);
+      return gtk_rc_parse_path_pattern (context, scanner);
       
     case GTK_RC_TOKEN_WIDGET_CLASS:
-      return gtk_rc_parse_path_pattern (scanner);
+      return gtk_rc_parse_path_pattern (context, scanner);
       
     case GTK_RC_TOKEN_CLASS:
-      return gtk_rc_parse_path_pattern (scanner);
+      return gtk_rc_parse_path_pattern (context, scanner);
       
     case GTK_RC_TOKEN_MODULE_PATH:
       return gtk_rc_parse_module_path (scanner);
@@ -1818,7 +2140,8 @@
 }
 
 static guint
-gtk_rc_parse_style (GScanner *scanner)
+gtk_rc_parse_style (GtkRcContext *context,
+		    GScanner     *scanner)
 {
   GtkRcStyle *rc_style;
   GtkRcStyle *parent_style;
@@ -1836,7 +2159,7 @@
     return G_TOKEN_STRING;
   
   insert = FALSE;
-  rc_style = gtk_rc_style_find (scanner->value.v_string);
+  rc_style = gtk_rc_style_find (context, scanner->value.v_string);
 
   /* If there's a list, its first member is always the factory belonging
    * to this RcStyle
@@ -1871,7 +2194,7 @@
 	  return G_TOKEN_STRING;
 	}
       
-      parent_style = gtk_rc_style_find (scanner->value.v_string);
+      parent_style = gtk_rc_style_find (context, scanner->value.v_string);
       if (parent_style)
 	{
           GSList *factories;
@@ -1993,7 +2316,7 @@
 	  token = gtk_rc_parse_ythickness (scanner, rc_style);
 	  break;
 	case GTK_RC_TOKEN_BG_PIXMAP:
-	  token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
+	  token = gtk_rc_parse_bg_pixmap (context, scanner, rc_style);
 	  break;
 	case GTK_RC_TOKEN_FONT:
 	  token = gtk_rc_parse_font (scanner, rc_style);
@@ -2005,7 +2328,7 @@
 	  token = gtk_rc_parse_font_name (scanner, rc_style);
 	  break;
 	case GTK_RC_TOKEN_ENGINE:
-	  token = gtk_rc_parse_engine (scanner, &rc_style);
+	  token = gtk_rc_parse_engine (context, scanner, &rc_style);
 	  break;
         case GTK_RC_TOKEN_STOCK:
           if (our_factory == NULL)
@@ -2014,7 +2337,7 @@
               rc_style->icon_factories = g_slist_prepend (rc_style->icon_factories,
                                                           our_factory);
             }
-          token = gtk_rc_parse_stock (scanner, rc_style, our_factory);
+          token = gtk_rc_parse_stock (context, scanner, rc_style, our_factory);
           break;
 	case G_TOKEN_IDENTIFIER:
 	  if (is_c_identifier (scanner->next_value.v_identifier) &&
@@ -2110,11 +2433,11 @@
   
   if (insert)
     {
-      if (!rc_style_ht)
-	rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
-					(GEqualFunc) gtk_rc_style_equal);
+      if (!context->rc_style_ht)
+	context->rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
+						 (GEqualFunc) gtk_rc_style_equal);
       
-      g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
+      g_hash_table_insert (context->rc_style_ht, rc_style->name, rc_style);
     }
   
   return G_TOKEN_NONE;
@@ -2271,8 +2594,9 @@
 }
 
 static guint
-gtk_rc_parse_bg_pixmap (GScanner   *scanner,
-			GtkRcStyle *rc_style)
+gtk_rc_parse_bg_pixmap (GtkRcContext *context,
+			GScanner     *scanner,
+			GtkRcStyle   *rc_style)
 {
   GtkStateType state;
   guint token;
@@ -2298,7 +2622,7 @@
       (strcmp (scanner->value.v_string, "<none>") == 0))
     pixmap_file = g_strdup (scanner->value.v_string);
   else
-    pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
+    pixmap_file = gtk_rc_context_find_pixmap_in_path (context, scanner, scanner->value.v_string);
   
   if (pixmap_file)
     {
@@ -2329,18 +2653,31 @@
  
    return NULL;
  }
- 
+
+/**
+ * gtk_rc_context_find_pixmap_in_path:
+ * @context:
+ * @scanner: 
+ * @pixmap_file: name of the pixmap file to locate.
+ * 
+ * Looks up a file in the current pixmap path. If the file is
+ * not found, it outputs a warning message using g_warning()
+ * and returns %NULL.
+ *
+ * Return value: 
+ **/
 gchar*
-gtk_rc_find_pixmap_in_path (GScanner *scanner,
-  			    const gchar *pixmap_file)
+gtk_rc_context_find_pixmap_in_path (GtkRcContext *context,
+				    GScanner     *scanner,
+				    const gchar  *pixmap_file)
 {
   gint i;
   gchar *filename;
   GSList *tmp_list;
     
-  for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
+  for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (context->pixmap_path[i] != NULL); i++)
     {
-      filename = gtk_rc_check_pixmap_dir (pixmap_path[i], pixmap_file);
+      filename = gtk_rc_check_pixmap_dir (context->pixmap_path[i], pixmap_file);
       if (filename)
  	return filename;
     }
@@ -2460,8 +2797,9 @@
 }
 
 static guint	   
-gtk_rc_parse_engine (GScanner	 *scanner,
-		     GtkRcStyle	**rc_style)
+gtk_rc_parse_engine (GtkRcContext *context,
+		     GScanner	  *scanner,
+		     GtkRcStyle	 **rc_style)
 {
   guint token;
   GtkThemeEngine *engine;
@@ -2499,7 +2837,7 @@
       if (new_class->parse)
 	{
 	  parsed_curlies = TRUE;
-	  result = new_class->parse (new_style, scanner);
+	  result = new_class->parse (new_style, context, scanner);
 
 	  if (result != G_TOKEN_NONE)
 	    {
@@ -2623,6 +2961,9 @@
     case GTK_RC_TOKEN_APPLICATION:
       *priority = GTK_PATH_PRIO_APPLICATION;
       break;
+    case GTK_RC_TOKEN_THEME:
+      *priority = GTK_PATH_PRIO_THEME;
+      break;
     case GTK_RC_TOKEN_RC:
       *priority = GTK_PATH_PRIO_RC;
       break;
@@ -2756,7 +3097,8 @@
 }
 
 static guint
-gtk_rc_parse_pixmap_path (GScanner *scanner)
+gtk_rc_parse_pixmap_path (GtkRcContext *context,
+			  GScanner     *scanner)
 {
   guint token;
   
@@ -2768,46 +3110,54 @@
   if (token != G_TOKEN_STRING)
     return G_TOKEN_STRING;
   
-  gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
+  gtk_rc_parse_pixmap_path_string (context, scanner, scanner->value.v_string);
   
   return G_TOKEN_NONE;
 }
 
 static void
-gtk_rc_parse_pixmap_path_string (gchar *pix_path)
+gtk_rc_parse_pixmap_path_string (GtkRcContext *context,
+				 GScanner     *scanner,
+				 const gchar  *pix_path)
 {
-  gchar *buf;
   gint end_offset;
   gint start_offset = 0;
   gint path_len;
   gint path_num;
   
   /* free the old one, or just add to the old one ? */
-  for (path_num=0; pixmap_path[path_num]; path_num++)
+  for (path_num = 0; context->pixmap_path[path_num]; path_num++)
     {
-      g_free (pixmap_path[path_num]);
-      pixmap_path[path_num] = NULL;
+      g_free (context->pixmap_path[path_num]);
+      context->pixmap_path[path_num] = NULL;
     }
   
   path_num = 0;
   
   path_len = strlen (pix_path);
   
-  buf = g_strdup (pix_path);
-  
   for (end_offset = 0; end_offset <= path_len; end_offset++)
     {
-      if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
+      if ((pix_path[end_offset] == G_SEARCHPATH_SEPARATOR) ||
 	  (end_offset == path_len))
 	{
-	  buf[end_offset] = '\0';
-	  pixmap_path[path_num] = g_strdup (buf + start_offset);
-	  path_num++;
-	  pixmap_path[path_num] = NULL;
+	  gchar *path_element = g_strndup (pix_path + start_offset, end_offset - start_offset);
+	  if (g_path_is_absolute (path_element))
+	    {
+	      context->pixmap_path[path_num] = path_element;
+	      path_num++;
+	      context->pixmap_path[path_num] = NULL;
+	    }
+	  else
+	    {
+	      g_warning (_("Pixmap path element: \"%s\" must be absolute, %s, line %d"),
+			 path_element, scanner->input_name, scanner->line);
+	      g_free (path_element);
+	    }
+
 	  start_offset = end_offset + 1;
 	}
     }
-  g_free (buf);
 }
 
 static guint
@@ -2871,9 +3221,8 @@
 }
 
 static void
-gtk_rc_parse_module_path_string (gchar *mod_path)
+gtk_rc_parse_module_path_string (const gchar *mod_path)
 {
-  gchar *buf;
   gint end_offset;
   gint start_offset = 0;
   gint path_len;
@@ -2890,32 +3239,44 @@
   
   path_len = strlen (mod_path);
   
-  buf = g_strdup (mod_path);
-  
   for (end_offset = 0; end_offset <= path_len; end_offset++)
     {
-      if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
+      if ((mod_path[end_offset] == G_SEARCHPATH_SEPARATOR) ||
 	  (end_offset == path_len))
 	{
-	  buf[end_offset] = '\0';
-	  module_path[path_num] = g_strdup (buf + start_offset);
+	  module_path[path_num] = g_strndup (mod_path + start_offset, end_offset - start_offset);
 	  path_num++;
 	  module_path[path_num] = NULL;
 	  start_offset = end_offset + 1;
 	}
     }
-  g_free (buf);
   gtk_rc_append_default_module_path();
 }
 
+static gint
+rc_set_compare (gconstpointer a, gconstpointer b)
+{
+  const GtkRcSet *set_a = a;
+  const GtkRcSet *set_b = b;
+
+  return (set_a->priority < set_b->priority) ? 1 : (set_a->priority == set_b->priority ? 0 : -1);
+}
+
+static GSList *
+insert_rc_set (GSList *list, GtkRcSet *set)
+{
+  return g_slist_insert_sorted (list, set, rc_set_compare);
+}
+
 static guint
-gtk_rc_parse_path_pattern (GScanner   *scanner)
+gtk_rc_parse_path_pattern (GtkRcContext *context,
+			   GScanner     *scanner)
 {
   guint token;
   GtkPathType path_type;
   gchar *pattern;
   gboolean is_binding;
-  GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
+  GtkPathPriorityType priority = context->default_priority;
   
   token = g_scanner_get_next_token (scanner);
   switch (token)
@@ -2932,7 +3293,7 @@
     default:
       return GTK_RC_TOKEN_WIDGET_CLASS;
     }
-  
+
   token = g_scanner_get_next_token (scanner);
   if (token != G_TOKEN_STRING)
     return G_TOKEN_STRING;
@@ -2943,24 +3304,23 @@
   if (token == GTK_RC_TOKEN_STYLE)
     is_binding = FALSE;
   else if (token == GTK_RC_TOKEN_BINDING)
-    {
-      is_binding = TRUE;
-      if (g_scanner_peek_next_token (scanner) == ':')
-	{
-	  token = gtk_rc_parse_priority (scanner, &priority);
-	  if (token != G_TOKEN_NONE)
-	    {
-	      g_free (pattern);
-	      return token;
-	    }
-	}
-    }
+    is_binding = TRUE;
   else
     {
       g_free (pattern);
       return GTK_RC_TOKEN_STYLE;
     }
   
+  if (g_scanner_peek_next_token (scanner) == ':')
+    {
+      token = gtk_rc_parse_priority (scanner, &priority);
+      if (token != G_TOKEN_NONE)
+	{
+	  g_free (pattern);
+	  return token;
+	}
+    }
+  
   token = g_scanner_get_next_token (scanner);
   if (token != G_TOKEN_STRING)
     {
@@ -2985,7 +3345,7 @@
       GtkRcStyle *rc_style;
       GtkRcSet *rc_set;
 
-      rc_style = gtk_rc_style_find (scanner->value.v_string);
+      rc_style = gtk_rc_style_find (context, scanner->value.v_string);
       
       if (!rc_style)
 	{
@@ -2996,13 +3356,14 @@
       rc_set = g_new (GtkRcSet, 1);
       rc_set->pspec = g_pattern_spec_new (pattern);
       rc_set->rc_style = rc_style;
+      rc_set->priority = priority;
 
       if (path_type == GTK_PATH_WIDGET)
-	gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
+	context->rc_sets_widget = insert_rc_set (context->rc_sets_widget, rc_set);
       else if (path_type == GTK_PATH_WIDGET_CLASS)
-	gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
+	context->rc_sets_widget_class = insert_rc_set (context->rc_sets_widget_class, rc_set);
       else
-	gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
+	context->rc_sets_class = insert_rc_set (context->rc_sets_class, rc_set);
     }
 
   g_free (pattern);
@@ -3037,11 +3398,13 @@
 }
 
 static guint
-gtk_rc_parse_icon_source (GScanner	 *scanner,
+gtk_rc_parse_icon_source (GtkRcContext   *context,
+			  GScanner	 *scanner,
                           GtkIconSet     *icon_set)
 {
   guint token;
   GtkIconSource *source;
+  gchar *full_filename;
   
   token = g_scanner_get_next_token (scanner);
   if (token != G_TOKEN_LEFT_CURLY)
@@ -3052,18 +3415,23 @@
   if (token != G_TOKEN_STRING)
     return G_TOKEN_STRING;
 
+  
   source = gtk_icon_source_new ();
-
-  gtk_icon_source_set_filename (source, scanner->value.v_string);
   
+  full_filename = gtk_rc_context_find_pixmap_in_path (context, scanner, scanner->value.v_string);
+  if (full_filename)
+    {
+      gtk_icon_source_set_filename (source, full_filename);
+      g_free (full_filename);
+    }
+
+  /* We continue parsing even if we didn't find the pixmap so that rest of the
+   * file is read, even if the syntax is bad
+   */
   token = g_scanner_get_next_token (scanner);
 
   if (token == G_TOKEN_RIGHT_CURLY)
-    {
-      gtk_icon_set_add_source (icon_set, source);
-      gtk_icon_source_free (source);
-      return G_TOKEN_NONE;
-    }  
+    goto done;
   else if (token != G_TOKEN_COMMA)
     {
       gtk_icon_source_free (source);
@@ -3098,11 +3466,7 @@
   token = g_scanner_get_next_token (scanner);
 
   if (token == G_TOKEN_RIGHT_CURLY)
-    {
-      gtk_icon_set_add_source (icon_set, source);
-      gtk_icon_source_free (source);
-      return G_TOKEN_NONE;
-    }  
+    goto done;
   else if (token != G_TOKEN_COMMA)
     {
       gtk_icon_source_free (source);
@@ -3153,11 +3517,7 @@
   token = g_scanner_get_next_token (scanner);
 
   if (token == G_TOKEN_RIGHT_CURLY)
-    {
-      gtk_icon_set_add_source (icon_set, source);
-      gtk_icon_source_free (source);
-      return G_TOKEN_NONE;
-    }
+    goto done;
   else if (token != G_TOKEN_COMMA)
     {
       gtk_icon_source_free (source);
@@ -3195,16 +3555,18 @@
       gtk_icon_source_free (source);
       return G_TOKEN_RIGHT_CURLY;
     }
-
-  gtk_icon_set_add_source (icon_set, source);
 
+ done:
+  if (gtk_icon_source_get_filename (source))
+    gtk_icon_set_add_source (icon_set, source);
   gtk_icon_source_free (source);
   
   return G_TOKEN_NONE;
 }
 
 static guint
-gtk_rc_parse_stock (GScanner       *scanner,
+gtk_rc_parse_stock (GtkRcContext   *context,
+		    GScanner       *scanner,
                     GtkRcStyle     *rc_style,
                     GtkIconFactory *factory)
 {
@@ -3240,7 +3602,7 @@
       if (icon_set == NULL)
         icon_set = gtk_icon_set_new ();
       
-      token = gtk_rc_parse_icon_source (scanner, icon_set);
+      token = gtk_rc_parse_icon_source (context, scanner, icon_set);
       if (token != G_TOKEN_NONE)
         {
           g_free (stock_id);
Index: gtk/gtkrc.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrc.h,v
retrieving revision 1.30
diff -u -r1.30 gtkrc.h
--- gtk/gtkrc.h	2001/06/21 17:45:26	1.30
+++ gtk/gtkrc.h	2001/06/22 22:56:41
@@ -39,7 +39,7 @@
 typedef struct _GtkIconFactory GtkIconFactory;
 
 typedef struct _GtkRcStyleClass GtkRcStyleClass;
-typedef struct _GtkRCContext    GtkRcContext;
+typedef struct _GtkRcContext    GtkRcContext;
 
 #define GTK_TYPE_RC_STYLE              (gtk_rc_style_get_type ())
 #define GTK_RC_STYLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_RC_STYLE, GtkRcStyle))
@@ -74,7 +74,7 @@
 
   gint xthickness;
   gint ythickness;
-  
+
   /*< private >*/
   GBSearchArray *rc_properties;
   
@@ -99,8 +99,9 @@
    * of brackets. Returns G_TOKEN_NONE if succesful, otherwise returns
    * the token it expected but didn't get.
    */
-  guint     (*parse)  (GtkRcStyle *rc_style,
-		       GScanner   *scanner);
+  guint     (*parse)  (GtkRcStyle   *rc_style,
+		       GtkRcContext *context,
+		       GScanner     *scanner);
   
   /* Combine RC style data from src into dest. If overriden, this
    * function should chain to the parent.
@@ -117,18 +118,27 @@
 void      gtk_rc_add_default_file	(const gchar *filename);
 void      gtk_rc_set_default_files      (gchar **filenames);
 gchar**   gtk_rc_get_default_files      (void);
-void	  gtk_rc_parse			(const gchar *filename);
-void	  gtk_rc_parse_string		(const gchar *rc_string);
 GtkStyle* gtk_rc_get_style		(GtkWidget   *widget);
 
+GtkRcContext *gtk_rc_context_get_default         (void);
+gboolean      gtk_rc_context_reparse_all         (GtkRcContext *context,
+						  gboolean      force_load);
+gchar*        gtk_rc_context_find_pixmap_in_path (GtkRcContext *context,
+						  GScanner     *scanner,
+						  const gchar  *pixmap_file);
+
+void	  gtk_rc_parse			(const gchar *filename);
+void	  gtk_rc_parse_string		(const gchar *rc_string);
 gboolean  gtk_rc_reparse_all		(void);
-void	  gtk_rc_add_widget_name_style	(GtkRcStyle  *rc_style,
-					 const gchar *pattern);
-void	  gtk_rc_add_widget_class_style (GtkRcStyle  *rc_style,
-					 const gchar *pattern);
-void	  gtk_rc_add_class_style	(GtkRcStyle  *rc_style,
-					 const gchar *pattern);
 
+#ifndef GTK_DISABLE_DEPRECATED
+void	  gtk_rc_add_widget_name_style	(GtkRcStyle   *rc_style,
+					 const gchar  *pattern);
+void	  gtk_rc_add_widget_class_style (GtkRcStyle   *rc_style,
+					 const gchar  *pattern);
+void	  gtk_rc_add_class_style	(GtkRcStyle   *rc_style,
+					 const gchar  *pattern);
+#endif /* GTK_DISABLE_DEPRECATED */
 
 
 GType       gtk_rc_style_get_type   (void) G_GNUC_CONST;
@@ -137,8 +147,6 @@
 void        gtk_rc_style_ref        (GtkRcStyle *rc_style);
 void        gtk_rc_style_unref      (GtkRcStyle *rc_style);
 
-gchar*		gtk_rc_find_pixmap_in_path	(GScanner    	*scanner,
-						 const gchar	*pixmap_file);
 gchar*		gtk_rc_find_module_in_path	(const gchar 	*module_file);
 gchar*		gtk_rc_get_theme_dir		(void);
 gchar*		gtk_rc_get_module_dir		(void);
@@ -174,6 +182,7 @@
   GTK_RC_TOKEN_LOWEST,
   GTK_RC_TOKEN_GTK,
   GTK_RC_TOKEN_APPLICATION,
+  GTK_RC_TOKEN_THEME,
   GTK_RC_TOKEN_RC,
   GTK_RC_TOKEN_HIGHEST,
   GTK_RC_TOKEN_ENGINE,
@@ -211,7 +220,6 @@
 const GtkRcProperty* _gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
 						       GQuark      type_name,
 						       GQuark      property_name);
-
 
 #ifdef G_OS_WIN32
 gchar*  gtk_win32_get_installation_directory (void);
Index: gtk/gtksettings.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtksettings.c,v
retrieving revision 1.13
diff -u -r1.13 gtksettings.c
--- gtk/gtksettings.c	2001/06/19 12:54:10	1.13
+++ gtk/gtksettings.c	2001/06/22 22:56:41
@@ -17,6 +17,7 @@
  */
 
 #include "gtksettings.h"
+#include "gtkrc.h"
 #include "gtkintl.h"
 
 enum {
@@ -24,7 +25,9 @@
   PROP_DOUBLE_CLICK_TIME,
   PROP_CURSOR_BLINK,
   PROP_CURSOR_BLINK_TIME,
-  PROP_SPLIT_CURSOR
+  PROP_SPLIT_CURSOR,
+  PROP_THEME_NAME,
+  PROP_KEY_THEME_NAME
 };
 
 
@@ -166,6 +169,22 @@
 								   G_PARAM_READWRITE),
                                              NULL);
   g_assert (result == PROP_SPLIT_CURSOR);
+  result = settings_install_property_parser (class,
+                                             g_param_spec_string ("gtk-theme-name",
+								   _("Theme Name"),
+								   _("Name of theme RC file to load"),
+								  NULL,
+								  G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_THEME_NAME);
+  result = settings_install_property_parser (class,
+                                             g_param_spec_string ("gtk-key-theme-name",
+								  _("Key Theme Name"),
+								  _("Name of key theme RC file to load"),
+								  NULL,
+								  G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_KEY_THEME_NAME);
 }
 
 static void
@@ -294,6 +313,7 @@
 {
   guint property_id = pspec->param_id;
   gint double_click_time;
+  gchar *str_value;
   
 #if 1
   GValue tmp_value = { 0, };
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.124
diff -u -r1.124 gtkwindow.c
--- gtk/gtkwindow.c	2001/06/15 15:58:21	1.124
+++ gtk/gtkwindow.c	2001/06/22 22:56:41
@@ -2328,29 +2328,7 @@
 	}
     }
 
-  if (gtk_rc_reparse_all ())
-    {
-      /* If the above returned true, some of our RC files are out
-       * of date, so we need to reset all our widgets. Our other
-       * toplevel windows will also get the message, but by
-       * then, the RC file will up to date, so we have to tell
-       * them now. Also, we have to invalidate cached icons in
-       * icon sets so they get re-rendered.
-       */
-      GList *list, *toplevels;
-
-      _gtk_icon_set_invalidate_caches ();
-      
-      toplevels = gtk_window_list_toplevels ();
-      g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
-      
-      for (list = toplevels; list; list = list->next)
-	{
-	  gtk_widget_reset_rc_styles (list->data);
-	  gtk_widget_unref (list->data);
-	}
-      g_list_free (toplevels);
-    }
+  gtk_rc_reparse_all ();
 }
 
 static gint
Index: tests/testgtk.c
===================================================================
RCS file: /cvs/gnome/gtk+/tests/testgtk.c,v
retrieving revision 1.261
diff -u -r1.261 testgtk.c
--- tests/testgtk.c	2001/06/19 12:54:10	1.261
+++ tests/testgtk.c	2001/06/22 22:56:41
@@ -9883,28 +9883,6 @@
  */
 
 void
-reload_rc_file (void)
-{
-  GList *toplevels;
-
-  if (gtk_rc_reparse_all ())
-    {
-      toplevels = gdk_window_get_toplevels();
-      while (toplevels)
-	{
-	  GtkWidget *widget;
-	  gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
-	  
-	  if (widget)
-	    gtk_widget_reset_rc_styles (widget);
-	  
-	  toplevels = toplevels->next;
-	}
-      g_list_free (toplevels);
-    }
-}
-
-void
 reload_all_rc_files (void)
 {
   static GdkAtom atom_rcfiles = GDK_NONE;
@@ -9941,7 +9919,7 @@
 
       button = gtk_button_new_with_label ("Reload");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
-			  GTK_SIGNAL_FUNC(reload_rc_file), NULL);
+			  GTK_SIGNAL_FUNC(gtk_rc_reparse_all), NULL);
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
 			  button, TRUE, TRUE, 0);
Index: tests/testgtkrc
===================================================================
RCS file: /cvs/gnome/gtk+/tests/testgtkrc,v
retrieving revision 1.47
diff -u -r1.47 testgtkrc
--- tests/testgtkrc	2001/04/28 00:12:47	1.47
+++ tests/testgtkrc	2001/06/22 22:56:41
@@ -26,8 +26,6 @@
 bell-duration = 39
 bell_duration = 40
 
-pixmap_path "."
-
 style "global-style-properties"
 {
 #  xthickness = 20


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