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>
27 #include "gtkbindings.h"
28 #include "gtkthemes.h"
30 typedef struct _GtkRcSet GtkRcSet;
31 typedef struct _GtkRcNode GtkRcNode;
32 typedef struct _GtkRcFile GtkRcFile;
44 gchar *canonical_name;
48 static guint gtk_rc_style_hash (const char *name);
49 static gint gtk_rc_style_compare (const char *a,
51 static guint gtk_rc_styles_hash (const GSList *rc_styles);
52 static gint gtk_rc_styles_compare (const GSList *a,
54 static GtkRcStyle* gtk_rc_style_find (const char *name);
55 static GSList * gtk_rc_styles_match (GSList *rc_styles,
59 gchar *path_reversed);
60 static GtkStyle * gtk_rc_style_to_style (GtkRcStyle *rc_style);
61 static GtkStyle* gtk_rc_style_init (GSList *rc_styles);
62 static void gtk_rc_parse_file (const gchar *filename,
65 static void gtk_rc_parse_any (const gchar *input_name,
67 const gchar *input_string);
68 static guint gtk_rc_parse_statement (GScanner *scanner);
69 static guint gtk_rc_parse_style (GScanner *scanner);
70 static guint gtk_rc_parse_base (GScanner *scanner,
72 static guint gtk_rc_parse_bg (GScanner *scanner,
74 static guint gtk_rc_parse_fg (GScanner *scanner,
76 static guint gtk_rc_parse_text (GScanner *scanner,
78 static guint gtk_rc_parse_bg_pixmap (GScanner *scanner,
79 GtkRcStyle *rc_style);
80 static guint gtk_rc_parse_font (GScanner *scanner,
81 GtkRcStyle *rc_style);
82 static guint gtk_rc_parse_fontset (GScanner *scanner,
83 GtkRcStyle *rc_style);
84 static guint gtk_rc_parse_engine (GScanner *scanner,
85 GtkRcStyle *rc_style);
86 static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
87 static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
88 static guint gtk_rc_parse_module_path (GScanner *scanner);
89 static void gtk_rc_parse_module_path_string (gchar *mod_path);
90 static guint gtk_rc_parse_path_pattern (GScanner *scanner);
91 static void gtk_rc_clear_hash_node (gpointer key,
94 static void gtk_rc_clear_styles (void);
95 static void gtk_rc_append_default_pixmap_path (void);
96 static void gtk_rc_append_default_module_path (void);
97 static void gtk_rc_append_pixmap_path (gchar *dir);
100 static const GScannerConfig gtk_rc_scanner_config =
104 ) /* cset_skip_characters */,
109 ) /* cset_identifier_first */,
114 ) /* cset_identifier_nth */,
115 ( "#\n" ) /* cpair_comment_single */,
117 TRUE /* case_sensitive */,
119 TRUE /* skip_comment_multi */,
120 TRUE /* skip_comment_single */,
121 TRUE /* scan_comment_multi */,
122 TRUE /* scan_identifier */,
123 FALSE /* scan_identifier_1char */,
124 FALSE /* scan_identifier_NULL */,
125 TRUE /* scan_symbols */,
126 TRUE /* scan_binary */,
127 TRUE /* scan_octal */,
128 TRUE /* scan_float */,
130 TRUE /* scan_hex_dollar */,
131 TRUE /* scan_string_sq */,
132 TRUE /* scan_string_dq */,
133 TRUE /* numbers_2_int */,
134 FALSE /* int_2_float */,
135 FALSE /* identifier_2_string */,
136 TRUE /* char_2_token */,
137 TRUE /* symbol_2_token */,
138 FALSE /* scope_0_fallback */,
146 { "include", GTK_RC_TOKEN_INCLUDE },
147 { "NORMAL", GTK_RC_TOKEN_NORMAL },
148 { "ACTIVE", GTK_RC_TOKEN_ACTIVE },
149 { "PRELIGHT", GTK_RC_TOKEN_PRELIGHT },
150 { "SELECTED", GTK_RC_TOKEN_SELECTED },
151 { "INSENSITIVE", GTK_RC_TOKEN_INSENSITIVE },
152 { "fg", GTK_RC_TOKEN_FG },
153 { "bg", GTK_RC_TOKEN_BG },
154 { "base", GTK_RC_TOKEN_BASE },
155 { "text", GTK_RC_TOKEN_TEXT },
156 { "font", GTK_RC_TOKEN_FONT },
157 { "fontset", GTK_RC_TOKEN_FONTSET },
158 { "bg_pixmap", GTK_RC_TOKEN_BG_PIXMAP },
159 { "pixmap_path", GTK_RC_TOKEN_PIXMAP_PATH },
160 { "style", GTK_RC_TOKEN_STYLE },
161 { "binding", GTK_RC_TOKEN_BINDING },
162 { "bind", GTK_RC_TOKEN_BIND },
163 { "widget", GTK_RC_TOKEN_WIDGET },
164 { "widget_class", GTK_RC_TOKEN_WIDGET_CLASS },
165 { "class", GTK_RC_TOKEN_CLASS },
166 { "lowest", GTK_RC_TOKEN_LOWEST },
167 { "gtk", GTK_RC_TOKEN_GTK },
168 { "application", GTK_RC_TOKEN_APPLICATION },
169 { "rc", GTK_RC_TOKEN_RC },
170 { "highest", GTK_RC_TOKEN_HIGHEST },
171 { "engine", GTK_RC_TOKEN_ENGINE },
172 { "module_path", GTK_RC_TOKEN_MODULE_PATH },
175 static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
177 static GHashTable *rc_style_ht = NULL;
178 static GHashTable *realized_style_ht = NULL;
179 static GSList *gtk_rc_sets_widget = NULL;
180 static GSList *gtk_rc_sets_widget_class = NULL;
181 static GSList *gtk_rc_sets_class = NULL;
183 #define GTK_RC_MAX_PIXMAP_PATHS 128
184 static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
185 #define GTK_RC_MAX_MODULE_PATHS 128
186 static gchar *module_path[GTK_RC_MAX_MODULE_PATHS];
188 /* The files we have parsed, to reread later if necessary */
189 GSList *rc_files = NULL;
191 static GtkImageLoader image_loader = NULL;
193 /* RC file handling */
197 gtk_rc_get_theme_dir(void)
201 var = getenv("GTK_DATA_PREFIX");
204 path = g_malloc(strlen(var) + strlen("/share/themes") +1);
205 sprintf(path, "%s%s", var, "/share/themes");
209 path = g_malloc(strlen(GTK_DATA_PREFIX) + strlen("/share/themes") +1);
210 sprintf(path, "%s%s", GTK_DATA_PREFIX, "/share/themes");
216 gtk_rc_get_module_dir(void)
220 var = getenv("GTK_EXE_PREFIX");
223 path = g_malloc(strlen(var) + strlen("/lib/gtk/themes/engines") +1);
224 sprintf(path, "%s%s", var, "/lib/gtk/themes/engines");
228 path = g_malloc(strlen(GTK_EXE_PREFIX) + strlen("/lib/gtk/themes/engines") +1);
229 sprintf(path, "%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
235 gtk_rc_append_default_pixmap_path(void)
240 var = getenv("GTK_DATA_PREFIX");
243 path = g_malloc(strlen(var) + strlen("/share/gtk/themes") +1);
244 sprintf(path, "%s%s", var, "/share/gtk/themes");
248 path = g_malloc(strlen(GTK_DATA_PREFIX) + strlen("/share/gtk/themes") +1);
249 sprintf(path, "%s%s", GTK_DATA_PREFIX, "/share/gtk/themes");
252 for (n = 0; pixmap_path[n]; n++) ;
253 if (n >= GTK_RC_MAX_PIXMAP_PATHS - 1)
255 pixmap_path[n++] = g_strdup(path);
256 pixmap_path[n] = NULL;
261 gtk_rc_append_pixmap_path(gchar *dir)
265 for (n = 0; pixmap_path[n]; n++) ;
266 if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
268 pixmap_path[n++] = g_strdup(dir);
269 pixmap_path[n] = NULL;
273 gtk_rc_append_default_module_path(void)
278 for (n = 0; module_path[n]; n++) ;
279 if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
282 var = getenv("GTK_EXE_PREFIX");
285 path = g_malloc(strlen(var) + strlen("/lib/gtk/themes/engines") +1);
286 sprintf(path, "%s%s", var, "/lib/gtk/themes/engines");
290 path = g_malloc(strlen(GTK_EXE_PREFIX) + strlen("/lib/gtk/themes/engines") +1);
291 sprintf(path, "%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
293 module_path[n++] = g_strdup(path);
295 var = getenv("HOME");
298 path = g_malloc(strlen(var) + strlen(".gtk/lib/themes/engines") +1);
299 sprintf(path, "%s%s", var, ".gtk/lib/themes/engines");
301 module_path[n++] = g_strdup(path);
302 module_path[n] = NULL;
309 rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
310 (GCompareFunc) gtk_rc_style_compare);
311 pixmap_path[0] = NULL;
312 module_path[0] = NULL;
313 gtk_rc_append_default_pixmap_path();
314 gtk_rc_append_default_module_path();
318 gtk_rc_parse_string (const gchar *rc_string)
320 g_return_if_fail (rc_string != NULL);
322 gtk_rc_parse_any ("-", -1, rc_string);
326 gtk_rc_parse_file (const gchar *filename, gboolean reload)
328 GtkRcFile *rc_file = NULL;
332 g_return_if_fail (filename != NULL);
337 rc_file = tmp_list->data;
338 if (!strcmp (rc_file->name, filename))
341 tmp_list = tmp_list->next;
346 rc_file = g_new (GtkRcFile, 1);
347 rc_file->name = g_strdup (filename);
348 rc_file->canonical_name = NULL;
350 rc_file->reload = reload;
352 rc_files = g_slist_append (rc_files, rc_file);
355 if (!rc_file->canonical_name)
357 /* Get the absolute pathname */
359 if (rc_file->name[0] == '/')
360 rc_file->canonical_name = rc_file->name;
366 cwd = g_get_current_dir ();
368 str = g_string_new (cwd);
370 g_string_append_c (str, '/');
371 g_string_append (str, rc_file->name);
373 rc_file->canonical_name = str->str;
374 g_string_free (str, FALSE);
378 if (!lstat (rc_file->canonical_name, &statbuf))
382 rc_file->mtime = statbuf.st_mtime;
384 fd = open (rc_file->canonical_name, O_RDONLY);
392 dir = g_strdup(rc_file->canonical_name);
393 for (i = strlen(dir) - 1; (i >= 0) && (dir[i] != '/'); i--)
395 gtk_rc_append_pixmap_path(dir);
398 gtk_rc_parse_any (filename, fd, NULL);
405 gtk_rc_parse (const gchar *filename)
407 g_return_if_fail (filename != NULL);
409 gtk_rc_parse_file (filename, TRUE);
412 /* Handling of RC styles */
415 gtk_rc_style_new (void)
417 GtkRcStyle *new_style;
419 new_style = g_new0 (GtkRcStyle, 1);
420 new_style->ref_count = 1;
426 gtk_rc_style_ref (GtkRcStyle *rc_style)
428 g_return_if_fail (rc_style != NULL);
430 rc_style->ref_count++;
434 gtk_rc_style_unref (GtkRcStyle *rc_style)
438 g_return_if_fail (rc_style != NULL);
440 rc_style->ref_count--;
442 if (rc_style->ref_count == 0)
444 if (rc_style->engine)
446 rc_style->engine->destroy_rc_style (rc_style);
447 gtk_theme_engine_unref (rc_style->engine);
451 g_free (rc_style->name);
452 if (rc_style->fontset_name)
453 g_free (rc_style->fontset_name);
454 if (rc_style->font_name)
455 g_free (rc_style->font_name);
457 for (i=0 ; i<5 ; i++)
458 if (rc_style->bg_pixmap_name[i])
459 g_free (rc_style->bg_pixmap_name[i]);
466 gtk_rc_clear_realized_node (gpointer key,
470 gtk_style_unref (data);
474 gtk_rc_clear_hash_node (gpointer key,
478 gtk_rc_style_unref (data);
482 gtk_rc_free_rc_sets (GSList *slist)
488 rc_set = slist->data;
489 gtk_pattern_spec_free_segs (&rc_set->pspec);
497 gtk_rc_clear_styles (void)
499 /* Clear out all old rc_styles */
503 g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
504 g_hash_table_destroy (rc_style_ht);
508 if (realized_style_ht)
510 g_hash_table_foreach (realized_style_ht, gtk_rc_clear_realized_node, NULL);
511 g_hash_table_destroy (realized_style_ht);
512 realized_style_ht = NULL;
515 gtk_rc_free_rc_sets (gtk_rc_sets_widget);
516 g_slist_free (gtk_rc_sets_widget);
517 gtk_rc_sets_widget = NULL;
519 gtk_rc_free_rc_sets (gtk_rc_sets_widget_class);
520 g_slist_free (gtk_rc_sets_widget_class);
521 gtk_rc_sets_widget_class = NULL;
523 gtk_rc_free_rc_sets (gtk_rc_sets_class);
524 g_slist_free (gtk_rc_sets_class);
525 gtk_rc_sets_class = NULL;
531 gtk_rc_reparse_all (void)
534 gboolean mtime_modified = FALSE;
539 /* Check through and see if any of the RC's have had their
540 * mtime modified. If so, reparse everything.
545 rc_file = tmp_list->data;
547 if (!lstat (rc_file->name, &statbuf) &&
548 (statbuf.st_mtime > rc_file->mtime))
550 mtime_modified = TRUE;
554 tmp_list = tmp_list->next;
559 gtk_rc_clear_styles();
564 rc_file = tmp_list->data;
566 gtk_rc_parse_file (rc_file->name, FALSE);
568 tmp_list = tmp_list->next;
572 return mtime_modified;
576 gtk_rc_styles_match (GSList *rc_styles,
580 gchar *path_reversed)
590 if (gtk_pattern_match (&rc_set->pspec, path_length, path, path_reversed))
591 rc_styles = g_slist_append (rc_styles, rc_set->rc_style);
598 gtk_rc_get_style (GtkWidget *widget)
600 GtkRcStyle *widget_rc_style;
601 GSList *rc_styles = NULL;
603 static guint rc_style_key_id = 0;
605 /* We allow the specification of a single rc style to be bound
606 * tightly to a widget, for application modifications
608 if (!rc_style_key_id)
609 rc_style_key_id = g_quark_from_static_string ("gtk-rc-style");
611 widget_rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
615 rc_styles = g_slist_prepend (rc_styles, widget_rc_style);
617 if (gtk_rc_sets_widget)
619 gchar *path, *path_reversed;
622 gtk_widget_path (widget, &path_length, &path, &path_reversed);
623 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget, path_length, path, path_reversed);
625 g_free (path_reversed);
629 if (gtk_rc_sets_widget_class)
631 gchar *path, *path_reversed;
634 gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
635 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget_class, path_length, path, path_reversed);
637 g_free (path_reversed);
640 if (gtk_rc_sets_class)
644 type = GTK_OBJECT_TYPE (widget);
647 gchar *path, *path_reversed;
650 path = gtk_type_name (type);
651 path_length = strlen (path);
652 path_reversed = g_strdup (path);
653 g_strreverse (path_reversed);
655 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_class, path_length, path, path_reversed);
656 g_free (path_reversed);
658 type = gtk_type_parent (type);
663 return gtk_rc_style_init (rc_styles);
669 gtk_rc_add_rc_sets (GSList *slist,
670 GtkRcStyle *rc_style,
673 GtkRcStyle *new_style;
677 new_style = gtk_rc_style_new ();
678 *new_style = *rc_style;
679 new_style->name = g_strdup (rc_style->name);
680 new_style->font_name = g_strdup (rc_style->font_name);
681 new_style->fontset_name = g_strdup (rc_style->fontset_name);
683 for (i = 0; i < 5; i++)
684 new_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
686 rc_set = g_new (GtkRcSet, 1);
687 gtk_pattern_spec_init (&rc_set->pspec, pattern);
688 rc_set->rc_style = rc_style;
690 return g_slist_prepend (slist, rc_set);
694 gtk_rc_add_widget_name_style (GtkRcStyle *rc_style,
695 const gchar *pattern)
697 g_return_if_fail (rc_style != NULL);
698 g_return_if_fail (pattern != NULL);
700 gtk_rc_sets_widget = gtk_rc_add_rc_sets (gtk_rc_sets_widget, rc_style, pattern);
704 gtk_rc_add_widget_class_style (GtkRcStyle *rc_style,
705 const gchar *pattern)
707 g_return_if_fail (rc_style != NULL);
708 g_return_if_fail (pattern != NULL);
710 gtk_rc_sets_widget_class = gtk_rc_add_rc_sets (gtk_rc_sets_widget_class, rc_style, pattern);
714 gtk_rc_add_class_style (GtkRcStyle *rc_style,
715 const gchar *pattern)
717 g_return_if_fail (rc_style != NULL);
718 g_return_if_fail (pattern != NULL);
720 gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
724 gtk_rc_parse_any (const gchar *input_name,
726 const gchar *input_string)
732 scanner = g_scanner_new (>k_rc_scanner_config);
736 g_assert (input_string == NULL);
738 g_scanner_input_file (scanner, input_fd);
742 g_assert (input_string != NULL);
744 g_scanner_input_text (scanner, input_string, strlen (input_string));
746 scanner->input_name = input_name;
748 g_scanner_freeze_symbol_table (scanner);
749 for (i = 0; i < n_symbols; i++)
750 g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
751 g_scanner_thaw_symbol_table (scanner);
756 if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
760 guint expected_token;
762 expected_token = gtk_rc_parse_statement (scanner);
764 if (expected_token != G_TOKEN_NONE)
771 if (scanner->scope_id == 0)
773 /* if we are in scope 0, we know the symbol names
774 * that are associated with certaintoken values.
775 * so we look them up to make the error messages
778 if (expected_token > GTK_RC_TOKEN_INVALID &&
779 expected_token < GTK_RC_TOKEN_LAST)
781 for (i = 0; i < n_symbols; i++)
782 if (symbols[i].token == expected_token)
783 msg = symbols[i].name;
785 msg = g_strconcat ("e.g. `", msg, "'", NULL);
787 if (scanner->token > GTK_RC_TOKEN_INVALID &&
788 scanner->token < GTK_RC_TOKEN_LAST)
791 for (i = 0; i < n_symbols; i++)
792 if (symbols[i].token == scanner->token)
793 symbol_name = symbols[i].name;
796 g_scanner_unexp_token (scanner,
809 g_scanner_destroy (scanner);
813 gtk_rc_styles_hash (const GSList *rc_styles)
820 result += (result << 9) + GPOINTER_TO_UINT (rc_styles->data);
821 rc_styles = rc_styles->next;
828 gtk_rc_styles_compare (const GSList *a,
833 if (a->data != b->data)
843 gtk_rc_style_hash (const char *name)
849 result += (result << 3) + *name++;
855 gtk_rc_style_compare (const char *a,
858 return (strcmp (a, b) == 0);
862 gtk_rc_style_find (const char *name)
864 GtkRcStyle *rc_style;
866 rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
871 /* Assumes ownership of rc_style */
873 gtk_rc_style_to_style (GtkRcStyle *rc_style)
879 style = gtk_style_new ();
881 style->rc_style = rc_style;
883 if (rc_style->fontset_name)
885 old_font = style->font;
886 style->font = gdk_fontset_load (rc_style->fontset_name);
888 gdk_font_unref (old_font);
890 style->font = old_font;
892 else if (rc_style->font_name)
894 old_font = style->font;
895 style->font = gdk_font_load (rc_style->font_name);
897 gdk_font_unref (old_font);
899 style->font = old_font;
902 for (i = 0; i < 5; i++)
904 if (rc_style->color_flags[i] & GTK_RC_FG)
905 style->fg[i] = rc_style->fg[i];
906 if (rc_style->color_flags[i] & GTK_RC_BG)
907 style->bg[i] = rc_style->bg[i];
908 if (rc_style->color_flags[i] & GTK_RC_TEXT)
909 style->text[i] = rc_style->text[i];
910 if (rc_style->color_flags[i] & GTK_RC_BASE)
911 style->base[i] = rc_style->base[i];
914 if (rc_style->engine)
916 style->engine = rc_style->engine;
917 gtk_theme_engine_ref (style->engine);
918 rc_style->engine->rc_style_to_style (style, rc_style);
924 /* Reuses or frees rc_styles */
926 gtk_rc_style_init (GSList *rc_styles)
930 GtkStyle *style = NULL;
931 GtkRcStyle *proto_style;
933 if (!realized_style_ht)
934 realized_style_ht = g_hash_table_new ((GHashFunc)gtk_rc_styles_hash,
935 (GCompareFunc)gtk_rc_styles_compare);
937 style = g_hash_table_lookup (realized_style_ht, rc_styles);
941 GSList *tmp_styles = rc_styles;
943 proto_style = gtk_rc_style_new ();
947 GtkRcStyle *rc_style = tmp_styles->data;
951 if (!proto_style->bg_pixmap_name[i] && rc_style->bg_pixmap_name[i])
952 proto_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
954 if (!(proto_style->color_flags[i] & GTK_RC_FG) &&
955 rc_style->color_flags[i] & GTK_RC_FG)
957 proto_style->fg[i] = rc_style->fg[i];
958 proto_style->color_flags[i] |= GTK_RC_FG;
960 if (!(proto_style->color_flags[i] & GTK_RC_BG) &&
961 rc_style->color_flags[i] & GTK_RC_BG)
963 proto_style->bg[i] = rc_style->bg[i];
964 proto_style->color_flags[i] |= GTK_RC_BG;
966 if (!(proto_style->color_flags[i] & GTK_RC_TEXT) &&
967 rc_style->color_flags[i] & GTK_RC_TEXT)
969 proto_style->text[i] = rc_style->text[i];
970 proto_style->color_flags[i] |= GTK_RC_TEXT;
972 if (!(proto_style->color_flags[i] & GTK_RC_BASE) &&
973 rc_style->color_flags[i] & GTK_RC_BASE)
975 proto_style->base[i] = rc_style->base[i];
976 proto_style->color_flags[i] |= GTK_RC_BASE;
980 if (!proto_style->font_name && rc_style->font_name)
981 proto_style->font_name = g_strdup (rc_style->font_name);
982 if (!proto_style->fontset_name && rc_style->fontset_name)
983 proto_style->fontset_name = g_strdup (rc_style->fontset_name);
985 if (!proto_style->engine && rc_style->engine)
987 proto_style->engine = rc_style->engine;
988 gtk_theme_engine_ref (proto_style->engine);
991 if (proto_style->engine &&
992 (proto_style->engine == rc_style->engine))
993 proto_style->engine->merge_rc_style (proto_style, rc_style);
995 tmp_styles = tmp_styles->next;
998 style = gtk_rc_style_to_style (proto_style);
1000 g_hash_table_insert (realized_style_ht, rc_styles, style);
1006 /*********************
1007 * Parsing functions *
1008 *********************/
1011 gtk_rc_parse_statement (GScanner *scanner)
1015 token = g_scanner_peek_next_token (scanner);
1019 case GTK_RC_TOKEN_INCLUDE:
1020 token = g_scanner_get_next_token (scanner);
1021 if (token != GTK_RC_TOKEN_INCLUDE)
1022 return GTK_RC_TOKEN_INCLUDE;
1024 token = g_scanner_get_next_token (scanner);
1025 if (token != G_TOKEN_STRING)
1026 return G_TOKEN_STRING;
1028 gtk_rc_parse_file (scanner->value.v_string, FALSE);
1029 return G_TOKEN_NONE;
1031 case GTK_RC_TOKEN_STYLE:
1032 return gtk_rc_parse_style (scanner);
1034 case GTK_RC_TOKEN_BINDING:
1035 return gtk_binding_parse_binding (scanner);
1037 case GTK_RC_TOKEN_PIXMAP_PATH:
1038 return gtk_rc_parse_pixmap_path (scanner);
1040 case GTK_RC_TOKEN_WIDGET:
1041 return gtk_rc_parse_path_pattern (scanner);
1043 case GTK_RC_TOKEN_WIDGET_CLASS:
1044 return gtk_rc_parse_path_pattern (scanner);
1046 case GTK_RC_TOKEN_CLASS:
1047 return gtk_rc_parse_path_pattern (scanner);
1049 case GTK_RC_TOKEN_MODULE_PATH:
1050 return gtk_rc_parse_module_path (scanner);
1053 g_scanner_get_next_token (scanner);
1054 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
1059 gtk_rc_parse_style (GScanner *scanner)
1061 GtkRcStyle *rc_style;
1062 GtkRcStyle *parent_style;
1067 token = g_scanner_get_next_token (scanner);
1068 if (token != GTK_RC_TOKEN_STYLE)
1069 return GTK_RC_TOKEN_STYLE;
1071 token = g_scanner_get_next_token (scanner);
1072 if (token != G_TOKEN_STRING)
1073 return G_TOKEN_STRING;
1076 rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
1081 rc_style = gtk_rc_style_new ();
1082 rc_style->name = g_strdup (scanner->value.v_string);
1084 for (i = 0; i < 5; i++)
1085 rc_style->bg_pixmap_name[i] = NULL;
1087 for (i = 0; i < 5; i++)
1088 rc_style->color_flags[i] = 0;
1090 rc_style->engine = NULL;
1091 rc_style->engine_data = NULL;
1094 token = g_scanner_peek_next_token (scanner);
1095 if (token == G_TOKEN_EQUAL_SIGN)
1097 token = g_scanner_get_next_token (scanner);
1099 token = g_scanner_get_next_token (scanner);
1100 if (token != G_TOKEN_STRING)
1105 return G_TOKEN_STRING;
1108 parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
1111 for (i = 0; i < 5; i++)
1113 rc_style->color_flags[i] = parent_style->color_flags[i];
1114 rc_style->fg[i] = parent_style->fg[i];
1115 rc_style->bg[i] = parent_style->bg[i];
1116 rc_style->text[i] = parent_style->text[i];
1117 rc_style->base[i] = parent_style->base[i];
1120 if (parent_style->fontset_name)
1122 if (rc_style->fontset_name)
1123 g_free (rc_style->fontset_name);
1124 rc_style->fontset_name = g_strdup (parent_style->fontset_name);
1126 else if (parent_style->font_name)
1128 if (rc_style->font_name)
1129 g_free (rc_style->font_name);
1130 rc_style->font_name = g_strdup (parent_style->font_name);
1133 for (i = 0; i < 5; i++)
1135 if (rc_style->bg_pixmap_name[i])
1136 g_free (rc_style->bg_pixmap_name[i]);
1137 rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
1142 token = g_scanner_get_next_token (scanner);
1143 if (token != G_TOKEN_LEFT_CURLY)
1148 return G_TOKEN_LEFT_CURLY;
1151 token = g_scanner_peek_next_token (scanner);
1152 while (token != G_TOKEN_RIGHT_CURLY)
1156 case GTK_RC_TOKEN_BASE:
1157 token = gtk_rc_parse_base (scanner, rc_style);
1159 case GTK_RC_TOKEN_BG:
1160 token = gtk_rc_parse_bg (scanner, rc_style);
1162 case GTK_RC_TOKEN_FG:
1163 token = gtk_rc_parse_fg (scanner, rc_style);
1165 case GTK_RC_TOKEN_TEXT:
1166 token = gtk_rc_parse_text (scanner, rc_style);
1168 case GTK_RC_TOKEN_BG_PIXMAP:
1169 token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
1171 case GTK_RC_TOKEN_FONT:
1172 token = gtk_rc_parse_font (scanner, rc_style);
1174 case GTK_RC_TOKEN_FONTSET:
1175 token = gtk_rc_parse_fontset (scanner, rc_style);
1177 case GTK_RC_TOKEN_ENGINE:
1178 token = gtk_rc_parse_engine (scanner, rc_style);
1181 g_scanner_get_next_token (scanner);
1182 token = G_TOKEN_RIGHT_CURLY;
1186 if (token != G_TOKEN_NONE)
1190 if (rc_style->fontset_name)
1191 g_free (rc_style->fontset_name);
1192 if (rc_style->font_name)
1193 g_free (rc_style->font_name);
1194 for (i = 0; i < 5; i++)
1195 if (rc_style->bg_pixmap_name[i])
1196 g_free (rc_style->bg_pixmap_name[i]);
1201 token = g_scanner_peek_next_token (scanner);
1204 token = g_scanner_get_next_token (scanner);
1205 if (token != G_TOKEN_RIGHT_CURLY)
1209 if (rc_style->fontset_name)
1210 g_free (rc_style->fontset_name);
1211 if (rc_style->font_name)
1212 g_free (rc_style->font_name);
1214 for (i = 0; i < 5; i++)
1215 if (rc_style->bg_pixmap_name[i])
1216 g_free (rc_style->bg_pixmap_name[i]);
1220 return G_TOKEN_RIGHT_CURLY;
1224 g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
1226 return G_TOKEN_NONE;
1230 gtk_rc_parse_base (GScanner *scanner,
1236 token = g_scanner_get_next_token (scanner);
1237 if (token != GTK_RC_TOKEN_BASE)
1238 return GTK_RC_TOKEN_BASE;
1240 token = gtk_rc_parse_state (scanner, &state);
1241 if (token != G_TOKEN_NONE)
1244 token = g_scanner_get_next_token (scanner);
1245 if (token != G_TOKEN_EQUAL_SIGN)
1246 return G_TOKEN_EQUAL_SIGN;
1248 style->color_flags[state] |= GTK_RC_BASE;
1249 return gtk_rc_parse_color (scanner, &style->base[state]);
1253 gtk_rc_parse_bg (GScanner *scanner,
1259 token = g_scanner_get_next_token (scanner);
1260 if (token != GTK_RC_TOKEN_BG)
1261 return GTK_RC_TOKEN_BG;
1263 token = gtk_rc_parse_state (scanner, &state);
1264 if (token != G_TOKEN_NONE)
1267 token = g_scanner_get_next_token (scanner);
1268 if (token != G_TOKEN_EQUAL_SIGN)
1269 return G_TOKEN_EQUAL_SIGN;
1271 style->color_flags[state] |= GTK_RC_BG;
1272 return gtk_rc_parse_color (scanner, &style->bg[state]);
1276 gtk_rc_parse_fg (GScanner *scanner,
1282 token = g_scanner_get_next_token (scanner);
1283 if (token != GTK_RC_TOKEN_FG)
1284 return GTK_RC_TOKEN_FG;
1286 token = gtk_rc_parse_state (scanner, &state);
1287 if (token != G_TOKEN_NONE)
1290 token = g_scanner_get_next_token (scanner);
1291 if (token != G_TOKEN_EQUAL_SIGN)
1292 return G_TOKEN_EQUAL_SIGN;
1294 style->color_flags[state] |= GTK_RC_FG;
1295 return gtk_rc_parse_color (scanner, &style->fg[state]);
1299 gtk_rc_parse_text (GScanner *scanner,
1305 token = g_scanner_get_next_token (scanner);
1306 if (token != GTK_RC_TOKEN_TEXT)
1307 return GTK_RC_TOKEN_TEXT;
1309 token = gtk_rc_parse_state (scanner, &state);
1310 if (token != G_TOKEN_NONE)
1313 token = g_scanner_get_next_token (scanner);
1314 if (token != G_TOKEN_EQUAL_SIGN)
1315 return G_TOKEN_EQUAL_SIGN;
1317 style->color_flags[state] |= GTK_RC_TEXT;
1318 return gtk_rc_parse_color (scanner, &style->text[state]);
1322 gtk_rc_parse_bg_pixmap (GScanner *scanner,
1323 GtkRcStyle *rc_style)
1329 token = g_scanner_get_next_token (scanner);
1330 if (token != GTK_RC_TOKEN_BG_PIXMAP)
1331 return GTK_RC_TOKEN_BG_PIXMAP;
1333 token = gtk_rc_parse_state (scanner, &state);
1334 if (token != G_TOKEN_NONE)
1337 token = g_scanner_get_next_token (scanner);
1338 if (token != G_TOKEN_EQUAL_SIGN)
1339 return G_TOKEN_EQUAL_SIGN;
1341 token = g_scanner_get_next_token (scanner);
1342 if (token != G_TOKEN_STRING)
1343 return G_TOKEN_STRING;
1345 if (strcmp (scanner->value.v_string, "<parent>"))
1346 pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
1348 pixmap_file = g_strdup (scanner->value.v_string);
1352 if (rc_style->bg_pixmap_name[state])
1353 g_free (rc_style->bg_pixmap_name[state]);
1354 rc_style->bg_pixmap_name[state] = pixmap_file;
1357 return G_TOKEN_NONE;
1361 gtk_rc_find_pixmap_in_path (GScanner *scanner,
1362 const gchar *pixmap_file)
1368 for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
1370 buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
1371 sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
1373 fd = open (buf, O_RDONLY);
1384 g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
1385 pixmap_file, scanner->line);
1387 g_warning ("Unable to locate image file in pixmap_path: \"%s\"",
1394 gtk_rc_find_module_in_path (const gchar *module_file)
1400 for (i = 0; (i < GTK_RC_MAX_MODULE_PATHS) && (module_path[i] != NULL); i++)
1402 buf = g_malloc (strlen (module_path[i]) + strlen (module_file) + 2);
1403 sprintf (buf, "%s%c%s", module_path[i], '/', module_file);
1405 fd = open (buf, O_RDONLY);
1419 gtk_rc_parse_font (GScanner *scanner,
1420 GtkRcStyle *rc_style)
1424 token = g_scanner_get_next_token (scanner);
1425 if (token != GTK_RC_TOKEN_FONT)
1426 return GTK_RC_TOKEN_FONT;
1428 token = g_scanner_get_next_token (scanner);
1429 if (token != G_TOKEN_EQUAL_SIGN)
1430 return G_TOKEN_EQUAL_SIGN;
1432 token = g_scanner_get_next_token (scanner);
1433 if (token != G_TOKEN_STRING)
1434 return G_TOKEN_STRING;
1436 if (rc_style->font_name)
1437 g_free (rc_style->font_name);
1438 rc_style->font_name = g_strdup (scanner->value.v_string);
1440 return G_TOKEN_NONE;
1444 gtk_rc_parse_fontset (GScanner *scanner,
1445 GtkRcStyle *rc_style)
1449 token = g_scanner_get_next_token (scanner);
1450 if (token != GTK_RC_TOKEN_FONTSET)
1451 return GTK_RC_TOKEN_FONTSET;
1453 token = g_scanner_get_next_token (scanner);
1454 if (token != G_TOKEN_EQUAL_SIGN)
1455 return G_TOKEN_EQUAL_SIGN;
1457 token = g_scanner_get_next_token (scanner);
1458 if (token != G_TOKEN_STRING)
1459 return G_TOKEN_STRING;
1461 if (rc_style->fontset_name)
1462 g_free (rc_style->fontset_name);
1463 rc_style->fontset_name = g_strdup (scanner->value.v_string);
1465 return G_TOKEN_NONE;
1469 gtk_rc_parse_engine (GScanner *scanner,
1470 GtkRcStyle *rc_style)
1474 token = g_scanner_get_next_token (scanner);
1475 if (token != GTK_RC_TOKEN_ENGINE)
1476 return GTK_RC_TOKEN_ENGINE;
1478 token = g_scanner_get_next_token (scanner);
1479 if (token != G_TOKEN_STRING)
1480 return G_TOKEN_STRING;
1482 rc_style->engine = gtk_theme_engine_get (scanner->value.v_string);
1484 token = g_scanner_get_next_token (scanner);
1485 if (token != G_TOKEN_LEFT_CURLY)
1486 return G_TOKEN_LEFT_CURLY;
1488 if (rc_style->engine)
1489 return rc_style->engine->parse_rc_style (scanner, rc_style);
1492 /* Skip over remainder, looking for nested {}'s */
1495 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
1497 if (token == G_TOKEN_LEFT_CURLY)
1499 else if (token == G_TOKEN_RIGHT_CURLY)
1503 return G_TOKEN_NONE;
1506 return G_TOKEN_RIGHT_CURLY;
1511 gtk_rc_parse_state (GScanner *scanner,
1512 GtkStateType *state)
1517 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1518 g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
1520 /* we don't know where we got called from, so we reset the scope here.
1521 * if we bail out due to errors, we *don't* reset the scope, so the
1522 * error messaging code can make sense of our tokens.
1524 old_scope = g_scanner_set_scope (scanner, 0);
1526 token = g_scanner_get_next_token (scanner);
1527 if (token != G_TOKEN_LEFT_BRACE)
1528 return G_TOKEN_LEFT_BRACE;
1530 token = g_scanner_get_next_token (scanner);
1533 case GTK_RC_TOKEN_ACTIVE:
1534 *state = GTK_STATE_ACTIVE;
1536 case GTK_RC_TOKEN_INSENSITIVE:
1537 *state = GTK_STATE_INSENSITIVE;
1539 case GTK_RC_TOKEN_NORMAL:
1540 *state = GTK_STATE_NORMAL;
1542 case GTK_RC_TOKEN_PRELIGHT:
1543 *state = GTK_STATE_PRELIGHT;
1545 case GTK_RC_TOKEN_SELECTED:
1546 *state = GTK_STATE_SELECTED;
1549 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
1552 token = g_scanner_get_next_token (scanner);
1553 if (token != G_TOKEN_RIGHT_BRACE)
1554 return G_TOKEN_RIGHT_BRACE;
1556 g_scanner_set_scope (scanner, old_scope);
1558 return G_TOKEN_NONE;
1562 gtk_rc_parse_priority (GScanner *scanner,
1563 GtkPathPriorityType *priority)
1568 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1569 g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
1571 /* we don't know where we got called from, so we reset the scope here.
1572 * if we bail out due to errors, we *don't* reset the scope, so the
1573 * error messaging code can make sense of our tokens.
1575 old_scope = g_scanner_set_scope (scanner, 0);
1577 token = g_scanner_get_next_token (scanner);
1581 token = g_scanner_get_next_token (scanner);
1584 case GTK_RC_TOKEN_LOWEST:
1585 *priority = GTK_PATH_PRIO_LOWEST;
1587 case GTK_RC_TOKEN_GTK:
1588 *priority = GTK_PATH_PRIO_GTK;
1590 case GTK_RC_TOKEN_APPLICATION:
1591 *priority = GTK_PATH_PRIO_APPLICATION;
1593 case GTK_RC_TOKEN_RC:
1594 *priority = GTK_PATH_PRIO_RC;
1596 case GTK_RC_TOKEN_HIGHEST:
1597 *priority = GTK_PATH_PRIO_HIGHEST;
1600 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
1603 g_scanner_set_scope (scanner, old_scope);
1605 return G_TOKEN_NONE;
1609 gtk_rc_parse_color (GScanner *scanner,
1614 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1616 /* we don't need to set our own scop here, because
1617 * we don't need own symbols
1620 token = g_scanner_get_next_token (scanner);
1629 case G_TOKEN_LEFT_CURLY:
1630 token = g_scanner_get_next_token (scanner);
1631 if (token == G_TOKEN_INT)
1632 token_int = scanner->value.v_int;
1633 else if (token == G_TOKEN_FLOAT)
1634 token_int = scanner->value.v_float * 65535.0;
1636 return G_TOKEN_FLOAT;
1637 color->red = CLAMP (token_int, 0, 65535);
1639 token = g_scanner_get_next_token (scanner);
1640 if (token != G_TOKEN_COMMA)
1641 return G_TOKEN_COMMA;
1643 token = g_scanner_get_next_token (scanner);
1644 if (token == G_TOKEN_INT)
1645 token_int = scanner->value.v_int;
1646 else if (token == G_TOKEN_FLOAT)
1647 token_int = scanner->value.v_float * 65535.0;
1649 return G_TOKEN_FLOAT;
1650 color->green = CLAMP (token_int, 0, 65535);
1652 token = g_scanner_get_next_token (scanner);
1653 if (token != G_TOKEN_COMMA)
1654 return G_TOKEN_COMMA;
1656 token = g_scanner_get_next_token (scanner);
1657 if (token == G_TOKEN_INT)
1658 token_int = scanner->value.v_int;
1659 else if (token == G_TOKEN_FLOAT)
1660 token_int = scanner->value.v_float * 65535.0;
1662 return G_TOKEN_FLOAT;
1663 color->blue = CLAMP (token_int, 0, 65535);
1665 token = g_scanner_get_next_token (scanner);
1666 if (token != G_TOKEN_RIGHT_CURLY)
1667 return G_TOKEN_RIGHT_CURLY;
1668 return G_TOKEN_NONE;
1670 case G_TOKEN_STRING:
1671 if (scanner->value.v_string[0] != '#')
1672 return G_TOKEN_STRING;
1674 length = strlen (scanner->value.v_string) - 1;
1675 if (((length % 3) != 0) || (length > 12))
1676 return G_TOKEN_STRING;
1679 for (i = 0, j = 1; i < length; i++, j++)
1680 buf[i] = scanner->value.v_string[j];
1683 sscanf (buf, "%x", &temp);
1686 for (i = 0; i < length; i++, j++)
1687 buf[i] = scanner->value.v_string[j];
1690 sscanf (buf, "%x", &temp);
1691 color->green = temp;
1693 for (i = 0; i < length; i++, j++)
1694 buf[i] = scanner->value.v_string[j];
1697 sscanf (buf, "%x", &temp);
1703 color->green *= 4369;
1704 color->blue *= 4369;
1706 else if (length == 2)
1709 color->green *= 257;
1712 else if (length == 3)
1718 return G_TOKEN_NONE;
1721 return G_TOKEN_STRING;
1726 gtk_rc_parse_pixmap_path (GScanner *scanner)
1730 token = g_scanner_get_next_token (scanner);
1731 if (token != GTK_RC_TOKEN_PIXMAP_PATH)
1732 return GTK_RC_TOKEN_PIXMAP_PATH;
1734 token = g_scanner_get_next_token (scanner);
1735 if (token != G_TOKEN_STRING)
1736 return G_TOKEN_STRING;
1738 gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
1740 return G_TOKEN_NONE;
1744 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
1748 gint start_offset = 0;
1752 /* free the old one, or just add to the old one ? */
1753 for (path_num=0; pixmap_path[path_num]; path_num++)
1755 g_free (pixmap_path[path_num]);
1756 pixmap_path[path_num] = NULL;
1761 path_len = strlen (pix_path);
1763 buf = g_strdup (pix_path);
1765 for (end_offset = 0; end_offset <= path_len; end_offset++)
1767 if ((buf[end_offset] == ':') ||
1768 (end_offset == path_len))
1770 buf[end_offset] = '\0';
1771 pixmap_path[path_num] = g_strdup (buf + start_offset);
1773 pixmap_path[path_num] = NULL;
1774 start_offset = end_offset + 1;
1778 gtk_rc_append_default_pixmap_path();
1782 gtk_rc_parse_module_path (GScanner *scanner)
1786 token = g_scanner_get_next_token (scanner);
1787 if (token != GTK_RC_TOKEN_MODULE_PATH)
1788 return GTK_RC_TOKEN_MODULE_PATH;
1790 token = g_scanner_get_next_token (scanner);
1791 if (token != G_TOKEN_STRING)
1792 return G_TOKEN_STRING;
1794 gtk_rc_parse_module_path_string (scanner->value.v_string);
1796 return G_TOKEN_NONE;
1800 gtk_rc_parse_module_path_string (gchar *mod_path)
1804 gint start_offset = 0;
1808 /* free the old one, or just add to the old one ? */
1809 for (path_num=0; module_path[path_num]; path_num++)
1811 g_free (module_path[path_num]);
1812 module_path[path_num] = NULL;
1817 path_len = strlen (mod_path);
1819 buf = g_strdup (mod_path);
1821 for (end_offset = 0; end_offset <= path_len; end_offset++)
1823 if ((buf[end_offset] == ':') ||
1824 (end_offset == path_len))
1826 buf[end_offset] = '\0';
1827 module_path[path_num] = g_strdup (buf + start_offset);
1829 module_path[path_num] = NULL;
1830 start_offset = end_offset + 1;
1834 gtk_rc_append_default_module_path();
1838 gtk_rc_parse_path_pattern (GScanner *scanner)
1841 GtkPathType path_type;
1843 gboolean is_binding;
1844 GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
1846 token = g_scanner_get_next_token (scanner);
1849 case GTK_RC_TOKEN_WIDGET:
1850 path_type = GTK_PATH_WIDGET;
1852 case GTK_RC_TOKEN_WIDGET_CLASS:
1853 path_type = GTK_PATH_WIDGET_CLASS;
1855 case GTK_RC_TOKEN_CLASS:
1856 path_type = GTK_PATH_CLASS;
1859 return GTK_RC_TOKEN_WIDGET_CLASS;
1862 token = g_scanner_get_next_token (scanner);
1863 if (token != G_TOKEN_STRING)
1864 return G_TOKEN_STRING;
1866 pattern = g_strdup (scanner->value.v_string);
1868 token = g_scanner_get_next_token (scanner);
1869 if (token == GTK_RC_TOKEN_STYLE)
1871 else if (token == GTK_RC_TOKEN_BINDING)
1874 if (g_scanner_peek_next_token (scanner) == ':')
1876 token = gtk_rc_parse_priority (scanner, &priority);
1877 if (token != G_TOKEN_NONE)
1887 return GTK_RC_TOKEN_STYLE;
1890 token = g_scanner_get_next_token (scanner);
1891 if (token != G_TOKEN_STRING)
1894 return G_TOKEN_STRING;
1899 GtkBindingSet *binding;
1901 binding = gtk_binding_set_find (scanner->value.v_string);
1905 return G_TOKEN_STRING;
1907 gtk_binding_set_add_path (binding, path_type, pattern, priority);
1911 GtkRcStyle *rc_style;
1914 rc_style = gtk_rc_style_find (scanner->value.v_string);
1919 return G_TOKEN_STRING;
1922 rc_set = g_new (GtkRcSet, 1);
1923 gtk_pattern_spec_init (&rc_set->pspec, pattern);
1924 rc_set->rc_style = rc_style;
1926 if (path_type == GTK_PATH_WIDGET)
1927 gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
1928 else if (path_type == GTK_PATH_WIDGET_CLASS)
1929 gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
1931 gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
1935 return G_TOKEN_NONE;
1939 typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
1940 GdkColormap *colormap,
1942 GdkColor *transparent_color,
1943 const gchar *filename);
1947 gtk_rc_set_image_loader(GtkImageLoader loader)
1949 image_loader = loader;
1953 gtk_rc_load_image (GdkColormap *colormap,
1954 GdkColor *transparent_color,
1955 const gchar *filename)
1957 if (strcmp (filename, "<parent>") == 0)
1958 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1962 return image_loader(NULL, colormap, NULL,
1966 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,