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 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 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_list_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 (rc_style->fontset_name)
1122 g_free (rc_style->fontset_name);
1123 rc_style->fontset_name = g_strdup (parent_style->fontset_name);
1125 else if (rc_style->font_name)
1127 g_free (rc_style->font_name);
1128 rc_style->font_name = g_strdup (parent_style->font_name);
1131 for (i = 0; i < 5; i++)
1133 if (rc_style->bg_pixmap_name[i])
1134 g_free (rc_style->bg_pixmap_name[i]);
1135 rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
1140 token = g_scanner_get_next_token (scanner);
1141 if (token != G_TOKEN_LEFT_CURLY)
1146 return G_TOKEN_LEFT_CURLY;
1149 token = g_scanner_peek_next_token (scanner);
1150 while (token != G_TOKEN_RIGHT_CURLY)
1154 case GTK_RC_TOKEN_BASE:
1155 token = gtk_rc_parse_base (scanner, rc_style);
1157 case GTK_RC_TOKEN_BG:
1158 token = gtk_rc_parse_bg (scanner, rc_style);
1160 case GTK_RC_TOKEN_FG:
1161 token = gtk_rc_parse_fg (scanner, rc_style);
1163 case GTK_RC_TOKEN_TEXT:
1164 token = gtk_rc_parse_text (scanner, rc_style);
1166 case GTK_RC_TOKEN_BG_PIXMAP:
1167 token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
1169 case GTK_RC_TOKEN_FONT:
1170 token = gtk_rc_parse_font (scanner, rc_style);
1172 case GTK_RC_TOKEN_FONTSET:
1173 token = gtk_rc_parse_fontset (scanner, rc_style);
1175 case GTK_RC_TOKEN_ENGINE:
1176 token = gtk_rc_parse_engine (scanner, rc_style);
1179 g_scanner_get_next_token (scanner);
1180 token = G_TOKEN_RIGHT_CURLY;
1184 if (token != G_TOKEN_NONE)
1188 if (rc_style->fontset_name)
1189 g_free (rc_style->fontset_name);
1190 if (rc_style->font_name)
1191 g_free (rc_style->font_name);
1192 for (i = 0; i < 5; i++)
1193 if (rc_style->bg_pixmap_name[i])
1194 g_free (rc_style->bg_pixmap_name[i]);
1199 token = g_scanner_peek_next_token (scanner);
1202 token = g_scanner_get_next_token (scanner);
1203 if (token != G_TOKEN_RIGHT_CURLY)
1207 if (rc_style->fontset_name)
1208 g_free (rc_style->fontset_name);
1209 if (rc_style->font_name)
1210 g_free (rc_style->font_name);
1212 for (i = 0; i < 5; i++)
1213 if (rc_style->bg_pixmap_name[i])
1214 g_free (rc_style->bg_pixmap_name[i]);
1218 return G_TOKEN_RIGHT_CURLY;
1222 g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
1224 return G_TOKEN_NONE;
1228 gtk_rc_parse_base (GScanner *scanner,
1234 token = g_scanner_get_next_token (scanner);
1235 if (token != GTK_RC_TOKEN_BASE)
1236 return GTK_RC_TOKEN_BASE;
1238 token = gtk_rc_parse_state (scanner, &state);
1239 if (token != G_TOKEN_NONE)
1242 token = g_scanner_get_next_token (scanner);
1243 if (token != G_TOKEN_EQUAL_SIGN)
1244 return G_TOKEN_EQUAL_SIGN;
1246 style->color_flags[state] |= GTK_RC_BASE;
1247 return gtk_rc_parse_color (scanner, &style->base[state]);
1251 gtk_rc_parse_bg (GScanner *scanner,
1257 token = g_scanner_get_next_token (scanner);
1258 if (token != GTK_RC_TOKEN_BG)
1259 return GTK_RC_TOKEN_BG;
1261 token = gtk_rc_parse_state (scanner, &state);
1262 if (token != G_TOKEN_NONE)
1265 token = g_scanner_get_next_token (scanner);
1266 if (token != G_TOKEN_EQUAL_SIGN)
1267 return G_TOKEN_EQUAL_SIGN;
1269 style->color_flags[state] |= GTK_RC_BG;
1270 return gtk_rc_parse_color (scanner, &style->bg[state]);
1274 gtk_rc_parse_fg (GScanner *scanner,
1280 token = g_scanner_get_next_token (scanner);
1281 if (token != GTK_RC_TOKEN_FG)
1282 return GTK_RC_TOKEN_FG;
1284 token = gtk_rc_parse_state (scanner, &state);
1285 if (token != G_TOKEN_NONE)
1288 token = g_scanner_get_next_token (scanner);
1289 if (token != G_TOKEN_EQUAL_SIGN)
1290 return G_TOKEN_EQUAL_SIGN;
1292 style->color_flags[state] |= GTK_RC_FG;
1293 return gtk_rc_parse_color (scanner, &style->fg[state]);
1297 gtk_rc_parse_text (GScanner *scanner,
1303 token = g_scanner_get_next_token (scanner);
1304 if (token != GTK_RC_TOKEN_TEXT)
1305 return GTK_RC_TOKEN_TEXT;
1307 token = gtk_rc_parse_state (scanner, &state);
1308 if (token != G_TOKEN_NONE)
1311 token = g_scanner_get_next_token (scanner);
1312 if (token != G_TOKEN_EQUAL_SIGN)
1313 return G_TOKEN_EQUAL_SIGN;
1315 style->color_flags[state] |= GTK_RC_TEXT;
1316 return gtk_rc_parse_color (scanner, &style->text[state]);
1320 gtk_rc_parse_bg_pixmap (GScanner *scanner,
1321 GtkRcStyle *rc_style)
1327 token = g_scanner_get_next_token (scanner);
1328 if (token != GTK_RC_TOKEN_BG_PIXMAP)
1329 return GTK_RC_TOKEN_BG_PIXMAP;
1331 token = gtk_rc_parse_state (scanner, &state);
1332 if (token != G_TOKEN_NONE)
1335 token = g_scanner_get_next_token (scanner);
1336 if (token != G_TOKEN_EQUAL_SIGN)
1337 return G_TOKEN_EQUAL_SIGN;
1339 token = g_scanner_get_next_token (scanner);
1340 if (token != G_TOKEN_STRING)
1341 return G_TOKEN_STRING;
1343 if (strcmp (scanner->value.v_string, "<parent>"))
1344 pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
1346 pixmap_file = g_strdup (scanner->value.v_string);
1350 if (rc_style->bg_pixmap_name[state])
1351 g_free (rc_style->bg_pixmap_name[state]);
1352 rc_style->bg_pixmap_name[state] = pixmap_file;
1355 return G_TOKEN_NONE;
1359 gtk_rc_find_pixmap_in_path (GScanner *scanner,
1366 for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
1368 buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
1369 sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
1371 fd = open (buf, O_RDONLY);
1382 g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
1383 pixmap_file, scanner->line);
1385 g_warning ("Unable to locate image file in pixmap_path: \"%s\"",
1392 gtk_rc_find_module_in_path (GScanner *scanner,
1399 for (i = 0; (i < GTK_RC_MAX_MODULE_PATHS) && (module_path[i] != NULL); i++)
1401 buf = g_malloc (strlen (module_path[i]) + strlen (module_file) + 2);
1402 sprintf (buf, "%s%c%s", module_path[i], '/', module_file);
1404 fd = open (buf, O_RDONLY);
1415 g_warning ("Unable to locate loadable module in module_path: \"%s\" line %d",
1416 module_file, scanner->line);
1418 g_warning ("Unable to locate loadable module in module_path: \"%s\",",
1425 gtk_rc_parse_font (GScanner *scanner,
1426 GtkRcStyle *rc_style)
1430 token = g_scanner_get_next_token (scanner);
1431 if (token != GTK_RC_TOKEN_FONT)
1432 return GTK_RC_TOKEN_FONT;
1434 token = g_scanner_get_next_token (scanner);
1435 if (token != G_TOKEN_EQUAL_SIGN)
1436 return G_TOKEN_EQUAL_SIGN;
1438 token = g_scanner_get_next_token (scanner);
1439 if (token != G_TOKEN_STRING)
1440 return G_TOKEN_STRING;
1442 if (rc_style->font_name)
1443 g_free (rc_style->font_name);
1444 rc_style->font_name = g_strdup (scanner->value.v_string);
1446 return G_TOKEN_NONE;
1450 gtk_rc_parse_fontset (GScanner *scanner,
1451 GtkRcStyle *rc_style)
1455 token = g_scanner_get_next_token (scanner);
1456 if (token != GTK_RC_TOKEN_FONTSET)
1457 return GTK_RC_TOKEN_FONTSET;
1459 token = g_scanner_get_next_token (scanner);
1460 if (token != G_TOKEN_EQUAL_SIGN)
1461 return G_TOKEN_EQUAL_SIGN;
1463 token = g_scanner_get_next_token (scanner);
1464 if (token != G_TOKEN_STRING)
1465 return G_TOKEN_STRING;
1467 if (rc_style->fontset_name)
1468 g_free (rc_style->fontset_name);
1469 rc_style->fontset_name = g_strdup (scanner->value.v_string);
1471 return G_TOKEN_NONE;
1475 gtk_rc_parse_engine (GScanner *scanner,
1476 GtkRcStyle *rc_style)
1480 token = g_scanner_get_next_token (scanner);
1481 if (token != GTK_RC_TOKEN_ENGINE)
1482 return GTK_RC_TOKEN_ENGINE;
1484 token = g_scanner_get_next_token (scanner);
1485 if (token != G_TOKEN_STRING)
1486 return G_TOKEN_STRING;
1488 rc_style->engine = gtk_theme_engine_get (scanner->value.v_string);
1490 token = g_scanner_get_next_token (scanner);
1491 if (token != G_TOKEN_LEFT_CURLY)
1492 return G_TOKEN_LEFT_CURLY;
1494 if (rc_style->engine)
1495 return rc_style->engine->parse_rc_style (scanner, rc_style);
1498 /* Skip over remainder, looking for nested {}'s */
1501 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
1503 if (token == G_TOKEN_LEFT_CURLY)
1505 else if (token == G_TOKEN_RIGHT_CURLY)
1509 return G_TOKEN_NONE;
1512 return G_TOKEN_RIGHT_CURLY;
1517 gtk_rc_parse_state (GScanner *scanner,
1518 GtkStateType *state)
1523 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1524 g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
1526 /* we don't know where we got called from, so we reset the scope here.
1527 * if we bail out due to errors, we *don't* reset the scope, so the
1528 * error messaging code can make sense of our tokens.
1530 old_scope = g_scanner_set_scope (scanner, 0);
1532 token = g_scanner_get_next_token (scanner);
1533 if (token != G_TOKEN_LEFT_BRACE)
1534 return G_TOKEN_LEFT_BRACE;
1536 token = g_scanner_get_next_token (scanner);
1539 case GTK_RC_TOKEN_ACTIVE:
1540 *state = GTK_STATE_ACTIVE;
1542 case GTK_RC_TOKEN_INSENSITIVE:
1543 *state = GTK_STATE_INSENSITIVE;
1545 case GTK_RC_TOKEN_NORMAL:
1546 *state = GTK_STATE_NORMAL;
1548 case GTK_RC_TOKEN_PRELIGHT:
1549 *state = GTK_STATE_PRELIGHT;
1551 case GTK_RC_TOKEN_SELECTED:
1552 *state = GTK_STATE_SELECTED;
1555 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
1558 token = g_scanner_get_next_token (scanner);
1559 if (token != G_TOKEN_RIGHT_BRACE)
1560 return G_TOKEN_RIGHT_BRACE;
1562 g_scanner_set_scope (scanner, old_scope);
1564 return G_TOKEN_NONE;
1568 gtk_rc_parse_priority (GScanner *scanner,
1569 GtkPathPriorityType *priority)
1574 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1575 g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
1577 /* we don't know where we got called from, so we reset the scope here.
1578 * if we bail out due to errors, we *don't* reset the scope, so the
1579 * error messaging code can make sense of our tokens.
1581 old_scope = g_scanner_set_scope (scanner, 0);
1583 token = g_scanner_get_next_token (scanner);
1587 token = g_scanner_get_next_token (scanner);
1590 case GTK_RC_TOKEN_LOWEST:
1591 *priority = GTK_PATH_PRIO_LOWEST;
1593 case GTK_RC_TOKEN_GTK:
1594 *priority = GTK_PATH_PRIO_GTK;
1596 case GTK_RC_TOKEN_APPLICATION:
1597 *priority = GTK_PATH_PRIO_APPLICATION;
1599 case GTK_RC_TOKEN_RC:
1600 *priority = GTK_PATH_PRIO_RC;
1602 case GTK_RC_TOKEN_HIGHEST:
1603 *priority = GTK_PATH_PRIO_HIGHEST;
1606 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
1609 g_scanner_set_scope (scanner, old_scope);
1611 return G_TOKEN_NONE;
1615 gtk_rc_parse_color (GScanner *scanner,
1620 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1622 /* we don't need to set our own scop here, because
1623 * we don't need own symbols
1626 token = g_scanner_get_next_token (scanner);
1635 case G_TOKEN_LEFT_CURLY:
1636 token = g_scanner_get_next_token (scanner);
1637 if (token == G_TOKEN_INT)
1638 token_int = scanner->value.v_int;
1639 else if (token == G_TOKEN_FLOAT)
1640 token_int = scanner->value.v_float * 65535.0;
1642 return G_TOKEN_FLOAT;
1643 color->red = CLAMP (token_int, 0, 65535);
1645 token = g_scanner_get_next_token (scanner);
1646 if (token != G_TOKEN_COMMA)
1647 return G_TOKEN_COMMA;
1649 token = g_scanner_get_next_token (scanner);
1650 if (token == G_TOKEN_INT)
1651 token_int = scanner->value.v_int;
1652 else if (token == G_TOKEN_FLOAT)
1653 token_int = scanner->value.v_float * 65535.0;
1655 return G_TOKEN_FLOAT;
1656 color->green = CLAMP (token_int, 0, 65535);
1658 token = g_scanner_get_next_token (scanner);
1659 if (token != G_TOKEN_COMMA)
1660 return G_TOKEN_COMMA;
1662 token = g_scanner_get_next_token (scanner);
1663 if (token == G_TOKEN_INT)
1664 token_int = scanner->value.v_int;
1665 else if (token == G_TOKEN_FLOAT)
1666 token_int = scanner->value.v_float * 65535.0;
1668 return G_TOKEN_FLOAT;
1669 color->blue = CLAMP (token_int, 0, 65535);
1671 token = g_scanner_get_next_token (scanner);
1672 if (token != G_TOKEN_RIGHT_CURLY)
1673 return G_TOKEN_RIGHT_CURLY;
1674 return G_TOKEN_NONE;
1676 case G_TOKEN_STRING:
1677 if (scanner->value.v_string[0] != '#')
1678 return G_TOKEN_STRING;
1680 length = strlen (scanner->value.v_string) - 1;
1681 if (((length % 3) != 0) || (length > 12))
1682 return G_TOKEN_STRING;
1685 for (i = 0, j = 1; i < length; i++, j++)
1686 buf[i] = scanner->value.v_string[j];
1689 sscanf (buf, "%x", &temp);
1692 for (i = 0; i < length; i++, j++)
1693 buf[i] = scanner->value.v_string[j];
1696 sscanf (buf, "%x", &temp);
1697 color->green = temp;
1699 for (i = 0; i < length; i++, j++)
1700 buf[i] = scanner->value.v_string[j];
1703 sscanf (buf, "%x", &temp);
1709 color->green *= 4369;
1710 color->blue *= 4369;
1712 else if (length == 2)
1715 color->green *= 257;
1718 else if (length == 3)
1724 return G_TOKEN_NONE;
1727 return G_TOKEN_STRING;
1732 gtk_rc_parse_pixmap_path (GScanner *scanner)
1736 token = g_scanner_get_next_token (scanner);
1737 if (token != GTK_RC_TOKEN_PIXMAP_PATH)
1738 return GTK_RC_TOKEN_PIXMAP_PATH;
1740 token = g_scanner_get_next_token (scanner);
1741 if (token != G_TOKEN_STRING)
1742 return G_TOKEN_STRING;
1744 gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
1746 return G_TOKEN_NONE;
1750 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
1754 gint start_offset = 0;
1758 /* free the old one, or just add to the old one ? */
1759 for (path_num=0; pixmap_path[path_num]; path_num++)
1761 g_free (pixmap_path[path_num]);
1762 pixmap_path[path_num] = NULL;
1767 path_len = strlen (pix_path);
1769 buf = g_strdup (pix_path);
1771 for (end_offset = 0; end_offset <= path_len; end_offset++)
1773 if ((buf[end_offset] == ':') ||
1774 (end_offset == path_len))
1776 buf[end_offset] = '\0';
1777 pixmap_path[path_num] = g_strdup (buf + start_offset);
1779 pixmap_path[path_num] = NULL;
1780 start_offset = end_offset + 1;
1784 gtk_rc_append_default_pixmap_path();
1788 gtk_rc_parse_module_path (GScanner *scanner)
1792 token = g_scanner_get_next_token (scanner);
1793 if (token != GTK_RC_TOKEN_MODULE_PATH)
1794 return GTK_RC_TOKEN_MODULE_PATH;
1796 token = g_scanner_get_next_token (scanner);
1797 if (token != G_TOKEN_STRING)
1798 return G_TOKEN_STRING;
1800 gtk_rc_parse_module_path_string (scanner->value.v_string);
1802 return G_TOKEN_NONE;
1806 gtk_rc_parse_module_path_string (gchar *mod_path)
1810 gint start_offset = 0;
1814 /* free the old one, or just add to the old one ? */
1815 for (path_num=0; module_path[path_num]; path_num++)
1817 g_free (module_path[path_num]);
1818 module_path[path_num] = NULL;
1823 path_len = strlen (mod_path);
1825 buf = g_strdup (mod_path);
1827 for (end_offset = 0; end_offset <= path_len; end_offset++)
1829 if ((buf[end_offset] == ':') ||
1830 (end_offset == path_len))
1832 buf[end_offset] = '\0';
1833 module_path[path_num] = g_strdup (buf + start_offset);
1835 module_path[path_num] = NULL;
1836 start_offset = end_offset + 1;
1840 gtk_rc_append_default_module_path();
1844 gtk_rc_parse_path_pattern (GScanner *scanner)
1847 GtkPathType path_type;
1849 gboolean is_binding;
1850 GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
1852 token = g_scanner_get_next_token (scanner);
1855 case GTK_RC_TOKEN_WIDGET:
1856 path_type = GTK_PATH_WIDGET;
1858 case GTK_RC_TOKEN_WIDGET_CLASS:
1859 path_type = GTK_PATH_WIDGET_CLASS;
1861 case GTK_RC_TOKEN_CLASS:
1862 path_type = GTK_PATH_CLASS;
1865 return GTK_RC_TOKEN_WIDGET_CLASS;
1868 token = g_scanner_get_next_token (scanner);
1869 if (token != G_TOKEN_STRING)
1870 return G_TOKEN_STRING;
1872 pattern = g_strdup (scanner->value.v_string);
1874 token = g_scanner_get_next_token (scanner);
1875 if (token == GTK_RC_TOKEN_STYLE)
1877 else if (token == GTK_RC_TOKEN_BINDING)
1880 if (g_scanner_peek_next_token (scanner) == ':')
1882 token = gtk_rc_parse_priority (scanner, &priority);
1883 if (token != G_TOKEN_NONE)
1893 return GTK_RC_TOKEN_STYLE;
1896 token = g_scanner_get_next_token (scanner);
1897 if (token != G_TOKEN_STRING)
1900 return G_TOKEN_STRING;
1905 GtkBindingSet *binding;
1907 binding = gtk_binding_set_find (scanner->value.v_string);
1911 return G_TOKEN_STRING;
1913 gtk_binding_set_add_path (binding, path_type, pattern, priority);
1917 GtkRcStyle *rc_style;
1920 rc_style = gtk_rc_style_find (scanner->value.v_string);
1925 return G_TOKEN_STRING;
1928 rc_set = g_new (GtkRcSet, 1);
1929 gtk_pattern_spec_init (&rc_set->pspec, pattern);
1930 rc_set->rc_style = rc_style;
1932 if (path_type == GTK_PATH_WIDGET)
1933 gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
1934 else if (path_type == GTK_PATH_WIDGET_CLASS)
1935 gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
1937 gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
1941 return G_TOKEN_NONE;
1945 typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
1946 GdkColormap *colormap,
1948 GdkColor *transparent_color,
1949 const gchar *filename);
1953 gtk_rc_set_image_loader(GtkImageLoader loader)
1955 image_loader = loader;
1959 gtk_rc_load_image (GdkColormap *colormap,
1960 GdkColor *transparent_color,
1961 const gchar *filename)
1963 if (strcmp (filename, "<parent>") == 0)
1964 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1968 return image_loader(NULL, colormap, NULL,
1972 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,