]> Pileus Git - ~andy/gtk/blob - gtk/gtkrc.c
4990532f82d375e0e8363b52d37e87ae150a242a
[~andy/gtk] / gtk / gtkrc.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #include "gdkx.h"
30
31 #ifdef GDK_WINDOWING_X11
32 #include <X11/Xlocale.h>        /* so we get the right setlocale */
33 #else
34 #include <locale.h>
35 #endif
36 #include <ctype.h>
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40 #include <sys/stat.h>
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
43 #endif
44 #include <fcntl.h>
45 #include <string.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48
49 #ifndef HAVE_LSTAT
50 #define lstat stat
51 #endif
52
53 #ifdef G_OS_WIN32
54 #include <io.h>
55 #endif
56
57 #include "gtkrc.h"
58 #include "gtkbindings.h"
59 #include "gtkthemes.h"
60 #include "gtkintl.h"
61
62 typedef struct _GtkRcSet    GtkRcSet;
63 typedef struct _GtkRcNode   GtkRcNode;
64 typedef struct _GtkRcFile   GtkRcFile;
65
66 struct _GtkRcSet
67 {
68   GtkPatternSpec pspec;
69   GtkRcStyle    *rc_style;
70 };
71
72 struct _GtkRcFile
73 {
74   time_t mtime;
75   gchar *name;
76   gchar *canonical_name;
77   gboolean reload;
78 };
79
80 static guint       gtk_rc_style_hash               (const char   *name);
81 static gint        gtk_rc_style_compare            (const char   *a,
82                                                     const char   *b);
83 static guint       gtk_rc_styles_hash              (const GSList *rc_styles);
84 static gint        gtk_rc_styles_compare           (const GSList *a,
85                                                     const GSList *b);
86 static GtkRcStyle* gtk_rc_style_find               (const char   *name);
87 static GSList *    gtk_rc_styles_match             (GSList       *rc_styles,
88                                                     GSList       *sets,
89                                                     guint         path_length,
90                                                     gchar        *path,
91                                                     gchar        *path_reversed);
92 static GtkStyle *  gtk_rc_style_to_style           (GtkRcStyle   *rc_style);
93 static GtkStyle*   gtk_rc_style_init               (GSList       *rc_styles);
94 static void        gtk_rc_parse_file               (const gchar  *filename,
95                                                     gboolean      reload);
96
97 static void        gtk_rc_parse_any                (const gchar  *input_name,
98                                                     gint          input_fd,
99                                                     const gchar  *input_string);
100 static guint       gtk_rc_parse_statement          (GScanner     *scanner);
101 static guint       gtk_rc_parse_style              (GScanner     *scanner);
102 static guint       gtk_rc_parse_base               (GScanner     *scanner,
103                                                     GtkRcStyle   *style);
104 static guint       gtk_rc_parse_bg                 (GScanner     *scanner,
105                                                     GtkRcStyle   *style);
106 static guint       gtk_rc_parse_fg                 (GScanner     *scanner,
107                                                     GtkRcStyle   *style);
108 static guint       gtk_rc_parse_text               (GScanner     *scanner,
109                                                     GtkRcStyle   *style);
110 static guint       gtk_rc_parse_bg_pixmap          (GScanner     *scanner,
111                                                     GtkRcStyle   *rc_style);
112 static guint       gtk_rc_parse_font               (GScanner     *scanner,
113                                                     GtkRcStyle   *rc_style);
114 static guint       gtk_rc_parse_fontset            (GScanner     *scanner,
115                                                     GtkRcStyle   *rc_style);
116 static guint       gtk_rc_parse_engine             (GScanner     *scanner,
117                                                     GtkRcStyle   *rc_style);
118 static guint       gtk_rc_parse_pixmap_path        (GScanner     *scanner);
119 static void        gtk_rc_parse_pixmap_path_string (gchar *pix_path);
120 static guint       gtk_rc_parse_module_path        (GScanner     *scanner);
121 static void        gtk_rc_parse_module_path_string (gchar *mod_path);
122 static guint       gtk_rc_parse_path_pattern       (GScanner     *scanner);
123 static void        gtk_rc_clear_hash_node          (gpointer   key, 
124                                                     gpointer   data, 
125                                                     gpointer   user_data);
126 static void        gtk_rc_clear_styles               (void);
127 static void        gtk_rc_append_default_pixmap_path (void);
128 static void        gtk_rc_append_default_module_path (void);
129 static void        gtk_rc_append_pixmap_path         (gchar *dir);
130 static void        gtk_rc_add_initial_default_files  (void);
131
132
133 static const GScannerConfig     gtk_rc_scanner_config =
134 {
135   (
136    " \t\r\n"
137    )                    /* cset_skip_characters */,
138   (
139    G_CSET_a_2_z
140    "_"
141    G_CSET_A_2_Z
142    )                    /* cset_identifier_first */,
143   (
144    G_CSET_a_2_z
145    "_-0123456789"
146    G_CSET_A_2_Z
147    )                    /* cset_identifier_nth */,
148   ( "#\n" )             /* cpair_comment_single */,
149   
150   TRUE                  /* case_sensitive */,
151   
152   TRUE                  /* skip_comment_multi */,
153   TRUE                  /* skip_comment_single */,
154   TRUE                  /* scan_comment_multi */,
155   TRUE                  /* scan_identifier */,
156   FALSE                 /* scan_identifier_1char */,
157   FALSE                 /* scan_identifier_NULL */,
158   TRUE                  /* scan_symbols */,
159   TRUE                  /* scan_binary */,
160   TRUE                  /* scan_octal */,
161   TRUE                  /* scan_float */,
162   TRUE                  /* scan_hex */,
163   TRUE                  /* scan_hex_dollar */,
164   TRUE                  /* scan_string_sq */,
165   TRUE                  /* scan_string_dq */,
166   TRUE                  /* numbers_2_int */,
167   FALSE                 /* int_2_float */,
168   FALSE                 /* identifier_2_string */,
169   TRUE                  /* char_2_token */,
170   TRUE                  /* symbol_2_token */,
171   FALSE                 /* scope_0_fallback */,
172 };
173
174 static const struct
175 {
176   gchar *name;
177   guint token;
178 } symbols[] = {
179   { "include", GTK_RC_TOKEN_INCLUDE },
180   { "NORMAL", GTK_RC_TOKEN_NORMAL },
181   { "ACTIVE", GTK_RC_TOKEN_ACTIVE },
182   { "PRELIGHT", GTK_RC_TOKEN_PRELIGHT },
183   { "SELECTED", GTK_RC_TOKEN_SELECTED },
184   { "INSENSITIVE", GTK_RC_TOKEN_INSENSITIVE },
185   { "fg", GTK_RC_TOKEN_FG },
186   { "bg", GTK_RC_TOKEN_BG },
187   { "base", GTK_RC_TOKEN_BASE },
188   { "text", GTK_RC_TOKEN_TEXT },
189   { "font", GTK_RC_TOKEN_FONT },
190   { "fontset", GTK_RC_TOKEN_FONTSET },
191   { "bg_pixmap", GTK_RC_TOKEN_BG_PIXMAP },
192   { "pixmap_path", GTK_RC_TOKEN_PIXMAP_PATH },
193   { "style", GTK_RC_TOKEN_STYLE },
194   { "binding", GTK_RC_TOKEN_BINDING },
195   { "bind", GTK_RC_TOKEN_BIND },
196   { "widget", GTK_RC_TOKEN_WIDGET },
197   { "widget_class", GTK_RC_TOKEN_WIDGET_CLASS },
198   { "class", GTK_RC_TOKEN_CLASS },
199   { "lowest", GTK_RC_TOKEN_LOWEST },
200   { "gtk", GTK_RC_TOKEN_GTK },
201   { "application", GTK_RC_TOKEN_APPLICATION },
202   { "rc", GTK_RC_TOKEN_RC },
203   { "highest", GTK_RC_TOKEN_HIGHEST },
204   { "engine", GTK_RC_TOKEN_ENGINE },
205   { "module_path", GTK_RC_TOKEN_MODULE_PATH },
206 };
207
208 static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
209
210 static GHashTable *rc_style_ht = NULL;
211 static GHashTable *realized_style_ht = NULL;
212 static GSList *gtk_rc_sets_widget = NULL;
213 static GSList *gtk_rc_sets_widget_class = NULL;
214 static GSList *gtk_rc_sets_class = NULL;
215
216 #define GTK_RC_MAX_DEFAULT_FILES 128
217 static gchar *gtk_rc_default_files[GTK_RC_MAX_DEFAULT_FILES];
218 static gboolean gtk_rc_auto_parse = TRUE;
219
220 #define GTK_RC_MAX_PIXMAP_PATHS 128
221 static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
222 #define GTK_RC_MAX_MODULE_PATHS 128
223 static gchar *module_path[GTK_RC_MAX_MODULE_PATHS];
224
225 /* The files we have parsed, to reread later if necessary */
226 GSList *rc_files = NULL;
227
228 static GtkImageLoader image_loader = NULL;
229
230 /* RC file handling */
231
232
233 #ifdef G_OS_WIN32
234
235 gchar *
236 get_gtk_sysconf_directory (void)
237 {
238   static gchar gtk_sysconf_dir[200];
239   gchar win_dir[100];
240
241   GetWindowsDirectory (win_dir, sizeof (win_dir));
242   sprintf (gtk_sysconf_dir, "%s\\gtk", win_dir);
243   return gtk_sysconf_dir;
244 }
245
246 static gchar *
247 get_themes_directory (void)
248 {
249   /* We really should fetch this from the Registry. The GIMP
250    * installation program stores the Themes installation
251    * directory in HKLM\Software\GNU\GTk+\Themes\InstallDirectory.
252    * Later.
253    */
254   static gchar themes_dir[200];
255
256   sprintf (themes_dir, "%s\\themes", get_gtk_sysconf_directory ());
257   return themes_dir;
258 }
259
260 #endif
261  
262 gchar *
263 gtk_rc_get_theme_dir(void)
264 {
265   gchar *var, *path;
266
267 #ifndef G_OS_WIN32
268   var = getenv("GTK_DATA_PREFIX");
269   if (var)
270     path = g_strdup_printf("%s%s", var, "/share/themes");
271   else
272     path = g_strdup_printf("%s%s", GTK_DATA_PREFIX, "/share/themes");
273 #else
274   path = g_strdup (get_themes_directory ());
275 #endif
276
277   return path;
278 }
279
280 gchar *
281 gtk_rc_get_module_dir(void)
282 {
283   gchar *var, *path;
284
285 #ifndef G_OS_WIN32
286   var = getenv("GTK_EXE_PREFIX");
287   if (var)
288     path = g_strdup_printf("%s%s", var, "/lib/gtk/themes/engines");
289   else
290     path = g_strdup_printf("%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
291 #else
292   path = g_strdup_printf ("%s%s", get_themes_directory (), "\\engines");
293 #endif
294
295   return path;
296 }
297
298 static void
299 gtk_rc_append_default_pixmap_path(void)
300 {
301   gchar *var, *path;
302   gint n;
303
304 #ifndef G_OS_WIN32
305   var = getenv("GTK_DATA_PREFIX");
306   if (var)
307     path = g_strdup_printf("%s%s", var, "/share/gtk/themes");
308   else
309     path = g_strdup_printf("%s%s", GTK_DATA_PREFIX, "/share/gtk/themes");
310 #else
311   path = g_strdup (get_themes_directory ());
312 #endif      
313   
314   for (n = 0; pixmap_path[n]; n++) ;
315   if (n >= GTK_RC_MAX_PIXMAP_PATHS - 1)
316     {
317       g_free (path);
318       return;
319     }
320   pixmap_path[n++] = path;
321   pixmap_path[n] = NULL;
322 }
323
324 static void
325 gtk_rc_append_pixmap_path(gchar *dir)
326 {
327   gint n;
328
329   for (n = 0; pixmap_path[n]; n++) ;
330   if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
331     return;
332   pixmap_path[n++] = g_strdup(dir);
333   pixmap_path[n] = NULL;
334 }
335
336 static void
337 gtk_rc_append_default_module_path(void)
338 {
339   gchar *var, *path;
340   gint n;
341
342   for (n = 0; module_path[n]; n++) ;
343   if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
344     return;
345   
346 #ifndef G_OS_WIN32
347   var = getenv("GTK_EXE_PREFIX");
348   if (var)
349     path = g_strdup_printf("%s%s", var, "/lib/gtk/themes/engines");
350   else
351     path = g_strdup_printf("%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
352 #else
353   path = g_strdup_printf ("%s%s", get_themes_directory (), "\\engines");
354 #endif
355   module_path[n++] = path;
356
357   var = g_get_home_dir ();
358   if (var)
359     {
360 #ifndef G_OS_WIN32
361       path = g_strdup_printf ("%s%s", var, "/.gtk/lib/themes/engines");
362 #else
363       path = g_strdup_printf ("%s%s", var, "\\_gtk\\themes\\engines");
364 #endif
365       module_path[n++] = path;
366     }
367   module_path[n] = NULL;
368 }
369
370 static void
371 gtk_rc_add_initial_default_files (void)
372 {
373   static gint init = FALSE;
374   gchar *var, *str;
375   gchar **files;
376   gint i;
377
378   if (init)
379     return;
380   
381   gtk_rc_default_files[0] = NULL;
382   init = TRUE;
383
384   var = g_getenv("GTK_RC_FILES");
385   if (var)
386     {
387       files = g_strsplit (var, G_SEARCHPATH_SEPARATOR_S, 128);
388       i=0;
389       while (files[i])
390         {
391           gtk_rc_add_default_file (files[i]);
392           i++;
393         }
394       g_strfreev (files);
395     }
396   else
397     {
398 #ifndef G_OS_WIN32
399       str = g_strdup (GTK_SYSCONFDIR G_DIR_SEPARATOR_S "gtk" G_DIR_SEPARATOR_S "gtkrc");
400 #else
401       str = g_strdup_printf ("%s\\gtkrc", get_gtk_sysconf_directory ());
402 #endif
403       gtk_rc_add_default_file (str);
404       g_free (str);
405
406       var = g_get_home_dir ();
407       if (var)
408         {
409           str = g_strdup_printf ("%s" G_DIR_SEPARATOR_S ".gtkrc", var);
410           gtk_rc_add_default_file (str);
411           g_free (str);
412         }
413     }
414 }
415
416 void
417 gtk_rc_add_default_file (const gchar *file)
418 {
419   guint n;
420   
421   gtk_rc_add_initial_default_files ();
422
423   for (n = 0; gtk_rc_default_files[n]; n++) ;
424   if (n >= GTK_RC_MAX_DEFAULT_FILES - 1)
425     return;
426   
427   gtk_rc_default_files[n++] = g_strdup (file);
428   gtk_rc_default_files[n] = NULL;
429 }
430
431 void
432 gtk_rc_set_default_files (gchar **files)
433 {
434   gint i;
435
436   gtk_rc_add_initial_default_files ();
437
438   i = 0;
439   while (gtk_rc_default_files[i])
440     {
441       g_free (gtk_rc_default_files[i]);
442       i++;
443     }
444     
445   gtk_rc_default_files[0] = NULL;
446   gtk_rc_auto_parse = FALSE;
447
448   i = 0;
449   while (files[i] != NULL)
450     {
451       gtk_rc_add_default_file (files[i]);
452       i++;
453     }
454 }
455
456 gchar **
457 gtk_rc_get_default_files (void)
458 {
459   gtk_rc_add_initial_default_files ();
460
461   return gtk_rc_default_files;
462 }
463
464 void
465 gtk_rc_init (void)
466 {
467   gchar *locale_suffixes[3];
468   gint n_locale_suffixes = 0;
469   gint i, j;
470 #ifdef HAVE_LC_MESSAGES
471   char *locale = setlocale (LC_MESSAGES, NULL);
472 #else
473   char *locale = setlocale (LC_CTYPE, NULL);
474 #endif
475   guint length;
476   char *p;
477
478   rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
479                                   (GCompareFunc) gtk_rc_style_compare);
480   pixmap_path[0] = NULL;
481   module_path[0] = NULL;
482   gtk_rc_append_default_pixmap_path();
483   gtk_rc_append_default_module_path();
484
485   gtk_rc_add_initial_default_files ();
486
487   if (strcmp (locale, "C") && strcmp (locale, "POSIX"))
488     {
489       /* Determine locale-specific suffixes for RC files
490        */
491       p = strchr (locale, '@');
492       length = p ? (p -locale) : strlen (locale);
493       
494       p = strchr (locale, '.');
495       if (p)
496         {
497           locale_suffixes[n_locale_suffixes++] = g_strndup (locale, length);
498           length = p - locale;
499         }
500       
501       p = strchr (locale, '_');
502       if (p)
503         {
504           locale_suffixes[n_locale_suffixes++] = g_strndup (locale, length);
505           length = p - locale;
506         }
507
508       locale_suffixes[n_locale_suffixes++] = g_strndup (locale, length);
509     }
510   
511   i = 0;
512   while (gtk_rc_default_files[i] != NULL)
513     {
514       /* Try to find a locale specific RC file corresponding to
515        * to parse before the default file.
516        */
517       for (j=n_locale_suffixes-1; j>=0; j--)
518         {
519           gchar *name = g_strconcat (gtk_rc_default_files[i],
520                                      ".",
521                                      locale_suffixes[j],
522                                      NULL);
523           gtk_rc_parse (name);
524           g_free (name);
525         }
526
527       gtk_rc_parse (gtk_rc_default_files[i]);
528       i++;
529     }
530  }
531
532 void
533 gtk_rc_parse_string (const gchar *rc_string)
534 {
535   g_return_if_fail (rc_string != NULL);
536
537   gtk_rc_parse_any ("-", -1, rc_string);
538 }
539
540 static void
541 gtk_rc_parse_file (const gchar *filename, gboolean reload)
542 {
543   GtkRcFile *rc_file = NULL;
544   struct stat statbuf;
545   GSList *tmp_list;
546
547   g_return_if_fail (filename != NULL);
548
549   tmp_list = rc_files;
550   while (tmp_list)
551     {
552       rc_file = tmp_list->data;
553       if (!strcmp (rc_file->name, filename))
554         break;
555       
556       tmp_list = tmp_list->next;
557     }
558
559   if (!tmp_list)
560     {
561       rc_file = g_new (GtkRcFile, 1);
562       rc_file->name = g_strdup (filename);
563       rc_file->canonical_name = NULL;
564       rc_file->mtime = 0;
565       rc_file->reload = reload;
566
567       rc_files = g_slist_append (rc_files, rc_file);
568     }
569
570   if (!rc_file->canonical_name)
571     {
572       /* Get the absolute pathname */
573
574       if (g_path_is_absolute (rc_file->name))
575         rc_file->canonical_name = rc_file->name;
576       else
577         {
578           GString *str;
579           gchar *cwd;
580
581           cwd = g_get_current_dir ();
582
583           str = g_string_new (cwd);
584           g_free (cwd);
585           g_string_append_c (str, G_DIR_SEPARATOR);
586           g_string_append (str, rc_file->name);
587           
588           rc_file->canonical_name = str->str;
589           g_string_free (str, FALSE);
590         }
591     }
592
593   if (!lstat (rc_file->canonical_name, &statbuf))
594     {
595       gint fd;
596
597       rc_file->mtime = statbuf.st_mtime;
598
599       fd = open (rc_file->canonical_name, O_RDONLY);
600       if (fd < 0)
601         return;
602
603         {
604           gint i;
605           gchar *dir;
606           
607           dir = g_strdup(rc_file->canonical_name);
608           for (i = strlen(dir) - 1; (i >= 0) && (dir[i] != G_DIR_SEPARATOR); i--)
609             dir[i] = 0;
610           if (i >= 0 && dir[i] == G_DIR_SEPARATOR)
611             dir[i] = 0;
612           gtk_rc_append_pixmap_path(dir);
613           g_free(dir);
614         }
615       gtk_rc_parse_any (filename, fd, NULL);
616
617       close (fd);
618     }
619 }
620
621 void
622 gtk_rc_parse (const gchar *filename)
623 {
624   g_return_if_fail (filename != NULL);
625
626   gtk_rc_parse_file (filename, TRUE);
627 }
628
629 /* Handling of RC styles */
630
631 GtkRcStyle *
632 gtk_rc_style_new              (void)
633 {
634   GtkRcStyle *new_style;
635
636   new_style = g_new0 (GtkRcStyle, 1);
637   new_style->ref_count = 1;
638
639   return new_style;
640 }
641
642 void      
643 gtk_rc_style_ref (GtkRcStyle  *rc_style)
644 {
645   g_return_if_fail (rc_style != NULL);
646
647   rc_style->ref_count++;
648 }
649
650 void      
651 gtk_rc_style_unref (GtkRcStyle  *rc_style)
652 {
653   gint i;
654
655   g_return_if_fail (rc_style != NULL);
656   g_return_if_fail (rc_style->ref_count > 0);
657
658   rc_style->ref_count--;
659
660   if (rc_style->ref_count == 0)
661     {
662       if (rc_style->engine)
663         {
664           rc_style->engine->destroy_rc_style (rc_style);
665           gtk_theme_engine_unref (rc_style->engine);
666         }
667
668       if (rc_style->name)
669         g_free (rc_style->name);
670       if (rc_style->fontset_name)
671         g_free (rc_style->fontset_name);
672       if (rc_style->font_name)
673         g_free (rc_style->font_name);
674       
675       for (i=0 ; i<5 ; i++)
676         if (rc_style->bg_pixmap_name[i])
677           g_free (rc_style->bg_pixmap_name[i]);
678       
679       g_free (rc_style);
680     }
681 }
682
683 static void
684 gtk_rc_clear_realized_node (gpointer key,
685                             gpointer data,
686                             gpointer user_data)
687 {
688   gtk_style_unref (data);
689 }
690
691 static void
692 gtk_rc_clear_hash_node (gpointer key, 
693                         gpointer data, 
694                         gpointer user_data)
695 {
696   gtk_rc_style_unref (data);
697 }
698
699 static void
700 gtk_rc_free_rc_sets (GSList *slist)
701 {
702   while (slist)
703     {
704       GtkRcSet *rc_set;
705
706       rc_set = slist->data;
707       gtk_pattern_spec_free_segs (&rc_set->pspec);
708       g_free (rc_set);
709
710       slist = slist->next;
711     }
712 }
713
714 static void
715 gtk_rc_clear_styles (void)
716 {
717   /* Clear out all old rc_styles */
718
719   if (rc_style_ht)
720     {
721       g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
722       g_hash_table_destroy (rc_style_ht);
723       rc_style_ht = NULL;
724     }
725
726   if (realized_style_ht)
727     {
728       g_hash_table_foreach (realized_style_ht, gtk_rc_clear_realized_node, NULL);
729       g_hash_table_destroy (realized_style_ht);
730       realized_style_ht = NULL;
731     }
732
733   gtk_rc_free_rc_sets (gtk_rc_sets_widget);
734   g_slist_free (gtk_rc_sets_widget);
735   gtk_rc_sets_widget = NULL;
736
737   gtk_rc_free_rc_sets (gtk_rc_sets_widget_class);
738   g_slist_free (gtk_rc_sets_widget_class);
739   gtk_rc_sets_widget_class = NULL;
740
741   gtk_rc_free_rc_sets (gtk_rc_sets_class);
742   g_slist_free (gtk_rc_sets_class);
743   gtk_rc_sets_class = NULL;
744
745   gtk_rc_init ();
746 }
747
748 gboolean
749 gtk_rc_reparse_all (void)
750 {
751   GSList *tmp_list;
752   gboolean mtime_modified = FALSE;
753   GtkRcFile *rc_file;
754
755   struct stat statbuf;
756
757   /* Check through and see if any of the RC's have had their
758    * mtime modified. If so, reparse everything.
759    */
760   tmp_list = rc_files;
761   while (tmp_list)
762     {
763       rc_file = tmp_list->data;
764       
765       if (!lstat (rc_file->name, &statbuf) && 
766           (statbuf.st_mtime > rc_file->mtime))
767         {
768           mtime_modified = TRUE;
769           break;
770         }
771       
772       tmp_list = tmp_list->next;
773     }
774
775   if (mtime_modified)
776     {
777       gtk_rc_clear_styles();
778
779       tmp_list = rc_files;
780       while (tmp_list)
781         {
782           rc_file = tmp_list->data;
783           if (rc_file->reload)
784             gtk_rc_parse_file (rc_file->name, FALSE);
785           
786           tmp_list = tmp_list->next;
787         }
788     }
789
790   return mtime_modified;
791 }
792
793 static GSList *
794 gtk_rc_styles_match (GSList       *rc_styles,
795                      GSList       *sets,
796                      guint         path_length,
797                      gchar        *path,
798                      gchar        *path_reversed)
799                      
800 {
801   GtkRcSet *rc_set;
802
803   while (sets)
804     {
805       rc_set = sets->data;
806       sets = sets->next;
807
808       if (gtk_pattern_match (&rc_set->pspec, path_length, path, path_reversed))
809         rc_styles = g_slist_append (rc_styles, rc_set->rc_style);
810     }
811   
812   return rc_styles;
813 }
814
815 GtkStyle*
816 gtk_rc_get_style (GtkWidget *widget)
817 {
818   GtkRcStyle *widget_rc_style;
819   GSList *rc_styles = NULL;
820
821   static guint rc_style_key_id = 0;
822
823   /* We allow the specification of a single rc style to be bound
824    * tightly to a widget, for application modifications
825    */
826   if (!rc_style_key_id)
827     rc_style_key_id = g_quark_from_static_string ("gtk-rc-style");
828
829   widget_rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
830                                                rc_style_key_id);
831
832   if (widget_rc_style)
833     rc_styles = g_slist_prepend (rc_styles, widget_rc_style);
834   
835   if (gtk_rc_sets_widget)
836     {
837       gchar *path, *path_reversed;
838       guint path_length;
839
840       gtk_widget_path (widget, &path_length, &path, &path_reversed);
841       rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget, path_length, path, path_reversed);
842       g_free (path);
843       g_free (path_reversed);
844       
845     }
846   
847   if (gtk_rc_sets_widget_class)
848     {
849       gchar *path, *path_reversed;
850       guint path_length;
851
852       gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
853       rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget_class, path_length, path, path_reversed);
854       g_free (path);
855       g_free (path_reversed);
856     }
857
858   if (gtk_rc_sets_class)
859     {
860       GtkType type;
861
862       type = GTK_OBJECT_TYPE (widget);
863       while (type)
864         {
865           gchar *path, *path_reversed;
866           guint path_length;
867
868           path = gtk_type_name (type);
869           path_length = strlen (path);
870           path_reversed = g_strdup (path);
871           g_strreverse (path_reversed);
872           
873           rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_class, path_length, path, path_reversed);
874           g_free (path_reversed);
875       
876           type = gtk_type_parent (type);
877         }
878     }
879   
880   if (rc_styles)
881     return gtk_rc_style_init (rc_styles);
882
883   return NULL;
884 }
885
886 static GSList*
887 gtk_rc_add_rc_sets (GSList     *slist,
888                     GtkRcStyle *rc_style,
889                     const char *pattern)
890 {
891   GtkRcStyle *new_style;
892   GtkRcSet *rc_set;
893   guint i;
894   
895   new_style = gtk_rc_style_new ();
896   *new_style = *rc_style;
897   new_style->name = g_strdup (rc_style->name);
898   new_style->font_name = g_strdup (rc_style->font_name);
899   new_style->fontset_name = g_strdup (rc_style->fontset_name);
900   
901   for (i = 0; i < 5; i++)
902     new_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
903   
904   rc_set = g_new (GtkRcSet, 1);
905   gtk_pattern_spec_init (&rc_set->pspec, pattern);
906   rc_set->rc_style = rc_style;
907   
908   return g_slist_prepend (slist, rc_set);
909 }
910
911 void
912 gtk_rc_add_widget_name_style (GtkRcStyle  *rc_style,
913                               const gchar *pattern)
914 {
915   g_return_if_fail (rc_style != NULL);
916   g_return_if_fail (pattern != NULL);
917
918   gtk_rc_sets_widget = gtk_rc_add_rc_sets (gtk_rc_sets_widget, rc_style, pattern);
919 }
920
921 void
922 gtk_rc_add_widget_class_style (GtkRcStyle  *rc_style,
923                                const gchar *pattern)
924 {
925   g_return_if_fail (rc_style != NULL);
926   g_return_if_fail (pattern != NULL);
927
928   gtk_rc_sets_widget_class = gtk_rc_add_rc_sets (gtk_rc_sets_widget_class, rc_style, pattern);
929 }
930
931 void
932 gtk_rc_add_class_style (GtkRcStyle  *rc_style,
933                         const gchar *pattern)
934 {
935   g_return_if_fail (rc_style != NULL);
936   g_return_if_fail (pattern != NULL);
937
938   gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
939 }
940
941 static void
942 gtk_rc_parse_any (const gchar  *input_name,
943                   gint          input_fd,
944                   const gchar  *input_string)
945 {
946   GScanner *scanner;
947   guint    i;
948   gboolean done;
949   
950   scanner = g_scanner_new ((GScannerConfig *) &gtk_rc_scanner_config);
951   
952   if (input_fd >= 0)
953     {
954       g_assert (input_string == NULL);
955       
956       g_scanner_input_file (scanner, input_fd);
957     }
958   else
959     {
960       g_assert (input_string != NULL);
961       
962       g_scanner_input_text (scanner, input_string, strlen (input_string));
963     }
964   scanner->input_name = input_name;
965
966   g_scanner_freeze_symbol_table (scanner);
967   for (i = 0; i < n_symbols; i++)
968     g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
969   g_scanner_thaw_symbol_table (scanner);
970   
971   done = FALSE;
972   while (!done)
973     {
974       if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
975         done = TRUE;
976       else
977         {
978           guint expected_token;
979           
980           expected_token = gtk_rc_parse_statement (scanner);
981
982           if (expected_token != G_TOKEN_NONE)
983             {
984               gchar *symbol_name;
985               gchar *msg;
986               
987               msg = NULL;
988               symbol_name = NULL;
989               if (scanner->scope_id == 0)
990                 {
991                   /* if we are in scope 0, we know the symbol names
992                    * that are associated with certaintoken values.
993                    * so we look them up to make the error messages
994                    * more readable.
995                    */
996                   if (expected_token > GTK_RC_TOKEN_INVALID &&
997                       expected_token < GTK_RC_TOKEN_LAST)
998                     {
999                       for (i = 0; i < n_symbols; i++)
1000                         if (symbols[i].token == expected_token)
1001                           msg = symbols[i].name;
1002                       if (msg)
1003                         msg = g_strconcat ("e.g. `", msg, "'", NULL);
1004                     }
1005                   if (scanner->token > GTK_RC_TOKEN_INVALID &&
1006                       scanner->token < GTK_RC_TOKEN_LAST)
1007                     {
1008                       symbol_name = "???";
1009                       for (i = 0; i < n_symbols; i++)
1010                         if (symbols[i].token == scanner->token)
1011                           symbol_name = symbols[i].name;
1012                     }
1013                 }
1014               g_scanner_unexp_token (scanner,
1015                                      expected_token,
1016                                      NULL,
1017                                      "keyword",
1018                                      symbol_name,
1019                                      msg,
1020                                      TRUE);
1021               g_free (msg);
1022               done = TRUE;
1023             }
1024         }
1025     }
1026   
1027   g_scanner_destroy (scanner);
1028 }
1029
1030 static guint       
1031 gtk_rc_styles_hash (const GSList *rc_styles)
1032 {
1033   guint result;
1034   
1035   result = 0;
1036   while (rc_styles)
1037     {
1038       result += (result << 9) + GPOINTER_TO_UINT (rc_styles->data);
1039       rc_styles = rc_styles->next;
1040     }
1041   
1042   return result;
1043 }
1044
1045 static gint        
1046 gtk_rc_styles_compare (const GSList *a,
1047                        const GSList *b)
1048 {
1049   while (a && b)
1050     {
1051       if (a->data != b->data)
1052         return FALSE;
1053       a = a->next;
1054       b = b->next;
1055     }
1056   
1057   return (a == b);
1058 }
1059
1060 static guint
1061 gtk_rc_style_hash (const char *name)
1062 {
1063   guint result;
1064   
1065   result = 0;
1066   while (*name)
1067     result += (result << 3) + *name++;
1068   
1069   return result;
1070 }
1071
1072 static gint
1073 gtk_rc_style_compare (const char *a,
1074                       const char *b)
1075 {
1076   return (strcmp (a, b) == 0);
1077 }
1078
1079 static GtkRcStyle*
1080 gtk_rc_style_find (const char *name)
1081 {
1082   GtkRcStyle *rc_style;
1083   
1084   rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
1085   
1086   return rc_style;
1087 }
1088
1089 /* Assumes ownership of rc_style */
1090 static GtkStyle *
1091 gtk_rc_style_to_style (GtkRcStyle *rc_style)
1092 {
1093   GtkStyle *style;
1094   GdkFont *old_font;
1095   gint i;
1096
1097   style = gtk_style_new ();
1098
1099   style->rc_style = rc_style;
1100   
1101   if (rc_style->fontset_name)
1102     {
1103       old_font = style->font;
1104       style->font = gdk_fontset_load (rc_style->fontset_name);
1105       if (style->font)
1106         gdk_font_unref (old_font);
1107       else
1108         style->font = old_font;
1109     }
1110   else if (rc_style->font_name)
1111     {
1112       old_font = style->font;
1113       style->font = gdk_font_load (rc_style->font_name);
1114       if (style->font)
1115         gdk_font_unref (old_font);
1116       else
1117         style->font = old_font;
1118     }
1119   
1120   for (i = 0; i < 5; i++)
1121     {
1122       if (rc_style->color_flags[i] & GTK_RC_FG)
1123         style->fg[i] = rc_style->fg[i];
1124       if (rc_style->color_flags[i] & GTK_RC_BG)
1125         style->bg[i] = rc_style->bg[i];
1126       if (rc_style->color_flags[i] & GTK_RC_TEXT)
1127         style->text[i] = rc_style->text[i];
1128       if (rc_style->color_flags[i] & GTK_RC_BASE)
1129         style->base[i] = rc_style->base[i];
1130     }
1131
1132   if (rc_style->engine)
1133     {
1134       style->engine = rc_style->engine;
1135       gtk_theme_engine_ref (style->engine);
1136       rc_style->engine->rc_style_to_style (style, rc_style);
1137     }
1138
1139   return style;
1140 }
1141
1142 /* Reuses or frees rc_styles */
1143 static GtkStyle *
1144 gtk_rc_style_init (GSList *rc_styles)
1145 {
1146   gint i;
1147
1148   GtkStyle *style = NULL;
1149   GtkRcStyle *proto_style;
1150
1151   if (!realized_style_ht)
1152     realized_style_ht = g_hash_table_new ((GHashFunc)gtk_rc_styles_hash,
1153                                            (GCompareFunc)gtk_rc_styles_compare);
1154
1155   style = g_hash_table_lookup (realized_style_ht, rc_styles);
1156
1157   if (!style)
1158     {
1159       GSList *tmp_styles = rc_styles;
1160       
1161       proto_style = gtk_rc_style_new ();
1162
1163       while (tmp_styles)
1164         {
1165           GtkRcStyle *rc_style = tmp_styles->data;
1166
1167           for (i=0; i<5; i++)
1168             {
1169               if (!proto_style->bg_pixmap_name[i] && rc_style->bg_pixmap_name[i])
1170                 proto_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
1171
1172               if (!(proto_style->color_flags[i] & GTK_RC_FG) && 
1173                     rc_style->color_flags[i] & GTK_RC_FG)
1174                 {
1175                   proto_style->fg[i] = rc_style->fg[i];
1176                   proto_style->color_flags[i] |= GTK_RC_FG;
1177                 }
1178               if (!(proto_style->color_flags[i] & GTK_RC_BG) && 
1179                     rc_style->color_flags[i] & GTK_RC_BG)
1180                 {
1181                   proto_style->bg[i] = rc_style->bg[i];
1182                   proto_style->color_flags[i] |= GTK_RC_BG;
1183                 }
1184               if (!(proto_style->color_flags[i] & GTK_RC_TEXT) && 
1185                     rc_style->color_flags[i] & GTK_RC_TEXT)
1186                 {
1187                   proto_style->text[i] = rc_style->text[i];
1188                   proto_style->color_flags[i] |= GTK_RC_TEXT;
1189                 }
1190               if (!(proto_style->color_flags[i] & GTK_RC_BASE) && 
1191                     rc_style->color_flags[i] & GTK_RC_BASE)
1192                 {
1193                   proto_style->base[i] = rc_style->base[i];
1194                   proto_style->color_flags[i] |= GTK_RC_BASE;
1195                 }
1196             }
1197
1198           if (!proto_style->font_name && rc_style->font_name)
1199             proto_style->font_name = g_strdup (rc_style->font_name);
1200           if (!proto_style->fontset_name && rc_style->fontset_name)
1201             proto_style->fontset_name = g_strdup (rc_style->fontset_name);
1202
1203           if (!proto_style->engine && rc_style->engine)
1204             {
1205               proto_style->engine = rc_style->engine;
1206               gtk_theme_engine_ref (proto_style->engine);
1207             }
1208           
1209           if (proto_style->engine &&
1210               (proto_style->engine == rc_style->engine))
1211             proto_style->engine->merge_rc_style (proto_style, rc_style);
1212
1213           tmp_styles = tmp_styles->next;
1214         }
1215
1216       for (i=0; i<5; i++)
1217         if (proto_style->bg_pixmap_name[i] &&
1218             (strcmp (proto_style->bg_pixmap_name[i], "<none>") == 0))
1219           {
1220             g_free (proto_style->bg_pixmap_name[i]);
1221             proto_style->bg_pixmap_name[i] = NULL;
1222           }
1223
1224       style = gtk_rc_style_to_style (proto_style);
1225
1226       g_hash_table_insert (realized_style_ht, rc_styles, style);
1227     }
1228
1229   return style;
1230 }
1231
1232 /*********************
1233  * Parsing functions *
1234  *********************/
1235
1236 static guint
1237 gtk_rc_parse_statement (GScanner *scanner)
1238 {
1239   guint token;
1240   
1241   token = g_scanner_peek_next_token (scanner);
1242
1243   switch (token)
1244     {
1245     case GTK_RC_TOKEN_INCLUDE:
1246       token = g_scanner_get_next_token (scanner);
1247       if (token != GTK_RC_TOKEN_INCLUDE)
1248         return GTK_RC_TOKEN_INCLUDE;
1249
1250       token = g_scanner_get_next_token (scanner);
1251       if (token != G_TOKEN_STRING)
1252         return G_TOKEN_STRING;
1253
1254       gtk_rc_parse_file (scanner->value.v_string, FALSE);
1255       return G_TOKEN_NONE;
1256
1257     case GTK_RC_TOKEN_STYLE:
1258       return gtk_rc_parse_style (scanner);
1259
1260     case GTK_RC_TOKEN_BINDING:
1261       return gtk_binding_parse_binding (scanner);
1262
1263     case GTK_RC_TOKEN_PIXMAP_PATH:
1264       return gtk_rc_parse_pixmap_path (scanner);
1265
1266     case GTK_RC_TOKEN_WIDGET:
1267       return gtk_rc_parse_path_pattern (scanner);
1268
1269     case GTK_RC_TOKEN_WIDGET_CLASS:
1270       return gtk_rc_parse_path_pattern (scanner);
1271
1272     case GTK_RC_TOKEN_CLASS:
1273       return gtk_rc_parse_path_pattern (scanner);
1274
1275     case GTK_RC_TOKEN_MODULE_PATH:
1276       return gtk_rc_parse_module_path (scanner);
1277        
1278     default:
1279       g_scanner_get_next_token (scanner);
1280       return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
1281     }
1282 }
1283
1284 static guint
1285 gtk_rc_parse_style (GScanner *scanner)
1286 {
1287   GtkRcStyle *rc_style;
1288   GtkRcStyle *parent_style;
1289   guint token;
1290   gint insert;
1291   gint i;
1292   
1293   token = g_scanner_get_next_token (scanner);
1294   if (token != GTK_RC_TOKEN_STYLE)
1295     return GTK_RC_TOKEN_STYLE;
1296   
1297   token = g_scanner_get_next_token (scanner);
1298   if (token != G_TOKEN_STRING)
1299     return G_TOKEN_STRING;
1300   
1301   insert = FALSE;
1302   rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
1303   
1304   if (!rc_style)
1305     {
1306       insert = TRUE;
1307       rc_style = gtk_rc_style_new ();
1308       rc_style->name = g_strdup (scanner->value.v_string);
1309       
1310       for (i = 0; i < 5; i++)
1311         rc_style->bg_pixmap_name[i] = NULL;
1312
1313       for (i = 0; i < 5; i++)
1314         rc_style->color_flags[i] = 0;
1315
1316       rc_style->engine = NULL;
1317       rc_style->engine_data = NULL;
1318     }
1319   
1320   token = g_scanner_peek_next_token (scanner);
1321   if (token == G_TOKEN_EQUAL_SIGN)
1322     {
1323       token = g_scanner_get_next_token (scanner);
1324       
1325       token = g_scanner_get_next_token (scanner);
1326       if (token != G_TOKEN_STRING)
1327         {
1328           if (insert)
1329             g_free (rc_style);
1330
1331           return G_TOKEN_STRING;
1332         }
1333       
1334       parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
1335       if (parent_style)
1336         {
1337           for (i = 0; i < 5; i++)
1338             {
1339               rc_style->color_flags[i] = parent_style->color_flags[i];
1340               rc_style->fg[i] = parent_style->fg[i];
1341               rc_style->bg[i] = parent_style->bg[i];
1342               rc_style->text[i] = parent_style->text[i];
1343               rc_style->base[i] = parent_style->base[i];
1344             }
1345           
1346           if (parent_style->fontset_name)
1347             {
1348               if (rc_style->fontset_name)
1349                 g_free (rc_style->fontset_name);
1350               rc_style->fontset_name = g_strdup (parent_style->fontset_name);
1351             }
1352           else if (parent_style->font_name)
1353             {
1354               if (rc_style->font_name)
1355                 g_free (rc_style->font_name);
1356               rc_style->font_name = g_strdup (parent_style->font_name);
1357             }
1358           
1359           for (i = 0; i < 5; i++)
1360             {
1361               if (rc_style->bg_pixmap_name[i])
1362                 g_free (rc_style->bg_pixmap_name[i]);
1363               rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
1364             }
1365         }
1366     }
1367   
1368   token = g_scanner_get_next_token (scanner);
1369   if (token != G_TOKEN_LEFT_CURLY)
1370     {
1371       if (insert)
1372         g_free (rc_style);
1373
1374       return G_TOKEN_LEFT_CURLY;
1375     }
1376   
1377   token = g_scanner_peek_next_token (scanner);
1378   while (token != G_TOKEN_RIGHT_CURLY)
1379     {
1380       switch (token)
1381         {
1382         case GTK_RC_TOKEN_BASE:
1383           token = gtk_rc_parse_base (scanner, rc_style);
1384           break;
1385         case GTK_RC_TOKEN_BG:
1386           token = gtk_rc_parse_bg (scanner, rc_style);
1387           break;
1388         case GTK_RC_TOKEN_FG:
1389           token = gtk_rc_parse_fg (scanner, rc_style);
1390           break;
1391         case GTK_RC_TOKEN_TEXT:
1392           token = gtk_rc_parse_text (scanner, rc_style);
1393           break;
1394         case GTK_RC_TOKEN_BG_PIXMAP:
1395           token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
1396           break;
1397         case GTK_RC_TOKEN_FONT:
1398           token = gtk_rc_parse_font (scanner, rc_style);
1399           break;
1400         case GTK_RC_TOKEN_FONTSET:
1401           token = gtk_rc_parse_fontset (scanner, rc_style);
1402           break;
1403         case GTK_RC_TOKEN_ENGINE:
1404           token = gtk_rc_parse_engine (scanner, rc_style);
1405           break;
1406         default:
1407           g_scanner_get_next_token (scanner);
1408           token = G_TOKEN_RIGHT_CURLY;
1409           break;
1410         }
1411
1412       if (token != G_TOKEN_NONE)
1413         {
1414           if (insert)
1415             {
1416               if (rc_style->fontset_name)
1417                 g_free (rc_style->fontset_name);
1418               if (rc_style->font_name)
1419                 g_free (rc_style->font_name);
1420               for (i = 0; i < 5; i++)
1421                 if (rc_style->bg_pixmap_name[i])
1422                   g_free (rc_style->bg_pixmap_name[i]);
1423               g_free (rc_style);
1424             }
1425           return token;
1426         }
1427       token = g_scanner_peek_next_token (scanner);
1428     }
1429   
1430   token = g_scanner_get_next_token (scanner);
1431   if (token != G_TOKEN_RIGHT_CURLY)
1432     {
1433       if (insert)
1434         {
1435           if (rc_style->fontset_name)
1436             g_free (rc_style->fontset_name);
1437           if (rc_style->font_name)
1438             g_free (rc_style->font_name);
1439           
1440           for (i = 0; i < 5; i++)
1441             if (rc_style->bg_pixmap_name[i])
1442               g_free (rc_style->bg_pixmap_name[i]);
1443           
1444           g_free (rc_style);
1445         }
1446       return G_TOKEN_RIGHT_CURLY;
1447     }
1448   
1449   if (insert)
1450     g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
1451   
1452   return G_TOKEN_NONE;
1453 }
1454
1455 static guint
1456 gtk_rc_parse_base (GScanner   *scanner,
1457                    GtkRcStyle *style)
1458 {
1459   GtkStateType state;
1460   guint token;
1461   
1462   token = g_scanner_get_next_token (scanner);
1463   if (token != GTK_RC_TOKEN_BASE)
1464     return GTK_RC_TOKEN_BASE;
1465   
1466   token = gtk_rc_parse_state (scanner, &state);
1467   if (token != G_TOKEN_NONE)
1468     return token;
1469   
1470   token = g_scanner_get_next_token (scanner);
1471   if (token != G_TOKEN_EQUAL_SIGN)
1472     return G_TOKEN_EQUAL_SIGN;
1473
1474   style->color_flags[state] |= GTK_RC_BASE;
1475   return gtk_rc_parse_color (scanner, &style->base[state]);
1476 }
1477
1478 static guint
1479 gtk_rc_parse_bg (GScanner   *scanner,
1480                  GtkRcStyle *style)
1481 {
1482   GtkStateType state;
1483   guint token;
1484   
1485   token = g_scanner_get_next_token (scanner);
1486   if (token != GTK_RC_TOKEN_BG)
1487     return GTK_RC_TOKEN_BG;
1488   
1489   token = gtk_rc_parse_state (scanner, &state);
1490   if (token != G_TOKEN_NONE)
1491     return token;
1492   
1493   token = g_scanner_get_next_token (scanner);
1494   if (token != G_TOKEN_EQUAL_SIGN)
1495     return G_TOKEN_EQUAL_SIGN;
1496
1497   style->color_flags[state] |= GTK_RC_BG;
1498   return gtk_rc_parse_color (scanner, &style->bg[state]);
1499 }
1500
1501 static guint
1502 gtk_rc_parse_fg (GScanner   *scanner,
1503                  GtkRcStyle *style)
1504 {
1505   GtkStateType state;
1506   guint token;
1507   
1508   token = g_scanner_get_next_token (scanner);
1509   if (token != GTK_RC_TOKEN_FG)
1510     return GTK_RC_TOKEN_FG;
1511   
1512   token = gtk_rc_parse_state (scanner, &state);
1513   if (token != G_TOKEN_NONE)
1514     return token;
1515   
1516   token = g_scanner_get_next_token (scanner);
1517   if (token != G_TOKEN_EQUAL_SIGN)
1518     return G_TOKEN_EQUAL_SIGN;
1519   
1520   style->color_flags[state] |= GTK_RC_FG;
1521   return gtk_rc_parse_color (scanner, &style->fg[state]);
1522 }
1523
1524 static guint
1525 gtk_rc_parse_text (GScanner   *scanner,
1526                    GtkRcStyle *style)
1527 {
1528   GtkStateType state;
1529   guint token;
1530   
1531   token = g_scanner_get_next_token (scanner);
1532   if (token != GTK_RC_TOKEN_TEXT)
1533     return GTK_RC_TOKEN_TEXT;
1534   
1535   token = gtk_rc_parse_state (scanner, &state);
1536   if (token != G_TOKEN_NONE)
1537     return token;
1538   
1539   token = g_scanner_get_next_token (scanner);
1540   if (token != G_TOKEN_EQUAL_SIGN)
1541     return G_TOKEN_EQUAL_SIGN;
1542   
1543   style->color_flags[state] |= GTK_RC_TEXT;
1544   return gtk_rc_parse_color (scanner, &style->text[state]);
1545 }
1546
1547 static guint
1548 gtk_rc_parse_bg_pixmap (GScanner   *scanner,
1549                         GtkRcStyle *rc_style)
1550 {
1551   GtkStateType state;
1552   guint token;
1553   gchar *pixmap_file;
1554   
1555   token = g_scanner_get_next_token (scanner);
1556   if (token != GTK_RC_TOKEN_BG_PIXMAP)
1557     return GTK_RC_TOKEN_BG_PIXMAP;
1558   
1559   token = gtk_rc_parse_state (scanner, &state);
1560   if (token != G_TOKEN_NONE)
1561     return token;
1562   
1563   token = g_scanner_get_next_token (scanner);
1564   if (token != G_TOKEN_EQUAL_SIGN)
1565     return G_TOKEN_EQUAL_SIGN;
1566   
1567   token = g_scanner_get_next_token (scanner);
1568   if (token != G_TOKEN_STRING)
1569     return G_TOKEN_STRING;
1570   
1571   if ((strcmp (scanner->value.v_string, "<parent>") == 0) ||
1572       (strcmp (scanner->value.v_string, "<none>") == 0))
1573     pixmap_file = g_strdup (scanner->value.v_string);
1574   else
1575     pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
1576   
1577   if (pixmap_file)
1578     {
1579       if (rc_style->bg_pixmap_name[state])
1580         g_free (rc_style->bg_pixmap_name[state]);
1581       rc_style->bg_pixmap_name[state] = pixmap_file;
1582     }
1583   
1584   return G_TOKEN_NONE;
1585 }
1586
1587 gchar*
1588 gtk_rc_find_pixmap_in_path (GScanner *scanner,
1589                             const gchar *pixmap_file)
1590 {
1591   gint i;
1592   gint fd;
1593   gchar *buf;
1594   
1595   for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
1596     {
1597       buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s",
1598                              pixmap_path[i], pixmap_file);
1599       
1600       fd = open (buf, O_RDONLY);
1601       if (fd >= 0)
1602         {
1603           close (fd);
1604           return buf;
1605         }
1606       
1607       g_free (buf);
1608     }
1609
1610   if (scanner)
1611     g_warning (_("Unable to locate image file in pixmap_path: \"%s\" line %d"),
1612                pixmap_file, scanner->line);
1613   else
1614     g_warning (_("Unable to locate image file in pixmap_path: \"%s\""),
1615                pixmap_file);
1616     
1617   return NULL;
1618 }
1619
1620 gchar*
1621 gtk_rc_find_module_in_path (const gchar *module_file)
1622 {
1623   gint i;
1624   gint fd;
1625   gchar *buf;
1626   
1627   for (i = 0; (i < GTK_RC_MAX_MODULE_PATHS) && (module_path[i] != NULL); i++)
1628     {
1629       buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s",
1630                              module_path[i], module_file);
1631       
1632       fd = open (buf, O_RDONLY);
1633       if (fd >= 0)
1634         {
1635           close (fd);
1636           return buf;
1637         }
1638       
1639       g_free (buf);
1640     }
1641     
1642   return NULL;
1643 }
1644
1645 static guint
1646 gtk_rc_parse_font (GScanner   *scanner,
1647                    GtkRcStyle *rc_style)
1648 {
1649   guint token;
1650   
1651   token = g_scanner_get_next_token (scanner);
1652   if (token != GTK_RC_TOKEN_FONT)
1653     return GTK_RC_TOKEN_FONT;
1654   
1655   token = g_scanner_get_next_token (scanner);
1656   if (token != G_TOKEN_EQUAL_SIGN)
1657     return G_TOKEN_EQUAL_SIGN;
1658   
1659   token = g_scanner_get_next_token (scanner);
1660   if (token != G_TOKEN_STRING)
1661     return G_TOKEN_STRING;
1662   
1663   if (rc_style->font_name)
1664     g_free (rc_style->font_name);
1665   rc_style->font_name = g_strdup (scanner->value.v_string);
1666   
1667   return G_TOKEN_NONE;
1668 }
1669
1670 static guint
1671 gtk_rc_parse_fontset (GScanner   *scanner,
1672                       GtkRcStyle *rc_style)
1673 {
1674   guint token;
1675   
1676   token = g_scanner_get_next_token (scanner);
1677   if (token != GTK_RC_TOKEN_FONTSET)
1678     return GTK_RC_TOKEN_FONTSET;
1679   
1680   token = g_scanner_get_next_token (scanner);
1681   if (token != G_TOKEN_EQUAL_SIGN)
1682     return G_TOKEN_EQUAL_SIGN;
1683   
1684   token = g_scanner_get_next_token (scanner);
1685   if (token != G_TOKEN_STRING)
1686     return G_TOKEN_STRING;
1687   
1688   if (rc_style->fontset_name)
1689     g_free (rc_style->fontset_name);
1690   rc_style->fontset_name = g_strdup (scanner->value.v_string);
1691   
1692   return G_TOKEN_NONE;
1693 }
1694
1695 static guint       
1696 gtk_rc_parse_engine (GScanner    *scanner,
1697                      GtkRcStyle  *rc_style)
1698 {
1699   guint token;
1700
1701   token = g_scanner_get_next_token (scanner);
1702   if (token != GTK_RC_TOKEN_ENGINE)
1703     return GTK_RC_TOKEN_ENGINE;
1704
1705   token = g_scanner_get_next_token (scanner);
1706   if (token != G_TOKEN_STRING)
1707     return G_TOKEN_STRING;
1708
1709   rc_style->engine = gtk_theme_engine_get (scanner->value.v_string);
1710
1711   token = g_scanner_get_next_token (scanner);
1712   if (token != G_TOKEN_LEFT_CURLY)
1713     return G_TOKEN_LEFT_CURLY;
1714
1715   if (rc_style->engine)
1716     return rc_style->engine->parse_rc_style (scanner, rc_style);
1717   else
1718     {
1719       /* Skip over remainder, looking for nested {}'s */
1720       guint count = 1;
1721       
1722       while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
1723         {
1724           if (token == G_TOKEN_LEFT_CURLY)
1725             count++;
1726           else if (token == G_TOKEN_RIGHT_CURLY)
1727             count--;
1728
1729           if (count == 0)
1730             return G_TOKEN_NONE;
1731         }
1732
1733       return G_TOKEN_RIGHT_CURLY;
1734     }
1735 }
1736
1737 guint
1738 gtk_rc_parse_state (GScanner     *scanner,
1739                     GtkStateType *state)
1740 {
1741   guint old_scope;
1742   guint token;
1743
1744   g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1745   g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
1746   
1747   /* we don't know where we got called from, so we reset the scope here.
1748    * if we bail out due to errors, we *don't* reset the scope, so the
1749    * error messaging code can make sense of our tokens.
1750    */
1751   old_scope = g_scanner_set_scope (scanner, 0);
1752   
1753   token = g_scanner_get_next_token (scanner);
1754   if (token != G_TOKEN_LEFT_BRACE)
1755     return G_TOKEN_LEFT_BRACE;
1756   
1757   token = g_scanner_get_next_token (scanner);
1758   switch (token)
1759     {
1760     case GTK_RC_TOKEN_ACTIVE:
1761       *state = GTK_STATE_ACTIVE;
1762       break;
1763     case GTK_RC_TOKEN_INSENSITIVE:
1764       *state = GTK_STATE_INSENSITIVE;
1765       break;
1766     case GTK_RC_TOKEN_NORMAL:
1767       *state = GTK_STATE_NORMAL;
1768       break;
1769     case GTK_RC_TOKEN_PRELIGHT:
1770       *state = GTK_STATE_PRELIGHT;
1771       break;
1772     case GTK_RC_TOKEN_SELECTED:
1773       *state = GTK_STATE_SELECTED;
1774       break;
1775     default:
1776       return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
1777     }
1778   
1779   token = g_scanner_get_next_token (scanner);
1780   if (token != G_TOKEN_RIGHT_BRACE)
1781     return G_TOKEN_RIGHT_BRACE;
1782   
1783   g_scanner_set_scope (scanner, old_scope);
1784
1785   return G_TOKEN_NONE;
1786 }
1787
1788 guint
1789 gtk_rc_parse_priority (GScanner            *scanner,
1790                        GtkPathPriorityType *priority)
1791 {
1792   guint old_scope;
1793   guint token;
1794
1795   g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1796   g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
1797
1798   /* we don't know where we got called from, so we reset the scope here.
1799    * if we bail out due to errors, we *don't* reset the scope, so the
1800    * error messaging code can make sense of our tokens.
1801    */
1802   old_scope = g_scanner_set_scope (scanner, 0);
1803   
1804   token = g_scanner_get_next_token (scanner);
1805   if (token != ':')
1806     return ':';
1807   
1808   token = g_scanner_get_next_token (scanner);
1809   switch (token)
1810     {
1811     case GTK_RC_TOKEN_LOWEST:
1812       *priority = GTK_PATH_PRIO_LOWEST;
1813       break;
1814     case GTK_RC_TOKEN_GTK:
1815       *priority = GTK_PATH_PRIO_GTK;
1816       break;
1817     case GTK_RC_TOKEN_APPLICATION:
1818       *priority = GTK_PATH_PRIO_APPLICATION;
1819       break;
1820     case GTK_RC_TOKEN_RC:
1821       *priority = GTK_PATH_PRIO_RC;
1822       break;
1823     case GTK_RC_TOKEN_HIGHEST:
1824       *priority = GTK_PATH_PRIO_HIGHEST;
1825       break;
1826     default:
1827       return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
1828     }
1829   
1830   g_scanner_set_scope (scanner, old_scope);
1831
1832   return G_TOKEN_NONE;
1833 }
1834
1835 guint
1836 gtk_rc_parse_color (GScanner *scanner,
1837                     GdkColor *color)
1838 {
1839   guint token;
1840
1841   g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1842
1843   /* we don't need to set our own scop here, because
1844    * we don't need own symbols
1845    */
1846   
1847   token = g_scanner_get_next_token (scanner);
1848   switch (token)
1849     {
1850       gint token_int;
1851       gint length;
1852       gint temp;
1853       gchar buf[9];
1854       gint i, j;
1855       
1856     case G_TOKEN_LEFT_CURLY:
1857       token = g_scanner_get_next_token (scanner);
1858       if (token == G_TOKEN_INT)
1859         token_int = scanner->value.v_int;
1860       else if (token == G_TOKEN_FLOAT)
1861         token_int = scanner->value.v_float * 65535.0;
1862       else
1863         return G_TOKEN_FLOAT;
1864       color->red = CLAMP (token_int, 0, 65535);
1865       
1866       token = g_scanner_get_next_token (scanner);
1867       if (token != G_TOKEN_COMMA)
1868         return G_TOKEN_COMMA;
1869       
1870       token = g_scanner_get_next_token (scanner);
1871       if (token == G_TOKEN_INT)
1872         token_int = scanner->value.v_int;
1873       else if (token == G_TOKEN_FLOAT)
1874         token_int = scanner->value.v_float * 65535.0;
1875       else
1876         return G_TOKEN_FLOAT;
1877       color->green = CLAMP (token_int, 0, 65535);
1878       
1879       token = g_scanner_get_next_token (scanner);
1880       if (token != G_TOKEN_COMMA)
1881         return G_TOKEN_COMMA;
1882       
1883       token = g_scanner_get_next_token (scanner);
1884       if (token == G_TOKEN_INT)
1885         token_int = scanner->value.v_int;
1886       else if (token == G_TOKEN_FLOAT)
1887         token_int = scanner->value.v_float * 65535.0;
1888       else
1889         return G_TOKEN_FLOAT;
1890       color->blue = CLAMP (token_int, 0, 65535);
1891       
1892       token = g_scanner_get_next_token (scanner);
1893       if (token != G_TOKEN_RIGHT_CURLY)
1894         return G_TOKEN_RIGHT_CURLY;
1895       return G_TOKEN_NONE;
1896       
1897     case G_TOKEN_STRING:
1898       if (scanner->value.v_string[0] != '#')
1899         return G_TOKEN_STRING;
1900       
1901       length = strlen (scanner->value.v_string) - 1;
1902       if (((length % 3) != 0) || (length > 12))
1903         return G_TOKEN_STRING;
1904       length /= 3;
1905       
1906       for (i = 0, j = 1; i < length; i++, j++)
1907         buf[i] = scanner->value.v_string[j];
1908       buf[i] = '\0';
1909       
1910       sscanf (buf, "%x", &temp);
1911       color->red = temp;
1912       
1913       for (i = 0; i < length; i++, j++)
1914         buf[i] = scanner->value.v_string[j];
1915       buf[i] = '\0';
1916       
1917       sscanf (buf, "%x", &temp);
1918       color->green = temp;
1919       
1920       for (i = 0; i < length; i++, j++)
1921         buf[i] = scanner->value.v_string[j];
1922       buf[i] = '\0';
1923       
1924       sscanf (buf, "%x", &temp);
1925       color->blue = temp;
1926       
1927       if (length == 1)
1928         {
1929           color->red *= 4369;
1930           color->green *= 4369;
1931           color->blue *= 4369;
1932         }
1933       else if (length == 2)
1934         {
1935           color->red *= 257;
1936           color->green *= 257;
1937           color->blue *= 257;
1938         }
1939       else if (length == 3)
1940         {
1941           color->red *= 16;
1942           color->green *= 16;
1943           color->blue *= 16;
1944         }
1945       return G_TOKEN_NONE;
1946       
1947     default:
1948       return G_TOKEN_STRING;
1949     }
1950 }
1951
1952 static guint
1953 gtk_rc_parse_pixmap_path (GScanner *scanner)
1954 {
1955   guint token;
1956   
1957   token = g_scanner_get_next_token (scanner);
1958   if (token != GTK_RC_TOKEN_PIXMAP_PATH)
1959     return GTK_RC_TOKEN_PIXMAP_PATH;
1960   
1961   token = g_scanner_get_next_token (scanner);
1962   if (token != G_TOKEN_STRING)
1963     return G_TOKEN_STRING;
1964   
1965   gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
1966   
1967   return G_TOKEN_NONE;
1968 }
1969
1970 static void
1971 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
1972 {
1973   gchar *buf;
1974   gint end_offset;
1975   gint start_offset = 0;
1976   gint path_len;
1977   gint path_num;
1978   
1979   /* free the old one, or just add to the old one ? */
1980   for (path_num=0; pixmap_path[path_num]; path_num++)
1981     {
1982       g_free (pixmap_path[path_num]);
1983       pixmap_path[path_num] = NULL;
1984     }
1985   
1986   path_num = 0;
1987   
1988   path_len = strlen (pix_path);
1989   
1990   buf = g_strdup (pix_path);
1991   
1992   for (end_offset = 0; end_offset <= path_len; end_offset++)
1993     {
1994       if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
1995           (end_offset == path_len))
1996         {
1997           buf[end_offset] = '\0';
1998           pixmap_path[path_num] = g_strdup (buf + start_offset);
1999           path_num++;
2000           pixmap_path[path_num] = NULL;
2001           start_offset = end_offset + 1;
2002         }
2003     }
2004   g_free (buf);
2005   gtk_rc_append_default_pixmap_path();
2006 }
2007
2008 static guint
2009 gtk_rc_parse_module_path (GScanner *scanner)
2010 {
2011   guint token;
2012   
2013   token = g_scanner_get_next_token (scanner);
2014   if (token != GTK_RC_TOKEN_MODULE_PATH)
2015     return GTK_RC_TOKEN_MODULE_PATH;
2016   
2017   token = g_scanner_get_next_token (scanner);
2018   if (token != G_TOKEN_STRING)
2019     return G_TOKEN_STRING;
2020   
2021   gtk_rc_parse_module_path_string (scanner->value.v_string);
2022   
2023   return G_TOKEN_NONE;
2024 }
2025
2026 static void
2027 gtk_rc_parse_module_path_string (gchar *mod_path)
2028 {
2029   gchar *buf;
2030   gint end_offset;
2031   gint start_offset = 0;
2032   gint path_len;
2033   gint path_num;
2034   
2035   /* free the old one, or just add to the old one ? */
2036   for (path_num=0; module_path[path_num]; path_num++)
2037     {
2038       g_free (module_path[path_num]);
2039       module_path[path_num] = NULL;
2040     }
2041   
2042   path_num = 0;
2043   
2044   path_len = strlen (mod_path);
2045   
2046   buf = g_strdup (mod_path);
2047   
2048   for (end_offset = 0; end_offset <= path_len; end_offset++)
2049     {
2050       if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
2051           (end_offset == path_len))
2052         {
2053           buf[end_offset] = '\0';
2054           module_path[path_num] = g_strdup (buf + start_offset);
2055           path_num++;
2056           module_path[path_num] = NULL;
2057           start_offset = end_offset + 1;
2058         }
2059     }
2060   g_free (buf);
2061   gtk_rc_append_default_module_path();
2062 }
2063
2064 static guint
2065 gtk_rc_parse_path_pattern (GScanner   *scanner)
2066 {
2067   guint token;
2068   GtkPathType path_type;
2069   gchar *pattern;
2070   gboolean is_binding;
2071   GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
2072   
2073   token = g_scanner_get_next_token (scanner);
2074   switch (token)
2075     {
2076     case GTK_RC_TOKEN_WIDGET:
2077       path_type = GTK_PATH_WIDGET;
2078       break;
2079     case GTK_RC_TOKEN_WIDGET_CLASS:
2080       path_type = GTK_PATH_WIDGET_CLASS;
2081       break;
2082     case GTK_RC_TOKEN_CLASS:
2083       path_type = GTK_PATH_CLASS;
2084       break;
2085     default:
2086       return GTK_RC_TOKEN_WIDGET_CLASS;
2087     }
2088   
2089   token = g_scanner_get_next_token (scanner);
2090   if (token != G_TOKEN_STRING)
2091     return G_TOKEN_STRING;
2092
2093   pattern = g_strdup (scanner->value.v_string);
2094
2095   token = g_scanner_get_next_token (scanner);
2096   if (token == GTK_RC_TOKEN_STYLE)
2097     is_binding = FALSE;
2098   else if (token == GTK_RC_TOKEN_BINDING)
2099     {
2100       is_binding = TRUE;
2101       if (g_scanner_peek_next_token (scanner) == ':')
2102         {
2103           token = gtk_rc_parse_priority (scanner, &priority);
2104           if (token != G_TOKEN_NONE)
2105             {
2106               g_free (pattern);
2107               return token;
2108             }
2109         }
2110     }
2111   else
2112     {
2113       g_free (pattern);
2114       return GTK_RC_TOKEN_STYLE;
2115     }
2116   
2117   token = g_scanner_get_next_token (scanner);
2118   if (token != G_TOKEN_STRING)
2119     {
2120       g_free (pattern);
2121       return G_TOKEN_STRING;
2122     }
2123
2124   if (is_binding)
2125     {
2126       GtkBindingSet *binding;
2127
2128       binding = gtk_binding_set_find (scanner->value.v_string);
2129       if (!binding)
2130         {
2131           g_free (pattern);
2132           return G_TOKEN_STRING;
2133         }
2134       gtk_binding_set_add_path (binding, path_type, pattern, priority);
2135     }
2136   else
2137     {
2138       GtkRcStyle *rc_style;
2139       GtkRcSet *rc_set;
2140
2141       rc_style = gtk_rc_style_find (scanner->value.v_string);
2142       
2143       if (!rc_style)
2144         {
2145           g_free (pattern);
2146           return G_TOKEN_STRING;
2147         }
2148
2149       rc_set = g_new (GtkRcSet, 1);
2150       gtk_pattern_spec_init (&rc_set->pspec, pattern);
2151       rc_set->rc_style = rc_style;
2152
2153       if (path_type == GTK_PATH_WIDGET)
2154         gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
2155       else if (path_type == GTK_PATH_WIDGET_CLASS)
2156         gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
2157       else
2158         gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
2159     }
2160
2161   g_free (pattern);
2162   return G_TOKEN_NONE;
2163 }
2164
2165 /*
2166 typedef  GdkPixmap * (*GtkImageLoader) (GdkWindow   *window,
2167                                         GdkColormap *colormap,
2168                                         GdkBitmap  **mask,
2169                                         GdkColor    *transparent_color,
2170                                         const gchar *filename);
2171 */
2172
2173 void
2174 gtk_rc_set_image_loader(GtkImageLoader loader)
2175 {
2176   image_loader = loader;
2177 }
2178
2179 GdkPixmap *
2180 gtk_rc_load_image (GdkColormap *colormap,
2181                    GdkColor    *transparent_color,
2182                    const gchar *filename)
2183 {
2184   if (strcmp (filename, "<parent>") == 0)
2185     return (GdkPixmap*) GDK_PARENT_RELATIVE;
2186   else
2187     {
2188       if(image_loader)
2189         return image_loader(NULL, colormap, NULL,
2190                             transparent_color,
2191                             filename);
2192       else
2193         return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
2194                                                     transparent_color,
2195                                                     filename);
2196     }
2197 }