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 Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 TOKEN_INVALID = G_TOKEN_LAST,
61 typedef struct _GtkRcStyle GtkRcStyle;
62 typedef struct _GtkRcSet GtkRcSet;
63 typedef struct _GtkRcNode GtkRcNode;
76 char *bg_pixmap_name[5];
77 GtkStyle *proto_style;
88 static guint gtk_rc_style_hash (const char *name);
89 static gint gtk_rc_style_compare (const char *a,
91 static GtkRcStyle* gtk_rc_style_find (const char *name);
92 static GtkRcStyle* gtk_rc_styles_match (GSList *sets,
94 static gint gtk_rc_style_match (const char *set,
96 static GtkStyle* gtk_rc_style_init (GtkRcStyle *rc_style,
98 static void gtk_rc_parse_any (const gchar *input_name,
100 const gchar *input_string);
101 static gint gtk_rc_parse_statement (GScanner *scanner);
102 static gint gtk_rc_parse_style (GScanner *scanner);
103 static gint gtk_rc_parse_style_option (GScanner *scanner,
104 GtkRcStyle *rc_style);
105 static gint gtk_rc_parse_base (GScanner *scanner,
107 static gint gtk_rc_parse_bg (GScanner *scanner,
109 static gint gtk_rc_parse_fg (GScanner *scanner,
111 static gint gtk_rc_parse_text (GScanner *scanner,
113 static gint gtk_rc_parse_bg_pixmap (GScanner *scanner,
114 GtkRcStyle *rc_style);
115 static gint gtk_rc_parse_font (GScanner *scanner,
116 GtkRcStyle *rc_style);
117 static gint gtk_rc_parse_fontset (GScanner *scanner,
118 GtkRcStyle *rc_style);
119 static gint gtk_rc_parse_state (GScanner *scanner,
120 GtkStateType *state);
121 static gint gtk_rc_parse_color (GScanner *scanner,
123 static gint gtk_rc_parse_pixmap_path (GScanner *scanner);
124 static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
125 static char* gtk_rc_find_pixmap_in_path (GScanner *scanner,
127 static gint gtk_rc_parse_widget_style (GScanner *scanner);
128 static gint gtk_rc_parse_widget_class_style (GScanner *scanner);
129 static char* gtk_rc_widget_path (GtkWidget *widget);
130 static char* gtk_rc_widget_class_path (GtkWidget *widget);
133 static GScannerConfig gtk_rc_scanner_config =
137 ) /* cset_skip_characters */,
142 ) /* cset_identifier_first */,
149 ) /* cset_identifier_nth */,
150 ( "#\n" ) /* cpair_comment_single */,
152 TRUE /* case_sensitive */,
154 TRUE /* skip_comment_multi */,
155 TRUE /* skip_comment_single */,
156 TRUE /* scan_comment_multi */,
157 TRUE /* scan_identifier */,
158 FALSE /* scan_identifier_1char */,
159 FALSE /* scan_identifier_NULL */,
160 TRUE /* scan_symbols */,
161 TRUE /* scan_binary */,
162 TRUE /* scan_octal */,
163 TRUE /* scan_float */,
165 TRUE /* scan_hex_dollar */,
166 TRUE /* scan_string_sq */,
167 TRUE /* scan_string_dq */,
168 TRUE /* numbers_2_int */,
169 FALSE /* int_2_float */,
170 TRUE /* identifier_2_string */,
171 TRUE /* char_2_token */,
172 TRUE /* symbol_2_token */,
181 { "ACTIVE", TOKEN_ACTIVE },
182 { "base", TOKEN_BASE },
184 { "bg_pixmap", TOKEN_BG_PIXMAP },
186 { "font", TOKEN_FONT },
187 { "fontset", TOKEN_FONTSET },
188 { "INSENSITIVE", TOKEN_INSENSITIVE },
189 { "NORMAL", TOKEN_NORMAL },
190 { "pixmap_path", TOKEN_PIXMAP_PATH },
191 { "PRELIGHT", TOKEN_PRELIGHT },
192 { "SELECTED", TOKEN_SELECTED },
193 { "style", TOKEN_STYLE },
194 { "text", TOKEN_TEXT },
195 { "widget", TOKEN_WIDGET },
196 { "widget_class", TOKEN_WIDGET_CLASS },
198 static int nsymbols = sizeof (symbols) / sizeof (symbols[0]);
202 static GHashTable *rc_style_ht = NULL;
203 static GSList *widget_sets = NULL;
204 static GSList *widget_class_sets = NULL;
206 #define GTK_RC_MAX_PIXMAP_PATHS 128
207 static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
213 rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
214 (GCompareFunc) gtk_rc_style_compare);
218 gtk_rc_parse_string (const gchar *rc_string)
220 g_return_if_fail (rc_string != NULL);
222 gtk_rc_parse_any ("-", -1, rc_string);
226 gtk_rc_parse (const gchar *filename)
230 g_return_if_fail (filename != NULL);
232 fd = open (filename, O_RDONLY);
236 gtk_rc_parse_any (filename, fd, NULL);
242 gtk_rc_get_style (GtkWidget *widget)
244 GtkRcStyle *rc_style;
249 path = gtk_rc_widget_path (widget);
252 rc_style = gtk_rc_styles_match (widget_sets, path);
257 return gtk_rc_style_init (rc_style,
258 gtk_widget_get_colormap (widget));
263 if (widget_class_sets)
265 path = gtk_rc_widget_class_path (widget);
268 rc_style = gtk_rc_styles_match (widget_class_sets, path);
273 return gtk_rc_style_init (rc_style,
274 gtk_widget_get_colormap (widget));
283 gtk_rc_add_widget_name_style (GtkStyle *style,
286 GtkRcStyle *rc_style;
290 gtk_style_ref (style);
292 rc_style = g_new (GtkRcStyle, 1);
293 rc_style->name = NULL;
294 rc_style->font_name = NULL;
295 rc_style->fontset_name = NULL;
297 for (i = 0; i < 5; i++)
298 rc_style->bg_pixmap_name[i] = NULL;
300 rc_style->styles = g_list_append (NULL, style);
302 rc_set = g_new (GtkRcSet, 1);
303 rc_set->set = g_strdup (pattern);
304 rc_set->rc_style = rc_style;
306 widget_sets = g_slist_append (widget_sets, rc_set);
310 gtk_rc_add_widget_class_style (GtkStyle *style,
313 GtkRcStyle *rc_style;
317 gtk_style_ref (style);
319 rc_style = g_new (GtkRcStyle, 1);
320 rc_style->name = NULL;
321 rc_style->font_name = NULL;
322 rc_style->fontset_name = NULL;
324 for (i = 0; i < 5; i++)
325 rc_style->bg_pixmap_name[i] = NULL;
327 rc_style->styles = g_list_append (NULL, style);
329 rc_set = g_new (GtkRcSet, 1);
330 rc_set->set = g_strdup (pattern);
331 rc_set->rc_style = rc_style;
333 widget_class_sets = g_slist_append (widget_class_sets, rc_set);
337 gtk_rc_parse_any (const gchar *input_name,
339 const gchar *input_string)
344 scanner = g_scanner_new (>k_rc_scanner_config);
348 g_assert (input_string == NULL);
350 g_scanner_input_file (scanner, input_fd);
354 g_assert (input_string != NULL);
356 g_scanner_input_text (scanner, input_string, strlen (input_string));
359 for (i = 0; i < nsymbols; i++)
360 g_scanner_add_symbol (scanner, symbols[i].name, (gpointer) symbols[i].token);
365 if (gtk_rc_parse_statement (scanner) != PARSE_OK)
367 if (scanner->next_token != G_TOKEN_NONE)
368 g_scanner_get_next_token (scanner);
371 g_warning ("rc string parse error: line %d",
374 g_warning ("rc file parse error: \"%s\" line %d",
381 g_scanner_destroy (scanner);
385 gtk_rc_style_hash (const char *name)
391 result += (result << 3) + *name++;
397 gtk_rc_style_compare (const char *a,
400 return (strcmp (a, b) == 0);
404 gtk_rc_style_find (const char *name)
406 GtkRcStyle *rc_style;
408 rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
414 gtk_rc_styles_match (GSList *sets,
424 if (gtk_rc_style_match (rc_set->set, path))
425 return rc_set->rc_style;
432 gtk_rc_style_match (const char *set,
441 return (*path == '\0');
455 while (*path && (ch != *path))
462 if (gtk_rc_style_match (set, path))
483 gtk_rc_style_init (GtkRcStyle *rc_style, GdkColormap *cmap)
489 GtkStyle *style = NULL;
491 tmp_list = rc_style->styles;
495 GtkRcNode *node = (GtkRcNode *)tmp_list->data;
497 if (node->cmap == cmap)
500 tmp_list = tmp_list->next;
505 style = gtk_style_copy (rc_style->proto_style);
507 if (rc_style->fontset_name)
509 old_font = style->font;
510 style->font = gdk_fontset_load (rc_style->fontset_name);
512 gdk_font_unref (old_font);
514 style->font = old_font;
516 else if (rc_style->font_name)
518 old_font = style->font;
519 style->font = gdk_font_load (rc_style->font_name);
521 gdk_font_unref (old_font);
523 style->font = old_font;
526 for (i = 0; i < 5; i++)
527 if (rc_style->bg_pixmap_name[i])
529 if (strcmp (rc_style->bg_pixmap_name[i], "<parent>") == 0)
530 style->bg_pixmap[i] = (GdkPixmap*) GDK_PARENT_RELATIVE;
532 style->bg_pixmap[i] =
533 gdk_pixmap_colormap_create_from_xpm (NULL, cmap,
536 rc_style->bg_pixmap_name[i]);
539 rc_style->styles = g_list_append (rc_style->styles, style);
541 /* FIXME, this leaks colormaps, but if we don't do this, then we'll
542 * be screwed, because we identify colormaps by address equality
544 gdk_colormap_ref (cmap);
551 gtk_rc_parse_statement (GScanner *scanner)
556 token = g_scanner_peek_next_token (scanner);
557 if (token == G_TOKEN_EOF)
563 error = gtk_rc_parse_style (scanner);
564 if (error != PARSE_SYNTAX)
567 error = gtk_rc_parse_pixmap_path (scanner);
568 if (error != PARSE_SYNTAX)
571 error = gtk_rc_parse_widget_style (scanner);
572 if (error != PARSE_SYNTAX)
575 error = gtk_rc_parse_widget_class_style (scanner);
581 gtk_rc_parse_style (GScanner *scanner)
583 GtkRcStyle *rc_style;
584 GtkRcStyle *parent_style;
590 token = g_scanner_peek_next_token (scanner);
591 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
593 if (token != TOKEN_STYLE)
595 token = g_scanner_get_next_token (scanner);
597 token = g_scanner_get_next_token (scanner);
598 if (token != G_TOKEN_STRING)
602 rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
607 rc_style = g_new (GtkRcStyle, 1);
608 rc_style->name = g_strdup (scanner->value.v_string);
609 rc_style->font_name = NULL;
610 rc_style->fontset_name = NULL;
612 for (i = 0; i < 5; i++)
613 rc_style->bg_pixmap_name[i] = NULL;
615 rc_style->proto_style = gtk_style_new();
616 rc_style->styles = NULL;
619 token = g_scanner_peek_next_token (scanner);
620 if (token == G_TOKEN_EQUAL_SIGN)
622 token = g_scanner_get_next_token (scanner);
624 token = g_scanner_get_next_token (scanner);
625 if (token != G_TOKEN_STRING)
629 gtk_style_unref (rc_style->proto_style);
635 parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
638 for (i = 0; i < 5; i++)
640 rc_style->proto_style->fg[i] = parent_style->proto_style->fg[i];
641 rc_style->proto_style->bg[i] = parent_style->proto_style->bg[i];
642 rc_style->proto_style->light[i] = parent_style->proto_style->light[i];
643 rc_style->proto_style->dark[i] = parent_style->proto_style->dark[i];
644 rc_style->proto_style->mid[i] = parent_style->proto_style->mid[i];
645 rc_style->proto_style->text[i] = parent_style->proto_style->text[i];
646 rc_style->proto_style->base[i] = parent_style->proto_style->base[i];
649 rc_style->proto_style->black = parent_style->proto_style->black;
650 rc_style->proto_style->white = parent_style->proto_style->white;
652 if (rc_style->fontset_name)
654 g_free (rc_style->fontset_name);
655 rc_style->fontset_name = g_strdup (parent_style->fontset_name);
657 else if (rc_style->font_name)
659 g_free (rc_style->font_name);
660 rc_style->font_name = g_strdup (parent_style->font_name);
663 for (i = 0; i < 5; i++)
665 if (rc_style->bg_pixmap_name[i])
666 g_free (rc_style->bg_pixmap_name[i]);
667 rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
672 token = g_scanner_get_next_token (scanner);
673 if (token != G_TOKEN_LEFT_CURLY)
677 gtk_style_unref (rc_style->proto_style);
685 error = gtk_rc_parse_style_option (scanner, rc_style);
686 if (error == PARSE_SYNTAX)
688 if (error == PARSE_ERROR)
692 gtk_style_unref (rc_style->proto_style);
699 token = g_scanner_get_next_token (scanner);
700 if (token != G_TOKEN_RIGHT_CURLY)
704 if (rc_style->fontset_name)
705 g_free (rc_style->fontset_name);
706 else if (rc_style->font_name)
707 g_free (rc_style->font_name);
709 for (i = 0; i < 5; i++)
710 if (rc_style->bg_pixmap_name[i])
711 g_free (rc_style->bg_pixmap_name[i]);
713 gtk_style_unref (rc_style->proto_style);
720 g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
726 gtk_rc_parse_style_option (GScanner *scanner,
727 GtkRcStyle *rc_style)
732 token = g_scanner_peek_next_token (scanner);
733 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
736 error = gtk_rc_parse_base (scanner, rc_style->proto_style);
737 if (error != PARSE_SYNTAX)
740 error = gtk_rc_parse_bg (scanner, rc_style->proto_style);
741 if (error != PARSE_SYNTAX)
744 error = gtk_rc_parse_fg (scanner, rc_style->proto_style);
745 if (error != PARSE_SYNTAX)
748 error = gtk_rc_parse_text (scanner, rc_style->proto_style);
749 if (error != PARSE_SYNTAX)
752 error = gtk_rc_parse_bg_pixmap (scanner, rc_style);
753 if (error != PARSE_SYNTAX)
756 error = gtk_rc_parse_font (scanner, rc_style);
757 if (error != PARSE_SYNTAX)
760 error = gtk_rc_parse_fontset (scanner, rc_style);
766 gtk_rc_parse_base (GScanner *scanner,
773 token = g_scanner_peek_next_token (scanner);
774 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
776 if (token != TOKEN_BASE)
778 token = g_scanner_get_next_token (scanner);
780 error = gtk_rc_parse_state (scanner, &state);
781 if (error != PARSE_OK)
784 token = g_scanner_get_next_token (scanner);
785 if (token != G_TOKEN_EQUAL_SIGN)
788 error = gtk_rc_parse_color (scanner, &style->base[state]);
794 gtk_rc_parse_bg (GScanner *scanner,
801 token = g_scanner_peek_next_token (scanner);
802 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
804 if (token != TOKEN_BG)
806 token = g_scanner_get_next_token (scanner);
808 error = gtk_rc_parse_state (scanner, &state);
809 if (error != PARSE_OK)
812 token = g_scanner_get_next_token (scanner);
813 if (token != G_TOKEN_EQUAL_SIGN)
816 error = gtk_rc_parse_color (scanner, &style->bg[state]);
822 gtk_rc_parse_fg (GScanner *scanner,
829 token = g_scanner_peek_next_token (scanner);
830 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
832 if (token != TOKEN_FG)
834 token = g_scanner_get_next_token (scanner);
836 error = gtk_rc_parse_state (scanner, &state);
837 if (error != PARSE_OK)
840 token = g_scanner_get_next_token (scanner);
841 if (token != G_TOKEN_EQUAL_SIGN)
844 error = gtk_rc_parse_color (scanner, &style->fg[state]);
850 gtk_rc_parse_text (GScanner *scanner,
857 token = g_scanner_peek_next_token (scanner);
858 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
860 if (token != TOKEN_TEXT)
862 token = g_scanner_get_next_token (scanner);
864 error = gtk_rc_parse_state (scanner, &state);
865 if (error != PARSE_OK)
868 token = g_scanner_get_next_token (scanner);
869 if (token != G_TOKEN_EQUAL_SIGN)
872 error = gtk_rc_parse_color (scanner, &style->text[state]);
878 gtk_rc_parse_bg_pixmap (GScanner *scanner,
879 GtkRcStyle *rc_style)
886 token = g_scanner_peek_next_token (scanner);
887 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
889 if (token != TOKEN_BG_PIXMAP)
891 token = g_scanner_get_next_token (scanner);
893 error = gtk_rc_parse_state (scanner, &state);
894 if (error != PARSE_OK)
897 token = g_scanner_get_next_token (scanner);
898 if (token != G_TOKEN_EQUAL_SIGN)
901 token = g_scanner_get_next_token (scanner);
902 if (token != G_TOKEN_STRING)
905 if (strcmp (scanner->value.v_string, "<parent>"))
906 pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
908 pixmap_file = g_strdup (scanner->value.v_string);
912 if (rc_style->bg_pixmap_name[state])
913 g_free (rc_style->bg_pixmap_name[state]);
914 rc_style->bg_pixmap_name[state] = pixmap_file;
921 gtk_rc_find_pixmap_in_path (GScanner *scanner,
928 for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
930 buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
931 sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
933 fd = open (buf, O_RDONLY);
943 g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
944 pixmap_file, scanner->line);
950 gtk_rc_parse_font (GScanner *scanner,
951 GtkRcStyle *rc_style)
955 token = g_scanner_peek_next_token (scanner);
956 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
958 if (token != TOKEN_FONT)
960 token = g_scanner_get_next_token (scanner);
962 token = g_scanner_get_next_token (scanner);
963 if (token != G_TOKEN_EQUAL_SIGN)
966 token = g_scanner_get_next_token (scanner);
967 if (token != G_TOKEN_STRING)
970 if (rc_style->font_name)
971 g_free (rc_style->font_name);
972 rc_style->font_name = g_strdup (scanner->value.v_string);
978 gtk_rc_parse_fontset (GScanner *scanner,
979 GtkRcStyle *rc_style)
983 token = g_scanner_peek_next_token (scanner);
984 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
986 if (token != TOKEN_FONTSET)
988 token = g_scanner_get_next_token (scanner);
990 token = g_scanner_get_next_token (scanner);
991 if (token != G_TOKEN_EQUAL_SIGN)
994 token = g_scanner_get_next_token (scanner);
995 if (token != G_TOKEN_STRING)
998 if (rc_style->fontset_name)
999 g_free (rc_style->fontset_name);
1000 rc_style->fontset_name = g_strdup (scanner->value.v_string);
1006 gtk_rc_parse_state (GScanner *scanner,
1007 GtkStateType *state)
1011 token = g_scanner_peek_next_token (scanner);
1012 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1014 if (token != G_TOKEN_LEFT_BRACE)
1015 return PARSE_SYNTAX;
1016 token = g_scanner_get_next_token (scanner);
1018 token = g_scanner_get_next_token (scanner);
1019 if (token == TOKEN_ACTIVE)
1020 *state = GTK_STATE_ACTIVE;
1021 else if (token == TOKEN_INSENSITIVE)
1022 *state = GTK_STATE_INSENSITIVE;
1023 else if (token == TOKEN_NORMAL)
1024 *state = GTK_STATE_NORMAL;
1025 else if (token == TOKEN_PRELIGHT)
1026 *state = GTK_STATE_PRELIGHT;
1027 else if (token == TOKEN_SELECTED)
1028 *state = GTK_STATE_SELECTED;
1032 token = g_scanner_get_next_token (scanner);
1033 if (token != G_TOKEN_RIGHT_BRACE)
1040 gtk_rc_parse_color (GScanner *scanner,
1050 token = g_scanner_peek_next_token (scanner);
1051 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1056 case G_TOKEN_LEFT_CURLY:
1057 token = g_scanner_get_next_token (scanner);
1059 token = g_scanner_get_next_token (scanner);
1060 if (token == G_TOKEN_INT)
1061 token_int = scanner->value.v_int;
1062 else if (token == G_TOKEN_FLOAT)
1063 token_int = scanner->value.v_float * 65535.0;
1066 color->red = CLAMP (token_int, 0, 65535);
1068 token = g_scanner_get_next_token (scanner);
1069 if (token != G_TOKEN_COMMA)
1072 token = g_scanner_get_next_token (scanner);
1073 if (token == G_TOKEN_INT)
1074 token_int = scanner->value.v_int;
1075 else if (token == G_TOKEN_FLOAT)
1076 token_int = scanner->value.v_float * 65535.0;
1079 color->green = CLAMP (token_int, 0, 65535);
1081 token = g_scanner_get_next_token (scanner);
1082 if (token != G_TOKEN_COMMA)
1085 token = g_scanner_get_next_token (scanner);
1086 if (token == G_TOKEN_INT)
1087 token_int = scanner->value.v_int;
1088 else if (token == G_TOKEN_FLOAT)
1089 token_int = scanner->value.v_float * 65535.0;
1092 color->blue = CLAMP (token_int, 0, 65535);
1094 token = g_scanner_get_next_token (scanner);
1095 if (token != G_TOKEN_RIGHT_CURLY)
1099 case G_TOKEN_STRING:
1100 token = g_scanner_get_next_token (scanner);
1102 if (scanner->value.v_string[0] != '#')
1105 length = strlen (scanner->value.v_string) - 1;
1106 if (((length % 3) != 0) || (length > 12))
1110 for (i = 0, j = 1; i < length; i++, j++)
1111 buf[i] = scanner->value.v_string[j];
1114 sscanf (buf, "%x", &temp);
1117 for (i = 0; i < length; i++, j++)
1118 buf[i] = scanner->value.v_string[j];
1121 sscanf (buf, "%x", &temp);
1122 color->green = temp;
1124 for (i = 0; i < length; i++, j++)
1125 buf[i] = scanner->value.v_string[j];
1128 sscanf (buf, "%x", &temp);
1134 color->green *= 4369;
1135 color->blue *= 4369;
1137 else if (length == 2)
1140 color->green *= 257;
1143 else if (length == 3)
1155 return PARSE_SYNTAX;
1162 gtk_rc_parse_pixmap_path (GScanner *scanner)
1166 token = g_scanner_peek_next_token (scanner);
1167 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1169 if (token != TOKEN_PIXMAP_PATH)
1170 return PARSE_SYNTAX;
1171 token = g_scanner_get_next_token (scanner);
1173 token = g_scanner_get_next_token (scanner);
1175 if (token != G_TOKEN_STRING)
1178 gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
1184 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
1188 gint start_offset = 0;
1192 /* free the old one, or just add to the old one ? */
1193 for (path_num=0; pixmap_path[path_num]; path_num++)
1195 g_free (pixmap_path[path_num]);
1196 pixmap_path[path_num] = NULL;
1201 path_len = strlen (pix_path);
1203 buf = g_strdup (pix_path);
1205 for (end_offset = 0; end_offset <= path_len; end_offset++)
1207 if ((buf[end_offset] == ':') ||
1208 (end_offset == path_len))
1210 buf[end_offset] = '\0';
1211 pixmap_path[path_num] = g_strdup (buf + start_offset);
1213 pixmap_path[path_num] = NULL;
1214 start_offset = end_offset + 1;
1221 gtk_rc_parse_widget_style (GScanner *scanner)
1226 token = g_scanner_peek_next_token (scanner);
1227 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1229 if (token != TOKEN_WIDGET)
1230 return PARSE_SYNTAX;
1231 token = g_scanner_get_next_token (scanner);
1233 token = g_scanner_get_next_token (scanner);
1234 if (token != G_TOKEN_STRING)
1237 rc_set = g_new (GtkRcSet, 1);
1238 rc_set->set = g_strdup (scanner->value.v_string);
1240 token = g_scanner_get_next_token (scanner);
1241 if (token != TOKEN_STYLE)
1243 g_free (rc_set->set);
1248 token = g_scanner_get_next_token (scanner);
1249 if (token != G_TOKEN_STRING)
1251 g_free (rc_set->set);
1256 rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string);
1257 if (!rc_set->rc_style)
1259 g_free (rc_set->set);
1264 widget_sets = g_slist_append (widget_sets, rc_set);
1270 gtk_rc_parse_widget_class_style (GScanner *scanner)
1275 token = g_scanner_peek_next_token (scanner);
1276 if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
1278 if (token != TOKEN_WIDGET_CLASS)
1279 return PARSE_SYNTAX;
1280 token = g_scanner_get_next_token (scanner);
1282 token = g_scanner_get_next_token (scanner);
1283 if (token != G_TOKEN_STRING)
1286 rc_set = g_new (GtkRcSet, 1);
1287 rc_set->set = g_strdup (scanner->value.v_string);
1289 token = g_scanner_get_next_token (scanner);
1290 if (token != TOKEN_STYLE)
1292 g_free (rc_set->set);
1297 token = g_scanner_get_next_token (scanner);
1298 if (token != G_TOKEN_STRING)
1300 g_free (rc_set->set);
1305 rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string);
1306 if (!rc_set->rc_style)
1308 g_free (rc_set->set);
1313 widget_class_sets = g_slist_append (widget_class_sets, rc_set);
1319 gtk_rc_widget_path (GtkWidget *widget)
1321 GtkWidget *tmp_widget;
1330 tmp_widget = widget;
1333 name = gtk_widget_get_name (tmp_widget);
1334 pathlength += strlen (name);
1336 tmp_widget = tmp_widget->parent;
1342 path = g_new (char, pathlength + 1);
1343 path[pathlength] = '\0';
1345 tmp_widget = widget;
1348 name = gtk_widget_get_name (tmp_widget);
1349 namelength = strlen (name);
1351 strncpy (&path[pathlength - namelength], name, namelength);
1352 pathlength -= namelength;
1354 tmp_widget = tmp_widget->parent;
1359 path[pathlength] = '.';
1367 gtk_rc_widget_class_path (GtkWidget *widget)
1369 GtkWidget *tmp_widget;
1378 tmp_widget = widget;
1381 name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
1382 pathlength += strlen (name);
1384 tmp_widget = tmp_widget->parent;
1390 path = g_new (char, pathlength + 1);
1391 path[pathlength] = '\0';
1393 tmp_widget = widget;
1396 name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
1397 namelength = strlen (name);
1399 strncpy (&path[pathlength - namelength], name, namelength);
1400 pathlength -= namelength;
1402 tmp_widget = tmp_widget->parent;
1407 path[pathlength] = '.';