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>
30 TOKEN_INVALID = G_TOKEN_LAST,
66 typedef struct _GtkRcStyle GtkRcStyle;
67 typedef struct _GtkRcSet GtkRcSet;
68 typedef struct _GtkRcNode GtkRcNode;
69 typedef struct _GtkRcFile GtkRcFile;
82 char *bg_pixmap_name[5];
83 GtkStyle *proto_style;
97 gchar *canonical_name;
101 static guint gtk_rc_style_hash (const char *name);
102 static gint gtk_rc_style_compare (const char *a,
104 static GtkRcStyle* gtk_rc_style_find (const char *name);
105 static GtkRcStyle* gtk_rc_styles_match (GSList *sets,
107 static gint gtk_rc_style_match (const char *set,
109 static GtkStyle* gtk_rc_style_init (GtkRcStyle *rc_style,
111 static void gtk_rc_parse_file (const gchar *filename,
114 static void gtk_rc_parse_any (const gchar *input_name,
116 const gchar *input_string);
117 static gint gtk_rc_parse_statement (GScanner *scanner);
118 static gint gtk_rc_parse_style (GScanner *scanner);
119 static gint gtk_rc_parse_style_option (GScanner *scanner,
120 GtkRcStyle *rc_style);
121 static gint gtk_rc_parse_base (GScanner *scanner,
123 static gint gtk_rc_parse_bg (GScanner *scanner,
125 static gint gtk_rc_parse_fg (GScanner *scanner,
127 static gint gtk_rc_parse_text (GScanner *scanner,
129 static gint gtk_rc_parse_bg_pixmap (GScanner *scanner,
130 GtkRcStyle *rc_style);
131 static gint gtk_rc_parse_font (GScanner *scanner,
132 GtkRcStyle *rc_style);
133 static gint gtk_rc_parse_fontset (GScanner *scanner,
134 GtkRcStyle *rc_style);
135 static gint gtk_rc_parse_state (GScanner *scanner,
136 GtkStateType *state);
137 static gint gtk_rc_parse_color (GScanner *scanner,
139 static gint gtk_rc_parse_pixmap_path (GScanner *scanner);
140 static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
141 static char* gtk_rc_find_pixmap_in_path (GScanner *scanner,
143 static gint gtk_rc_parse_widget_style (GScanner *scanner);
144 static gint gtk_rc_parse_widget_class_style (GScanner *scanner);
145 static char* gtk_rc_widget_path (GtkWidget *widget);
146 static char* gtk_rc_widget_class_path (GtkWidget *widget);
147 static void gtk_rc_clear_hash_node (gpointer key,
150 static void gtk_rc_clear_styles (void);
154 static GScannerConfig gtk_rc_scanner_config =
158 ) /* cset_skip_characters */,
163 ) /* cset_identifier_first */,
170 ) /* cset_identifier_nth */,
171 ( "#\n" ) /* cpair_comment_single */,
173 TRUE /* case_sensitive */,
175 TRUE /* skip_comment_multi */,
176 TRUE /* skip_comment_single */,
177 TRUE /* scan_comment_multi */,
178 TRUE /* scan_identifier */,
179 FALSE /* scan_identifier_1char */,
180 FALSE /* scan_identifier_NULL */,
181 TRUE /* scan_symbols */,
182 TRUE /* scan_binary */,
183 TRUE /* scan_octal */,
184 TRUE /* scan_float */,
186 TRUE /* scan_hex_dollar */,
187 TRUE /* scan_string_sq */,
188 TRUE /* scan_string_dq */,
189 TRUE /* numbers_2_int */,
190 FALSE /* int_2_float */,
191 TRUE /* identifier_2_string */,
192 TRUE /* char_2_token */,
193 TRUE /* symbol_2_token */,
201 { "include", TOKEN_INCLUDE },
202 { "ACTIVE", TOKEN_ACTIVE },
203 { "base", TOKEN_BASE },
205 { "bg_pixmap", TOKEN_BG_PIXMAP },
207 { "font", TOKEN_FONT },
208 { "fontset", TOKEN_FONTSET },
209 { "INSENSITIVE", TOKEN_INSENSITIVE },
210 { "NORMAL", TOKEN_NORMAL },
211 { "pixmap_path", TOKEN_PIXMAP_PATH },
212 { "PRELIGHT", TOKEN_PRELIGHT },
213 { "SELECTED", TOKEN_SELECTED },
214 { "style", TOKEN_STYLE },
215 { "text", TOKEN_TEXT },
216 { "widget", TOKEN_WIDGET },
217 { "widget_class", TOKEN_WIDGET_CLASS },
219 static guint nsymbols = sizeof (symbols) / sizeof (symbols[0]);
221 static GHashTable *rc_style_ht = NULL;
222 static GSList *widget_sets = NULL;
223 static GSList *widget_class_sets = NULL;
225 #define GTK_RC_MAX_PIXMAP_PATHS 128
226 static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
228 /* The files we have parsed, to reread later if necessary */
229 GSList *rc_files = NULL;
231 static GtkImageLoader image_loader = NULL;
236 rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
237 (GCompareFunc) gtk_rc_style_compare);
241 gtk_rc_parse_string (const gchar *rc_string)
243 g_return_if_fail (rc_string != NULL);
245 gtk_rc_parse_any ("-", -1, rc_string);
249 gtk_rc_parse_file (const gchar *filename, gboolean reload)
251 GtkRcFile *rc_file = NULL;
255 g_return_if_fail (filename != NULL);
260 rc_file = tmp_list->data;
261 if (!strcmp (rc_file->name, filename))
264 tmp_list = tmp_list->next;
269 rc_file = g_new (GtkRcFile, 1);
270 rc_file->name = g_strdup (filename);
271 rc_file->canonical_name = NULL;
273 rc_file->reload = reload;
275 rc_files = g_slist_append (rc_files, rc_file);
278 if (!rc_file->canonical_name)
280 /* Get the absolute pathname */
282 if (rc_file->name[0] == '/')
283 rc_file->canonical_name = rc_file->name;
287 gchar buffer[MAXPATHLEN];
289 #if defined(sun) && !defined(__SVR4)
292 if(!getcwd(buffer, MAXPATHLEN))
296 str = g_string_new (buffer);
297 g_string_append_c (str, '/');
298 g_string_append (str, rc_file->name);
300 rc_file->canonical_name = str->str;
301 g_string_free (str, FALSE);
305 if (!lstat (rc_file->canonical_name, &statbuf))
309 rc_file->mtime = statbuf.st_mtime;
311 fd = open (rc_file->canonical_name, O_RDONLY);
315 gtk_rc_parse_any (filename, fd, NULL);
322 gtk_rc_parse (const gchar *filename)
324 g_return_if_fail (filename != NULL);
326 gtk_rc_parse_file (filename, TRUE);
330 gtk_rc_clear_hash_node (gpointer key,
335 GtkRcStyle *rc_style = data;
338 g_free (rc_style->name);
339 g_free (rc_style->font_name);
340 g_free (rc_style->fontset_name);
342 for (i=0 ; i<5 ; i++)
343 g_free (rc_style->bg_pixmap_name[i]);
345 gtk_style_unref (rc_style->proto_style);
347 tmp_list = rc_style->styles;
350 GtkRcNode *node = tmp_list->data;
352 gdk_colormap_unref (node->cmap);
353 gtk_style_unref (node->style);
356 tmp_list = tmp_list->next;
363 gtk_rc_clear_styles (void)
368 /* Clear out all old rc_styles */
370 g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
371 g_hash_table_destroy (rc_style_ht);
374 tmp_list = widget_sets;
377 rc_set = (GtkRcSet *)tmp_list->data;
378 g_free (rc_set->set);
381 tmp_list = tmp_list->next;
383 g_slist_free (widget_sets);
386 tmp_list = widget_class_sets;
389 rc_set = (GtkRcSet *)tmp_list->data;
390 g_free (rc_set->set);
393 tmp_list = tmp_list->next;
395 g_slist_free (widget_class_sets);
396 widget_class_sets = NULL;
402 gtk_rc_reparse_all (void)
405 gboolean mtime_modified = FALSE;
410 /* Check through and see if any of the RC's have had their
411 * mtime modified. If so, reparse everything.
416 rc_file = tmp_list->data;
418 if (!lstat (rc_file->name, &statbuf) &&
419 (statbuf.st_mtime > rc_file->mtime))
421 mtime_modified = TRUE;
425 tmp_list = tmp_list->next;
430 gtk_rc_clear_styles();
435 rc_file = tmp_list->data;
437 gtk_rc_parse_file (rc_file->name, FALSE);
439 tmp_list = tmp_list->next;
443 return mtime_modified;
447 gtk_rc_get_style (GtkWidget *widget)
449 GtkRcStyle *rc_style;
454 path = gtk_rc_widget_path (widget);
457 rc_style = gtk_rc_styles_match (widget_sets, path);
462 return gtk_rc_style_init (rc_style,
463 gtk_widget_get_colormap (widget));
468 if (widget_class_sets)
470 path = gtk_rc_widget_class_path (widget);
473 rc_style = gtk_rc_styles_match (widget_class_sets, path);
478 return gtk_rc_style_init (rc_style,
479 gtk_widget_get_colormap (widget));
488 gtk_rc_add_widget_name_style (GtkStyle *style,
491 GtkRcStyle *rc_style;
495 gtk_style_ref (style);
497 rc_style = g_new (GtkRcStyle, 1);
498 rc_style->name = NULL;
499 rc_style->font_name = NULL;
500 rc_style->fontset_name = NULL;
502 for (i = 0; i < 5; i++)
503 rc_style->bg_pixmap_name[i] = NULL;
505 rc_style->styles = g_list_append (NULL, style);
507 rc_set = g_new (GtkRcSet, 1);
508 rc_set->set = g_strdup (pattern);
509 rc_set->rc_style = rc_style;
511 widget_sets = g_slist_append (widget_sets, rc_set);
515 gtk_rc_add_widget_class_style (GtkStyle *style,
518 GtkRcStyle *rc_style;
522 gtk_style_ref (style);
524 rc_style = g_new (GtkRcStyle, 1);
525 rc_style->name = NULL;
526 rc_style->font_name = NULL;
527 rc_style->fontset_name = NULL;
529 for (i = 0; i < 5; i++)
530 rc_style->bg_pixmap_name[i] = NULL;
532 rc_style->styles = g_list_append (NULL, style);
534 rc_set = g_new (GtkRcSet, 1);
535 rc_set->set = g_strdup (pattern);
536 rc_set->rc_style = rc_style;
538 widget_class_sets = g_slist_append (widget_class_sets, rc_set);
542 gtk_rc_parse_any (const gchar *input_name,
544 const gchar *input_string)
550 scanner = g_scanner_new (>k_rc_scanner_config);
554 g_assert (input_string == NULL);
556 g_scanner_input_file (scanner, input_fd);
560 g_assert (input_string != NULL);
562 g_scanner_input_text (scanner, input_string, strlen (input_string));
565 for (i = 0; i < nsymbols; i++)
566 g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
573 return_val = gtk_rc_parse_statement (scanner);
580 if (scanner->next_token != G_TOKEN_NONE)
581 g_scanner_get_next_token (scanner);
584 g_warning ("rc string parse error: line %d",
587 g_warning ("rc file parse error: \"%s\" line %d",
596 g_scanner_destroy (scanner);
600 gtk_rc_style_hash (const char *name)
606 result += (result << 3) + *name++;
612 gtk_rc_style_compare (const char *a,
615 return (strcmp (a, b) == 0);
619 gtk_rc_style_find (const char *name)
621 GtkRcStyle *rc_style;
623 rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
629 gtk_rc_styles_match (GSList *sets,
639 if (gtk_rc_style_match (rc_set->set, path))
640 return rc_set->rc_style;
647 gtk_rc_style_match (const char *set,
656 return (*path == '\0');
670 while (*path && (ch != *path))
677 if (gtk_rc_style_match (set, path))
698 gtk_rc_style_init (GtkRcStyle *rc_style, GdkColormap *cmap)
701 gboolean match_cmap = FALSE;
705 GtkStyle *style = NULL;
708 tmp_list = rc_style->styles;
711 if (rc_style->bg_pixmap_name[i])
716 node = (GtkRcNode *)tmp_list->data;
718 if (!match_cmap || (node->cmap == cmap))
724 tmp_list = tmp_list->next;
729 node = g_new (GtkRcNode, 1);
730 style = gtk_style_copy (rc_style->proto_style);
732 /* FIXME, this leaks colormaps, but if we don't do this, then we'll
733 * be screwed, because we identify colormaps by address equality
735 gdk_colormap_ref (cmap);
740 if (rc_style->fontset_name)
742 old_font = style->font;
743 style->font = gdk_fontset_load (rc_style->fontset_name);
745 gdk_font_unref (old_font);
747 style->font = old_font;
749 else if (rc_style->font_name)
751 old_font = style->font;
752 style->font = gdk_font_load (rc_style->font_name);
754 gdk_font_unref (old_font);
756 style->font = old_font;
759 for (i = 0; i < 5; i++)
760 if (rc_style->bg_pixmap_name[i])
762 if (strcmp (rc_style->bg_pixmap_name[i], "<parent>") == 0)
763 style->bg_pixmap[i] = (GdkPixmap*) GDK_PARENT_RELATIVE;
767 style->bg_pixmap[i] = image_loader(NULL, cmap, NULL,
769 rc_style->bg_pixmap_name[i]);
771 style->bg_pixmap[i] =
772 gdk_pixmap_colormap_create_from_xpm (NULL, cmap,
775 rc_style->bg_pixmap_name[i]);
779 rc_style->styles = g_list_append (rc_style->styles, node);
786 gtk_rc_parse_statement (GScanner *scanner)
791 token = g_scanner_peek_next_token (scanner);
792 if (token == G_TOKEN_EOF)
795 if (token == TOKEN_INCLUDE)
797 g_scanner_get_next_token (scanner);
798 token = g_scanner_get_next_token (scanner);
800 if (token != G_TOKEN_STRING)
803 gtk_rc_parse_file (scanner->value.v_string, FALSE);
808 error = gtk_rc_parse_style (scanner);
809 if (error != PARSE_SYNTAX)
812 error = gtk_rc_parse_pixmap_path (scanner);
813 if (error != PARSE_SYNTAX)
816 error = gtk_rc_parse_widget_style (scanner);
817 if (error != PARSE_SYNTAX)
820 error = gtk_rc_parse_widget_class_style (scanner);
826 gtk_rc_parse_style (GScanner *scanner)
828 GtkRcStyle *rc_style;
829 GtkRcStyle *parent_style;
835 token = g_scanner_peek_next_token (scanner);
836 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
838 if (token != TOKEN_STYLE)
840 token = g_scanner_get_next_token (scanner);
842 token = g_scanner_get_next_token (scanner);
843 if (token != G_TOKEN_STRING)
847 rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
852 rc_style = g_new (GtkRcStyle, 1);
853 rc_style->name = g_strdup (scanner->value.v_string);
854 rc_style->font_name = NULL;
855 rc_style->fontset_name = NULL;
857 for (i = 0; i < 5; i++)
858 rc_style->bg_pixmap_name[i] = NULL;
860 rc_style->proto_style = gtk_style_new();
861 rc_style->styles = NULL;
864 token = g_scanner_peek_next_token (scanner);
865 if (token == G_TOKEN_EQUAL_SIGN)
867 token = g_scanner_get_next_token (scanner);
869 token = g_scanner_get_next_token (scanner);
870 if (token != G_TOKEN_STRING)
874 gtk_style_unref (rc_style->proto_style);
880 parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
883 for (i = 0; i < 5; i++)
885 rc_style->proto_style->fg[i] = parent_style->proto_style->fg[i];
886 rc_style->proto_style->bg[i] = parent_style->proto_style->bg[i];
887 rc_style->proto_style->light[i] = parent_style->proto_style->light[i];
888 rc_style->proto_style->dark[i] = parent_style->proto_style->dark[i];
889 rc_style->proto_style->mid[i] = parent_style->proto_style->mid[i];
890 rc_style->proto_style->text[i] = parent_style->proto_style->text[i];
891 rc_style->proto_style->base[i] = parent_style->proto_style->base[i];
894 rc_style->proto_style->black = parent_style->proto_style->black;
895 rc_style->proto_style->white = parent_style->proto_style->white;
897 if (rc_style->fontset_name)
899 g_free (rc_style->fontset_name);
900 rc_style->fontset_name = g_strdup (parent_style->fontset_name);
902 else if (rc_style->font_name)
904 g_free (rc_style->font_name);
905 rc_style->font_name = g_strdup (parent_style->font_name);
908 for (i = 0; i < 5; i++)
910 if (rc_style->bg_pixmap_name[i])
911 g_free (rc_style->bg_pixmap_name[i]);
912 rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
917 token = g_scanner_get_next_token (scanner);
918 if (token != G_TOKEN_LEFT_CURLY)
922 gtk_style_unref (rc_style->proto_style);
930 error = gtk_rc_parse_style_option (scanner, rc_style);
931 if (error == PARSE_SYNTAX)
933 if (error == PARSE_ERROR)
937 gtk_style_unref (rc_style->proto_style);
944 token = g_scanner_get_next_token (scanner);
945 if (token != G_TOKEN_RIGHT_CURLY)
949 if (rc_style->fontset_name)
950 g_free (rc_style->fontset_name);
951 else if (rc_style->font_name)
952 g_free (rc_style->font_name);
954 for (i = 0; i < 5; i++)
955 if (rc_style->bg_pixmap_name[i])
956 g_free (rc_style->bg_pixmap_name[i]);
958 gtk_style_unref (rc_style->proto_style);
965 g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
971 gtk_rc_parse_style_option (GScanner *scanner,
972 GtkRcStyle *rc_style)
977 token = g_scanner_peek_next_token (scanner);
978 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
981 error = gtk_rc_parse_base (scanner, rc_style->proto_style);
982 if (error != PARSE_SYNTAX)
985 error = gtk_rc_parse_bg (scanner, rc_style->proto_style);
986 if (error != PARSE_SYNTAX)
989 error = gtk_rc_parse_fg (scanner, rc_style->proto_style);
990 if (error != PARSE_SYNTAX)
993 error = gtk_rc_parse_text (scanner, rc_style->proto_style);
994 if (error != PARSE_SYNTAX)
997 error = gtk_rc_parse_bg_pixmap (scanner, rc_style);
998 if (error != PARSE_SYNTAX)
1001 error = gtk_rc_parse_font (scanner, rc_style);
1002 if (error != PARSE_SYNTAX)
1005 error = gtk_rc_parse_fontset (scanner, rc_style);
1011 gtk_rc_parse_base (GScanner *scanner,
1018 token = g_scanner_peek_next_token (scanner);
1019 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1021 if (token != TOKEN_BASE)
1022 return PARSE_SYNTAX;
1023 token = g_scanner_get_next_token (scanner);
1025 error = gtk_rc_parse_state (scanner, &state);
1026 if (error != PARSE_OK)
1029 token = g_scanner_get_next_token (scanner);
1030 if (token != G_TOKEN_EQUAL_SIGN)
1033 error = gtk_rc_parse_color (scanner, &style->base[state]);
1039 gtk_rc_parse_bg (GScanner *scanner,
1046 token = g_scanner_peek_next_token (scanner);
1047 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1049 if (token != TOKEN_BG)
1050 return PARSE_SYNTAX;
1051 token = g_scanner_get_next_token (scanner);
1053 error = gtk_rc_parse_state (scanner, &state);
1054 if (error != PARSE_OK)
1057 token = g_scanner_get_next_token (scanner);
1058 if (token != G_TOKEN_EQUAL_SIGN)
1061 error = gtk_rc_parse_color (scanner, &style->bg[state]);
1067 gtk_rc_parse_fg (GScanner *scanner,
1074 token = g_scanner_peek_next_token (scanner);
1075 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1077 if (token != TOKEN_FG)
1078 return PARSE_SYNTAX;
1079 token = g_scanner_get_next_token (scanner);
1081 error = gtk_rc_parse_state (scanner, &state);
1082 if (error != PARSE_OK)
1085 token = g_scanner_get_next_token (scanner);
1086 if (token != G_TOKEN_EQUAL_SIGN)
1089 error = gtk_rc_parse_color (scanner, &style->fg[state]);
1095 gtk_rc_parse_text (GScanner *scanner,
1102 token = g_scanner_peek_next_token (scanner);
1103 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1105 if (token != TOKEN_TEXT)
1106 return PARSE_SYNTAX;
1107 token = g_scanner_get_next_token (scanner);
1109 error = gtk_rc_parse_state (scanner, &state);
1110 if (error != PARSE_OK)
1113 token = g_scanner_get_next_token (scanner);
1114 if (token != G_TOKEN_EQUAL_SIGN)
1117 error = gtk_rc_parse_color (scanner, &style->text[state]);
1123 gtk_rc_parse_bg_pixmap (GScanner *scanner,
1124 GtkRcStyle *rc_style)
1131 token = g_scanner_peek_next_token (scanner);
1132 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1134 if (token != TOKEN_BG_PIXMAP)
1135 return PARSE_SYNTAX;
1136 token = g_scanner_get_next_token (scanner);
1138 error = gtk_rc_parse_state (scanner, &state);
1139 if (error != PARSE_OK)
1142 token = g_scanner_get_next_token (scanner);
1143 if (token != G_TOKEN_EQUAL_SIGN)
1146 token = g_scanner_get_next_token (scanner);
1147 if (token != G_TOKEN_STRING)
1150 if (strcmp (scanner->value.v_string, "<parent>"))
1151 pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
1153 pixmap_file = g_strdup (scanner->value.v_string);
1157 if (rc_style->bg_pixmap_name[state])
1158 g_free (rc_style->bg_pixmap_name[state]);
1159 rc_style->bg_pixmap_name[state] = pixmap_file;
1166 gtk_rc_find_pixmap_in_path (GScanner *scanner,
1173 for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
1175 buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
1176 sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
1178 fd = open (buf, O_RDONLY);
1188 g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
1189 pixmap_file, scanner->line);
1195 gtk_rc_parse_font (GScanner *scanner,
1196 GtkRcStyle *rc_style)
1200 token = g_scanner_peek_next_token (scanner);
1201 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1203 if (token != TOKEN_FONT)
1204 return PARSE_SYNTAX;
1205 token = g_scanner_get_next_token (scanner);
1207 token = g_scanner_get_next_token (scanner);
1208 if (token != G_TOKEN_EQUAL_SIGN)
1211 token = g_scanner_get_next_token (scanner);
1212 if (token != G_TOKEN_STRING)
1215 if (rc_style->font_name)
1216 g_free (rc_style->font_name);
1217 rc_style->font_name = g_strdup (scanner->value.v_string);
1223 gtk_rc_parse_fontset (GScanner *scanner,
1224 GtkRcStyle *rc_style)
1228 token = g_scanner_peek_next_token (scanner);
1229 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1231 if (token != TOKEN_FONTSET)
1232 return PARSE_SYNTAX;
1233 token = g_scanner_get_next_token (scanner);
1235 token = g_scanner_get_next_token (scanner);
1236 if (token != G_TOKEN_EQUAL_SIGN)
1239 token = g_scanner_get_next_token (scanner);
1240 if (token != G_TOKEN_STRING)
1243 if (rc_style->fontset_name)
1244 g_free (rc_style->fontset_name);
1245 rc_style->fontset_name = g_strdup (scanner->value.v_string);
1251 gtk_rc_parse_state (GScanner *scanner,
1252 GtkStateType *state)
1256 token = g_scanner_peek_next_token (scanner);
1257 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1259 if (token != G_TOKEN_LEFT_BRACE)
1260 return PARSE_SYNTAX;
1261 token = g_scanner_get_next_token (scanner);
1263 token = g_scanner_get_next_token (scanner);
1264 if (token == TOKEN_ACTIVE)
1265 *state = GTK_STATE_ACTIVE;
1266 else if (token == TOKEN_INSENSITIVE)
1267 *state = GTK_STATE_INSENSITIVE;
1268 else if (token == TOKEN_NORMAL)
1269 *state = GTK_STATE_NORMAL;
1270 else if (token == TOKEN_PRELIGHT)
1271 *state = GTK_STATE_PRELIGHT;
1272 else if (token == TOKEN_SELECTED)
1273 *state = GTK_STATE_SELECTED;
1277 token = g_scanner_get_next_token (scanner);
1278 if (token != G_TOKEN_RIGHT_BRACE)
1285 gtk_rc_parse_color (GScanner *scanner,
1295 token = g_scanner_peek_next_token (scanner);
1296 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1301 case G_TOKEN_LEFT_CURLY:
1302 token = g_scanner_get_next_token (scanner);
1304 token = g_scanner_get_next_token (scanner);
1305 if (token == G_TOKEN_INT)
1306 token_int = scanner->value.v_int;
1307 else if (token == G_TOKEN_FLOAT)
1308 token_int = scanner->value.v_float * 65535.0;
1311 color->red = CLAMP (token_int, 0, 65535);
1313 token = g_scanner_get_next_token (scanner);
1314 if (token != G_TOKEN_COMMA)
1317 token = g_scanner_get_next_token (scanner);
1318 if (token == G_TOKEN_INT)
1319 token_int = scanner->value.v_int;
1320 else if (token == G_TOKEN_FLOAT)
1321 token_int = scanner->value.v_float * 65535.0;
1324 color->green = CLAMP (token_int, 0, 65535);
1326 token = g_scanner_get_next_token (scanner);
1327 if (token != G_TOKEN_COMMA)
1330 token = g_scanner_get_next_token (scanner);
1331 if (token == G_TOKEN_INT)
1332 token_int = scanner->value.v_int;
1333 else if (token == G_TOKEN_FLOAT)
1334 token_int = scanner->value.v_float * 65535.0;
1337 color->blue = CLAMP (token_int, 0, 65535);
1339 token = g_scanner_get_next_token (scanner);
1340 if (token != G_TOKEN_RIGHT_CURLY)
1344 case G_TOKEN_STRING:
1345 token = g_scanner_get_next_token (scanner);
1347 if (scanner->value.v_string[0] != '#')
1350 length = strlen (scanner->value.v_string) - 1;
1351 if (((length % 3) != 0) || (length > 12))
1355 for (i = 0, j = 1; i < length; i++, j++)
1356 buf[i] = scanner->value.v_string[j];
1359 sscanf (buf, "%x", &temp);
1362 for (i = 0; i < length; i++, j++)
1363 buf[i] = scanner->value.v_string[j];
1366 sscanf (buf, "%x", &temp);
1367 color->green = temp;
1369 for (i = 0; i < length; i++, j++)
1370 buf[i] = scanner->value.v_string[j];
1373 sscanf (buf, "%x", &temp);
1379 color->green *= 4369;
1380 color->blue *= 4369;
1382 else if (length == 2)
1385 color->green *= 257;
1388 else if (length == 3)
1400 return PARSE_SYNTAX;
1407 gtk_rc_parse_pixmap_path (GScanner *scanner)
1411 token = g_scanner_peek_next_token (scanner);
1412 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1414 if (token != TOKEN_PIXMAP_PATH)
1415 return PARSE_SYNTAX;
1416 token = g_scanner_get_next_token (scanner);
1418 token = g_scanner_get_next_token (scanner);
1420 if (token != G_TOKEN_STRING)
1423 gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
1429 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
1433 gint start_offset = 0;
1437 /* free the old one, or just add to the old one ? */
1438 for (path_num=0; pixmap_path[path_num]; path_num++)
1440 g_free (pixmap_path[path_num]);
1441 pixmap_path[path_num] = NULL;
1446 path_len = strlen (pix_path);
1448 buf = g_strdup (pix_path);
1450 for (end_offset = 0; end_offset <= path_len; end_offset++)
1452 if ((buf[end_offset] == ':') ||
1453 (end_offset == path_len))
1455 buf[end_offset] = '\0';
1456 pixmap_path[path_num] = g_strdup (buf + start_offset);
1458 pixmap_path[path_num] = NULL;
1459 start_offset = end_offset + 1;
1466 gtk_rc_parse_widget_style (GScanner *scanner)
1471 token = g_scanner_peek_next_token (scanner);
1472 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1474 if (token != TOKEN_WIDGET)
1475 return PARSE_SYNTAX;
1476 token = g_scanner_get_next_token (scanner);
1478 token = g_scanner_get_next_token (scanner);
1479 if (token != G_TOKEN_STRING)
1482 rc_set = g_new (GtkRcSet, 1);
1483 rc_set->set = g_strdup (scanner->value.v_string);
1485 token = g_scanner_get_next_token (scanner);
1486 if (token != TOKEN_STYLE)
1488 g_free (rc_set->set);
1493 token = g_scanner_get_next_token (scanner);
1494 if (token != G_TOKEN_STRING)
1496 g_free (rc_set->set);
1501 rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string);
1502 if (!rc_set->rc_style)
1504 g_free (rc_set->set);
1509 widget_sets = g_slist_append (widget_sets, rc_set);
1515 gtk_rc_parse_widget_class_style (GScanner *scanner)
1520 token = g_scanner_peek_next_token (scanner);
1521 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1523 if (token != TOKEN_WIDGET_CLASS)
1524 return PARSE_SYNTAX;
1525 token = g_scanner_get_next_token (scanner);
1527 token = g_scanner_get_next_token (scanner);
1528 if (token != G_TOKEN_STRING)
1531 rc_set = g_new (GtkRcSet, 1);
1532 rc_set->set = g_strdup (scanner->value.v_string);
1534 token = g_scanner_get_next_token (scanner);
1535 if (token != TOKEN_STYLE)
1537 g_free (rc_set->set);
1542 token = g_scanner_get_next_token (scanner);
1543 if (token != G_TOKEN_STRING)
1545 g_free (rc_set->set);
1550 rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string);
1551 if (!rc_set->rc_style)
1553 g_free (rc_set->set);
1558 widget_class_sets = g_slist_append (widget_class_sets, rc_set);
1564 gtk_rc_widget_path (GtkWidget *widget)
1566 GtkWidget *tmp_widget;
1575 tmp_widget = widget;
1578 name = gtk_widget_get_name (tmp_widget);
1579 pathlength += strlen (name);
1581 tmp_widget = tmp_widget->parent;
1587 path = g_new (char, pathlength + 1);
1588 path[pathlength] = '\0';
1590 tmp_widget = widget;
1593 name = gtk_widget_get_name (tmp_widget);
1594 namelength = strlen (name);
1596 strncpy (&path[pathlength - namelength], name, namelength);
1597 pathlength -= namelength;
1599 tmp_widget = tmp_widget->parent;
1604 path[pathlength] = '.';
1612 gtk_rc_widget_class_path (GtkWidget *widget)
1614 GtkWidget *tmp_widget;
1623 tmp_widget = widget;
1626 name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
1627 pathlength += strlen (name);
1629 tmp_widget = tmp_widget->parent;
1635 path = g_new (char, pathlength + 1);
1636 path[pathlength] = '\0';
1638 tmp_widget = widget;
1641 name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
1642 namelength = strlen (name);
1644 strncpy (&path[pathlength - namelength], name, namelength);
1645 pathlength -= namelength;
1647 tmp_widget = tmp_widget->parent;
1652 path[pathlength] = '.';
1660 typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
1661 GdkColormap *colormap,
1663 GdkColor *transparent_color,
1664 const gchar *filename);
1668 gtk_rc_set_loader(GtkImageLoader loader)
1670 image_loader = loader;