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 Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 #ifdef GDK_WINDOWING_X11
30 #include <X11/Xlocale.h> /* so we get the right setlocale */
39 #ifdef HAVE_SYS_PARAM_H
40 #include <sys/param.h>
52 #include "gdkconfig.h"
54 #include "gtkcompat.h"
56 #include "gtkbindings.h"
57 #include "gtkthemes.h"
59 #include "gtkiconfactory.h"
65 typedef struct _GtkRcSet GtkRcSet;
66 typedef struct _GtkRcNode GtkRcNode;
67 typedef struct _GtkRcFile GtkRcFile;
79 gchar *canonical_name;
83 static guint gtk_rc_style_hash (const char *name);
84 static gboolean gtk_rc_style_equal (const char *a,
86 static guint gtk_rc_styles_hash (const GSList *rc_styles);
87 static gboolean gtk_rc_styles_equal (const GSList *a,
89 static GtkRcStyle* gtk_rc_style_find (const char *name);
90 static GSList * gtk_rc_styles_match (GSList *rc_styles,
94 gchar *path_reversed);
95 static GtkStyle * gtk_rc_style_to_style (GtkRcStyle *rc_style);
96 static GtkStyle* gtk_rc_init_style (GSList *rc_styles);
97 static void gtk_rc_parse_file (const gchar *filename,
99 static void gtk_rc_parse_any (const gchar *input_name,
101 const gchar *input_string);
102 static guint gtk_rc_parse_statement (GScanner *scanner);
103 static guint gtk_rc_parse_style (GScanner *scanner);
104 static guint gtk_rc_parse_bg (GScanner *scanner,
106 static guint gtk_rc_parse_fg (GScanner *scanner,
108 static guint gtk_rc_parse_text (GScanner *scanner,
110 static guint gtk_rc_parse_base (GScanner *scanner,
112 static guint gtk_rc_parse_xthickness (GScanner *scanner,
114 static guint gtk_rc_parse_ythickness (GScanner *scanner,
116 static guint gtk_rc_parse_bg_pixmap (GScanner *scanner,
117 GtkRcStyle *rc_style);
118 static guint gtk_rc_parse_font (GScanner *scanner,
119 GtkRcStyle *rc_style);
120 static guint gtk_rc_parse_fontset (GScanner *scanner,
121 GtkRcStyle *rc_style);
122 static guint gtk_rc_parse_font_name (GScanner *scanner,
123 GtkRcStyle *rc_style);
124 static guint gtk_rc_parse_engine (GScanner *scanner,
125 GtkRcStyle **rc_style);
126 static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
127 static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
128 static guint gtk_rc_parse_module_path (GScanner *scanner);
129 static void gtk_rc_parse_module_path_string (gchar *mod_path);
130 static guint gtk_rc_parse_im_module_path (GScanner *scanner);
131 static guint gtk_rc_parse_im_module_file (GScanner *scanner);
132 static guint gtk_rc_parse_path_pattern (GScanner *scanner);
133 static guint gtk_rc_parse_stock (GScanner *scanner,
134 GtkRcStyle *rc_style,
135 GtkIconFactory *factory);
136 static void gtk_rc_clear_hash_node (gpointer key,
139 static void gtk_rc_clear_styles (void);
140 static void gtk_rc_append_default_module_path (void);
141 static void gtk_rc_add_initial_default_files (void);
143 static void gtk_rc_style_init (GtkRcStyle *style);
144 static void gtk_rc_style_class_init (GtkRcStyleClass *klass);
145 static void gtk_rc_style_finalize (GObject *object);
146 static void gtk_rc_style_real_merge (GtkRcStyle *dest,
148 static GtkRcStyle *gtk_rc_style_real_clone (GtkRcStyle *rc_style);
149 static GtkStyle * gtk_rc_style_real_create_style (GtkRcStyle *rc_style);
151 static gpointer parent_class = NULL;
153 static const GScannerConfig gtk_rc_scanner_config =
157 ) /* cset_skip_characters */,
162 ) /* cset_identifier_first */,
167 ) /* cset_identifier_nth */,
168 ( "#\n" ) /* cpair_comment_single */,
170 TRUE /* case_sensitive */,
172 TRUE /* skip_comment_multi */,
173 TRUE /* skip_comment_single */,
174 TRUE /* scan_comment_multi */,
175 TRUE /* scan_identifier */,
176 FALSE /* scan_identifier_1char */,
177 FALSE /* scan_identifier_NULL */,
178 TRUE /* scan_symbols */,
179 TRUE /* scan_binary */,
180 TRUE /* scan_octal */,
181 TRUE /* scan_float */,
183 TRUE /* scan_hex_dollar */,
184 TRUE /* scan_string_sq */,
185 TRUE /* scan_string_dq */,
186 TRUE /* numbers_2_int */,
187 FALSE /* int_2_float */,
188 FALSE /* identifier_2_string */,
189 TRUE /* char_2_token */,
190 TRUE /* symbol_2_token */,
191 FALSE /* scope_0_fallback */,
199 { "include", GTK_RC_TOKEN_INCLUDE },
200 { "NORMAL", GTK_RC_TOKEN_NORMAL },
201 { "ACTIVE", GTK_RC_TOKEN_ACTIVE },
202 { "PRELIGHT", GTK_RC_TOKEN_PRELIGHT },
203 { "SELECTED", GTK_RC_TOKEN_SELECTED },
204 { "INSENSITIVE", GTK_RC_TOKEN_INSENSITIVE },
205 { "fg", GTK_RC_TOKEN_FG },
206 { "bg", GTK_RC_TOKEN_BG },
207 { "text", GTK_RC_TOKEN_TEXT },
208 { "base", GTK_RC_TOKEN_BASE },
209 { "xthickness", GTK_RC_TOKEN_XTHICKNESS },
210 { "ythickness", GTK_RC_TOKEN_YTHICKNESS },
211 { "font", GTK_RC_TOKEN_FONT },
212 { "fontset", GTK_RC_TOKEN_FONTSET },
213 { "font_name", GTK_RC_TOKEN_FONT_NAME },
214 { "bg_pixmap", GTK_RC_TOKEN_BG_PIXMAP },
215 { "pixmap_path", GTK_RC_TOKEN_PIXMAP_PATH },
216 { "style", GTK_RC_TOKEN_STYLE },
217 { "binding", GTK_RC_TOKEN_BINDING },
218 { "bind", GTK_RC_TOKEN_BIND },
219 { "widget", GTK_RC_TOKEN_WIDGET },
220 { "widget_class", GTK_RC_TOKEN_WIDGET_CLASS },
221 { "class", GTK_RC_TOKEN_CLASS },
222 { "lowest", GTK_RC_TOKEN_LOWEST },
223 { "gtk", GTK_RC_TOKEN_GTK },
224 { "application", GTK_RC_TOKEN_APPLICATION },
225 { "rc", GTK_RC_TOKEN_RC },
226 { "highest", GTK_RC_TOKEN_HIGHEST },
227 { "engine", GTK_RC_TOKEN_ENGINE },
228 { "module_path", GTK_RC_TOKEN_MODULE_PATH },
229 { "stock", GTK_RC_TOKEN_STOCK },
230 { "im_module_path", GTK_RC_TOKEN_IM_MODULE_PATH },
231 { "im_module_file", GTK_RC_TOKEN_IM_MODULE_FILE },
232 { "LTR", GTK_RC_TOKEN_LTR },
233 { "RTL", GTK_RC_TOKEN_RTL }
236 static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
238 static gchar *im_module_path = NULL;
239 static gchar *im_module_file = NULL;
241 static GHashTable *rc_style_ht = NULL;
242 static GHashTable *realized_style_ht = NULL;
243 static GSList *gtk_rc_sets_widget = NULL;
244 static GSList *gtk_rc_sets_widget_class = NULL;
245 static GSList *gtk_rc_sets_class = NULL;
247 #define GTK_RC_MAX_DEFAULT_FILES 128
248 static gchar *gtk_rc_default_files[GTK_RC_MAX_DEFAULT_FILES];
249 static gboolean gtk_rc_auto_parse = TRUE;
251 #define GTK_RC_MAX_PIXMAP_PATHS 128
252 static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
253 #define GTK_RC_MAX_MODULE_PATHS 128
254 static gchar *module_path[GTK_RC_MAX_MODULE_PATHS];
256 /* A stack of directories for RC files we are parsing currently.
257 * these are implicitely added to the end of PIXMAP_PATHS
259 GSList *rc_dir_stack = NULL;
261 /* The files we have parsed, to reread later if necessary */
262 GSList *rc_files = NULL;
264 static GtkImageLoader image_loader = NULL;
266 /* RC file handling */
272 get_gtk_dll_name (void)
274 static gchar *gtk_dll = NULL;
277 gtk_dll = g_strdup_printf ("gtk-%d.%d.dll", GTK_MAJOR_VERSION, GTK_MINOR_VERSION);
283 get_themes_directory (void)
285 return g_win32_get_package_installation_subdirectory (GETTEXT_PACKAGE,
293 gtk_rc_make_default_dir (const gchar *type)
298 var = getenv("GTK_EXE_PREFIX");
300 path = g_strconcat (var, "/lib/gtk-2.0/" GTK_VERSION "/", type, NULL);
302 path = g_strconcat (GTK_LIBDIR "/gtk-2.0/" GTK_VERSION "/", type, NULL);
304 path = g_strconcat ("%s\\%s", get_themes_directory (), type);
311 gtk_rc_get_im_module_path (void)
313 gchar *result = g_getenv ("GTK_IM_MODULE_PATH");
318 result = im_module_path;
320 return gtk_rc_make_default_dir ("immodules");
323 return g_strdup (result);
327 gtk_rc_get_im_module_file (void)
329 gchar *result = g_strdup (g_getenv ("GTK_IM_MODULE_FILE"));
334 result = g_strdup (im_module_file);
337 result = g_strdup (GTK_SYSCONFDIR G_DIR_SEPARATOR_S "gtk-2.0" G_DIR_SEPARATOR_S "gtk.immodules");
339 result = g_strdup_printf ("%s\\gtk.immodules", g_win32_get_package_installation_directory (GETTEXT_PACKAGE, get_gtk_dll_name ()));
347 gtk_rc_get_theme_dir(void)
352 var = getenv("GTK_DATA_PREFIX");
354 path = g_strconcat (var, "/share/themes", NULL);
356 path = g_strconcat (GTK_DATA_PREFIX, "/share/themes", NULL);
358 path = g_strdup (get_themes_directory ());
365 gtk_rc_get_module_dir(void)
367 return gtk_rc_make_default_dir ("engines");
371 gtk_rc_append_default_module_path(void)
376 for (n = 0; module_path[n]; n++) ;
377 if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
381 var = getenv("GTK_EXE_PREFIX");
383 path = g_strconcat(var, "/lib/gtk-2.0/" GTK_VERSION "/engines", NULL);
385 path = g_strdup (GTK_LIBDIR "/gtk-2.0/" GTK_VERSION "/engines");
387 path = g_strconcat (get_themes_directory (), "\\engines", NULL);
389 module_path[n++] = path;
391 var = g_get_home_dir ();
395 /* Don't duplicate the directory separator, causes trouble at
398 if (var[strlen (var) -1] != G_DIR_SEPARATOR)
399 sep = G_DIR_SEPARATOR_S;
402 /* This produces something like ~/.gtk-2.0/2.0/engines */
403 path = g_strconcat (var, sep,
404 ".gtk-2.0" G_DIR_SEPARATOR_S
405 GTK_VERSION G_DIR_SEPARATOR_S
407 module_path[n++] = path;
409 module_path[n] = NULL;
413 gtk_rc_add_initial_default_files (void)
415 static gint init = FALSE;
423 gtk_rc_default_files[0] = NULL;
426 var = g_getenv("GTK_RC_FILES");
429 files = g_strsplit (var, G_SEARCHPATH_SEPARATOR_S, 128);
433 gtk_rc_add_default_file (files[i]);
441 str = g_strdup (GTK_SYSCONFDIR G_DIR_SEPARATOR_S "gtk-2.0" G_DIR_SEPARATOR_S "gtkrc");
443 str = g_strdup_printf ("%s\\gtkrc", g_win32_get_package_installation_directory (GETTEXT_PACKAGE, get_gtk_dll_name ()));
446 gtk_rc_add_default_file (str);
449 var = g_get_home_dir ();
453 if (var[strlen (var) -1] != G_DIR_SEPARATOR)
454 sep = G_DIR_SEPARATOR_S;
457 str = g_strdup_printf ("%s%s.gtkrc-2.0", var, sep);
458 gtk_rc_add_default_file (str);
465 gtk_rc_add_default_file (const gchar *file)
469 gtk_rc_add_initial_default_files ();
471 for (n = 0; gtk_rc_default_files[n]; n++) ;
472 if (n >= GTK_RC_MAX_DEFAULT_FILES - 1)
475 gtk_rc_default_files[n++] = g_strdup (file);
476 gtk_rc_default_files[n] = NULL;
480 gtk_rc_set_default_files (gchar **files)
484 gtk_rc_add_initial_default_files ();
487 while (gtk_rc_default_files[i])
489 g_free (gtk_rc_default_files[i]);
493 gtk_rc_default_files[0] = NULL;
494 gtk_rc_auto_parse = FALSE;
497 while (files[i] != NULL)
499 gtk_rc_add_default_file (files[i]);
505 gtk_rc_get_default_files (void)
507 gtk_rc_add_initial_default_files ();
509 return gtk_rc_default_files;
512 /* The following routine is based on _nl_normalize_codeset from
513 * the GNU C library. Contributed by
515 * Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
516 * Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
518 * Normalize codeset name. There is no standard for the codeset
519 * names. Normalization allows the user to use any of the common
523 _gtk_normalize_codeset (const char *codeset, int name_len)
531 for (cnt = 0; cnt < name_len; ++cnt)
532 if (isalnum (codeset[cnt]))
536 if (isalpha (codeset[cnt]))
540 retval = g_malloc ((only_digit ? 3 : 0) + len + 1);
544 memcpy (retval, "iso", 4);
550 for (cnt = 0; cnt < name_len; ++cnt)
551 if (isalpha (codeset[cnt]))
552 *wp++ = isupper(codeset[cnt]) ? tolower (codeset[cnt]) : codeset[cnt];
553 else if (isdigit (codeset[cnt]))
554 *wp++ = codeset[cnt];
564 static gchar *locale_suffixes[3];
565 static gint n_locale_suffixes = 0;
569 static gboolean initialized = FALSE;
578 locale = g_win32_getlocale ();
580 locale = setlocale (LC_CTYPE, NULL);
584 pixmap_path[0] = NULL;
585 module_path[0] = NULL;
586 gtk_rc_append_default_module_path();
588 gtk_rc_add_initial_default_files ();
590 if (strcmp (locale, "C") && strcmp (locale, "POSIX"))
592 /* Determine locale-specific suffixes for RC files
594 * We normalize the charset into a standard form,
595 * which has all '-' and '_' characters removed,
598 gchar *normalized_locale;
600 p = strchr (locale, '@');
601 length = p ? (p -locale) : strlen (locale);
603 p = strchr (locale, '.');
606 gchar *tmp1 = g_strndup (locale, p - locale + 1);
607 gchar *tmp2 = _gtk_normalize_codeset (p + 1, length - (p - locale + 1));
609 normalized_locale = g_strconcat (tmp1, tmp2, NULL);
613 locale_suffixes[n_locale_suffixes++] = g_strdup (normalized_locale);
617 normalized_locale = g_strndup (locale, length);
619 p = strchr (normalized_locale, '_');
622 locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
623 length = p - normalized_locale;
626 locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
628 g_free (normalized_locale);
633 while (gtk_rc_default_files[i] != NULL)
635 /* Try to find a locale specific RC file corresponding to
636 * to parse before the default file.
638 for (j=n_locale_suffixes-1; j>=0; j--)
640 gchar *name = g_strconcat (gtk_rc_default_files[i],
648 gtk_rc_parse (gtk_rc_default_files[i]);
654 gtk_rc_parse_string (const gchar *rc_string)
656 g_return_if_fail (rc_string != NULL);
658 gtk_rc_parse_any ("-", -1, rc_string);
662 gtk_rc_parse_file (const gchar *filename, gboolean reload)
664 GtkRcFile *rc_file = NULL;
668 g_return_if_fail (filename != NULL);
673 rc_file = tmp_list->data;
674 if (!strcmp (rc_file->name, filename))
677 tmp_list = tmp_list->next;
682 rc_file = g_new (GtkRcFile, 1);
683 rc_file->name = g_strdup (filename);
684 rc_file->canonical_name = NULL;
686 rc_file->reload = reload;
688 rc_files = g_slist_append (rc_files, rc_file);
691 if (!rc_file->canonical_name)
693 /* Get the absolute pathname */
695 if (g_path_is_absolute (rc_file->name))
696 rc_file->canonical_name = rc_file->name;
702 cwd = g_get_current_dir ();
704 str = g_string_new (cwd);
706 g_string_append_c (str, G_DIR_SEPARATOR);
707 g_string_append (str, rc_file->name);
709 rc_file->canonical_name = str->str;
710 g_string_free (str, FALSE);
714 if (!lstat (rc_file->canonical_name, &statbuf))
719 rc_file->mtime = statbuf.st_mtime;
721 fd = open (rc_file->canonical_name, O_RDONLY);
725 /* Temporarily push directory name for this file on
726 * a stack of directory names while parsing it
729 g_slist_prepend (rc_dir_stack,
730 g_path_get_dirname (rc_file->canonical_name));
731 gtk_rc_parse_any (filename, fd, NULL);
733 tmp_list = rc_dir_stack;
734 rc_dir_stack = rc_dir_stack->next;
736 g_free (tmp_list->data);
737 g_slist_free_1 (tmp_list);
744 gtk_rc_parse (const gchar *filename)
746 g_return_if_fail (filename != NULL);
748 gtk_rc_parse_file (filename, TRUE);
751 /* Handling of RC styles */
754 gtk_rc_style_get_type (void)
756 static GType object_type = 0;
760 static const GTypeInfo object_info =
762 sizeof (GtkRcStyleClass),
763 (GBaseInitFunc) NULL,
764 (GBaseFinalizeFunc) NULL,
765 (GClassInitFunc) gtk_rc_style_class_init,
766 NULL, /* class_finalize */
767 NULL, /* class_data */
770 (GInstanceInitFunc) gtk_rc_style_init,
773 object_type = g_type_register_static (G_TYPE_OBJECT,
782 gtk_rc_style_init (GtkRcStyle *style)
787 for (i = 0; i < 5; i++)
789 static const GdkColor init_color = { 0, 0, 0, 0, };
791 style->bg_pixmap_name[i] = NULL;
792 style->color_flags[i] = 0;
793 style->fg[i] = init_color;
794 style->bg[i] = init_color;
795 style->text[i] = init_color;
796 style->base[i] = init_color;
798 style->xthickness = -1;
799 style->ythickness = -1;
800 style->rc_style_lists = NULL;
804 gtk_rc_style_class_init (GtkRcStyleClass *klass)
806 GObjectClass *object_class = G_OBJECT_CLASS (klass);
808 parent_class = g_type_class_peek_parent (klass);
810 object_class->finalize = gtk_rc_style_finalize;
813 klass->clone = gtk_rc_style_real_clone;
814 klass->merge = gtk_rc_style_real_merge;
815 klass->create_style = gtk_rc_style_real_create_style;
818 /* Like g_slist_remove, but remove all copies of data */
820 gtk_rc_slist_remove_all (GSList *list,
831 if (tmp->data == data)
837 prev->next = tmp->next;
839 g_slist_free_1 (tmp);
857 gtk_rc_style_finalize (GObject *object)
860 GSList *tmp_list1, *tmp_list2;
861 GtkRcStyle *rc_style;
863 rc_style = GTK_RC_STYLE (object);
866 g_free (rc_style->name);
867 if (rc_style->font_desc)
868 pango_font_description_free (rc_style->font_desc);
870 for (i=0 ; i < 5 ; i++)
871 if (rc_style->bg_pixmap_name[i])
872 g_free (rc_style->bg_pixmap_name[i]);
874 /* Now remove all references to this rc_style from
877 tmp_list1 = rc_style->rc_style_lists;
880 GSList *rc_styles = tmp_list1->data;
881 GtkStyle *style = g_hash_table_lookup (realized_style_ht, rc_styles);
882 gtk_style_unref (style);
884 /* Remove the list of styles from the other rc_styles
887 tmp_list2 = rc_styles;
890 GtkRcStyle *other_style = tmp_list2->data;
892 if (other_style != rc_style)
893 other_style->rc_style_lists =
894 gtk_rc_slist_remove_all (other_style->rc_style_lists, rc_styles);
896 tmp_list2 = tmp_list2->next;
899 /* And from the hash table itself
901 g_hash_table_remove (realized_style_ht, rc_styles);
902 g_slist_free (rc_styles);
904 tmp_list1 = tmp_list1->next;
907 g_slist_free (rc_style->rc_style_lists);
909 tmp_list1 = rc_style->icon_factories;
912 g_object_unref (G_OBJECT (tmp_list1->data));
914 tmp_list1 = tmp_list1->next;
917 g_slist_free (rc_style->icon_factories);
919 G_OBJECT_CLASS (parent_class)->finalize (object);
923 gtk_rc_style_new (void)
927 style = g_object_new (GTK_TYPE_RC_STYLE, NULL);
934 * @orig: the style to copy
936 * Make a copy of the specified #GtkRcStyle. This function
937 * will correctly copy an rc style that is a member of a class
938 * derived from #GtkRcStyle.
940 * Return value: the resulting #GtkRcStyle
943 gtk_rc_style_copy (GtkRcStyle *orig)
947 g_return_val_if_fail (GTK_IS_RC_STYLE (orig), NULL);
949 style = GTK_RC_STYLE_GET_CLASS (orig)->clone (orig);
950 GTK_RC_STYLE_GET_CLASS (style)->merge (style, orig);
956 gtk_rc_style_ref (GtkRcStyle *rc_style)
958 g_return_if_fail (GTK_IS_RC_STYLE (rc_style));
960 g_object_ref (G_OBJECT (rc_style));
964 gtk_rc_style_unref (GtkRcStyle *rc_style)
966 g_return_if_fail (GTK_IS_RC_STYLE (rc_style));
968 g_object_unref (G_OBJECT (rc_style));
972 gtk_rc_style_real_clone (GtkRcStyle *style)
974 return GTK_RC_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
978 gtk_rc_style_real_merge (GtkRcStyle *dest,
983 for (i = 0; i < 5; i++)
985 if (!dest->bg_pixmap_name[i] && src->bg_pixmap_name[i])
986 dest->bg_pixmap_name[i] = g_strdup (src->bg_pixmap_name[i]);
988 if (!(dest->color_flags[i] & GTK_RC_FG) &&
989 src->color_flags[i] & GTK_RC_FG)
991 dest->fg[i] = src->fg[i];
992 dest->color_flags[i] |= GTK_RC_FG;
994 if (!(dest->color_flags[i] & GTK_RC_BG) &&
995 src->color_flags[i] & GTK_RC_BG)
997 dest->bg[i] = src->bg[i];
998 dest->color_flags[i] |= GTK_RC_BG;
1000 if (!(dest->color_flags[i] & GTK_RC_TEXT) &&
1001 src->color_flags[i] & GTK_RC_TEXT)
1003 dest->text[i] = src->text[i];
1004 dest->color_flags[i] |= GTK_RC_TEXT;
1006 if (!(dest->color_flags[i] & GTK_RC_BASE) &&
1007 src->color_flags[i] & GTK_RC_BASE)
1009 dest->base[i] = src->base[i];
1010 dest->color_flags[i] |= GTK_RC_BASE;
1014 if (dest->xthickness < 0 && src->xthickness >= 0)
1015 dest->xthickness = src->xthickness;
1016 if (dest->ythickness < 0 && src->ythickness >= 0)
1017 dest->ythickness = src->ythickness;
1019 if (!dest->font_desc && src->font_desc)
1020 dest->font_desc = pango_font_description_copy (src->font_desc);
1024 gtk_rc_style_real_create_style (GtkRcStyle *rc_style)
1026 return gtk_style_new ();
1030 gtk_rc_clear_hash_node (gpointer key,
1034 gtk_rc_style_unref (data);
1038 gtk_rc_free_rc_sets (GSList *slist)
1044 rc_set = slist->data;
1045 gtk_pattern_spec_free_segs (&rc_set->pspec);
1048 slist = slist->next;
1053 gtk_rc_clear_styles (void)
1055 /* Clear out all old rc_styles */
1059 g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
1060 g_hash_table_destroy (rc_style_ht);
1064 gtk_rc_free_rc_sets (gtk_rc_sets_widget);
1065 g_slist_free (gtk_rc_sets_widget);
1066 gtk_rc_sets_widget = NULL;
1068 gtk_rc_free_rc_sets (gtk_rc_sets_widget_class);
1069 g_slist_free (gtk_rc_sets_widget_class);
1070 gtk_rc_sets_widget_class = NULL;
1072 gtk_rc_free_rc_sets (gtk_rc_sets_class);
1073 g_slist_free (gtk_rc_sets_class);
1074 gtk_rc_sets_class = NULL;
1078 gtk_rc_reparse_all (void)
1081 gboolean mtime_modified = FALSE;
1084 struct stat statbuf;
1086 /* Check through and see if any of the RC's have had their
1087 * mtime modified. If so, reparse everything.
1089 tmp_list = rc_files;
1092 rc_file = tmp_list->data;
1094 if (!lstat (rc_file->name, &statbuf) &&
1095 (statbuf.st_mtime > rc_file->mtime))
1097 mtime_modified = TRUE;
1101 tmp_list = tmp_list->next;
1106 gtk_rc_clear_styles();
1108 tmp_list = rc_files;
1111 rc_file = tmp_list->data;
1112 if (rc_file->reload)
1113 gtk_rc_parse_file (rc_file->name, FALSE);
1115 tmp_list = tmp_list->next;
1119 return mtime_modified;
1123 gtk_rc_styles_match (GSList *rc_styles,
1127 gchar *path_reversed)
1134 rc_set = sets->data;
1137 if (gtk_pattern_match (&rc_set->pspec, path_length, path, path_reversed))
1138 rc_styles = g_slist_append (rc_styles, rc_set->rc_style);
1145 gtk_rc_get_style (GtkWidget *widget)
1147 GtkRcStyle *widget_rc_style;
1148 GSList *rc_styles = NULL;
1150 static guint rc_style_key_id = 0;
1152 /* We allow the specification of a single rc style to be bound
1153 * tightly to a widget, for application modifications
1155 if (!rc_style_key_id)
1156 rc_style_key_id = g_quark_from_static_string ("gtk-rc-style");
1158 widget_rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1161 if (widget_rc_style)
1162 rc_styles = g_slist_prepend (rc_styles, widget_rc_style);
1164 if (gtk_rc_sets_widget)
1166 gchar *path, *path_reversed;
1169 gtk_widget_path (widget, &path_length, &path, &path_reversed);
1170 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget, path_length, path, path_reversed);
1172 g_free (path_reversed);
1176 if (gtk_rc_sets_widget_class)
1178 gchar *path, *path_reversed;
1181 gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
1182 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_widget_class, path_length, path, path_reversed);
1184 g_free (path_reversed);
1187 if (gtk_rc_sets_class)
1191 type = GTK_OBJECT_TYPE (widget);
1194 gchar *path, *path_reversed;
1197 path = gtk_type_name (type);
1198 path_length = strlen (path);
1199 path_reversed = g_strdup (path);
1200 g_strreverse (path_reversed);
1202 rc_styles = gtk_rc_styles_match (rc_styles, gtk_rc_sets_class, path_length, path, path_reversed);
1203 g_free (path_reversed);
1205 type = gtk_type_parent (type);
1210 return gtk_rc_init_style (rc_styles);
1216 gtk_rc_add_rc_sets (GSList *slist,
1217 GtkRcStyle *rc_style,
1218 const char *pattern)
1220 GtkRcStyle *new_style;
1224 new_style = gtk_rc_style_new ();
1225 *new_style = *rc_style;
1226 new_style->name = g_strdup (rc_style->name);
1227 if (rc_style->font_desc)
1228 new_style->font_desc = pango_font_description_copy (rc_style->font_desc);
1230 for (i = 0; i < 5; i++)
1231 new_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
1233 rc_set = g_new (GtkRcSet, 1);
1234 gtk_pattern_spec_init (&rc_set->pspec, pattern);
1235 rc_set->rc_style = rc_style;
1237 return g_slist_prepend (slist, rc_set);
1241 gtk_rc_add_widget_name_style (GtkRcStyle *rc_style,
1242 const gchar *pattern)
1244 g_return_if_fail (rc_style != NULL);
1245 g_return_if_fail (pattern != NULL);
1247 gtk_rc_sets_widget = gtk_rc_add_rc_sets (gtk_rc_sets_widget, rc_style, pattern);
1251 gtk_rc_add_widget_class_style (GtkRcStyle *rc_style,
1252 const gchar *pattern)
1254 g_return_if_fail (rc_style != NULL);
1255 g_return_if_fail (pattern != NULL);
1257 gtk_rc_sets_widget_class = gtk_rc_add_rc_sets (gtk_rc_sets_widget_class, rc_style, pattern);
1261 gtk_rc_add_class_style (GtkRcStyle *rc_style,
1262 const gchar *pattern)
1264 g_return_if_fail (rc_style != NULL);
1265 g_return_if_fail (pattern != NULL);
1267 gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
1271 gtk_rc_parse_any (const gchar *input_name,
1273 const gchar *input_string)
1279 scanner = g_scanner_new ((GScannerConfig *) >k_rc_scanner_config);
1283 g_assert (input_string == NULL);
1285 g_scanner_input_file (scanner, input_fd);
1289 g_assert (input_string != NULL);
1291 g_scanner_input_text (scanner, input_string, strlen (input_string));
1293 scanner->input_name = input_name;
1295 for (i = 0; i < n_symbols; i++)
1296 g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
1301 if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
1305 guint expected_token;
1307 expected_token = gtk_rc_parse_statement (scanner);
1309 if (expected_token != G_TOKEN_NONE)
1316 if (scanner->scope_id == 0)
1318 /* if we are in scope 0, we know the symbol names
1319 * that are associated with certaintoken values.
1320 * so we look them up to make the error messages
1323 if (expected_token > GTK_RC_TOKEN_INVALID &&
1324 expected_token < GTK_RC_TOKEN_LAST)
1326 for (i = 0; i < n_symbols; i++)
1327 if (symbols[i].token == expected_token)
1328 msg = symbols[i].name;
1330 msg = g_strconcat ("e.g. `", msg, "'", NULL);
1332 if (scanner->token > GTK_RC_TOKEN_INVALID &&
1333 scanner->token < GTK_RC_TOKEN_LAST)
1335 symbol_name = "???";
1336 for (i = 0; i < n_symbols; i++)
1337 if (symbols[i].token == scanner->token)
1338 symbol_name = symbols[i].name;
1341 g_scanner_unexp_token (scanner,
1354 g_scanner_destroy (scanner);
1358 gtk_rc_styles_hash (const GSList *rc_styles)
1365 result += (result << 9) + GPOINTER_TO_UINT (rc_styles->data);
1366 rc_styles = rc_styles->next;
1373 gtk_rc_styles_equal (const GSList *a,
1378 if (a->data != b->data)
1388 gtk_rc_style_hash (const char *name)
1394 result += (result << 3) + *name++;
1400 gtk_rc_style_equal (const char *a,
1403 return (strcmp (a, b) == 0);
1407 gtk_rc_style_find (const char *name)
1410 return g_hash_table_lookup (rc_style_ht, (gpointer) name);
1416 gtk_rc_style_to_style (GtkRcStyle *rc_style)
1420 style = GTK_RC_STYLE_GET_CLASS (rc_style)->create_style (rc_style);
1422 style->rc_style = rc_style;
1424 gtk_rc_style_ref (rc_style);
1426 GTK_STYLE_GET_CLASS (style)->init_from_rc (style, rc_style);
1431 /* Reuses or frees rc_styles */
1433 gtk_rc_init_style (GSList *rc_styles)
1435 GtkStyle *style = NULL;
1438 g_return_val_if_fail (rc_styles != NULL, NULL);
1440 if (!realized_style_ht)
1441 realized_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_styles_hash,
1442 (GEqualFunc) gtk_rc_styles_equal);
1444 style = g_hash_table_lookup (realized_style_ht, rc_styles);
1448 GtkRcStyle *base_style = NULL;
1449 GtkRcStyle *proto_style;
1450 GtkRcStyleClass *proto_style_class;
1452 GType rc_style_type = GTK_TYPE_RC_STYLE;
1454 /* Find the first derived style in the list, and use that to
1455 * create the merged style. If we only have raw GtkRcStyles, use
1456 * the first style to create the merged style.
1458 base_style = rc_styles->data;
1459 tmp_styles = rc_styles;
1462 GtkRcStyle *rc_style = tmp_styles->data;
1464 if (G_OBJECT_TYPE (rc_style) != rc_style_type)
1466 base_style = rc_style;
1470 tmp_styles = tmp_styles->next;
1473 proto_style_class = GTK_RC_STYLE_GET_CLASS (base_style);
1474 proto_style = proto_style_class->clone (base_style);
1476 tmp_styles = rc_styles;
1479 GtkRcStyle *rc_style = tmp_styles->data;
1482 proto_style_class->merge (proto_style, rc_style);
1484 /* Point from each rc_style to the list of styles */
1485 if (!g_slist_find (rc_style->rc_style_lists, rc_styles))
1486 rc_style->rc_style_lists = g_slist_prepend (rc_style->rc_style_lists, rc_styles);
1488 factories = g_slist_copy (rc_style->icon_factories);
1494 while (iter != NULL)
1496 g_object_ref (G_OBJECT (iter->data));
1497 iter = g_slist_next (iter);
1500 proto_style->icon_factories = g_slist_concat (proto_style->icon_factories,
1505 tmp_styles = tmp_styles->next;
1508 for (i = 0; i < 5; i++)
1509 if (proto_style->bg_pixmap_name[i] &&
1510 (strcmp (proto_style->bg_pixmap_name[i], "<none>") == 0))
1512 g_free (proto_style->bg_pixmap_name[i]);
1513 proto_style->bg_pixmap_name[i] = NULL;
1516 style = gtk_rc_style_to_style (proto_style);
1517 gtk_rc_style_unref (proto_style);
1519 g_hash_table_insert (realized_style_ht, rc_styles, style);
1522 g_slist_free (rc_styles);
1527 /*********************
1528 * Parsing functions *
1529 *********************/
1532 gtk_rc_parse_statement (GScanner *scanner)
1536 token = g_scanner_peek_next_token (scanner);
1540 gboolean is_varname;
1542 case GTK_RC_TOKEN_INCLUDE:
1543 token = g_scanner_get_next_token (scanner);
1544 if (token != GTK_RC_TOKEN_INCLUDE)
1545 return GTK_RC_TOKEN_INCLUDE;
1547 token = g_scanner_get_next_token (scanner);
1548 if (token != G_TOKEN_STRING)
1549 return G_TOKEN_STRING;
1551 gtk_rc_parse_file (scanner->value.v_string, FALSE);
1552 return G_TOKEN_NONE;
1554 case GTK_RC_TOKEN_STYLE:
1555 return gtk_rc_parse_style (scanner);
1557 case GTK_RC_TOKEN_BINDING:
1558 return gtk_binding_parse_binding (scanner);
1560 case GTK_RC_TOKEN_PIXMAP_PATH:
1561 return gtk_rc_parse_pixmap_path (scanner);
1563 case GTK_RC_TOKEN_WIDGET:
1564 return gtk_rc_parse_path_pattern (scanner);
1566 case GTK_RC_TOKEN_WIDGET_CLASS:
1567 return gtk_rc_parse_path_pattern (scanner);
1569 case GTK_RC_TOKEN_CLASS:
1570 return gtk_rc_parse_path_pattern (scanner);
1572 case GTK_RC_TOKEN_MODULE_PATH:
1573 return gtk_rc_parse_module_path (scanner);
1575 case GTK_RC_TOKEN_IM_MODULE_PATH:
1576 return gtk_rc_parse_im_module_path (scanner);
1578 case GTK_RC_TOKEN_IM_MODULE_FILE:
1579 return gtk_rc_parse_im_module_file (scanner);
1582 g_scanner_get_next_token (scanner);
1583 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
1588 gtk_rc_parse_style (GScanner *scanner)
1590 GtkRcStyle *rc_style;
1591 GtkRcStyle *parent_style;
1595 GtkIconFactory *our_factory = NULL;
1597 token = g_scanner_get_next_token (scanner);
1598 if (token != GTK_RC_TOKEN_STYLE)
1599 return GTK_RC_TOKEN_STYLE;
1601 token = g_scanner_get_next_token (scanner);
1602 if (token != G_TOKEN_STRING)
1603 return G_TOKEN_STRING;
1606 rc_style = gtk_rc_style_find (scanner->value.v_string);
1608 /* If there's a list, its first member is always the factory belonging
1611 if (rc_style && rc_style->icon_factories)
1612 our_factory = rc_style->icon_factories->data;
1617 rc_style = gtk_rc_style_new ();
1618 rc_style->name = g_strdup (scanner->value.v_string);
1620 for (i = 0; i < 5; i++)
1621 rc_style->bg_pixmap_name[i] = NULL;
1623 for (i = 0; i < 5; i++)
1624 rc_style->color_flags[i] = 0;
1627 token = g_scanner_peek_next_token (scanner);
1628 if (token == G_TOKEN_EQUAL_SIGN)
1630 token = g_scanner_get_next_token (scanner);
1632 token = g_scanner_get_next_token (scanner);
1633 if (token != G_TOKEN_STRING)
1638 return G_TOKEN_STRING;
1641 parent_style = gtk_rc_style_find (scanner->value.v_string);
1646 for (i = 0; i < 5; i++)
1648 rc_style->color_flags[i] = parent_style->color_flags[i];
1649 rc_style->fg[i] = parent_style->fg[i];
1650 rc_style->bg[i] = parent_style->bg[i];
1651 rc_style->text[i] = parent_style->text[i];
1652 rc_style->base[i] = parent_style->base[i];
1655 rc_style->xthickness = parent_style->xthickness;
1656 rc_style->ythickness = parent_style->ythickness;
1658 if (parent_style->font_desc)
1660 if (rc_style->font_desc)
1661 pango_font_description_free (rc_style->font_desc);
1662 rc_style->font_desc = pango_font_description_copy (parent_style->font_desc);
1665 for (i = 0; i < 5; i++)
1667 if (rc_style->bg_pixmap_name[i])
1668 g_free (rc_style->bg_pixmap_name[i]);
1669 rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
1672 /* Append parent's factories, adding a ref to them */
1673 if (parent_style->icon_factories != NULL)
1675 /* Add a factory for ourselves if we have none,
1676 * in case we end up defining more stock icons.
1677 * I see no real way around this; we need to maintain
1678 * the invariant that the first factory in the list
1679 * is always our_factory, the one belonging to us,
1680 * and if we put parent factories in the list we can't
1681 * do that if the style is reopened.
1683 if (our_factory == NULL)
1685 our_factory = gtk_icon_factory_new ();
1686 rc_style->icon_factories = g_slist_prepend (rc_style->icon_factories,
1690 rc_style->icon_factories = g_slist_concat (rc_style->icon_factories,
1691 g_slist_copy (parent_style->icon_factories));
1693 factories = parent_style->icon_factories;
1694 while (factories != NULL)
1696 g_object_ref (G_OBJECT (factories->data));
1697 factories = factories->next;
1703 token = g_scanner_get_next_token (scanner);
1704 if (token != G_TOKEN_LEFT_CURLY)
1709 return G_TOKEN_LEFT_CURLY;
1712 token = g_scanner_peek_next_token (scanner);
1713 while (token != G_TOKEN_RIGHT_CURLY)
1717 case GTK_RC_TOKEN_BG:
1718 token = gtk_rc_parse_bg (scanner, rc_style);
1720 case GTK_RC_TOKEN_FG:
1721 token = gtk_rc_parse_fg (scanner, rc_style);
1723 case GTK_RC_TOKEN_TEXT:
1724 token = gtk_rc_parse_text (scanner, rc_style);
1726 case GTK_RC_TOKEN_BASE:
1727 token = gtk_rc_parse_base (scanner, rc_style);
1729 case GTK_RC_TOKEN_XTHICKNESS:
1730 token = gtk_rc_parse_xthickness (scanner, rc_style);
1732 case GTK_RC_TOKEN_YTHICKNESS:
1733 token = gtk_rc_parse_ythickness (scanner, rc_style);
1735 case GTK_RC_TOKEN_BG_PIXMAP:
1736 token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
1738 case GTK_RC_TOKEN_FONT:
1739 token = gtk_rc_parse_font (scanner, rc_style);
1741 case GTK_RC_TOKEN_FONTSET:
1742 token = gtk_rc_parse_fontset (scanner, rc_style);
1744 case GTK_RC_TOKEN_FONT_NAME:
1745 token = gtk_rc_parse_font_name (scanner, rc_style);
1747 case GTK_RC_TOKEN_ENGINE:
1748 token = gtk_rc_parse_engine (scanner, &rc_style);
1750 case GTK_RC_TOKEN_STOCK:
1751 if (our_factory == NULL)
1753 our_factory = gtk_icon_factory_new ();
1754 rc_style->icon_factories = g_slist_prepend (rc_style->icon_factories,
1757 token = gtk_rc_parse_stock (scanner, rc_style, our_factory);
1760 g_scanner_get_next_token (scanner);
1761 token = G_TOKEN_RIGHT_CURLY;
1765 if (token != G_TOKEN_NONE)
1769 if (rc_style->font_desc)
1770 pango_font_description_free (rc_style->font_desc);
1772 for (i = 0; i < 5; i++)
1773 if (rc_style->bg_pixmap_name[i])
1774 g_free (rc_style->bg_pixmap_name[i]);
1779 token = g_scanner_peek_next_token (scanner);
1782 token = g_scanner_get_next_token (scanner);
1783 if (token != G_TOKEN_RIGHT_CURLY)
1787 if (rc_style->font_desc)
1788 pango_font_description_free (rc_style->font_desc);
1790 for (i = 0; i < 5; i++)
1791 if (rc_style->bg_pixmap_name[i])
1792 g_free (rc_style->bg_pixmap_name[i]);
1796 return G_TOKEN_RIGHT_CURLY;
1802 rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
1803 (GEqualFunc) gtk_rc_style_equal);
1805 g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
1808 return G_TOKEN_NONE;
1812 gtk_rc_parse_bg (GScanner *scanner,
1818 token = g_scanner_get_next_token (scanner);
1819 if (token != GTK_RC_TOKEN_BG)
1820 return GTK_RC_TOKEN_BG;
1822 token = gtk_rc_parse_state (scanner, &state);
1823 if (token != G_TOKEN_NONE)
1826 token = g_scanner_get_next_token (scanner);
1827 if (token != G_TOKEN_EQUAL_SIGN)
1828 return G_TOKEN_EQUAL_SIGN;
1830 style->color_flags[state] |= GTK_RC_BG;
1831 return gtk_rc_parse_color (scanner, &style->bg[state]);
1835 gtk_rc_parse_fg (GScanner *scanner,
1841 token = g_scanner_get_next_token (scanner);
1842 if (token != GTK_RC_TOKEN_FG)
1843 return GTK_RC_TOKEN_FG;
1845 token = gtk_rc_parse_state (scanner, &state);
1846 if (token != G_TOKEN_NONE)
1849 token = g_scanner_get_next_token (scanner);
1850 if (token != G_TOKEN_EQUAL_SIGN)
1851 return G_TOKEN_EQUAL_SIGN;
1853 style->color_flags[state] |= GTK_RC_FG;
1854 return gtk_rc_parse_color (scanner, &style->fg[state]);
1858 gtk_rc_parse_text (GScanner *scanner,
1864 token = g_scanner_get_next_token (scanner);
1865 if (token != GTK_RC_TOKEN_TEXT)
1866 return GTK_RC_TOKEN_TEXT;
1868 token = gtk_rc_parse_state (scanner, &state);
1869 if (token != G_TOKEN_NONE)
1872 token = g_scanner_get_next_token (scanner);
1873 if (token != G_TOKEN_EQUAL_SIGN)
1874 return G_TOKEN_EQUAL_SIGN;
1876 style->color_flags[state] |= GTK_RC_TEXT;
1877 return gtk_rc_parse_color (scanner, &style->text[state]);
1881 gtk_rc_parse_base (GScanner *scanner,
1887 token = g_scanner_get_next_token (scanner);
1888 if (token != GTK_RC_TOKEN_BASE)
1889 return GTK_RC_TOKEN_BASE;
1891 token = gtk_rc_parse_state (scanner, &state);
1892 if (token != G_TOKEN_NONE)
1895 token = g_scanner_get_next_token (scanner);
1896 if (token != G_TOKEN_EQUAL_SIGN)
1897 return G_TOKEN_EQUAL_SIGN;
1899 style->color_flags[state] |= GTK_RC_BASE;
1900 return gtk_rc_parse_color (scanner, &style->base[state]);
1904 gtk_rc_parse_xthickness (GScanner *scanner,
1907 if (g_scanner_get_next_token (scanner) != GTK_RC_TOKEN_XTHICKNESS)
1908 return GTK_RC_TOKEN_XTHICKNESS;
1910 if (g_scanner_get_next_token (scanner) != G_TOKEN_EQUAL_SIGN)
1911 return G_TOKEN_EQUAL_SIGN;
1913 if (g_scanner_get_next_token (scanner) != G_TOKEN_INT)
1916 style->xthickness = scanner->value.v_int;
1918 return G_TOKEN_NONE;
1922 gtk_rc_parse_ythickness (GScanner *scanner,
1925 if (g_scanner_get_next_token (scanner) != GTK_RC_TOKEN_YTHICKNESS)
1926 return GTK_RC_TOKEN_YTHICKNESS;
1928 if (g_scanner_get_next_token (scanner) != G_TOKEN_EQUAL_SIGN)
1929 return G_TOKEN_EQUAL_SIGN;
1931 if (g_scanner_get_next_token (scanner) != G_TOKEN_INT)
1934 style->ythickness = scanner->value.v_int;
1936 return G_TOKEN_NONE;
1940 gtk_rc_parse_bg_pixmap (GScanner *scanner,
1941 GtkRcStyle *rc_style)
1947 token = g_scanner_get_next_token (scanner);
1948 if (token != GTK_RC_TOKEN_BG_PIXMAP)
1949 return GTK_RC_TOKEN_BG_PIXMAP;
1951 token = gtk_rc_parse_state (scanner, &state);
1952 if (token != G_TOKEN_NONE)
1955 token = g_scanner_get_next_token (scanner);
1956 if (token != G_TOKEN_EQUAL_SIGN)
1957 return G_TOKEN_EQUAL_SIGN;
1959 token = g_scanner_get_next_token (scanner);
1960 if (token != G_TOKEN_STRING)
1961 return G_TOKEN_STRING;
1963 if ((strcmp (scanner->value.v_string, "<parent>") == 0) ||
1964 (strcmp (scanner->value.v_string, "<none>") == 0))
1965 pixmap_file = g_strdup (scanner->value.v_string);
1967 pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
1971 if (rc_style->bg_pixmap_name[state])
1972 g_free (rc_style->bg_pixmap_name[state]);
1973 rc_style->bg_pixmap_name[state] = pixmap_file;
1976 return G_TOKEN_NONE;
1980 gtk_rc_check_pixmap_dir (const gchar *dir, const gchar *pixmap_file)
1985 buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s", dir, pixmap_file);
1987 fd = open (buf, O_RDONLY);
2000 gtk_rc_find_pixmap_in_path (GScanner *scanner,
2001 const gchar *pixmap_file)
2007 for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
2009 filename = gtk_rc_check_pixmap_dir (pixmap_path[i], pixmap_file);
2014 tmp_list = rc_dir_stack;
2017 filename = gtk_rc_check_pixmap_dir (tmp_list->data, pixmap_file);
2021 tmp_list = tmp_list->next;
2025 g_warning (_("Unable to locate image file in pixmap_path: \"%s\" line %d"),
2026 pixmap_file, scanner->line);
2028 g_warning (_("Unable to locate image file in pixmap_path: \"%s\""),
2035 gtk_rc_find_module_in_path (const gchar *module_file)
2041 for (i = 0; (i < GTK_RC_MAX_MODULE_PATHS) && (module_path[i] != NULL); i++)
2043 buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s",
2044 module_path[i], module_file);
2046 fd = open (buf, O_RDONLY);
2060 gtk_rc_parse_font (GScanner *scanner,
2061 GtkRcStyle *rc_style)
2065 token = g_scanner_get_next_token (scanner);
2066 if (token != GTK_RC_TOKEN_FONT)
2067 return GTK_RC_TOKEN_FONT;
2069 token = g_scanner_get_next_token (scanner);
2070 if (token != G_TOKEN_EQUAL_SIGN)
2071 return G_TOKEN_EQUAL_SIGN;
2073 token = g_scanner_get_next_token (scanner);
2074 if (token != G_TOKEN_STRING)
2075 return G_TOKEN_STRING;
2077 /* Ignore, do nothing */
2079 return G_TOKEN_NONE;
2083 gtk_rc_parse_fontset (GScanner *scanner,
2084 GtkRcStyle *rc_style)
2088 token = g_scanner_get_next_token (scanner);
2089 if (token != GTK_RC_TOKEN_FONTSET)
2090 return GTK_RC_TOKEN_FONTSET;
2092 token = g_scanner_get_next_token (scanner);
2093 if (token != G_TOKEN_EQUAL_SIGN)
2094 return G_TOKEN_EQUAL_SIGN;
2096 token = g_scanner_get_next_token (scanner);
2097 if (token != G_TOKEN_STRING)
2098 return G_TOKEN_STRING;
2100 /* Do nothing - silently ignore */
2102 return G_TOKEN_NONE;
2106 gtk_rc_parse_font_name (GScanner *scanner,
2107 GtkRcStyle *rc_style)
2111 token = g_scanner_get_next_token (scanner);
2112 if (token != GTK_RC_TOKEN_FONT_NAME)
2113 return GTK_RC_TOKEN_FONT;
2115 token = g_scanner_get_next_token (scanner);
2116 if (token != G_TOKEN_EQUAL_SIGN)
2117 return G_TOKEN_EQUAL_SIGN;
2119 token = g_scanner_get_next_token (scanner);
2120 if (token != G_TOKEN_STRING)
2121 return G_TOKEN_STRING;
2123 rc_style->font_desc = pango_font_description_from_string (scanner->value.v_string);
2125 return G_TOKEN_NONE;
2129 gtk_rc_parse_engine (GScanner *scanner,
2130 GtkRcStyle **rc_style)
2133 GtkThemeEngine *engine;
2134 guint result = G_TOKEN_NONE;
2135 GtkRcStyle *new_style = NULL;
2136 gboolean parsed_curlies = FALSE;
2138 token = g_scanner_get_next_token (scanner);
2139 if (token != GTK_RC_TOKEN_ENGINE)
2140 return GTK_RC_TOKEN_ENGINE;
2142 token = g_scanner_get_next_token (scanner);
2143 if (token != G_TOKEN_STRING)
2144 return G_TOKEN_STRING;
2146 engine = gtk_theme_engine_get (scanner->value.v_string);
2148 token = g_scanner_get_next_token (scanner);
2149 if (token != G_TOKEN_LEFT_CURLY)
2150 return G_TOKEN_LEFT_CURLY;
2154 GtkRcStyleClass *new_class;
2156 new_style = gtk_theme_engine_create_rc_style (engine);
2157 g_type_module_unuse (G_TYPE_MODULE (engine));
2159 new_class = GTK_RC_STYLE_GET_CLASS (new_style);
2161 new_class->merge (new_style, *rc_style);
2162 if ((*rc_style)->name)
2163 new_style->name = g_strdup ((*rc_style)->name);
2165 if (new_class->parse)
2167 parsed_curlies = TRUE;
2168 result = new_class->parse (new_style, scanner);
2170 if (result != G_TOKEN_NONE)
2172 g_object_unref (G_OBJECT (new_style));
2178 if (!parsed_curlies)
2180 /* Skip over remainder, looking for nested {}'s
2184 result = G_TOKEN_RIGHT_CURLY;
2185 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
2187 if (token == G_TOKEN_LEFT_CURLY)
2189 else if (token == G_TOKEN_RIGHT_CURLY)
2194 result = G_TOKEN_NONE;
2202 g_object_unref (G_OBJECT (*rc_style));
2203 *rc_style = new_style;
2210 gtk_rc_parse_state (GScanner *scanner,
2211 GtkStateType *state)
2216 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
2217 g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
2219 /* we don't know where we got called from, so we reset the scope here.
2220 * if we bail out due to errors, we *don't* reset the scope, so the
2221 * error messaging code can make sense of our tokens.
2223 old_scope = g_scanner_set_scope (scanner, 0);
2225 token = g_scanner_get_next_token (scanner);
2226 if (token != G_TOKEN_LEFT_BRACE)
2227 return G_TOKEN_LEFT_BRACE;
2229 token = g_scanner_get_next_token (scanner);
2232 case GTK_RC_TOKEN_ACTIVE:
2233 *state = GTK_STATE_ACTIVE;
2235 case GTK_RC_TOKEN_INSENSITIVE:
2236 *state = GTK_STATE_INSENSITIVE;
2238 case GTK_RC_TOKEN_NORMAL:
2239 *state = GTK_STATE_NORMAL;
2241 case GTK_RC_TOKEN_PRELIGHT:
2242 *state = GTK_STATE_PRELIGHT;
2244 case GTK_RC_TOKEN_SELECTED:
2245 *state = GTK_STATE_SELECTED;
2248 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
2251 token = g_scanner_get_next_token (scanner);
2252 if (token != G_TOKEN_RIGHT_BRACE)
2253 return G_TOKEN_RIGHT_BRACE;
2255 g_scanner_set_scope (scanner, old_scope);
2257 return G_TOKEN_NONE;
2261 gtk_rc_parse_priority (GScanner *scanner,
2262 GtkPathPriorityType *priority)
2267 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
2268 g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
2270 /* we don't know where we got called from, so we reset the scope here.
2271 * if we bail out due to errors, we *don't* reset the scope, so the
2272 * error messaging code can make sense of our tokens.
2274 old_scope = g_scanner_set_scope (scanner, 0);
2276 token = g_scanner_get_next_token (scanner);
2280 token = g_scanner_get_next_token (scanner);
2283 case GTK_RC_TOKEN_LOWEST:
2284 *priority = GTK_PATH_PRIO_LOWEST;
2286 case GTK_RC_TOKEN_GTK:
2287 *priority = GTK_PATH_PRIO_GTK;
2289 case GTK_RC_TOKEN_APPLICATION:
2290 *priority = GTK_PATH_PRIO_APPLICATION;
2292 case GTK_RC_TOKEN_RC:
2293 *priority = GTK_PATH_PRIO_RC;
2295 case GTK_RC_TOKEN_HIGHEST:
2296 *priority = GTK_PATH_PRIO_HIGHEST;
2299 return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
2302 g_scanner_set_scope (scanner, old_scope);
2304 return G_TOKEN_NONE;
2308 gtk_rc_parse_color (GScanner *scanner,
2313 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
2315 /* we don't need to set our own scop here, because
2316 * we don't need own symbols
2319 token = g_scanner_get_next_token (scanner);
2328 case G_TOKEN_LEFT_CURLY:
2329 token = g_scanner_get_next_token (scanner);
2330 if (token == G_TOKEN_INT)
2331 token_int = scanner->value.v_int;
2332 else if (token == G_TOKEN_FLOAT)
2333 token_int = scanner->value.v_float * 65535.0;
2335 return G_TOKEN_FLOAT;
2336 color->red = CLAMP (token_int, 0, 65535);
2338 token = g_scanner_get_next_token (scanner);
2339 if (token != G_TOKEN_COMMA)
2340 return G_TOKEN_COMMA;
2342 token = g_scanner_get_next_token (scanner);
2343 if (token == G_TOKEN_INT)
2344 token_int = scanner->value.v_int;
2345 else if (token == G_TOKEN_FLOAT)
2346 token_int = scanner->value.v_float * 65535.0;
2348 return G_TOKEN_FLOAT;
2349 color->green = CLAMP (token_int, 0, 65535);
2351 token = g_scanner_get_next_token (scanner);
2352 if (token != G_TOKEN_COMMA)
2353 return G_TOKEN_COMMA;
2355 token = g_scanner_get_next_token (scanner);
2356 if (token == G_TOKEN_INT)
2357 token_int = scanner->value.v_int;
2358 else if (token == G_TOKEN_FLOAT)
2359 token_int = scanner->value.v_float * 65535.0;
2361 return G_TOKEN_FLOAT;
2362 color->blue = CLAMP (token_int, 0, 65535);
2364 token = g_scanner_get_next_token (scanner);
2365 if (token != G_TOKEN_RIGHT_CURLY)
2366 return G_TOKEN_RIGHT_CURLY;
2367 return G_TOKEN_NONE;
2369 case G_TOKEN_STRING:
2370 if (scanner->value.v_string[0] != '#')
2371 return G_TOKEN_STRING;
2373 length = strlen (scanner->value.v_string) - 1;
2374 if (((length % 3) != 0) || (length > 12))
2375 return G_TOKEN_STRING;
2378 for (i = 0, j = 1; i < length; i++, j++)
2379 buf[i] = scanner->value.v_string[j];
2382 sscanf (buf, "%x", &temp);
2385 for (i = 0; i < length; i++, j++)
2386 buf[i] = scanner->value.v_string[j];
2389 sscanf (buf, "%x", &temp);
2390 color->green = temp;
2392 for (i = 0; i < length; i++, j++)
2393 buf[i] = scanner->value.v_string[j];
2396 sscanf (buf, "%x", &temp);
2402 color->green *= 4369;
2403 color->blue *= 4369;
2405 else if (length == 2)
2408 color->green *= 257;
2411 else if (length == 3)
2417 return G_TOKEN_NONE;
2420 return G_TOKEN_STRING;
2425 gtk_rc_parse_pixmap_path (GScanner *scanner)
2429 token = g_scanner_get_next_token (scanner);
2430 if (token != GTK_RC_TOKEN_PIXMAP_PATH)
2431 return GTK_RC_TOKEN_PIXMAP_PATH;
2433 token = g_scanner_get_next_token (scanner);
2434 if (token != G_TOKEN_STRING)
2435 return G_TOKEN_STRING;
2437 gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
2439 return G_TOKEN_NONE;
2443 gtk_rc_parse_pixmap_path_string (gchar *pix_path)
2447 gint start_offset = 0;
2451 /* free the old one, or just add to the old one ? */
2452 for (path_num=0; pixmap_path[path_num]; path_num++)
2454 g_free (pixmap_path[path_num]);
2455 pixmap_path[path_num] = NULL;
2460 path_len = strlen (pix_path);
2462 buf = g_strdup (pix_path);
2464 for (end_offset = 0; end_offset <= path_len; end_offset++)
2466 if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
2467 (end_offset == path_len))
2469 buf[end_offset] = '\0';
2470 pixmap_path[path_num] = g_strdup (buf + start_offset);
2472 pixmap_path[path_num] = NULL;
2473 start_offset = end_offset + 1;
2480 gtk_rc_parse_module_path (GScanner *scanner)
2484 token = g_scanner_get_next_token (scanner);
2485 if (token != GTK_RC_TOKEN_MODULE_PATH)
2486 return GTK_RC_TOKEN_MODULE_PATH;
2488 token = g_scanner_get_next_token (scanner);
2489 if (token != G_TOKEN_STRING)
2490 return G_TOKEN_STRING;
2492 gtk_rc_parse_module_path_string (scanner->value.v_string);
2494 return G_TOKEN_NONE;
2498 gtk_rc_parse_im_module_path (GScanner *scanner)
2502 token = g_scanner_get_next_token (scanner);
2503 if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
2504 return GTK_RC_TOKEN_IM_MODULE_FILE;
2506 token = g_scanner_get_next_token (scanner);
2507 if (token != G_TOKEN_STRING)
2508 return G_TOKEN_STRING;
2511 g_free (im_module_path);
2513 im_module_path = g_strdup (scanner->value.v_string);
2515 return G_TOKEN_NONE;
2519 gtk_rc_parse_im_module_file (GScanner *scanner)
2523 token = g_scanner_get_next_token (scanner);
2524 if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
2525 return GTK_RC_TOKEN_IM_MODULE_FILE;
2527 token = g_scanner_get_next_token (scanner);
2528 if (token != G_TOKEN_STRING)
2529 return G_TOKEN_STRING;
2532 g_free (im_module_file);
2534 im_module_file = g_strdup (scanner->value.v_string);
2536 return G_TOKEN_NONE;
2540 gtk_rc_parse_module_path_string (gchar *mod_path)
2544 gint start_offset = 0;
2548 /* free the old one, or just add to the old one ? */
2549 for (path_num=0; module_path[path_num]; path_num++)
2551 g_free (module_path[path_num]);
2552 module_path[path_num] = NULL;
2557 path_len = strlen (mod_path);
2559 buf = g_strdup (mod_path);
2561 for (end_offset = 0; end_offset <= path_len; end_offset++)
2563 if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
2564 (end_offset == path_len))
2566 buf[end_offset] = '\0';
2567 module_path[path_num] = g_strdup (buf + start_offset);
2569 module_path[path_num] = NULL;
2570 start_offset = end_offset + 1;
2574 gtk_rc_append_default_module_path();
2578 gtk_rc_parse_path_pattern (GScanner *scanner)
2581 GtkPathType path_type;
2583 gboolean is_binding;
2584 GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
2586 token = g_scanner_get_next_token (scanner);
2589 case GTK_RC_TOKEN_WIDGET:
2590 path_type = GTK_PATH_WIDGET;
2592 case GTK_RC_TOKEN_WIDGET_CLASS:
2593 path_type = GTK_PATH_WIDGET_CLASS;
2595 case GTK_RC_TOKEN_CLASS:
2596 path_type = GTK_PATH_CLASS;
2599 return GTK_RC_TOKEN_WIDGET_CLASS;
2602 token = g_scanner_get_next_token (scanner);
2603 if (token != G_TOKEN_STRING)
2604 return G_TOKEN_STRING;
2606 pattern = g_strdup (scanner->value.v_string);
2608 token = g_scanner_get_next_token (scanner);
2609 if (token == GTK_RC_TOKEN_STYLE)
2611 else if (token == GTK_RC_TOKEN_BINDING)
2614 if (g_scanner_peek_next_token (scanner) == ':')
2616 token = gtk_rc_parse_priority (scanner, &priority);
2617 if (token != G_TOKEN_NONE)
2627 return GTK_RC_TOKEN_STYLE;
2630 token = g_scanner_get_next_token (scanner);
2631 if (token != G_TOKEN_STRING)
2634 return G_TOKEN_STRING;
2639 GtkBindingSet *binding;
2641 binding = gtk_binding_set_find (scanner->value.v_string);
2645 return G_TOKEN_STRING;
2647 gtk_binding_set_add_path (binding, path_type, pattern, priority);
2651 GtkRcStyle *rc_style;
2654 rc_style = gtk_rc_style_find (scanner->value.v_string);
2659 return G_TOKEN_STRING;
2662 rc_set = g_new (GtkRcSet, 1);
2663 gtk_pattern_spec_init (&rc_set->pspec, pattern);
2664 rc_set->rc_style = rc_style;
2666 if (path_type == GTK_PATH_WIDGET)
2667 gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
2668 else if (path_type == GTK_PATH_WIDGET_CLASS)
2669 gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
2671 gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
2675 return G_TOKEN_NONE;
2679 gtk_rc_parse_stock_id (GScanner *scanner,
2684 token = g_scanner_get_next_token (scanner);
2685 if (token != G_TOKEN_LEFT_BRACE)
2686 return G_TOKEN_LEFT_BRACE;
2688 token = g_scanner_get_next_token (scanner);
2690 if (token != G_TOKEN_STRING)
2691 return G_TOKEN_STRING;
2693 *stock_id = g_strdup (scanner->value.v_string);
2695 token = g_scanner_get_next_token (scanner);
2696 if (token != G_TOKEN_RIGHT_BRACE)
2699 return G_TOKEN_RIGHT_BRACE;
2702 return G_TOKEN_NONE;
2706 cleanup_source (GtkIconSource *source)
2708 g_free (source->filename);
2709 g_free (source->size);
2713 gtk_rc_parse_icon_source (GScanner *scanner,
2714 GtkIconSet *icon_set)
2717 GtkIconSource source = { NULL, NULL,
2721 token = g_scanner_get_next_token (scanner);
2722 if (token != G_TOKEN_LEFT_CURLY)
2723 return G_TOKEN_LEFT_CURLY;
2725 token = g_scanner_get_next_token (scanner);
2727 if (token != G_TOKEN_STRING)
2728 return G_TOKEN_STRING;
2730 source.filename = g_strdup (scanner->value.v_string);
2732 token = g_scanner_get_next_token (scanner);
2734 if (token == G_TOKEN_RIGHT_CURLY)
2736 gtk_icon_set_add_source (icon_set, &source);
2737 cleanup_source (&source);
2738 return G_TOKEN_NONE;
2740 else if (token != G_TOKEN_COMMA)
2742 cleanup_source (&source);
2743 return G_TOKEN_COMMA;
2746 /* Get the direction */
2748 token = g_scanner_get_next_token (scanner);
2752 case GTK_RC_TOKEN_RTL:
2753 source.any_direction = FALSE;
2754 source.direction = GTK_TEXT_DIR_RTL;
2757 case GTK_RC_TOKEN_LTR:
2758 source.any_direction = FALSE;
2759 source.direction = GTK_TEXT_DIR_LTR;
2766 cleanup_source (&source);
2767 return GTK_RC_TOKEN_RTL;
2771 token = g_scanner_get_next_token (scanner);
2773 if (token == G_TOKEN_RIGHT_CURLY)
2775 gtk_icon_set_add_source (icon_set, &source);
2776 cleanup_source (&source);
2777 return G_TOKEN_NONE;
2779 else if (token != G_TOKEN_COMMA)
2781 cleanup_source (&source);
2782 return G_TOKEN_COMMA;
2787 token = g_scanner_get_next_token (scanner);
2791 case GTK_RC_TOKEN_NORMAL:
2792 source.any_state = FALSE;
2793 source.state = GTK_STATE_NORMAL;
2796 case GTK_RC_TOKEN_PRELIGHT:
2797 source.any_state = FALSE;
2798 source.state = GTK_STATE_PRELIGHT;
2802 case GTK_RC_TOKEN_INSENSITIVE:
2803 source.any_state = FALSE;
2804 source.state = GTK_STATE_INSENSITIVE;
2807 case GTK_RC_TOKEN_ACTIVE:
2808 source.any_state = FALSE;
2809 source.state = GTK_STATE_ACTIVE;
2812 case GTK_RC_TOKEN_SELECTED:
2813 source.any_state = FALSE;
2814 source.state = GTK_STATE_SELECTED;
2821 cleanup_source (&source);
2822 return GTK_RC_TOKEN_PRELIGHT;
2826 token = g_scanner_get_next_token (scanner);
2828 if (token == G_TOKEN_RIGHT_CURLY)
2830 gtk_icon_set_add_source (icon_set, &source);
2831 cleanup_source (&source);
2832 return G_TOKEN_NONE;
2834 else if (token != G_TOKEN_COMMA)
2836 cleanup_source (&source);
2837 return G_TOKEN_COMMA;
2842 token = g_scanner_get_next_token (scanner);
2846 if (token != G_TOKEN_STRING)
2848 cleanup_source (&source);
2849 return G_TOKEN_STRING;
2852 source.size = g_strdup (scanner->value.v_string);
2853 source.any_size = FALSE;
2856 /* Check the close brace */
2858 token = g_scanner_get_next_token (scanner);
2859 if (token != G_TOKEN_RIGHT_CURLY)
2861 cleanup_source (&source);
2862 return G_TOKEN_RIGHT_CURLY;
2865 gtk_icon_set_add_source (icon_set, &source);
2867 cleanup_source (&source);
2869 return G_TOKEN_NONE;
2873 gtk_rc_parse_stock (GScanner *scanner,
2874 GtkRcStyle *rc_style,
2875 GtkIconFactory *factory)
2877 GtkIconSet *icon_set = NULL;
2878 gchar *stock_id = NULL;
2881 token = g_scanner_get_next_token (scanner);
2882 if (token != GTK_RC_TOKEN_STOCK)
2883 return GTK_RC_TOKEN_STOCK;
2885 token = gtk_rc_parse_stock_id (scanner, &stock_id);
2886 if (token != G_TOKEN_NONE)
2889 token = g_scanner_get_next_token (scanner);
2890 if (token != G_TOKEN_EQUAL_SIGN)
2893 return G_TOKEN_EQUAL_SIGN;
2896 token = g_scanner_get_next_token (scanner);
2897 if (token != G_TOKEN_LEFT_CURLY)
2900 return G_TOKEN_LEFT_CURLY;
2903 token = g_scanner_peek_next_token (scanner);
2904 while (token != G_TOKEN_RIGHT_CURLY)
2906 if (icon_set == NULL)
2907 icon_set = gtk_icon_set_new ();
2909 token = gtk_rc_parse_icon_source (scanner, icon_set);
2910 if (token != G_TOKEN_NONE)
2913 gtk_icon_set_unref (icon_set);
2917 token = g_scanner_get_next_token (scanner);
2919 if (token != G_TOKEN_COMMA &&
2920 token != G_TOKEN_RIGHT_CURLY)
2923 gtk_icon_set_unref (icon_set);
2924 return G_TOKEN_RIGHT_CURLY;
2930 gtk_icon_factory_add (factory,
2934 gtk_icon_set_unref (icon_set);
2939 return G_TOKEN_NONE;
2943 typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
2944 GdkColormap *colormap,
2946 GdkColor *transparent_color,
2947 const gchar *filename);
2951 gtk_rc_set_image_loader(GtkImageLoader loader)
2953 image_loader = loader;
2957 gtk_rc_load_image (GdkColormap *colormap,
2958 GdkColor *transparent_color,
2959 const gchar *filename)
2961 if (strcmp (filename, "<parent>") == 0)
2962 return (GdkPixmap*) GDK_PARENT_RELATIVE;
2966 return image_loader(NULL, colormap, NULL,
2970 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,