1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
22 #include <sys/param.h>
28 #include "gtkbindings.h"
29 #include "gtkthemes.h"
31 typedef struct _GtkRcSet GtkRcSet;
32 typedef struct _GtkRcNode GtkRcNode;
33 typedef struct _GtkRcFile GtkRcFile;
45 gchar *canonical_name;
49 static guint gtk_rc_style_hash (const char *name);
50 static gint gtk_rc_style_compare (const char *a,
52 static guint gtk_rc_styles_hash (const GSList *rc_styles);
53 static gint gtk_rc_styles_compare (const GSList *a,
55 static GtkRcStyle* gtk_rc_style_find (const char *name);
56 static GSList * gtk_rc_styles_match (GSList *rc_styles,
60 gchar *path_reversed);
61 static GtkStyle * gtk_rc_style_to_style (GtkRcStyle *rc_style);
62 static GtkStyle* gtk_rc_style_init (GSList *rc_styles);
63 static void gtk_rc_parse_file (const gchar *filename,
66 static void gtk_rc_parse_any (const gchar *input_name,
68 const gchar *input_string);
69 static guint gtk_rc_parse_statement (GScanner *scanner);
70 static guint gtk_rc_parse_style (GScanner *scanner);
71 static guint gtk_rc_parse_base (GScanner *scanner,
73 static guint gtk_rc_parse_bg (GScanner *scanner,
75 static guint gtk_rc_parse_fg (GScanner *scanner,
77 static guint gtk_rc_parse_text (GScanner *scanner,
79 static guint gtk_rc_parse_bg_pixmap (GScanner *scanner,
80 GtkRcStyle *rc_style);
81 static guint gtk_rc_parse_font (GScanner *scanner,
82 GtkRcStyle *rc_style);
83 static guint gtk_rc_parse_fontset (GScanner *scanner,
84 GtkRcStyle *rc_style);
85 static guint gtk_rc_parse_engine (GScanner *scanner,
86 GtkRcStyle *rc_style);
87 static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
88 static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
89 static guint gtk_rc_parse_module_path (GScanner *scanner);
90 static void gtk_rc_parse_module_path_string (gchar *mod_path);
91 static guint gtk_rc_parse_path_pattern (GScanner *scanner);
92 static void gtk_rc_clear_hash_node (gpointer key,
95 static void gtk_rc_clear_styles (void);
96 static void gtk_rc_append_default_pixmap_path (void);
97 static void gtk_rc_append_default_module_path (void);
98 static void gtk_rc_append_pixmap_path (gchar *dir);
99 static void gtk_rc_add_initial_default_files (void);
102 static const GScannerConfig gtk_rc_scanner_config =
106 ) /* cset_skip_characters */,
111 ) /* cset_identifier_first */,
116 ) /* cset_identifier_nth */,
117 ( "#\n" ) /* cpair_comment_single */,
119 TRUE /* case_sensitive */,
121 TRUE /* skip_comment_multi */,
122 TRUE /* skip_comment_single */,
123 TRUE /* scan_comment_multi */,
124 TRUE /* scan_identifier */,
125 FALSE /* scan_identifier_1char */,
126 FALSE /* scan_identifier_NULL */,
127 TRUE /* scan_symbols */,
128 TRUE /* scan_binary */,
129 TRUE /* scan_octal */,
130 TRUE /* scan_float */,
132 TRUE /* scan_hex_dollar */,
133 TRUE /* scan_string_sq */,
134 TRUE /* scan_string_dq */,
135 TRUE /* numbers_2_int */,
136 FALSE /* int_2_float */,
137 FALSE /* identifier_2_string */,
138 TRUE /* char_2_token */,
139 TRUE /* symbol_2_token */,
140 FALSE /* scope_0_fallback */,
148 { "include", GTK_RC_TOKEN_INCLUDE },
149 { "NORMAL", GTK_RC_TOKEN_NORMAL },
150 { "ACTIVE", GTK_RC_TOKEN_ACTIVE },
151 { "PRELIGHT", GTK_RC_TOKEN_PRELIGHT },
152 { "SELECTED", GTK_RC_TOKEN_SELECTED },
153 { "INSENSITIVE", GTK_RC_TOKEN_INSENSITIVE },
154 { "fg", GTK_RC_TOKEN_FG },
155 { "bg", GTK_RC_TOKEN_BG },
156 { "base", GTK_RC_TOKEN_BASE },
157 { "text", GTK_RC_TOKEN_TEXT },
158 { "font", GTK_RC_TOKEN_FONT },
159 { "fontset", GTK_RC_TOKEN_FONTSET },
160 { "bg_pixmap", GTK_RC_TOKEN_BG_PIXMAP },
161 { "pixmap_path", GTK_RC_TOKEN_PIXMAP_PATH },
162 { "style", GTK_RC_TOKEN_STYLE },
163 { "binding", GTK_RC_TOKEN_BINDING },
164 { "bind", GTK_RC_TOKEN_BIND },
165 { "widget", GTK_RC_TOKEN_WIDGET },
166 { "widget_class", GTK_RC_TOKEN_WIDGET_CLASS },
167 { "class", GTK_RC_TOKEN_CLASS },
168 { "lowest", GTK_RC_TOKEN_LOWEST },
169 { "gtk", GTK_RC_TOKEN_GTK },
170 { "application", GTK_RC_TOKEN_APPLICATION },
171 { "rc", GTK_RC_TOKEN_RC },
172 { "highest", GTK_RC_TOKEN_HIGHEST },
173 { "engine", GTK_RC_TOKEN_ENGINE },
174 { "module_path", GTK_RC_TOKEN_MODULE_PATH },
177 static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
179 static GHashTable *rc_style_ht = NULL;
180 static GHashTable *realized_style_ht = NULL;
181 static GSList *gtk_rc_sets_widget = NULL;
182 static GSList *gtk_rc_sets_widget_class = NULL;
183 static GSList *gtk_rc_sets_class = NULL;
185 #define GTK_RC_MAX_DEFAULT_FILES 128
186 static gchar *gtk_rc_default_files[GTK_RC_MAX_DEFAULT_FILES];
187 static gboolean gtk_rc_auto_parse = TRUE;
189 #define GTK_RC_MAX_PIXMAP_PATHS 128
190 static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
191 #define GTK_RC_MAX_MODULE_PATHS 128
192 static gchar *module_path[GTK_RC_MAX_MODULE_PATHS];
194 /* The files we have parsed, to reread later if necessary */
195 GSList *rc_files = NULL;
197 static GtkImageLoader image_loader = NULL;
199 /* RC file handling */
203 gtk_rc_get_theme_dir(void)
207 var = getenv("GTK_DATA_PREFIX");
210 path = g_malloc(strlen(var) + strlen("/share/themes") +1);
211 sprintf(path, "%s%s", var, "/share/themes");
215 path = g_malloc(strlen(GTK_DATA_PREFIX) + strlen("/share/themes") +1);
216 sprintf(path, "%s%s", GTK_DATA_PREFIX, "/share/themes");
222 gtk_rc_get_module_dir(void)
226 var = getenv("GTK_EXE_PREFIX");
229 path = g_malloc(strlen(var) + strlen("/lib/gtk/themes/engines") +1);
230 sprintf(path, "%s%s", var, "/lib/gtk/themes/engines");
234 path = g_malloc(strlen(GTK_EXE_PREFIX) + strlen("/lib/gtk/themes/engines") +1);
235 sprintf(path, "%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
241 gtk_rc_append_default_pixmap_path(void)
246 var = getenv("GTK_DATA_PREFIX");
249 path = g_malloc(strlen(var) + strlen("/share/gtk/themes") +1);
250 sprintf(path, "%s%s", var, "/share/gtk/themes");
254 path = g_malloc(strlen(GTK_DATA_PREFIX) + strlen("/share/gtk/themes") +1);
255 sprintf(path, "%s%s", GTK_DATA_PREFIX, "/share/gtk/themes");
258 for (n = 0; pixmap_path[n]; n++) ;
259 if (n >= GTK_RC_MAX_PIXMAP_PATHS - 1)
261 pixmap_path[n++] = g_strdup(path);
262 pixmap_path[n] = NULL;
267 gtk_rc_append_pixmap_path(gchar *dir)
271 for (n = 0; pixmap_path[n]; n++) ;
272 if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
274 pixmap_path[n++] = g_strdup(dir);
275 pixmap_path[n] = NULL;
279 gtk_rc_append_default_module_path(void)
284 for (n = 0; module_path[n]; n++) ;
285 if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
288 var = getenv("GTK_EXE_PREFIX");
291 path = g_malloc(strlen(var) + strlen("/lib/gtk/themes/engines") +1);
292 sprintf(path, "%s%s", var, "/lib/gtk/themes/engines");
296 path = g_malloc(strlen(GTK_EXE_PREFIX) + strlen("/lib/gtk/themes/engines") +1);
297 sprintf(path, "%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
299 module_path[n++] = g_strdup(path);
301 var = getenv("HOME");
304 path = g_malloc(strlen(var) + strlen(".gtk/lib/themes/engines") +1);
305 sprintf(path, "%s%s", var, ".gtk/lib/themes/engines");
307 module_path[n++] = g_strdup(path);
308 module_path[n] = NULL;
313 gtk_rc_add_initial_default_files (void)
315 static gint init = FALSE;
323 gtk_rc_default_files[0] = NULL;
326 var = getenv("GTK_RC_FILES");
329 files = g_strsplit (var, ":", 128);
333 gtk_rc_add_default_file (files[i]);
339 str = g_malloc (strlen(GTK_SYSCONFDIR) + strlen("/gtkrc") + 1);
340 sprintf (str, "%s%s", GTK_SYSCONFDIR, "/gtkrc");
341 gtk_rc_add_default_file (str);
343 var = g_get_home_dir ();
344 str = g_malloc (strlen(var) + strlen("/.gtkrc") + 1);
345 sprintf (str, "%s%s", var, "/.gtkrc");
346 gtk_rc_add_default_file (str);
351 gtk_rc_add_default_file (const gchar *file)
355 gtk_rc_add_initial_default_files ();
357 for (n = 0; gtk_rc_default_files[n]; n++) ;
358 if (n >= GTK_RC_MAX_DEFAULT_FILES - 1)
361 gtk_rc_default_files[n++] = g_strdup (file);
362 gtk_rc_default_files[n] = NULL;
366 gtk_rc_set_default_files (gchar **files)
370 gtk_rc_add_initial_default_files ();
373 while (gtk_rc_default_files[i])
375 g_free (gtk_rc_default_files[i]);
379 gtk_rc_default_files[0] = NULL;
380 gtk_rc_auto_parse = FALSE;
383 while (files[i] != NULL)
385 gtk_rc_add_default_file (files[i]);
391 gtk_rc_get_default_files (void)
393 gtk_rc_add_initial_default_files ();
395 return gtk_rc_default_files;
403 rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
404 (GCompareFunc) gtk_rc_style_compare);
405 pixmap_path[0] = NULL;
406 module_path[0] = NULL;
407 gtk_rc_append_default_pixmap_path();
408 gtk_rc_append_default_module_path();
410 gtk_rc_add_initial_default_files ();
413 while (gtk_rc_default_files[i] != NULL)
415 gtk_rc_parse (gtk_rc_default_files[i]);
421 gtk_rc_parse_string (const gchar *rc_string)
423 g_return_if_fail (rc_string != NULL);
425 gtk_rc_parse_any ("-", -1, rc_string);
429 gtk_rc_parse_file (const gchar *filename, gboolean reload)
431 GtkRcFile *rc_file = NULL;
435 g_return_if_fail (filename != NULL);
440 rc_file = tmp_list->data;
441 if (!strcmp (rc_file->name, filename))
444 tmp_list = tmp_list->next;
449 rc_file = g_new (GtkRcFile, 1);
450 rc_file->name = g_strdup (filename);
451 rc_file->canonical_name = NULL;
453 rc_file->reload = reload;
455 rc_files = g_slist_append (rc_files, rc_file);
458 if (!rc_file->canonical_name)
460 /* Get the absolute pathname */
462 if (rc_file->name[0] == '/')
463 rc_file->canonical_name = rc_file->name;
469 cwd = g_get_current_dir ();
471 str = g_string_new (cwd);
473 g_string_append_c (str, '/');
474 g_string_append (str, rc_file->name);
476 rc_file->canonical_name = str->str;
477 g_string_free (str, FALSE);
481 if (!lstat (rc_file->canonical_name, &statbuf))
485 rc_file->mtime = statbuf.st_mtime;
487 fd = open (rc_file->canonical_name, O_RDONLY);
495 dir = g_strdup(rc_file->canonical_name);
496 for (i = strlen(dir) - 1; (i >= 0) && (dir[i] != '/'); i--)
498 gtk_rc_append_pixmap_path(dir);
501 gtk_rc_parse_any (filename, fd, NULL);
508 gtk_rc_parse (const gchar *filename)
510 g_return_if_fail (filename != NULL);
512 gtk_rc_parse_file (filename, TRUE);
515 /* Handling of RC styles */
518 gtk_rc_style_new (void)
520 GtkRcStyle *new_style;
522 new_style = g_new0 (GtkRcStyle, 1);
523 new_style->ref_count = 1;
529 gtk_rc_style_ref (GtkRcStyle *rc_style)
531 g_return_if_fail (rc_style != NULL);
533 rc_style->ref_count++;
537 gtk_rc_style_unref (GtkRcStyle *rc_style)
541 g_return_if_fail (rc_style != NULL);
543 rc_style->ref_count--;
545 if (rc_style->ref_count == 0)
547 if (rc_style->engine)
549 rc_style->engine->destroy_rc_style (rc_style);
550 gtk_theme_engine_unref (rc_style->engine);
554 g_free (rc_style->name);
555 if (rc_style->fontset_name)
556 g_free (rc_style->fontset_name);
557 if (rc_style->font_name)
558 g_free (rc_style->font_name);
560 for (i=0 ; i<5 ; i++)
561 if (rc_style->bg_pixmap_name[i])
562 g_free (rc_style->bg_pixmap_name[i]);
569 gtk_rc_clear_realized_node (gpointer key,
573 gtk_style_unref (data);
577 gtk_rc_clear_hash_node (gpointer key,
581 gtk_rc_style_unref (data);
585 gtk_rc_free_rc_sets (GSList *slist)
591 rc_set = slist->data;
592 gtk_pattern_spec_free_segs (&rc_set->pspec);
600 gtk_rc_clear_styles (void)
602 /* Clear out all old rc_styles */
606 g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
607 g_hash_table_destroy (rc_style_ht);
611 if (realized_style_ht)
613 g_hash_table_foreach (realized_style_ht, gtk_rc_clear_realized_node, NULL);
614 g_hash_table_destroy (realized_style_ht);
615 realized_style_ht = NULL;
618 gtk_rc_free_rc_sets (gtk_rc_sets_widget);
619 g_slist_free (gtk_rc_sets_widget);
620 gtk_rc_sets_widget = NULL;
622 gtk_rc_free_rc_sets (gtk_rc_sets_widget_class);
623 g_slist_free (gtk_rc_sets_widget_class);
624 gtk_rc_sets_widget_class = NULL;
626 gtk_rc_free_rc_sets (gtk_rc_sets_class);
627 g_slist_free (gtk_rc_sets_class);
628 gtk_rc_sets_class = NULL;
634 gtk_rc_reparse_all (void)
637 gboolean mtime_modified = FALSE;
642 /* Check through and see if any of the RC's have had their
643 * mtime modified. If so, reparse everything.
648 rc_file = tmp_list->data;
650 if (!lstat (rc_file->name, &statbuf) &&
651 (statbuf.st_mtime > rc_file->mtime))
653 mtime_modified = TRUE;
657 tmp_list = tmp_list->next;
662 gtk_rc_clear_styles();
667 rc_file = tmp_list->data;
669 gtk_rc_parse_file (rc_file->name, FALSE);
671 tmp_list = tmp_list->next;
675 return mtime_modified;
679 gtk_rc_styles_match (GSList *rc_styles,
683 gchar *path_reversed)
693 if (gtk_pattern_match (&rc_set->pspec, path_length, path, path_reversed))
694 rc_styles = g_slist_append (rc_styles, rc_set->rc_style);
701 gtk_rc_get_style (GtkWidget *widget)
703 GtkRcStyle *widget_rc_style;
704 GSList *rc_styles = NULL;
706 static guint rc_style_key_id = 0;
708 /* We allow the specification of a single rc style to be bound
709 * tightly to a widget, for application modifications
711 if (!rc_style_key_id)
712 rc_style_key_id = g_quark_from_static_string ("gtk-rc-style");
714 widget_rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
718 rc_styles = g_slist_prepend (rc_styles, widget_rc_style);
720 if (gtk_rc_sets_widget)
722 gchar *path, *path_reversed;
725 gtk_widget_path (widget, &path_length, &path, &path_reversed);
726 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget, path_length, path, path_reversed);
728 g_free (path_reversed);
732 if (gtk_rc_sets_widget_class)
734 gchar *path, *path_reversed;
737 gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
738 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget_class, path_length, path, path_reversed);
740 g_free (path_reversed);
743 if (gtk_rc_sets_class)
747 type = GTK_OBJECT_TYPE (widget);
750 gchar *path, *path_reversed;
753 path = gtk_type_name (type);
754 path_length = strlen (path);
755 path_reversed = g_strdup (path);
756 g_strreverse (path_reversed);
758 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_class, path_length, path, path_reversed);
759 g_free (path_reversed);
761 type = gtk_type_parent (type);
766 return gtk_rc_style_init (rc_styles);
772 gtk_rc_add_rc_sets (GSList *slist,
773 GtkRcStyle *rc_style,
776 GtkRcStyle *new_style;
780 new_style = gtk_rc_style_new ();
781 *new_style = *rc_style;
782 new_style->name = g_strdup (rc_style->name);
783 new_style->font_name = g_strdup (rc_style->font_name);
784 new_style->fontset_name = g_strdup (rc_style->fontset_name);
786 for (i = 0; i < 5; i++)
787 new_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
789 rc_set = g_new (GtkRcSet, 1);
790 gtk_pattern_spec_init (&rc_set->pspec, pattern);
791 rc_set->rc_style = rc_style;
793 return g_slist_prepend (slist, rc_set);
797 gtk_rc_add_widget_name_style (GtkRcStyle *rc_style,
798 const gchar *pattern)
800 g_return_if_fail (rc_style != NULL);
801 g_return_if_fail (pattern != NULL);
803 gtk_rc_sets_widget = gtk_rc_add_rc_sets (gtk_rc_sets_widget, rc_style, pattern);
807 gtk_rc_add_widget_class_style (GtkRcStyle *rc_style,
808 const gchar *pattern)
810 g_return_if_fail (rc_style != NULL);
811 g_return_if_fail (pattern != NULL);
813 gtk_rc_sets_widget_class = gtk_rc_add_rc_sets (gtk_rc_sets_widget_class, rc_style, pattern);
817 gtk_rc_add_class_style (GtkRcStyle *rc_style,
818 const gchar *pattern)
820 g_return_if_fail (rc_style != NULL);
821 g_return_if_fail (pattern != NULL);
823 gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
827 gtk_rc_parse_any (const gchar *input_name,
829 const gchar *input_string)
835 scanner = g_scanner_new (>k_rc_scanner_config);
839 g_assert (input_string == NULL);
841 g_scanner_input_file (scanner, input_fd);
845 g_assert (input_string != NULL);
847 g_scanner_input_text (scanner, input_string, strlen (input_string));
849 scanner->input_name = input_name;
851 g_scanner_freeze_symbol_table (scanner);
852 for (i = 0; i < n_symbols; i++)
853 g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
854 g_scanner_thaw_symbol_table (scanner);
859 if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
863 guint expected_token;
865 expected_token = gtk_rc_parse_statement (scanner);
867 if (expected_token != G_TOKEN_NONE)
874 if (scanner->scope_id == 0)
876 /* if we are in scope 0, we know the symbol names
877 * that are associated with certaintoken values.
878 * so we look them up to make the error messages
881 if (expected_token > GTK_RC_TOKEN_INVALID &&
882 expected_token < GTK_RC_TOKEN_LAST)
884 for (i = 0; i < n_symbols; i++)
885 if (symbols[i].token == expected_token)
886 msg = symbols[i].name;
888 msg = g_strconcat ("e.g. `", msg, "'", NULL);
890 if (scanner->token > GTK_RC_TOKEN_INVALID &&
891 scanner->token < GTK_RC_TOKEN_LAST)
894 for (i = 0; i < n_symbols; i++)
895 if (symbols[i].token == scanner->token)
896 symbol_name = symbols[i].name;
899 g_scanner_unexp_token (scanner,
912 g_scanner_destroy (scanner);
916 gtk_rc_styles_hash (const GSList *rc_styles)
923 result += (result << 9) + GPOINTER_TO_UINT (rc_styles->data);
924 rc_styles = rc_styles->next;
931 gtk_rc_styles_compare (const GSList *a,
936 if (a->data != b->data)
946 gtk_rc_style_hash (const char *name)
952 result += (result << 3) + *name++;
958 gtk_rc_style_compare (const char *a,
961 return (strcmp (a, b) == 0);
965 gtk_rc_style_find (const char *name)
967 GtkRcStyle *rc_style;
969 rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
974 /* Assumes ownership of rc_style */
976 gtk_rc_style_to_style (GtkRcStyle *rc_style)
982 style = gtk_style_new ();
984 style->rc_style = rc_style;
986 if (rc_style->fontset_name)
988 old_font = style->font;
989 style->font = gdk_fontset_load (rc_style->fontset_name);
991 gdk_font_unref (old_font);
993 style->font = old_font;
995 else if (rc_style->font_name)
997 old_font = style->font;
998 style->font = gdk_font_load (rc_style->font_name);
1000 gdk_font_unref (old_font);
1002 style->font = old_font;
1005 for (i = 0; i < 5; i++)
1007 if (rc_style->color_flags[i] & GTK_RC_FG)
1008 style->fg[i] = rc_style->fg[i];
1009 if (rc_style->color_flags[i] & GTK_RC_BG)
1010 style->bg[i] = rc_style->bg[i];
1011 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1012 style->text[i] = rc_style->text[i];
1013 if (rc_style->color_flags[i] & GTK_RC_BASE)
1014 style->base[i] = rc_style->base[i];
1017 if (rc_style->engine)
1019 style->engine = rc_style->engine;
1020 gtk_theme_engine_ref (style->engine);
1021 rc_style->engine->rc_style_to_style (style, rc_style);
1027 /* Reuses or frees rc_styles */
1029 gtk_rc_style_init (GSList *rc_styles)
1033 GtkStyle *style = NULL;
1034 GtkRcStyle *proto_style;
1036 if (!realized_style_ht)
1037 realized_style_ht = g_hash_table_new ((GHashFunc)gtk_rc_styles_hash,
1038 (GCompareFunc)gtk_rc_styles_compare);
1040 style = g_hash_table_lookup (realized_style_ht, rc_styles);
1044 GSList *tmp_styles = rc_styles;
1046 proto_style = gtk_rc_style_new ();
1050 GtkRcStyle *rc_style = tmp_styles->data;
1054 if (!proto_style->bg_pixmap_name[i] && rc_style->bg_pixmap_name[i])
1055 proto_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
1057 if (!(proto_style->color_flags[i] & GTK_RC_FG) &&
1058 rc_style->color_flags[i] & GTK_RC_FG)
1060 proto_style->fg[i] = rc_style->fg[i];
1061 proto_style->color_flags[i] |= GTK_RC_FG;
1063 if (!(proto_style->color_flags[i] & GTK_RC_BG) &&
1064 rc_style->color_flags[i] & GTK_RC_BG)
1066 proto_style->bg[i] = rc_style->bg[i];
1067 proto_style->color_flags[i] |= GTK_RC_BG;
1069 if (!(proto_style->color_flags[i] & GTK_RC_TEXT) &&
1070 rc_style->color_flags[i] & GTK_RC_TEXT)
1072 proto_style->text[i] = rc_style->text[i];
1073 proto_style->color_flags[i] |= GTK_RC_TEXT;
1075 if (!(proto_style->color_flags[i] & GTK_RC_BASE) &&
1076 rc_style->color_flags[i] & GTK_RC_BASE)
1078 proto_style->base[i] = rc_style->base[i];
1079 proto_style->color_flags[i] |= GTK_RC_BASE;
1083 if (!proto_style->font_name && rc_style->font_name)
1084 proto_style->font_name = g_strdup (rc_style->font_name);
1085 if (!proto_style->fontset_name && rc_style->fontset_name)
1086 proto_style->fontset_name = g_strdup (rc_style->fontset_name);
1088 if (!proto_style->engine && rc_style->engine)
1090 proto_style->engine = rc_style->engine;
1091 gtk_theme_engine_ref (proto_style->engine);
1094 if (proto_style->engine &&
1095 (proto_style->engine == rc_style->engine))
1096 proto_style->engine->merge_rc_style (proto_style, rc_style);
1098 tmp_styles = tmp_styles->next;
1101 style = gtk_rc_style_to_style (proto_style);
1103 g_hash_table_insert (realized_style_ht, rc_styles, style);
1109 /*********************
1110 * Parsing functions *
1111 *********************/
1114 gtk_rc_parse_statement (GScanner *scanner)
1118 token = g_scanner_peek_next_token (scanner);
1122 case GTK_RC_TOKEN_INCLUDE:
1123 token = g_scanner_get_next_token (scanner);
1124 if (token != GTK_RC_TOKEN_INCLUDE)
1125 return GTK_RC_TOKEN_INCLUDE;
1127 token = g_scanner_get_next_token (scanner);
1128 if (token != G_TOKEN_STRING)
1129 return G_TOKEN_STRING;
1131 gtk_rc_parse_file (scanner->value.v_string, FALSE);
1132 return G_TOKEN_NONE;
1134 case GTK_RC_TOKEN_STYLE:
1135 return gtk_rc_parse_style (scanner);
1137 case GTK_RC_TOKEN_BINDING:
1138 return gtk_binding_parse_binding (scanner);
1140 case GTK_RC_TOKEN_PIXMAP_PATH:
1141 return gtk_rc_parse_pixmap_path (scanner);
1143 case GTK_RC_TOKEN_WIDGET:
1144 return gtk_rc_parse_path_pattern (scanner);
1146 case GTK_RC_TOKEN_WIDGET_CLASS:
1147 return gtk_rc_parse_path_pattern (scanner);
1149 case GTK_RC_TOKEN_CLASS:
1150 return gtk_rc_parse_path_pattern (scanner);
1152 case GTK_RC_TOKEN_MODULE_PATH:
1153 return gtk_rc_parse_module_path (scanner);
1156 g_scanner_get_next_token (scanner);
1157 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
1162 gtk_rc_parse_style (GScanner *scanner)
1164 GtkRcStyle *rc_style;
1165 GtkRcStyle *parent_style;
1170 token = g_scanner_get_next_token (scanner);
1171 if (token != GTK_RC_TOKEN_STYLE)
1172 return GTK_RC_TOKEN_STYLE;
1174 token = g_scanner_get_next_token (scanner);
1175 if (token != G_TOKEN_STRING)
1176 return G_TOKEN_STRING;
1179 rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
1184 rc_style = gtk_rc_style_new ();
1185 rc_style->name = g_strdup (scanner->value.v_string);
1187 for (i = 0; i < 5; i++)
1188 rc_style->bg_pixmap_name[i] = NULL;
1190 for (i = 0; i < 5; i++)
1191 rc_style->color_flags[i] = 0;
1193 rc_style->engine = NULL;
1194 rc_style->engine_data = NULL;
1197 token = g_scanner_peek_next_token (scanner);
1198 if (token == G_TOKEN_EQUAL_SIGN)
1200 token = g_scanner_get_next_token (scanner);
1202 token = g_scanner_get_next_token (scanner);
1203 if (token != G_TOKEN_STRING)
1208 return G_TOKEN_STRING;
1211 parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
1214 for (i = 0; i < 5; i++)
1216 rc_style->color_flags[i] = parent_style->color_flags[i];
1217 rc_style->fg[i] = parent_style->fg[i];
1218 rc_style->bg[i] = parent_style->bg[i];
1219 rc_style->text[i] = parent_style->text[i];
1220 rc_style->base[i] = parent_style->base[i];
1223 if (parent_style->fontset_name)
1225 if (rc_style->fontset_name)
1226 g_free (rc_style->fontset_name);
1227 rc_style->fontset_name = g_strdup (parent_style->fontset_name);
1229 else if (parent_style->font_name)
1231 if (rc_style->font_name)
1232 g_free (rc_style->font_name);
1233 rc_style->font_name = g_strdup (parent_style->font_name);
1236 for (i = 0; i < 5; i++)
1238 if (rc_style->bg_pixmap_name[i])
1239 g_free (rc_style->bg_pixmap_name[i]);
1240 rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
1245 token = g_scanner_get_next_token (scanner);
1246 if (token != G_TOKEN_LEFT_CURLY)
1251 return G_TOKEN_LEFT_CURLY;
1254 token = g_scanner_peek_next_token (scanner);
1255 while (token != G_TOKEN_RIGHT_CURLY)
1259 case GTK_RC_TOKEN_BASE:
1260 token = gtk_rc_parse_base (scanner, rc_style);
1262 case GTK_RC_TOKEN_BG:
1263 token = gtk_rc_parse_bg (scanner, rc_style);
1265 case GTK_RC_TOKEN_FG:
1266 token = gtk_rc_parse_fg (scanner, rc_style);
1268 case GTK_RC_TOKEN_TEXT:
1269 token = gtk_rc_parse_text (scanner, rc_style);
1271 case GTK_RC_TOKEN_BG_PIXMAP:
1272 token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
1274 case GTK_RC_TOKEN_FONT:
1275 token = gtk_rc_parse_font (scanner, rc_style);
1277 case GTK_RC_TOKEN_FONTSET:
1278 token = gtk_rc_parse_fontset (scanner, rc_style);
1280 case GTK_RC_TOKEN_ENGINE:
1281 token = gtk_rc_parse_engine (scanner, rc_style);
1284 g_scanner_get_next_token (scanner);
1285 token = G_TOKEN_RIGHT_CURLY;
1289 if (token != G_TOKEN_NONE)
1293 if (rc_style->fontset_name)
1294 g_free (rc_style->fontset_name);
1295 if (rc_style->font_name)
1296 g_free (rc_style->font_name);
1297 for (i = 0; i < 5; i++)
1298 if (rc_style->bg_pixmap_name[i])
1299 g_free (rc_style->bg_pixmap_name[i]);
1304 token = g_scanner_peek_next_token (scanner);
1307 token = g_scanner_get_next_token (scanner);
1308 if (token != G_TOKEN_RIGHT_CURLY)
1312 if (rc_style->fontset_name)
1313 g_free (rc_style->fontset_name);
1314 if (rc_style->font_name)
1315 g_free (rc_style->font_name);
1317 for (i = 0; i < 5; i++)
1318 if (rc_style->bg_pixmap_name[i])
1319 g_free (rc_style->bg_pixmap_name[i]);
1323 return G_TOKEN_RIGHT_CURLY;
1327 g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
1329 return G_TOKEN_NONE;
1333 gtk_rc_parse_base (GScanner *scanner,
1339 token = g_scanner_get_next_token (scanner);
1340 if (token != GTK_RC_TOKEN_BASE)
1341 return GTK_RC_TOKEN_BASE;
1343 token = gtk_rc_parse_state (scanner, &state);
1344 if (token != G_TOKEN_NONE)
1347 token = g_scanner_get_next_token (scanner);
1348 if (token != G_TOKEN_EQUAL_SIGN)
1349 return G_TOKEN_EQUAL_SIGN;
1351 style->color_flags[state] |= GTK_RC_BASE;
1352 return gtk_rc_parse_color (scanner, &style->base[state]);
1356 gtk_rc_parse_bg (GScanner *scanner,
1362 token = g_scanner_get_next_token (scanner);
1363 if (token != GTK_RC_TOKEN_BG)
1364 return GTK_RC_TOKEN_BG;
1366 token = gtk_rc_parse_state (scanner, &state);
1367 if (token != G_TOKEN_NONE)
1370 token = g_scanner_get_next_token (scanner);
1371 if (token != G_TOKEN_EQUAL_SIGN)
1372 return G_TOKEN_EQUAL_SIGN;
1374 style->color_flags[state] |= GTK_RC_BG;
1375 return gtk_rc_parse_color (scanner, &style->bg[state]);
1379 gtk_rc_parse_fg (GScanner *scanner,
1385 token = g_scanner_get_next_token (scanner);
1386 if (token != GTK_RC_TOKEN_FG)
1387 return GTK_RC_TOKEN_FG;
1389 token = gtk_rc_parse_state (scanner, &state);
1390 if (token != G_TOKEN_NONE)
1393 token = g_scanner_get_next_token (scanner);
1394 if (token != G_TOKEN_EQUAL_SIGN)
1395 return G_TOKEN_EQUAL_SIGN;
1397 style->color_flags[state] |= GTK_RC_FG;
1398 return gtk_rc_parse_color (scanner, &style->fg[state]);
1402 gtk_rc_parse_text (GScanner *scanner,
1408 token = g_scanner_get_next_token (scanner);
1409 if (token != GTK_RC_TOKEN_TEXT)
1410 return GTK_RC_TOKEN_TEXT;
1412 token = gtk_rc_parse_state (scanner, &state);
1413 if (token != G_TOKEN_NONE)
1416 token = g_scanner_get_next_token (scanner);
1417 if (token != G_TOKEN_EQUAL_SIGN)
1418 return G_TOKEN_EQUAL_SIGN;
1420 style->color_flags[state] |= GTK_RC_TEXT;
1421 return gtk_rc_parse_color (scanner, &style->text[state]);
1425 gtk_rc_parse_bg_pixmap (GScanner *scanner,
1426 GtkRcStyle *rc_style)
1432 token = g_scanner_get_next_token (scanner);
1433 if (token != GTK_RC_TOKEN_BG_PIXMAP)
1434 return GTK_RC_TOKEN_BG_PIXMAP;
1436 token = gtk_rc_parse_state (scanner, &state);
1437 if (token != G_TOKEN_NONE)
1440 token = g_scanner_get_next_token (scanner);
1441 if (token != G_TOKEN_EQUAL_SIGN)
1442 return G_TOKEN_EQUAL_SIGN;
1444 token = g_scanner_get_next_token (scanner);
1445 if (token != G_TOKEN_STRING)
1446 return G_TOKEN_STRING;
1448 if (strcmp (scanner->value.v_string, "<parent>"))
1449 pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
1451 pixmap_file = g_strdup (scanner->value.v_string);
1455 if (rc_style->bg_pixmap_name[state])
1456 g_free (rc_style->bg_pixmap_name[state]);
1457 rc_style->bg_pixmap_name[state] = pixmap_file;
1460 return G_TOKEN_NONE;
1464 gtk_rc_find_pixmap_in_path (GScanner *scanner,
1465 const gchar *pixmap_file)
1471 for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
1473 buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
1474 sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
1476 fd = open (buf, O_RDONLY);
1487 g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
1488 pixmap_file, scanner->line);
1490 g_warning ("Unable to locate image file in pixmap_path: \"%s\"",
1497 gtk_rc_find_module_in_path (const gchar *module_file)
1503 for (i = 0; (i < GTK_RC_MAX_MODULE_PATHS) && (module_path[i] != NULL); i++)
1505 buf = g_malloc (strlen (module_path[i]) + strlen (module_file) + 2);
1506 sprintf (buf, "%s%c%s", module_path[i], '/', module_file);
1508 fd = open (buf, O_RDONLY);
1522 gtk_rc_parse_font (GScanner *scanner,
1523 GtkRcStyle *rc_style)
1527 token = g_scanner_get_next_token (scanner);
1528 if (token != GTK_RC_TOKEN_FONT)
1529 return GTK_RC_TOKEN_FONT;
1531 token = g_scanner_get_next_token (scanner);
1532 if (token != G_TOKEN_EQUAL_SIGN)
1533 return G_TOKEN_EQUAL_SIGN;
1535 token = g_scanner_get_next_token (scanner);
1536 if (token != G_TOKEN_STRING)
1537 return G_TOKEN_STRING;
1539 if (rc_style->font_name)
1540 g_free (rc_style->font_name);
1541 rc_style->font_name = g_strdup (scanner->value.v_string);
1543 return G_TOKEN_NONE;
1547 gtk_rc_parse_fontset (GScanner *scanner,
1548 GtkRcStyle *rc_style)
1552 token = g_scanner_get_next_token (scanner);
1553 if (token != GTK_RC_TOKEN_FONTSET)
1554 return GTK_RC_TOKEN_FONTSET;
1556 token = g_scanner_get_next_token (scanner);
1557 if (token != G_TOKEN_EQUAL_SIGN)
1558 return G_TOKEN_EQUAL_SIGN;
1560 token = g_scanner_get_next_token (scanner);
1561 if (token != G_TOKEN_STRING)
1562 return G_TOKEN_STRING;
1564 if (rc_style->fontset_name)
1565 g_free (rc_style->fontset_name);
1566 rc_style->fontset_name = g_strdup (scanner->value.v_string);
1568 return G_TOKEN_NONE;
1572 gtk_rc_parse_engine (GScanner *scanner,
1573 GtkRcStyle *rc_style)
1577 token = g_scanner_get_next_token (scanner);
1578 if (token != GTK_RC_TOKEN_ENGINE)
1579 return GTK_RC_TOKEN_ENGINE;
1581 token = g_scanner_get_next_token (scanner);
1582 if (token != G_TOKEN_STRING)
1583 return G_TOKEN_STRING;
1585 rc_style->engine = gtk_theme_engine_get (scanner->value.v_string);
1587 token = g_scanner_get_next_token (scanner);
1588 if (token != G_TOKEN_LEFT_CURLY)
1589 return G_TOKEN_LEFT_CURLY;
1591 if (rc_style->engine)
1592 return rc_style->engine->parse_rc_style (scanner, rc_style);
1595 /* Skip over remainder, looking for nested {}'s */
1598 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
1600 if (token == G_TOKEN_LEFT_CURLY)
1602 else if (token == G_TOKEN_RIGHT_CURLY)
1606 return G_TOKEN_NONE;
1609 return G_TOKEN_RIGHT_CURLY;
1614 gtk_rc_parse_state (GScanner *scanner,
1615 GtkStateType *state)
1620 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1621 g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
1623 /* we don't know where we got called from, so we reset the scope here.
1624 * if we bail out due to errors, we *don't* reset the scope, so the
1625 * error messaging code can make sense of our tokens.
1627 old_scope = g_scanner_set_scope (scanner, 0);
1629 token = g_scanner_get_next_token (scanner);
1630 if (token != G_TOKEN_LEFT_BRACE)
1631 return G_TOKEN_LEFT_BRACE;
1633 token = g_scanner_get_next_token (scanner);
1636 case GTK_RC_TOKEN_ACTIVE:
1637 *state = GTK_STATE_ACTIVE;
1639 case GTK_RC_TOKEN_INSENSITIVE:
1640 *state = GTK_STATE_INSENSITIVE;
1642 case GTK_RC_TOKEN_NORMAL:
1643 *state = GTK_STATE_NORMAL;
1645 case GTK_RC_TOKEN_PRELIGHT:
1646 *state = GTK_STATE_PRELIGHT;
1648 case GTK_RC_TOKEN_SELECTED:
1649 *state = GTK_STATE_SELECTED;
1652 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
1655 token = g_scanner_get_next_token (scanner);
1656 if (token != G_TOKEN_RIGHT_BRACE)
1657 return G_TOKEN_RIGHT_BRACE;
1659 g_scanner_set_scope (scanner, old_scope);
1661 return G_TOKEN_NONE;
1665 gtk_rc_parse_priority (GScanner *scanner,
1666 GtkPathPriorityType *priority)
1671 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1672 g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
1674 /* we don't know where we got called from, so we reset the scope here.
1675 * if we bail out due to errors, we *don't* reset the scope, so the
1676 * error messaging code can make sense of our tokens.
1678 old_scope = g_scanner_set_scope (scanner, 0);
1680 token = g_scanner_get_next_token (scanner);
1684 token = g_scanner_get_next_token (scanner);
1687 case GTK_RC_TOKEN_LOWEST:
1688 *priority = GTK_PATH_PRIO_LOWEST;
1690 case GTK_RC_TOKEN_GTK:
1691 *priority = GTK_PATH_PRIO_GTK;
1693 case GTK_RC_TOKEN_APPLICATION:
1694 *priority = GTK_PATH_PRIO_APPLICATION;
1696 case GTK_RC_TOKEN_RC:
1697 *priority = GTK_PATH_PRIO_RC;
1699 case GTK_RC_TOKEN_HIGHEST:
1700 *priority = GTK_PATH_PRIO_HIGHEST;
1703 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
1706 g_scanner_set_scope (scanner, old_scope);
1708 return G_TOKEN_NONE;
1712 gtk_rc_parse_color (GScanner *scanner,
1717 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1719 /* we don't need to set our own scop here, because
1720 * we don't need own symbols
1723 token = g_scanner_get_next_token (scanner);
1732 case G_TOKEN_LEFT_CURLY:
1733 token = g_scanner_get_next_token (scanner);
1734 if (token == G_TOKEN_INT)
1735 token_int = scanner->value.v_int;
1736 else if (token == G_TOKEN_FLOAT)
1737 token_int = scanner->value.v_float * 65535.0;
1739 return G_TOKEN_FLOAT;
1740 color->red = CLAMP (token_int, 0, 65535);
1742 token = g_scanner_get_next_token (scanner);
1743 if (token != G_TOKEN_COMMA)
1744 return G_TOKEN_COMMA;
1746 token = g_scanner_get_next_token (scanner);
1747 if (token == G_TOKEN_INT)
1748 token_int = scanner->value.v_int;
1749 else if (token == G_TOKEN_FLOAT)
1750 token_int = scanner->value.v_float * 65535.0;
1752 return G_TOKEN_FLOAT;
1753 color->green = CLAMP (token_int, 0, 65535);
1755 token = g_scanner_get_next_token (scanner);
1756 if (token != G_TOKEN_COMMA)
1757 return G_TOKEN_COMMA;
1759 token = g_scanner_get_next_token (scanner);
1760 if (token == G_TOKEN_INT)
1761 token_int = scanner->value.v_int;
1762 else if (token == G_TOKEN_FLOAT)
1763 token_int = scanner->value.v_float * 65535.0;
1765 return G_TOKEN_FLOAT;
1766 color->blue = CLAMP (token_int, 0, 65535);
1768 token = g_scanner_get_next_token (scanner);
1769 if (token != G_TOKEN_RIGHT_CURLY)
1770 return G_TOKEN_RIGHT_CURLY;
1771 return G_TOKEN_NONE;
1773 case G_TOKEN_STRING:
1774 if (scanner->value.v_string[0] != '#')
1775 return G_TOKEN_STRING;
1777 length = strlen (scanner->value.v_string) - 1;
1778 if (((length % 3) != 0) || (length > 12))
1779 return G_TOKEN_STRING;
1782 for (i = 0, j = 1; i < length; i++, j++)
1783 buf[i] = scanner->value.v_string[j];
1786 sscanf (buf, "%x", &temp);
1789 for (i = 0; i < length; i++, j++)
1790 buf[i] = scanner->value.v_string[j];
1793 sscanf (buf, "%x", &temp);
1794 color->green = temp;
1796 for (i = 0; i < length; i++, j++)
1797 buf[i] = scanner->value.v_string[j];
1800 sscanf (buf, "%x", &temp);
1806 color->green *= 4369;
1807 color->blue *= 4369;
1809 else if (length == 2)
1812 color->green *= 257;
1815 else if (length == 3)
1821 return G_TOKEN_NONE;
1824 return G_TOKEN_STRING;
1829 gtk_rc_parse_pixmap_path (GScanner *scanner)
1833 token = g_scanner_get_next_token (scanner);
1834 if (token != GTK_RC_TOKEN_PIXMAP_PATH)
1835 return GTK_RC_TOKEN_PIXMAP_PATH;
1837 token = g_scanner_get_next_token (scanner);
1838 if (token != G_TOKEN_STRING)
1839 return G_TOKEN_STRING;
1841 gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
1843 return G_TOKEN_NONE;
1847 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
1851 gint start_offset = 0;
1855 /* free the old one, or just add to the old one ? */
1856 for (path_num=0; pixmap_path[path_num]; path_num++)
1858 g_free (pixmap_path[path_num]);
1859 pixmap_path[path_num] = NULL;
1864 path_len = strlen (pix_path);
1866 buf = g_strdup (pix_path);
1868 for (end_offset = 0; end_offset <= path_len; end_offset++)
1870 if ((buf[end_offset] == ':') ||
1871 (end_offset == path_len))
1873 buf[end_offset] = '\0';
1874 pixmap_path[path_num] = g_strdup (buf + start_offset);
1876 pixmap_path[path_num] = NULL;
1877 start_offset = end_offset + 1;
1881 gtk_rc_append_default_pixmap_path();
1885 gtk_rc_parse_module_path (GScanner *scanner)
1889 token = g_scanner_get_next_token (scanner);
1890 if (token != GTK_RC_TOKEN_MODULE_PATH)
1891 return GTK_RC_TOKEN_MODULE_PATH;
1893 token = g_scanner_get_next_token (scanner);
1894 if (token != G_TOKEN_STRING)
1895 return G_TOKEN_STRING;
1897 gtk_rc_parse_module_path_string (scanner->value.v_string);
1899 return G_TOKEN_NONE;
1903 gtk_rc_parse_module_path_string (gchar *mod_path)
1907 gint start_offset = 0;
1911 /* free the old one, or just add to the old one ? */
1912 for (path_num=0; module_path[path_num]; path_num++)
1914 g_free (module_path[path_num]);
1915 module_path[path_num] = NULL;
1920 path_len = strlen (mod_path);
1922 buf = g_strdup (mod_path);
1924 for (end_offset = 0; end_offset <= path_len; end_offset++)
1926 if ((buf[end_offset] == ':') ||
1927 (end_offset == path_len))
1929 buf[end_offset] = '\0';
1930 module_path[path_num] = g_strdup (buf + start_offset);
1932 module_path[path_num] = NULL;
1933 start_offset = end_offset + 1;
1937 gtk_rc_append_default_module_path();
1941 gtk_rc_parse_path_pattern (GScanner *scanner)
1944 GtkPathType path_type;
1946 gboolean is_binding;
1947 GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
1949 token = g_scanner_get_next_token (scanner);
1952 case GTK_RC_TOKEN_WIDGET:
1953 path_type = GTK_PATH_WIDGET;
1955 case GTK_RC_TOKEN_WIDGET_CLASS:
1956 path_type = GTK_PATH_WIDGET_CLASS;
1958 case GTK_RC_TOKEN_CLASS:
1959 path_type = GTK_PATH_CLASS;
1962 return GTK_RC_TOKEN_WIDGET_CLASS;
1965 token = g_scanner_get_next_token (scanner);
1966 if (token != G_TOKEN_STRING)
1967 return G_TOKEN_STRING;
1969 pattern = g_strdup (scanner->value.v_string);
1971 token = g_scanner_get_next_token (scanner);
1972 if (token == GTK_RC_TOKEN_STYLE)
1974 else if (token == GTK_RC_TOKEN_BINDING)
1977 if (g_scanner_peek_next_token (scanner) == ':')
1979 token = gtk_rc_parse_priority (scanner, &priority);
1980 if (token != G_TOKEN_NONE)
1990 return GTK_RC_TOKEN_STYLE;
1993 token = g_scanner_get_next_token (scanner);
1994 if (token != G_TOKEN_STRING)
1997 return G_TOKEN_STRING;
2002 GtkBindingSet *binding;
2004 binding = gtk_binding_set_find (scanner->value.v_string);
2008 return G_TOKEN_STRING;
2010 gtk_binding_set_add_path (binding, path_type, pattern, priority);
2014 GtkRcStyle *rc_style;
2017 rc_style = gtk_rc_style_find (scanner->value.v_string);
2022 return G_TOKEN_STRING;
2025 rc_set = g_new (GtkRcSet, 1);
2026 gtk_pattern_spec_init (&rc_set->pspec, pattern);
2027 rc_set->rc_style = rc_style;
2029 if (path_type == GTK_PATH_WIDGET)
2030 gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
2031 else if (path_type == GTK_PATH_WIDGET_CLASS)
2032 gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
2034 gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
2038 return G_TOKEN_NONE;
2042 typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
2043 GdkColormap *colormap,
2045 GdkColor *transparent_color,
2046 const gchar *filename);
2050 gtk_rc_set_image_loader(GtkImageLoader loader)
2052 image_loader = loader;
2056 gtk_rc_load_image (GdkColormap *colormap,
2057 GdkColor *transparent_color,
2058 const gchar *filename)
2060 if (strcmp (filename, "<parent>") == 0)
2061 return (GdkPixmap*) GDK_PARENT_RELATIVE;
2065 return image_loader(NULL, colormap, NULL,
2069 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,