* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "gdkconfig.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlocale.h> /* so we get the right setlocale */
+#else
+#include <locale.h>
+#endif
#include <ctype.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <sys/stat.h>
+#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
+#endif
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HAVE_LSTAT
+#define lstat stat
+#endif
+
+#ifdef G_OS_WIN32
+#include <windows.h> /* For GetWindowsDirectory */
+#include <io.h>
+#endif
+
#include "gtkrc.h"
#include "gtkbindings.h"
#include "gtkthemes.h"
+#include "gtkintl.h"
typedef struct _GtkRcSet GtkRcSet;
typedef struct _GtkRcNode GtkRcNode;
typedef struct _GtkRcFile GtkRcFile;
+typedef struct _GtkRcStylePrivate GtkRcStylePrivate;
struct _GtkRcSet
{
gboolean reload;
};
+struct _GtkRcStylePrivate
+{
+ GtkRcStyle style;
+
+ guint ref_count;
+ /* list of RC style lists including this RC style */
+ GSList *rc_style_lists;
+};
+
static guint gtk_rc_style_hash (const char *name);
static gint gtk_rc_style_compare (const char *a,
const char *b);
static void gtk_rc_clear_styles (void);
static void gtk_rc_append_default_pixmap_path (void);
static void gtk_rc_append_default_module_path (void);
-static void gtk_rc_append_pixmap_path (gchar *dir);
+static void gtk_rc_add_initial_default_files (void);
-static GScannerConfig gtk_rc_scanner_config =
+static const GScannerConfig gtk_rc_scanner_config =
{
(
- " \t\n"
+ " \t\r\n"
) /* cset_skip_characters */,
(
G_CSET_a_2_z
FALSE /* scope_0_fallback */,
};
-static struct
+static const struct
{
gchar *name;
guint token;
{ "module_path", GTK_RC_TOKEN_MODULE_PATH },
};
-static guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
+static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
static GHashTable *rc_style_ht = NULL;
static GHashTable *realized_style_ht = NULL;
static GSList *gtk_rc_sets_widget_class = NULL;
static GSList *gtk_rc_sets_class = NULL;
+#define GTK_RC_MAX_DEFAULT_FILES 128
+static gchar *gtk_rc_default_files[GTK_RC_MAX_DEFAULT_FILES];
+static gboolean gtk_rc_auto_parse = TRUE;
+
#define GTK_RC_MAX_PIXMAP_PATHS 128
static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
#define GTK_RC_MAX_MODULE_PATHS 128
static gchar *module_path[GTK_RC_MAX_MODULE_PATHS];
+/* A stack of directories for RC files we are parsing currently.
+ * these are implicitely added to the end of PIXMAP_PATHS
+ */
+GSList *rc_dir_stack = NULL;
+
/* The files we have parsed, to reread later if necessary */
GSList *rc_files = NULL;
/* RC file handling */
+#ifdef G_OS_WIN32
+
+gchar *
+get_gtk_sysconf_directory (void)
+{
+ static gchar gtk_sysconf_dir[200];
+ gchar win_dir[100];
+
+ GetWindowsDirectory (win_dir, sizeof (win_dir));
+ sprintf (gtk_sysconf_dir, "%s\\gtk+", win_dir);
+ return gtk_sysconf_dir;
+}
+
+static gchar *
+get_themes_directory (void)
+{
+ /* We really should fetch this from the Registry. The GIMP
+ * installation program stores the Themes installation
+ * directory in HKLM\Software\GNU\GTk+\Themes\InstallDirectory.
+ * Later.
+ */
+ static gchar themes_dir[200];
+
+ sprintf (themes_dir, "%s\\themes", get_gtk_sysconf_directory ());
+ return themes_dir;
+}
+
+#endif
+
gchar *
gtk_rc_get_theme_dir(void)
{
gchar *var, *path;
+#ifndef G_OS_WIN32
var = getenv("GTK_DATA_PREFIX");
if (var)
- {
- path = g_malloc(strlen(var) + strlen("/share/themes") +1);
- sprintf(path, "%s%s", var, "/share/themes");
- }
+ path = g_strdup_printf("%s%s", var, "/share/themes");
else
- {
- path = g_malloc(strlen(GTK_DATA_PREFIX) + strlen("/share/themes") +1);
- sprintf(path, "%s%s", GTK_DATA_PREFIX, "/share/themes");
- }
+ path = g_strdup_printf("%s%s", GTK_DATA_PREFIX, "/share/themes");
+#else
+ path = g_strdup (get_themes_directory ());
+#endif
+
return path;
}
{
gchar *var, *path;
+#ifndef G_OS_WIN32
var = getenv("GTK_EXE_PREFIX");
if (var)
- {
- path = g_malloc(strlen(var) + strlen("/lib/gtk/themes/engines") +1);
- sprintf(path, "%s%s", var, "/lib/gtk/themes/engines");
- }
+ path = g_strdup_printf("%s%s", var, "/lib/gtk/themes/engines");
else
- {
- path = g_malloc(strlen(GTK_EXE_PREFIX) + strlen("/lib/gtk/themes/engines") +1);
- sprintf(path, "%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
- }
+ path = g_strdup_printf("%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
+#else
+ path = g_strdup_printf ("%s%s", get_themes_directory (), "\\engines");
+#endif
+
return path;
}
gchar *var, *path;
gint n;
+#ifndef G_OS_WIN32
var = getenv("GTK_DATA_PREFIX");
if (var)
- {
- path = g_malloc(strlen(var) + strlen("/share/gtk/themes") +1);
- sprintf(path, "%s%s", var, "/share/gtk/themes");
- }
+ path = g_strdup_printf("%s%s", var, "/share/gtk/themes");
else
- {
- path = g_malloc(strlen(GTK_DATA_PREFIX) + strlen("/share/gtk/themes") +1);
- sprintf(path, "%s%s", GTK_DATA_PREFIX, "/share/gtk/themes");
- }
+ path = g_strdup_printf("%s%s", GTK_DATA_PREFIX, "/share/gtk/themes");
+#else
+ path = g_strdup (get_themes_directory ());
+#endif
for (n = 0; pixmap_path[n]; n++) ;
if (n >= GTK_RC_MAX_PIXMAP_PATHS - 1)
- return;
- pixmap_path[n++] = g_strdup(path);
+ {
+ g_free (path);
+ return;
+ }
+ pixmap_path[n++] = path;
pixmap_path[n] = NULL;
- g_free(path);
}
static void
-gtk_rc_append_pixmap_path(gchar *dir)
+gtk_rc_append_default_module_path(void)
{
+ gchar *var, *path;
gint n;
- for (n = 0; pixmap_path[n]; n++) ;
+ for (n = 0; module_path[n]; n++) ;
if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
return;
- pixmap_path[n++] = g_strdup(dir);
- pixmap_path[n] = NULL;
+
+#ifndef G_OS_WIN32
+ var = getenv("GTK_EXE_PREFIX");
+ if (var)
+ path = g_strdup_printf("%s%s", var, "/lib/gtk/themes/engines");
+ else
+ path = g_strdup_printf("%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
+#else
+ path = g_strdup_printf ("%s%s", get_themes_directory (), "\\engines");
+#endif
+ module_path[n++] = path;
+
+ var = g_get_home_dir ();
+ if (var)
+ {
+#ifndef G_OS_WIN32
+ path = g_strdup_printf ("%s%s", var, "/.gtk/lib/themes/engines");
+#else
+ path = g_strdup_printf ("%s%s", var, "\\_gtk\\themes\\engines");
+#endif
+ module_path[n++] = path;
+ }
+ module_path[n] = NULL;
}
static void
-gtk_rc_append_default_module_path(void)
+gtk_rc_add_initial_default_files (void)
{
- gchar *var, *path;
- gint n;
+ static gint init = FALSE;
+ gchar *var, *str;
+ gchar **files;
+ gint i;
- for (n = 0; module_path[n]; n++) ;
- if (n >= GTK_RC_MAX_MODULE_PATHS - 1)
+ if (init)
return;
- var = getenv("GTK_EXE_PREFIX");
+ gtk_rc_default_files[0] = NULL;
+ init = TRUE;
+
+ var = g_getenv("GTK_RC_FILES");
if (var)
{
- path = g_malloc(strlen(var) + strlen("/lib/gtk/themes/engines") +1);
- sprintf(path, "%s%s", var, "/lib/gtk/themes/engines");
+ files = g_strsplit (var, G_SEARCHPATH_SEPARATOR_S, 128);
+ i=0;
+ while (files[i])
+ {
+ gtk_rc_add_default_file (files[i]);
+ i++;
+ }
+ g_strfreev (files);
}
else
{
- path = g_malloc(strlen(GTK_EXE_PREFIX) + strlen("/lib/gtk/themes/engines") +1);
- sprintf(path, "%s%s", GTK_EXE_PREFIX, "/lib/gtk/themes/engines");
+#ifndef G_OS_WIN32
+ str = g_strdup (GTK_SYSCONFDIR G_DIR_SEPARATOR_S "gtk" G_DIR_SEPARATOR_S "gtkrc");
+#else
+ str = g_strdup_printf ("%s\\gtkrc", get_gtk_sysconf_directory ());
+#endif
+ gtk_rc_add_default_file (str);
+ g_free (str);
+
+ var = g_get_home_dir ();
+ if (var)
+ {
+ str = g_strdup_printf ("%s" G_DIR_SEPARATOR_S ".gtkrc", var);
+ gtk_rc_add_default_file (str);
+ g_free (str);
+ }
}
- module_path[n++] = g_strdup(path);
- g_free(path);
- var = getenv("HOME");
- if (var)
+}
+
+void
+gtk_rc_add_default_file (const gchar *file)
+{
+ guint n;
+
+ gtk_rc_add_initial_default_files ();
+
+ for (n = 0; gtk_rc_default_files[n]; n++) ;
+ if (n >= GTK_RC_MAX_DEFAULT_FILES - 1)
+ return;
+
+ gtk_rc_default_files[n++] = g_strdup (file);
+ gtk_rc_default_files[n] = NULL;
+}
+
+void
+gtk_rc_set_default_files (gchar **files)
+{
+ gint i;
+
+ gtk_rc_add_initial_default_files ();
+
+ i = 0;
+ while (gtk_rc_default_files[i])
{
- path = g_malloc(strlen(var) + strlen(".gtk/lib/themes/engines") +1);
- sprintf(path, "%s%s", var, ".gtk/lib/themes/engines");
+ g_free (gtk_rc_default_files[i]);
+ i++;
+ }
+
+ gtk_rc_default_files[0] = NULL;
+ gtk_rc_auto_parse = FALSE;
+
+ i = 0;
+ while (files[i] != NULL)
+ {
+ gtk_rc_add_default_file (files[i]);
+ i++;
}
- module_path[n++] = g_strdup(path);
- module_path[n] = NULL;
- g_free(path);
}
+gchar **
+gtk_rc_get_default_files (void)
+{
+ gtk_rc_add_initial_default_files ();
+
+ return gtk_rc_default_files;
+}
+
+ /* The following routine is based on _nl_normalize_codeset from
+ * the GNU C library. Contributed by
+ *
+ * Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ *
+ * Normalize codeset name. There is no standard for the codeset
+ * names. Normalization allows the user to use any of the common
+ * names.
+ */
+ static char *
+ _gtk_normalize_codeset (const char *codeset, int name_len)
+ {
+ int len = 0;
+ int only_digit = 1;
+ char *retval;
+ char *wp;
+ int cnt;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalnum (codeset[cnt]))
+ {
+ ++len;
+
+ if (isalpha (codeset[cnt]))
+ only_digit = 0;
+ }
+
+ retval = g_malloc ((only_digit ? 3 : 0) + len + 1);
+
+ if (only_digit)
+ {
+ strcpy (retval, "iso");
+ wp = retval + 3;
+ }
+ else
+ wp = retval;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalpha (codeset[cnt]))
+ *wp++ = isupper(codeset[cnt]) ? tolower (codeset[cnt]) : codeset[cnt];
+ else if (isdigit (codeset[cnt]))
+ *wp++ = codeset[cnt];
+
+ *wp = '\0';
+
+ return retval;
+ }
+
void
gtk_rc_init (void)
{
- rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
- (GCompareFunc) gtk_rc_style_compare);
- pixmap_path[0] = NULL;
- module_path[0] = NULL;
- gtk_rc_append_default_pixmap_path();
- gtk_rc_append_default_module_path();
+ static gchar *locale_suffixes[3];
+ static gint n_locale_suffixes = 0;
+
+ gint i, j;
+
+ static gboolean initted = FALSE;
+
+ if (!initted)
+ {
+ gint length;
+ gchar *locale;
+ gchar *p;
+
+#ifdef G_OS_WIN32
+ locale = g_win32_getlocale ();
+#else
+ locale = setlocale (LC_CTYPE, NULL);
+#endif
+
+ initted = TRUE;
+
+ pixmap_path[0] = NULL;
+ module_path[0] = NULL;
+ gtk_rc_append_default_pixmap_path();
+ gtk_rc_append_default_module_path();
+
+ gtk_rc_add_initial_default_files ();
+
+ if (strcmp (locale, "C") && strcmp (locale, "POSIX"))
+ {
+ /* Determine locale-specific suffixes for RC files
+ *
+ * We normalize the charset into a standard form,
+ * which has all '-' and '_' characters removed,
+ * and is lowercase.
+ */
+ gchar *normalized_locale;
+
+ p = strchr (locale, '@');
+ length = p ? (p -locale) : strlen (locale);
+
+ p = strchr (locale, '.');
+ if (p)
+ {
+ gchar *tmp1 = g_strndup (locale, p - locale + 1);
+ gchar *tmp2 = _gtk_normalize_codeset (p + 1, length - (p - locale + 1));
+
+ normalized_locale = g_strconcat (tmp1, tmp2, NULL);
+ g_free (tmp1);
+ g_free (tmp2);
+
+ locale_suffixes[n_locale_suffixes++] = g_strdup (normalized_locale);
+ length = p - locale;
+ }
+ else
+ normalized_locale = g_strndup (locale, length);
+
+ p = strchr (normalized_locale, '_');
+ if (p)
+ {
+ locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
+ length = p - normalized_locale;
+ }
+
+ locale_suffixes[n_locale_suffixes++] = g_strndup (normalized_locale, length);
+
+ g_free (normalized_locale);
+ }
+ }
+
+ i = 0;
+ while (gtk_rc_default_files[i] != NULL)
+ {
+ /* Try to find a locale specific RC file corresponding to
+ * to parse before the default file.
+ */
+ for (j=n_locale_suffixes-1; j>=0; j--)
+ {
+ gchar *name = g_strconcat (gtk_rc_default_files[i],
+ ".",
+ locale_suffixes[j],
+ NULL);
+ gtk_rc_parse (name);
+ g_free (name);
+ }
+
+ gtk_rc_parse (gtk_rc_default_files[i]);
+ i++;
+ }
}
void
{
/* Get the absolute pathname */
- if (rc_file->name[0] == '/')
+ if (g_path_is_absolute (rc_file->name))
rc_file->canonical_name = rc_file->name;
else
{
str = g_string_new (cwd);
g_free (cwd);
- g_string_append_c (str, '/');
+ g_string_append_c (str, G_DIR_SEPARATOR);
g_string_append (str, rc_file->name);
rc_file->canonical_name = str->str;
if (!lstat (rc_file->canonical_name, &statbuf))
{
gint fd;
+ GSList *tmp_list;
rc_file->mtime = statbuf.st_mtime;
if (fd < 0)
return;
- {
- gint i;
- gchar *dir;
-
- dir = g_strdup(rc_file->canonical_name);
- for (i = strlen(dir) - 1; (i >= 0) && (dir[i] != '/'); i--)
- dir[i] = 0;
- gtk_rc_append_pixmap_path(dir);
- g_free(dir);
- }
+ /* Temporarily push directory name for this file on
+ * a stack of directory names while parsing it
+ */
+ rc_dir_stack = g_slist_prepend (rc_dir_stack,
+ g_dirname (rc_file->canonical_name));
gtk_rc_parse_any (filename, fd, NULL);
+
+ tmp_list = rc_dir_stack;
+ rc_dir_stack = rc_dir_stack->next;
+
+ g_free (tmp_list->data);
+ g_slist_free_1 (tmp_list);
close (fd);
}
GtkRcStyle *
gtk_rc_style_new (void)
{
- GtkRcStyle *new_style;
+ GtkRcStylePrivate *new_style;
- new_style = g_new0 (GtkRcStyle, 1);
+ new_style = g_new0 (GtkRcStylePrivate, 1);
new_style->ref_count = 1;
- return new_style;
+ return (GtkRcStyle *)new_style;
}
void
{
g_return_if_fail (rc_style != NULL);
- rc_style->ref_count++;
+ ((GtkRcStylePrivate *)rc_style)->ref_count++;
+}
+
+/* Like g_slist_remove, but remove all copies of data */
+static GSList*
+gtk_rc_slist_remove_all (GSList *list,
+ gpointer data)
+{
+ GSList *tmp;
+ GSList *prev;
+
+ prev = NULL;
+ tmp = list;
+
+ while (tmp)
+ {
+ if (tmp->data == data)
+ {
+ if (list == tmp)
+ list = list->next;
+
+ if (prev)
+ prev->next = tmp->next;
+
+ g_slist_free_1 (tmp);
+
+ if (prev)
+ tmp = prev->next;
+ else
+ tmp = list;
+ }
+ else
+ {
+ prev = tmp;
+ tmp = tmp->next;
+ }
+ }
+
+ return list;
}
void
gtk_rc_style_unref (GtkRcStyle *rc_style)
{
+ GtkRcStylePrivate *private = (GtkRcStylePrivate *)rc_style;
gint i;
g_return_if_fail (rc_style != NULL);
+ g_return_if_fail (private->ref_count > 0);
- rc_style->ref_count--;
+ private->ref_count--;
- if (rc_style->ref_count == 0)
+ if (private->ref_count == 0)
{
+ GSList *tmp_list1, *tmp_list2;
+
if (rc_style->engine)
{
rc_style->engine->destroy_rc_style (rc_style);
if (rc_style->bg_pixmap_name[i])
g_free (rc_style->bg_pixmap_name[i]);
- g_free (rc_style);
- }
-}
+ /* Now remove all references to this rc_style from
+ * realized_style_ht
+ */
+ tmp_list1 = private->rc_style_lists;
+ while (tmp_list1)
+ {
+ GSList *rc_styles = tmp_list1->data;
+ GtkStyle *style = g_hash_table_lookup (realized_style_ht, rc_styles);
+ gtk_style_unref (style);
+
+ /* Remove the list of styles from the other rc_styles
+ * in the list
+ */
+ tmp_list2 = rc_styles;
+ while (tmp_list2)
+ {
+ GtkRcStylePrivate *other_style = tmp_list2->data;
-static void
-gtk_rc_clear_realized_node (gpointer key,
- gpointer data,
- gpointer user_data)
-{
- gtk_style_unref (data);
+ if (other_style != private)
+ other_style->rc_style_lists =
+ gtk_rc_slist_remove_all (other_style->rc_style_lists, rc_styles);
+
+ tmp_list2 = tmp_list2->next;
+ }
+
+ /* And from the hash table itself
+ */
+ g_hash_table_remove (realized_style_ht, rc_styles);
+ g_slist_free (rc_styles);
+
+ tmp_list1 = tmp_list1->next;
+ }
+ g_slist_free (private->rc_style_lists);
+
+ g_free (private);
+ }
}
static void
rc_style_ht = NULL;
}
- if (realized_style_ht)
- {
- g_hash_table_foreach (realized_style_ht, gtk_rc_clear_realized_node, NULL);
- g_hash_table_destroy (realized_style_ht);
- realized_style_ht = NULL;
- }
-
gtk_rc_free_rc_sets (gtk_rc_sets_widget);
g_slist_free (gtk_rc_sets_widget);
gtk_rc_sets_widget = NULL;
gtk_rc_free_rc_sets (gtk_rc_sets_class);
g_slist_free (gtk_rc_sets_class);
gtk_rc_sets_class = NULL;
-
- gtk_rc_init ();
}
gboolean
guint i;
gboolean done;
- scanner = g_scanner_new (>k_rc_scanner_config);
+ scanner = g_scanner_new ((GScannerConfig *) >k_rc_scanner_config);
if (input_fd >= 0)
{
static GtkRcStyle*
gtk_rc_style_find (const char *name)
{
- GtkRcStyle *rc_style;
-
- rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
-
- return rc_style;
+ if (rc_style_ht)
+ return g_hash_table_lookup (rc_style_ht, (gpointer) name);
+ else
+ return NULL;
}
/* Assumes ownership of rc_style */
gint i;
GtkStyle *style = NULL;
- GtkRcStyle *proto_style;
if (!realized_style_ht)
realized_style_ht = g_hash_table_new ((GHashFunc)gtk_rc_styles_hash,
if (!style)
{
- GSList *tmp_styles = rc_styles;
+ GtkRcStyle *proto_style;
+ GSList *tmp_styles;
proto_style = gtk_rc_style_new ();
+ tmp_styles = rc_styles;
while (tmp_styles)
{
GtkRcStyle *rc_style = tmp_styles->data;
+ GtkRcStylePrivate *rc_style_private;
for (i=0; i<5; i++)
{
(proto_style->engine == rc_style->engine))
proto_style->engine->merge_rc_style (proto_style, rc_style);
+ /* Point from each rc_style to the list of styles */
+
+ rc_style_private = (GtkRcStylePrivate *)rc_style;
+ if (!g_slist_find (rc_style_private->rc_style_lists, rc_styles))
+ rc_style_private->rc_style_lists = g_slist_prepend (rc_style_private->rc_style_lists, rc_styles);
+
tmp_styles = tmp_styles->next;
}
+ for (i=0; i<5; i++)
+ if (proto_style->bg_pixmap_name[i] &&
+ (strcmp (proto_style->bg_pixmap_name[i], "<none>") == 0))
+ {
+ g_free (proto_style->bg_pixmap_name[i]);
+ proto_style->bg_pixmap_name[i] = NULL;
+ }
+
style = gtk_rc_style_to_style (proto_style);
g_hash_table_insert (realized_style_ht, rc_styles, style);
}
+ else
+ g_slist_free (rc_styles);
return style;
}
return G_TOKEN_STRING;
insert = FALSE;
- rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
+ rc_style = gtk_rc_style_find (scanner->value.v_string);
if (!rc_style)
{
return G_TOKEN_STRING;
}
- parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
+ parent_style = gtk_rc_style_find (scanner->value.v_string);
if (parent_style)
{
for (i = 0; i < 5; i++)
}
if (insert)
- g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
+ {
+ if (!rc_style_ht)
+ rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
+ (GCompareFunc) gtk_rc_style_compare);
+
+ g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
+ }
return G_TOKEN_NONE;
}
if (token != G_TOKEN_STRING)
return G_TOKEN_STRING;
- if (strcmp (scanner->value.v_string, "<parent>"))
- pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
- else
+ if ((strcmp (scanner->value.v_string, "<parent>") == 0) ||
+ (strcmp (scanner->value.v_string, "<none>") == 0))
pixmap_file = g_strdup (scanner->value.v_string);
+ else
+ pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
if (pixmap_file)
{
return G_TOKEN_NONE;
}
+static gchar*
+gtk_rc_check_pixmap_dir (const gchar *dir, const gchar *pixmap_file)
+{
+ gchar *buf;
+ gint fd;
+
+ buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s", dir, pixmap_file);
+
+ fd = open (buf, O_RDONLY);
+ if (fd >= 0)
+ {
+ close (fd);
+ return buf;
+ }
+
+ g_free (buf);
+
+ return NULL;
+ }
+
gchar*
gtk_rc_find_pixmap_in_path (GScanner *scanner,
- const gchar *pixmap_file)
+ const gchar *pixmap_file)
{
gint i;
- gint fd;
- gchar *buf;
-
+ gchar *filename;
+ GSList *tmp_list;
+
for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
{
- buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
- sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
-
- fd = open (buf, O_RDONLY);
- if (fd >= 0)
- {
- close (fd);
- return buf;
- }
-
- g_free (buf);
+ filename = gtk_rc_check_pixmap_dir (pixmap_path[i], pixmap_file);
+ if (filename)
+ return filename;
}
-
+
+ tmp_list = rc_dir_stack;
+ while (tmp_list)
+ {
+ filename = gtk_rc_check_pixmap_dir (tmp_list->data, pixmap_file);
+ if (filename)
+ return filename;
+
+ tmp_list = tmp_list->next;
+ }
+
if (scanner)
- g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
+ g_warning (_("Unable to locate image file in pixmap_path: \"%s\" line %d"),
pixmap_file, scanner->line);
else
- g_warning ("Unable to locate image file in pixmap_path: \"%s\"",
+ g_warning (_("Unable to locate image file in pixmap_path: \"%s\""),
pixmap_file);
return NULL;
for (i = 0; (i < GTK_RC_MAX_MODULE_PATHS) && (module_path[i] != NULL); i++)
{
- buf = g_malloc (strlen (module_path[i]) + strlen (module_file) + 2);
- sprintf (buf, "%s%c%s", module_path[i], '/', module_file);
+ buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s",
+ module_path[i], module_file);
fd = open (buf, O_RDONLY);
if (fd >= 0)
for (end_offset = 0; end_offset <= path_len; end_offset++)
{
- if ((buf[end_offset] == ':') ||
+ if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
(end_offset == path_len))
{
buf[end_offset] = '\0';
for (end_offset = 0; end_offset <= path_len; end_offset++)
{
- if ((buf[end_offset] == ':') ||
+ if ((buf[end_offset] == G_SEARCHPATH_SEPARATOR) ||
(end_offset == path_len))
{
buf[end_offset] = '\0';