* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#include <ctype.h>
#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/param.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include "gtkrc.h"
-
-
-enum {
- TOKEN_INVALID = G_TOKEN_LAST,
- TOKEN_ACTIVE,
- TOKEN_BASE,
- TOKEN_BG,
- TOKEN_BG_PIXMAP,
- TOKEN_FG,
- TOKEN_FONT,
- TOKEN_FONTSET,
- TOKEN_INSENSITIVE,
- TOKEN_NORMAL,
- TOKEN_PIXMAP_PATH,
- TOKEN_PRELIGHT,
- TOKEN_SELECTED,
- TOKEN_STYLE,
- TOKEN_TEXT,
- TOKEN_WIDGET,
- TOKEN_WIDGET_CLASS
-};
-
-enum {
- PARSE_OK,
- PARSE_ERROR,
- PARSE_SYNTAX
-};
-
-enum {
- PARSE_START,
- PARSE_COMMENT,
- PARSE_STRING,
- PARSE_SYMBOL,
- PARSE_NUMBER
-};
+#include "gtkbindings.h"
typedef struct _GtkRcStyle GtkRcStyle;
typedef struct _GtkRcSet GtkRcSet;
+typedef struct _GtkRcNode GtkRcNode;
+typedef struct _GtkRcFile GtkRcFile;
+
+struct _GtkRcNode
+{
+ GdkColormap *cmap;
+ GtkStyle *style;
+};
struct _GtkRcStyle
{
- int initialize;
char *name;
char *font_name;
char *fontset_name;
char *bg_pixmap_name[5];
- GtkStyle *style;
+ GtkStyle *proto_style;
+ GList *styles;
};
struct _GtkRcSet
{
- char *set;
- GtkRcStyle *rc_style;
+ GtkPatternSpec pspec;
+ GtkRcStyle *rc_style;
};
+struct _GtkRcFile
+{
+ time_t mtime;
+ gchar *name;
+ gchar *canonical_name;
+ gboolean reload;
+};
static guint gtk_rc_style_hash (const char *name);
static gint gtk_rc_style_compare (const char *a,
const char *b);
static GtkRcStyle* gtk_rc_style_find (const char *name);
static GtkRcStyle* gtk_rc_styles_match (GSList *sets,
- const char *path);
-static gint gtk_rc_style_match (const char *set,
- const char *path);
-static void gtk_rc_style_init (GtkRcStyle *rc_style);
+ guint path_length,
+ gchar *path,
+ gchar *path_reversed);
+static GtkStyle* gtk_rc_style_init (GtkRcStyle *rc_style,
+ GdkColormap *cmap);
+static void gtk_rc_parse_file (const gchar *filename,
+ gboolean reload);
+
static void gtk_rc_parse_any (const gchar *input_name,
gint input_fd,
const gchar *input_string);
-static gint gtk_rc_parse_statement (GScanner *scanner);
-static gint gtk_rc_parse_style (GScanner *scanner);
-static gint gtk_rc_parse_style_option (GScanner *scanner,
- GtkRcStyle *rc_style);
-static gint gtk_rc_parse_base (GScanner *scanner,
+static guint gtk_rc_parse_statement (GScanner *scanner);
+static guint gtk_rc_parse_style (GScanner *scanner);
+static guint gtk_rc_parse_base (GScanner *scanner,
GtkStyle *style);
-static gint gtk_rc_parse_bg (GScanner *scanner,
+static guint gtk_rc_parse_bg (GScanner *scanner,
GtkStyle *style);
-static gint gtk_rc_parse_fg (GScanner *scanner,
+static guint gtk_rc_parse_fg (GScanner *scanner,
GtkStyle *style);
-static gint gtk_rc_parse_bg_pixmap (GScanner *scanner,
+static guint gtk_rc_parse_text (GScanner *scanner,
+ GtkStyle *style);
+static guint gtk_rc_parse_bg_pixmap (GScanner *scanner,
GtkRcStyle *rc_style);
-static gint gtk_rc_parse_font (GScanner *scanner,
+static guint gtk_rc_parse_font (GScanner *scanner,
GtkRcStyle *rc_style);
-static gint gtk_rc_parse_fontset (GScanner *scanner,
+static guint gtk_rc_parse_fontset (GScanner *scanner,
GtkRcStyle *rc_style);
-static gint gtk_rc_parse_state (GScanner *scanner,
- GtkStateType *state);
-static gint gtk_rc_parse_color (GScanner *scanner,
- GdkColor *color);
-static gint gtk_rc_parse_pixmap_path (GScanner *scanner);
+static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
static char* gtk_rc_find_pixmap_in_path (GScanner *scanner,
gchar *pixmap_file);
-static gint gtk_rc_parse_widget_style (GScanner *scanner);
-static gint gtk_rc_parse_widget_class_style (GScanner *scanner);
-static char* gtk_rc_widget_path (GtkWidget *widget);
-static char* gtk_rc_widget_class_path (GtkWidget *widget);
+static guint gtk_rc_parse_path_pattern (GScanner *scanner);
+static void gtk_rc_clear_hash_node (gpointer key,
+ gpointer data,
+ gpointer user_data);
+static void gtk_rc_clear_styles (void);
+
static GScannerConfig gtk_rc_scanner_config =
) /* cset_identifier_first */,
(
G_CSET_a_2_z
- "_0123456789"
+ "_-0123456789"
G_CSET_A_2_Z
- G_CSET_LATINS
- G_CSET_LATINC
) /* cset_identifier_nth */,
( "#\n" ) /* cpair_comment_single */,
TRUE /* scan_float */,
TRUE /* scan_hex */,
TRUE /* scan_hex_dollar */,
- FALSE /* scan_string_sq */,
+ TRUE /* scan_string_sq */,
TRUE /* scan_string_dq */,
TRUE /* numbers_2_int */,
FALSE /* int_2_float */,
- TRUE /* identifier_2_string */,
+ FALSE /* identifier_2_string */,
TRUE /* char_2_token */,
TRUE /* symbol_2_token */,
+ FALSE /* scope_0_fallback */,
};
static struct
{
- char *name;
- int token;
-} symbols[] =
- {
- { "ACTIVE", TOKEN_ACTIVE },
- { "base", TOKEN_BASE },
- { "bg", TOKEN_BG },
- { "bg_pixmap", TOKEN_BG_PIXMAP },
- { "fg", TOKEN_FG },
- { "font", TOKEN_FONT },
- { "fontset", TOKEN_FONTSET },
- { "INSENSITIVE", TOKEN_INSENSITIVE },
- { "NORMAL", TOKEN_NORMAL },
- { "pixmap_path", TOKEN_PIXMAP_PATH },
- { "PRELIGHT", TOKEN_PRELIGHT },
- { "SELECTED", TOKEN_SELECTED },
- { "style", TOKEN_STYLE },
- { "text", TOKEN_TEXT },
- { "widget", TOKEN_WIDGET },
- { "widget_class", TOKEN_WIDGET_CLASS },
- };
-static int nsymbols = sizeof (symbols) / sizeof (symbols[0]);
-
-static int done;
+ gchar *name;
+ guint token;
+} symbols[] = {
+ { "include", GTK_RC_TOKEN_INCLUDE },
+ { "NORMAL", GTK_RC_TOKEN_NORMAL },
+ { "ACTIVE", GTK_RC_TOKEN_ACTIVE },
+ { "PRELIGHT", GTK_RC_TOKEN_PRELIGHT },
+ { "SELECTED", GTK_RC_TOKEN_SELECTED },
+ { "INSENSITIVE", GTK_RC_TOKEN_INSENSITIVE },
+ { "fg", GTK_RC_TOKEN_FG },
+ { "bg", GTK_RC_TOKEN_BG },
+ { "base", GTK_RC_TOKEN_BASE },
+ { "text", GTK_RC_TOKEN_TEXT },
+ { "font", GTK_RC_TOKEN_FONT },
+ { "fontset", GTK_RC_TOKEN_FONTSET },
+ { "bg_pixmap", GTK_RC_TOKEN_BG_PIXMAP },
+ { "pixmap_path", GTK_RC_TOKEN_PIXMAP_PATH },
+ { "style", GTK_RC_TOKEN_STYLE },
+ { "binding", GTK_RC_TOKEN_BINDING },
+ { "bind", GTK_RC_TOKEN_BIND },
+ { "widget", GTK_RC_TOKEN_WIDGET },
+ { "widget_class", GTK_RC_TOKEN_WIDGET_CLASS },
+ { "class", GTK_RC_TOKEN_CLASS },
+ { "lowest", GTK_RC_TOKEN_LOWEST },
+ { "gtk", GTK_RC_TOKEN_GTK },
+ { "application", GTK_RC_TOKEN_APPLICATION },
+ { "rc", GTK_RC_TOKEN_RC },
+ { "highest", GTK_RC_TOKEN_HIGHEST },
+};
+
+static guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
static GHashTable *rc_style_ht = NULL;
-static GSList *widget_sets = NULL;
-static GSList *widget_class_sets = NULL;
+static GSList *gtk_rc_sets_widget = NULL;
+static GSList *gtk_rc_sets_widget_class = NULL;
+static GSList *gtk_rc_sets_class = NULL;
#define GTK_RC_MAX_PIXMAP_PATHS 128
static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
+/* The files we have parsed, to reread later if necessary */
+GSList *rc_files = NULL;
+
+static GtkImageLoader image_loader = NULL;
void
-gtk_rc_init ()
+gtk_rc_init (void)
{
rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
(GCompareFunc) gtk_rc_style_compare);
gtk_rc_parse_any ("-", -1, rc_string);
}
+static void
+gtk_rc_parse_file (const gchar *filename, gboolean reload)
+{
+ GtkRcFile *rc_file = NULL;
+ struct stat statbuf;
+ GSList *tmp_list;
+
+ g_return_if_fail (filename != NULL);
+
+ tmp_list = rc_files;
+ while (tmp_list)
+ {
+ rc_file = tmp_list->data;
+ if (!strcmp (rc_file->name, filename))
+ break;
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (!tmp_list)
+ {
+ rc_file = g_new (GtkRcFile, 1);
+ rc_file->name = g_strdup (filename);
+ rc_file->canonical_name = NULL;
+ rc_file->mtime = 0;
+ rc_file->reload = reload;
+
+ rc_files = g_slist_append (rc_files, rc_file);
+ }
+
+ if (!rc_file->canonical_name)
+ {
+ /* Get the absolute pathname */
+
+ if (rc_file->name[0] == '/')
+ rc_file->canonical_name = rc_file->name;
+ else
+ {
+ GString *str;
+ gchar buffer[MAXPATHLEN];
+
+#if defined(sun) && !defined(__SVR4)
+ if(!getwd(buffer))
+#else
+ if(!getcwd(buffer, MAXPATHLEN))
+#endif
+ return;
+
+ str = g_string_new (buffer);
+ g_string_append_c (str, '/');
+ g_string_append (str, rc_file->name);
+
+ rc_file->canonical_name = str->str;
+ g_string_free (str, FALSE);
+ }
+ }
+
+ if (!lstat (rc_file->canonical_name, &statbuf))
+ {
+ gint fd;
+
+ rc_file->mtime = statbuf.st_mtime;
+
+ fd = open (rc_file->canonical_name, O_RDONLY);
+ if (fd < 0)
+ return;
+
+ gtk_rc_parse_any (filename, fd, NULL);
+
+ close (fd);
+ }
+}
+
void
gtk_rc_parse (const gchar *filename)
{
- gint fd;
-
g_return_if_fail (filename != NULL);
- fd = open (filename, O_RDONLY);
- if (fd < 0)
- return;
+ gtk_rc_parse_file (filename, TRUE);
+}
+
+static void
+gtk_rc_clear_hash_node (gpointer key,
+ gpointer data,
+ gpointer user_data)
+{
+ int i;
+ GtkRcStyle *rc_style = data;
+ GList *tmp_list;
+
+ g_free (rc_style->name);
+ g_free (rc_style->font_name);
+ g_free (rc_style->fontset_name);
+
+ for (i=0 ; i<5 ; i++)
+ g_free (rc_style->bg_pixmap_name[i]);
+
+ gtk_style_unref (rc_style->proto_style);
+
+ tmp_list = rc_style->styles;
+ while (tmp_list)
+ {
+ GtkRcNode *node = tmp_list->data;
+
+ gdk_colormap_unref (node->cmap);
+ gtk_style_unref (node->style);
+
+ g_free (node);
+ tmp_list = tmp_list->next;
+ }
+
+ g_free (rc_style);
+}
+
+static void
+gtk_rc_free_rc_sets (GSList *slist)
+{
+ while (slist)
+ {
+ GtkRcSet *rc_set;
+
+ rc_set = slist->data;
+ gtk_pattern_spec_free_segs (&rc_set->pspec);
+ g_free (rc_set);
+
+ slist = slist->next;
+ }
+}
- gtk_rc_parse_any (filename, fd, NULL);
+static void
+gtk_rc_clear_styles (void)
+{
+ /* Clear out all old rc_styles */
- close (fd);
+ g_hash_table_foreach (rc_style_ht, gtk_rc_clear_hash_node, NULL);
+ g_hash_table_destroy (rc_style_ht);
+ rc_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_widget_class);
+ g_slist_free (gtk_rc_sets_widget_class);
+ gtk_rc_sets_widget_class = 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
+gtk_rc_reparse_all (void)
+{
+ GSList *tmp_list;
+ gboolean mtime_modified = FALSE;
+ GtkRcFile *rc_file;
+
+ struct stat statbuf;
+
+ /* Check through and see if any of the RC's have had their
+ * mtime modified. If so, reparse everything.
+ */
+ tmp_list = rc_files;
+ while (tmp_list)
+ {
+ rc_file = tmp_list->data;
+
+ if (!lstat (rc_file->name, &statbuf) &&
+ (statbuf.st_mtime > rc_file->mtime))
+ {
+ mtime_modified = TRUE;
+ break;
+ }
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (mtime_modified)
+ {
+ gtk_rc_clear_styles();
+
+ tmp_list = rc_files;
+ while (tmp_list)
+ {
+ rc_file = tmp_list->data;
+ if (rc_file->reload)
+ gtk_rc_parse_file (rc_file->name, FALSE);
+
+ tmp_list = tmp_list->next;
+ }
+ }
+
+ return mtime_modified;
+}
+
+static GtkRcStyle*
+gtk_rc_styles_match (GSList *sets,
+ guint path_length,
+ gchar *path,
+ gchar *path_reversed)
+{
+ GtkRcSet *rc_set;
+
+ while (sets)
+ {
+ rc_set = sets->data;
+ sets = sets->next;
+
+ if (gtk_pattern_match (&rc_set->pspec, path_length, path, path_reversed))
+ return rc_set->rc_style;
+ }
+
+ return NULL;
}
GtkStyle*
gtk_rc_get_style (GtkWidget *widget)
{
GtkRcStyle *rc_style;
- char *path;
- if (widget_sets)
+ if (gtk_rc_sets_widget)
{
- path = gtk_rc_widget_path (widget);
- if (path)
- {
- rc_style = gtk_rc_styles_match (widget_sets, path);
- g_free (path);
-
- if (rc_style)
- {
- gtk_rc_style_init (rc_style);
- return rc_style->style;
- }
- }
+ gchar *path, *path_reversed;
+ guint path_length;
+
+ gtk_widget_path (widget, &path_length, &path, &path_reversed);
+ rc_style = gtk_rc_styles_match (gtk_rc_sets_widget, path_length, path, path_reversed);
+ g_free (path);
+ g_free (path_reversed);
+
+ if (rc_style)
+ return gtk_rc_style_init (rc_style, gtk_widget_get_colormap (widget));
}
- if (widget_class_sets)
+ if (gtk_rc_sets_widget_class)
+ {
+ gchar *path, *path_reversed;
+ guint path_length;
+
+ gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
+ rc_style = gtk_rc_styles_match (gtk_rc_sets_widget_class, path_length, path, path_reversed);
+ g_free (path);
+ g_free (path_reversed);
+
+ if (rc_style)
+ return gtk_rc_style_init (rc_style, gtk_widget_get_colormap (widget));
+ }
+
+ if (gtk_rc_sets_class)
{
- path = gtk_rc_widget_class_path (widget);
- if (path)
+ GtkType type;
+
+ type = GTK_OBJECT_TYPE (widget);
+ while (type)
{
- rc_style = gtk_rc_styles_match (widget_class_sets, path);
- g_free (path);
+ gchar *path, *path_reversed;
+ guint path_length;
+
+ path = gtk_type_name (type);
+ path_length = strlen (path);
+ path_reversed = g_strdup (path);
+ g_strreverse (path_reversed);
+ rc_style = gtk_rc_styles_match (gtk_rc_sets_class, path_length, path, path_reversed);
+ g_free (path_reversed);
+
if (rc_style)
- {
- gtk_rc_style_init (rc_style);
- return rc_style->style;
- }
+ return gtk_rc_style_init (rc_style, gtk_widget_get_colormap (widget));
+
+ type = gtk_type_parent (type);
}
}
- return widget->style;
+ return NULL;
}
-void
-gtk_rc_add_widget_name_style (GtkStyle *style,
- const char *pattern)
+static GSList*
+gtk_rc_add_rc_sets (GSList *slist,
+ GtkStyle *style,
+ const char *pattern)
{
GtkRcStyle *rc_style;
GtkRcSet *rc_set;
- int i;
+ guint i;
gtk_style_ref (style);
rc_style = g_new (GtkRcStyle, 1);
- rc_style->initialize = FALSE;
rc_style->name = NULL;
rc_style->font_name = NULL;
rc_style->fontset_name = NULL;
for (i = 0; i < 5; i++)
rc_style->bg_pixmap_name[i] = NULL;
- rc_style->style = style;
-
+ rc_style->styles = g_list_append (NULL, style);
+
rc_set = g_new (GtkRcSet, 1);
- rc_set->set = g_strdup (pattern);
+ gtk_pattern_spec_init (&rc_set->pspec, pattern);
rc_set->rc_style = rc_style;
- widget_sets = g_slist_append (widget_sets, rc_set);
+ return g_slist_prepend (slist, rc_set);
}
void
-gtk_rc_add_widget_class_style (GtkStyle *style,
- const char *pattern)
+gtk_rc_add_widget_name_style (GtkStyle *style,
+ const gchar *pattern)
{
- GtkRcStyle *rc_style;
- GtkRcSet *rc_set;
- int i;
-
- gtk_style_ref (style);
-
- rc_style = g_new (GtkRcStyle, 1);
- rc_style->initialize = FALSE;
- rc_style->name = NULL;
- rc_style->font_name = NULL;
- rc_style->fontset_name = NULL;
-
- for (i = 0; i < 5; i++)
- rc_style->bg_pixmap_name[i] = NULL;
-
- rc_style->style = style;
-
- rc_set = g_new (GtkRcSet, 1);
- rc_set->set = g_strdup (pattern);
- rc_set->rc_style = rc_style;
-
- widget_class_sets = g_slist_append (widget_class_sets, rc_set);
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (pattern != NULL);
+
+ gtk_rc_sets_widget = gtk_rc_add_rc_sets (gtk_rc_sets_widget, style, pattern);
+}
+
+void
+gtk_rc_add_widget_class_style (GtkStyle *style,
+ const gchar *pattern)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (pattern != NULL);
+
+ gtk_rc_sets_widget_class = gtk_rc_add_rc_sets (gtk_rc_sets_widget_class, style, pattern);
+}
+
+void
+gtk_rc_add_class_style (GtkStyle *style,
+ const gchar *pattern)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (pattern != NULL);
+
+ gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, style, pattern);
}
static void
{
GScanner *scanner;
guint i;
+ gboolean done;
scanner = g_scanner_new (>k_rc_scanner_config);
g_scanner_input_text (scanner, input_string, strlen (input_string));
}
-
- for (i = 0; i < nsymbols; i++)
- g_scanner_add_symbol (scanner, symbols[i].name, (gpointer) symbols[i].token);
+ scanner->input_name = input_name;
+
+ g_scanner_freeze_symbol_table (scanner);
+ for (i = 0; i < n_symbols; i++)
+ g_scanner_add_symbol (scanner, symbols[i].name, GINT_TO_POINTER (symbols[i].token));
+ g_scanner_thaw_symbol_table (scanner);
done = FALSE;
while (!done)
{
- if (gtk_rc_parse_statement (scanner) != PARSE_OK)
+ if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
+ done = TRUE;
+ else
{
- if (scanner->next_token != G_TOKEN_NONE)
- g_scanner_get_next_token (scanner);
-
- if (input_string)
- g_warning ("rc string parse error: line %d",
- scanner->line);
- else
- g_warning ("rc file parse error: \"%s\" line %d",
- input_name,
- scanner->line);
+ guint expected_token;
- done = TRUE;
+ expected_token = gtk_rc_parse_statement (scanner);
+
+ if (expected_token != G_TOKEN_NONE)
+ {
+ gchar *symbol_name;
+ gchar *msg;
+
+ msg = NULL;
+ symbol_name = NULL;
+ if (scanner->scope_id == 0)
+ {
+ /* if we are in scope 0, we know the symbol names
+ * that are associated with certaintoken values.
+ * so we look them up to make the error messages
+ * more readable.
+ */
+ if (expected_token > GTK_RC_TOKEN_INVALID &&
+ expected_token < GTK_RC_TOKEN_LAST)
+ {
+ for (i = 0; i < n_symbols; i++)
+ if (symbols[i].token == expected_token)
+ msg = symbols[i].name;
+ if (msg)
+ msg = g_strconcat ("e.g. `", msg, "'", NULL);
+ }
+ if (scanner->token > GTK_RC_TOKEN_INVALID &&
+ scanner->token < GTK_RC_TOKEN_LAST)
+ {
+ symbol_name = "???";
+ for (i = 0; i < n_symbols; i++)
+ if (symbols[i].token == scanner->token)
+ symbol_name = symbols[i].name;
+ }
+ }
+ g_scanner_unexp_token (scanner,
+ expected_token,
+ NULL,
+ "keyword",
+ symbol_name,
+ msg,
+ TRUE);
+ g_free (msg);
+ done = TRUE;
+ }
}
}
+
g_scanner_destroy (scanner);
}
return rc_style;
}
-static GtkRcStyle*
-gtk_rc_styles_match (GSList *sets,
- const char *path)
+static GtkStyle *
+gtk_rc_style_init (GtkRcStyle *rc_style, GdkColormap *cmap)
{
- GtkRcSet *rc_set;
-
- while (sets)
- {
- rc_set = sets->data;
- sets = sets->next;
-
- if (gtk_rc_style_match (rc_set->set, path))
- return rc_set->rc_style;
- }
-
- return NULL;
-}
+ GdkFont *old_font;
+ gboolean match_cmap = FALSE;
+ gint i;
-static gint
-gtk_rc_style_match (const char *set,
- const char *path)
-{
- char ch;
-
- while (1)
- {
- ch = *set++;
- if (ch == '\0')
- return (*path == '\0');
+ GList *tmp_list;
+ GtkStyle *style = NULL;
+ GtkRcNode *node;
+
+ tmp_list = rc_style->styles;
+
+ for (i=0; i<5; i++)
+ if (rc_style->bg_pixmap_name[i])
+ match_cmap = TRUE;
- switch (ch)
+ while (tmp_list)
+ {
+ node = (GtkRcNode *)tmp_list->data;
+
+ if (!match_cmap || (node->cmap == cmap))
{
- case '*':
- while (*set == '*')
- set++;
-
- ch = *set++;
- if (ch == '\0')
- return TRUE;
-
- while (*path)
- {
- while (*path && (ch != *path))
- path++;
-
- if (!(*path))
- return FALSE;
-
- path++;
- if (gtk_rc_style_match (set, path))
- return TRUE;
- }
- break;
-
- case '?':
- break;
-
- default:
- if (ch == *path)
- path++;
- else
- return FALSE;
+ style = node->style;
break;
}
- }
-
- return TRUE;
-}
-static void
-gtk_rc_style_init (GtkRcStyle *rc_style)
-{
- GdkFont *old_font;
- gint i;
+ tmp_list = tmp_list->next;
+ }
- if (rc_style->initialize)
+ if (!style)
{
- rc_style->initialize = FALSE;
+ node = g_new (GtkRcNode, 1);
+ style = gtk_style_copy (rc_style->proto_style);
+
+ /* FIXME, this leaks colormaps, but if we don't do this, then we'll
+ * be screwed, because we identify colormaps by address equality
+ */
+ gdk_colormap_ref (cmap);
+
+ node->style = style;
+ node->cmap = cmap;
if (rc_style->fontset_name)
{
- old_font = rc_style->style->font;
- rc_style->style->font = gdk_fontset_load (rc_style->fontset_name);
- if (rc_style->style->font)
+ old_font = style->font;
+ style->font = gdk_fontset_load (rc_style->fontset_name);
+ if (style->font)
gdk_font_unref (old_font);
else
- rc_style->style->font = old_font;
+ style->font = old_font;
}
else if (rc_style->font_name)
{
- old_font = rc_style->style->font;
- rc_style->style->font = gdk_font_load (rc_style->font_name);
- if (rc_style->style->font)
+ old_font = style->font;
+ style->font = gdk_font_load (rc_style->font_name);
+ if (style->font)
gdk_font_unref (old_font);
else
- rc_style->style->font = old_font;
+ style->font = old_font;
}
for (i = 0; i < 5; i++)
if (rc_style->bg_pixmap_name[i])
{
if (strcmp (rc_style->bg_pixmap_name[i], "<parent>") == 0)
- rc_style->style->bg_pixmap[i] = (GdkPixmap*) GDK_PARENT_RELATIVE;
+ style->bg_pixmap[i] = (GdkPixmap*) GDK_PARENT_RELATIVE;
else
- rc_style->style->bg_pixmap[i] = gdk_pixmap_create_from_xpm (NULL, NULL,
- &rc_style->style->bg[i],
- rc_style->bg_pixmap_name[i]);
+ {
+ if(image_loader)
+ style->bg_pixmap[i] = image_loader(NULL, cmap, NULL,
+ &style->bg[i],
+ rc_style->bg_pixmap_name[i]);
+ else
+ style->bg_pixmap[i] =
+ gdk_pixmap_colormap_create_from_xpm (NULL, cmap,
+ NULL,
+ &style->bg[i],
+ rc_style->bg_pixmap_name[i]);
+ }
}
+
+ rc_style->styles = g_list_append (rc_style->styles, node);
}
+
+ return style;
}
-static gint
+static guint
gtk_rc_parse_statement (GScanner *scanner)
{
- gint token;
- gint error;
+ guint token;
token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF)
+
+ switch (token)
{
- done = TRUE;
- return PARSE_OK;
+ case GTK_RC_TOKEN_INCLUDE:
+ token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_INCLUDE)
+ return GTK_RC_TOKEN_INCLUDE;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_STRING)
+ return G_TOKEN_STRING;
+
+ gtk_rc_parse_file (scanner->value.v_string, FALSE);
+ return G_TOKEN_NONE;
+
+ case GTK_RC_TOKEN_STYLE:
+ return gtk_rc_parse_style (scanner);
+
+ case GTK_RC_TOKEN_BINDING:
+ return gtk_binding_parse_binding (scanner);
+
+ case GTK_RC_TOKEN_PIXMAP_PATH:
+ return gtk_rc_parse_pixmap_path (scanner);
+
+ case GTK_RC_TOKEN_WIDGET:
+ return gtk_rc_parse_path_pattern (scanner);
+
+ case GTK_RC_TOKEN_WIDGET_CLASS:
+ return gtk_rc_parse_path_pattern (scanner);
+
+ case GTK_RC_TOKEN_CLASS:
+ return gtk_rc_parse_path_pattern (scanner);
+
+ default:
+ g_scanner_get_next_token (scanner);
+ return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
}
-
- error = gtk_rc_parse_style (scanner);
- if (error != PARSE_SYNTAX)
- return error;
-
- error = gtk_rc_parse_pixmap_path (scanner);
- if (error != PARSE_SYNTAX)
- return error;
-
- error = gtk_rc_parse_widget_style (scanner);
- if (error != PARSE_SYNTAX)
- return error;
-
- error = gtk_rc_parse_widget_class_style (scanner);
-
- return error;
}
-static gint
+static guint
gtk_rc_parse_style (GScanner *scanner)
{
GtkRcStyle *rc_style;
GtkRcStyle *parent_style;
- gint token;
- gint error;
+ guint token;
gint insert;
gint i;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_STYLE)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_STYLE)
+ return GTK_RC_TOKEN_STYLE;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
insert = FALSE;
rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
{
insert = TRUE;
rc_style = g_new (GtkRcStyle, 1);
- rc_style->initialize = TRUE;
rc_style->name = g_strdup (scanner->value.v_string);
rc_style->font_name = NULL;
rc_style->fontset_name = NULL;
for (i = 0; i < 5; i++)
rc_style->bg_pixmap_name[i] = NULL;
-
- rc_style->style = gtk_style_new ();
- gtk_style_ref (rc_style->style);
+
+ rc_style->proto_style = gtk_style_new();
+ rc_style->styles = NULL;
}
token = g_scanner_peek_next_token (scanner);
{
if (insert)
{
- gtk_style_unref (rc_style->style);
+ gtk_style_unref (rc_style->proto_style);
g_free (rc_style);
}
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
}
parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
{
for (i = 0; i < 5; i++)
{
- rc_style->style->fg[i] = parent_style->style->fg[i];
- rc_style->style->bg[i] = parent_style->style->bg[i];
- rc_style->style->light[i] = parent_style->style->light[i];
- rc_style->style->dark[i] = parent_style->style->dark[i];
- rc_style->style->mid[i] = parent_style->style->mid[i];
- rc_style->style->text[i] = parent_style->style->text[i];
- rc_style->style->base[i] = parent_style->style->base[i];
+ rc_style->proto_style->fg[i] = parent_style->proto_style->fg[i];
+ rc_style->proto_style->bg[i] = parent_style->proto_style->bg[i];
+ rc_style->proto_style->light[i] = parent_style->proto_style->light[i];
+ rc_style->proto_style->dark[i] = parent_style->proto_style->dark[i];
+ rc_style->proto_style->mid[i] = parent_style->proto_style->mid[i];
+ rc_style->proto_style->text[i] = parent_style->proto_style->text[i];
+ rc_style->proto_style->base[i] = parent_style->proto_style->base[i];
}
- rc_style->style->black = parent_style->style->black;
- rc_style->style->white = parent_style->style->white;
+ rc_style->proto_style->black = parent_style->proto_style->black;
+ rc_style->proto_style->white = parent_style->proto_style->white;
if (rc_style->fontset_name)
{
{
if (insert)
{
- gtk_style_unref (rc_style->style);
+ gtk_style_unref (rc_style->proto_style);
g_free (rc_style);
}
- return PARSE_ERROR;
+ return G_TOKEN_LEFT_CURLY;
}
- while (1)
+ token = g_scanner_peek_next_token (scanner);
+ while (token != G_TOKEN_RIGHT_CURLY)
{
- error = gtk_rc_parse_style_option (scanner, rc_style);
- if (error == PARSE_SYNTAX)
- break;
- if (error == PARSE_ERROR)
+ switch (token)
+ {
+ case GTK_RC_TOKEN_BASE:
+ token = gtk_rc_parse_base (scanner, rc_style->proto_style);
+ break;
+ case GTK_RC_TOKEN_BG:
+ token = gtk_rc_parse_bg (scanner, rc_style->proto_style);
+ break;
+ case GTK_RC_TOKEN_FG:
+ token = gtk_rc_parse_fg (scanner, rc_style->proto_style);
+ break;
+ case GTK_RC_TOKEN_TEXT:
+ token = gtk_rc_parse_text (scanner, rc_style->proto_style);
+ break;
+ case GTK_RC_TOKEN_BG_PIXMAP:
+ token = gtk_rc_parse_bg_pixmap (scanner, rc_style);
+ break;
+ case GTK_RC_TOKEN_FONT:
+ token = gtk_rc_parse_font (scanner, rc_style);
+ break;
+ case GTK_RC_TOKEN_FONTSET:
+ token = gtk_rc_parse_fontset (scanner, rc_style);
+ break;
+ default:
+ g_scanner_get_next_token (scanner);
+ token = G_TOKEN_RIGHT_CURLY;
+ break;
+ }
+
+ if (token != G_TOKEN_NONE)
{
if (insert)
{
- gtk_style_unref (rc_style->style);
+ if (rc_style->fontset_name)
+ g_free (rc_style->fontset_name);
+ if (rc_style->font_name)
+ g_free (rc_style->font_name);
+ for (i = 0; i < 5; i++)
+ if (rc_style->bg_pixmap_name[i])
+ g_free (rc_style->bg_pixmap_name[i]);
+ gtk_style_unref (rc_style->proto_style);
g_free (rc_style);
}
- return error;
+ return token;
}
+ token = g_scanner_peek_next_token (scanner);
}
token = g_scanner_get_next_token (scanner);
{
if (rc_style->fontset_name)
g_free (rc_style->fontset_name);
- else if (rc_style->font_name)
+ if (rc_style->font_name)
g_free (rc_style->font_name);
for (i = 0; i < 5; i++)
if (rc_style->bg_pixmap_name[i])
g_free (rc_style->bg_pixmap_name[i]);
- gtk_style_unref (rc_style->style);
+ gtk_style_unref (rc_style->proto_style);
g_free (rc_style);
}
- return PARSE_ERROR;
+ return G_TOKEN_RIGHT_CURLY;
}
if (insert)
g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
- return PARSE_OK;
+ return G_TOKEN_NONE;
}
-static gint
-gtk_rc_parse_style_option (GScanner *scanner,
- GtkRcStyle *rc_style)
+static guint
+gtk_rc_parse_base (GScanner *scanner,
+ GtkStyle *style)
{
- gint token;
- gint error;
-
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
-
- error = gtk_rc_parse_base (scanner, rc_style->style);
- if (error != PARSE_SYNTAX)
- return error;
-
- error = gtk_rc_parse_bg (scanner, rc_style->style);
- if (error != PARSE_SYNTAX)
- return error;
-
- error = gtk_rc_parse_fg (scanner, rc_style->style);
- if (error != PARSE_SYNTAX)
- return error;
+ GtkStateType state;
+ guint token;
- error = gtk_rc_parse_bg_pixmap (scanner, rc_style);
- if (error != PARSE_SYNTAX)
- return error;
+ token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_BASE)
+ return GTK_RC_TOKEN_BASE;
- error = gtk_rc_parse_font (scanner, rc_style);
- if (error != PARSE_SYNTAX)
- return error;
+ token = gtk_rc_parse_state (scanner, &state);
+ if (token != G_TOKEN_NONE)
+ return token;
- error = gtk_rc_parse_fontset (scanner, rc_style);
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
- return error;
+ return gtk_rc_parse_color (scanner, &style->base[state]);
}
-static gint
-gtk_rc_parse_base (GScanner *scanner,
- GtkStyle *style)
+static guint
+gtk_rc_parse_bg (GScanner *scanner,
+ GtkStyle *style)
{
GtkStateType state;
- gint token;
- gint error;
+ guint token;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_BASE)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_BG)
+ return GTK_RC_TOKEN_BG;
- error = gtk_rc_parse_state (scanner, &state);
- if (error != PARSE_OK)
- return error;
+ token = gtk_rc_parse_state (scanner, &state);
+ if (token != G_TOKEN_NONE)
+ return token;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
- return PARSE_ERROR;
+ return G_TOKEN_EQUAL_SIGN;
- error = gtk_rc_parse_color (scanner, &style->base[state]);
-
- return error;
+ return gtk_rc_parse_color (scanner, &style->bg[state]);
}
-static gint
-gtk_rc_parse_bg (GScanner *scanner,
+static guint
+gtk_rc_parse_fg (GScanner *scanner,
GtkStyle *style)
{
GtkStateType state;
- gint token;
- gint error;
+ guint token;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_BG)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_FG)
+ return GTK_RC_TOKEN_FG;
- error = gtk_rc_parse_state (scanner, &state);
- if (error != PARSE_OK)
- return error;
+ token = gtk_rc_parse_state (scanner, &state);
+ if (token != G_TOKEN_NONE)
+ return token;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
- return PARSE_ERROR;
+ return G_TOKEN_EQUAL_SIGN;
- error = gtk_rc_parse_color (scanner, &style->bg[state]);
-
- return error;
+ return gtk_rc_parse_color (scanner, &style->fg[state]);
}
-static gint
-gtk_rc_parse_fg (GScanner *scanner,
- GtkStyle *style)
+static guint
+gtk_rc_parse_text (GScanner *scanner,
+ GtkStyle *style)
{
GtkStateType state;
- gint token;
- gint error;
+ guint token;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_FG)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_TEXT)
+ return GTK_RC_TOKEN_TEXT;
- error = gtk_rc_parse_state (scanner, &state);
- if (error != PARSE_OK)
- return error;
+ token = gtk_rc_parse_state (scanner, &state);
+ if (token != G_TOKEN_NONE)
+ return token;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
- return PARSE_ERROR;
-
- error = gtk_rc_parse_color (scanner, &style->fg[state]);
+ return G_TOKEN_EQUAL_SIGN;
- return error;
+ return gtk_rc_parse_color (scanner, &style->text[state]);
}
-static gint
+static guint
gtk_rc_parse_bg_pixmap (GScanner *scanner,
GtkRcStyle *rc_style)
{
GtkStateType state;
- gint token;
- gint error;
+ guint token;
gchar *pixmap_file;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_BG_PIXMAP)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_BG_PIXMAP)
+ return GTK_RC_TOKEN_BG_PIXMAP;
- error = gtk_rc_parse_state (scanner, &state);
- if (error != PARSE_OK)
- return error;
+ token = gtk_rc_parse_state (scanner, &state);
+ if (token != G_TOKEN_NONE)
+ return token;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
- return PARSE_ERROR;
+ return G_TOKEN_EQUAL_SIGN;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
if (strcmp (scanner->value.v_string, "<parent>"))
pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
rc_style->bg_pixmap_name[state] = pixmap_file;
}
- return PARSE_OK;
+ return G_TOKEN_NONE;
}
-static char*
+static gchar*
gtk_rc_find_pixmap_in_path (GScanner *scanner,
gchar *pixmap_file)
{
return NULL;
}
-static gint
+static guint
gtk_rc_parse_font (GScanner *scanner,
GtkRcStyle *rc_style)
{
- gint token;
+ guint token;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_FONT)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_FONT)
+ return GTK_RC_TOKEN_FONT;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
- return PARSE_ERROR;
+ return G_TOKEN_EQUAL_SIGN;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
if (rc_style->font_name)
g_free (rc_style->font_name);
rc_style->font_name = g_strdup (scanner->value.v_string);
- return PARSE_OK;
+ return G_TOKEN_NONE;
}
-static gint
+static guint
gtk_rc_parse_fontset (GScanner *scanner,
GtkRcStyle *rc_style)
{
- gint token;
+ guint token;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_FONTSET)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_FONTSET)
+ return GTK_RC_TOKEN_FONTSET;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
- return PARSE_ERROR;
+ return G_TOKEN_EQUAL_SIGN;
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
if (rc_style->fontset_name)
g_free (rc_style->fontset_name);
rc_style->fontset_name = g_strdup (scanner->value.v_string);
- return PARSE_OK;
+ return G_TOKEN_NONE;
}
-static gint
+guint
gtk_rc_parse_state (GScanner *scanner,
GtkStateType *state)
{
- gint token;
+ guint old_scope;
+ guint token;
+
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
+ g_return_val_if_fail (state != NULL, G_TOKEN_ERROR);
+
+ /* we don't know where we got called from, so we reset the scope here.
+ * if we bail out due to errors, we *don't* reset the scope, so the
+ * error messaging code can make sense of our tokens.
+ */
+ old_scope = g_scanner_set_scope (scanner, 0);
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != G_TOKEN_LEFT_BRACE)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_BRACE)
+ return G_TOKEN_LEFT_BRACE;
token = g_scanner_get_next_token (scanner);
- if (token == TOKEN_ACTIVE)
- *state = GTK_STATE_ACTIVE;
- else if (token == TOKEN_INSENSITIVE)
- *state = GTK_STATE_INSENSITIVE;
- else if (token == TOKEN_NORMAL)
- *state = GTK_STATE_NORMAL;
- else if (token == TOKEN_PRELIGHT)
- *state = GTK_STATE_PRELIGHT;
- else if (token == TOKEN_SELECTED)
- *state = GTK_STATE_SELECTED;
- else
- return PARSE_ERROR;
+ switch (token)
+ {
+ case GTK_RC_TOKEN_ACTIVE:
+ *state = GTK_STATE_ACTIVE;
+ break;
+ case GTK_RC_TOKEN_INSENSITIVE:
+ *state = GTK_STATE_INSENSITIVE;
+ break;
+ case GTK_RC_TOKEN_NORMAL:
+ *state = GTK_STATE_NORMAL;
+ break;
+ case GTK_RC_TOKEN_PRELIGHT:
+ *state = GTK_STATE_PRELIGHT;
+ break;
+ case GTK_RC_TOKEN_SELECTED:
+ *state = GTK_STATE_SELECTED;
+ break;
+ default:
+ return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_NORMAL;
+ }
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_RIGHT_BRACE)
- return PARSE_ERROR;
+ return G_TOKEN_RIGHT_BRACE;
- return PARSE_OK;
+ g_scanner_set_scope (scanner, old_scope);
+
+ return G_TOKEN_NONE;
}
-static gint
+guint
+gtk_rc_parse_priority (GScanner *scanner,
+ GtkPathPriorityType *priority)
+{
+ guint old_scope;
+ guint token;
+
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
+ g_return_val_if_fail (priority != NULL, G_TOKEN_ERROR);
+
+ /* we don't know where we got called from, so we reset the scope here.
+ * if we bail out due to errors, we *don't* reset the scope, so the
+ * error messaging code can make sense of our tokens.
+ */
+ old_scope = g_scanner_set_scope (scanner, 0);
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != ':')
+ return ':';
+
+ token = g_scanner_get_next_token (scanner);
+ switch (token)
+ {
+ case GTK_RC_TOKEN_LOWEST:
+ *priority = GTK_PATH_PRIO_LOWEST;
+ break;
+ case GTK_RC_TOKEN_GTK:
+ *priority = GTK_PATH_PRIO_GTK;
+ break;
+ case GTK_RC_TOKEN_APPLICATION:
+ *priority = GTK_PATH_PRIO_APPLICATION;
+ break;
+ case GTK_RC_TOKEN_RC:
+ *priority = GTK_PATH_PRIO_RC;
+ break;
+ case GTK_RC_TOKEN_HIGHEST:
+ *priority = GTK_PATH_PRIO_HIGHEST;
+ break;
+ default:
+ return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_APPLICATION;
+ }
+
+ g_scanner_set_scope (scanner, old_scope);
+
+ return G_TOKEN_NONE;
+}
+
+guint
gtk_rc_parse_color (GScanner *scanner,
GdkColor *color)
{
- gint token;
- gint token_int;
- gint length;
- gint temp;
- gchar buf[9];
- gint i, j;
-
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
+ guint token;
+
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
+
+ /* we don't need to set our own scop here, because
+ * we don't need own symbols
+ */
+ token = g_scanner_get_next_token (scanner);
switch (token)
{
- case G_TOKEN_LEFT_CURLY:
- token = g_scanner_get_next_token (scanner);
+ gint token_int;
+ gint length;
+ gint temp;
+ gchar buf[9];
+ gint i, j;
+ case G_TOKEN_LEFT_CURLY:
token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_INT)
token_int = scanner->value.v_int;
else if (token == G_TOKEN_FLOAT)
token_int = scanner->value.v_float * 65535.0;
else
- return PARSE_ERROR;
+ return G_TOKEN_FLOAT;
color->red = CLAMP (token_int, 0, 65535);
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_COMMA)
- return PARSE_ERROR;
+ return G_TOKEN_COMMA;
token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_INT)
else if (token == G_TOKEN_FLOAT)
token_int = scanner->value.v_float * 65535.0;
else
- return PARSE_ERROR;
+ return G_TOKEN_FLOAT;
color->green = CLAMP (token_int, 0, 65535);
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_COMMA)
- return PARSE_ERROR;
+ return G_TOKEN_COMMA;
token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_INT)
else if (token == G_TOKEN_FLOAT)
token_int = scanner->value.v_float * 65535.0;
else
- return PARSE_ERROR;
+ return G_TOKEN_FLOAT;
color->blue = CLAMP (token_int, 0, 65535);
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_RIGHT_CURLY)
- return PARSE_ERROR;
- break;
+ return G_TOKEN_RIGHT_CURLY;
+ return G_TOKEN_NONE;
case G_TOKEN_STRING:
- token = g_scanner_get_next_token (scanner);
-
if (scanner->value.v_string[0] != '#')
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
length = strlen (scanner->value.v_string) - 1;
if (((length % 3) != 0) || (length > 12))
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
length /= 3;
for (i = 0, j = 1; i < length; i++, j++)
color->green *= 16;
color->blue *= 16;
}
- break;
-
- case G_TOKEN_ERROR:
- return PARSE_ERROR;
+ return G_TOKEN_NONE;
default:
- return PARSE_SYNTAX;
+ return G_TOKEN_STRING;
}
-
- return PARSE_OK;
}
-static gint
+static guint
gtk_rc_parse_pixmap_path (GScanner *scanner)
{
- gint token;
+ guint token;
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_PIXMAP_PATH)
- return PARSE_SYNTAX;
token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_PIXMAP_PATH)
+ return GTK_RC_TOKEN_PIXMAP_PATH;
token = g_scanner_get_next_token (scanner);
-
if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
+ return G_TOKEN_STRING;
gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
- return PARSE_OK;
+ return G_TOKEN_NONE;
}
static void
g_free (buf);
}
-static gint
-gtk_rc_parse_widget_style (GScanner *scanner)
+static guint
+gtk_rc_parse_path_pattern (GScanner *scanner)
{
- GtkRcSet *rc_set;
- gint token;
-
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_WIDGET)
- return PARSE_SYNTAX;
- token = g_scanner_get_next_token (scanner);
+ guint token;
+ GtkPathType path_type;
+ gchar *pattern;
+ gboolean is_binding;
+ GtkPathPriorityType priority = GTK_PATH_PRIO_RC;
token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
-
- rc_set = g_new (GtkRcSet, 1);
- rc_set->set = g_strdup (scanner->value.v_string);
-
- token = g_scanner_get_next_token (scanner);
- if (token != TOKEN_STYLE)
+ switch (token)
{
- g_free (rc_set->set);
- g_free (rc_set);
- return PARSE_ERROR;
+ case GTK_RC_TOKEN_WIDGET:
+ path_type = GTK_PATH_WIDGET;
+ break;
+ case GTK_RC_TOKEN_WIDGET_CLASS:
+ path_type = GTK_PATH_WIDGET_CLASS;
+ break;
+ case GTK_RC_TOKEN_CLASS:
+ path_type = GTK_PATH_CLASS;
+ break;
+ default:
+ return GTK_RC_TOKEN_WIDGET_CLASS;
}
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
- {
- g_free (rc_set->set);
- g_free (rc_set);
- return PARSE_ERROR;
- }
-
- rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string);
- if (!rc_set->rc_style)
- {
- g_free (rc_set->set);
- g_free (rc_set);
- return PARSE_ERROR;
- }
-
- widget_sets = g_slist_append (widget_sets, rc_set);
-
- return PARSE_OK;
-}
+ return G_TOKEN_STRING;
+
+ pattern = g_strdup (scanner->value.v_string);
-static gint
-gtk_rc_parse_widget_class_style (GScanner *scanner)
-{
- GtkRcSet *rc_set;
- gint token;
-
- token = g_scanner_peek_next_token (scanner);
- if (token == G_TOKEN_EOF || token == G_TOKEN_ERROR)
- return PARSE_ERROR;
- if (token != TOKEN_WIDGET_CLASS)
- return PARSE_SYNTAX;
- token = g_scanner_get_next_token (scanner);
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
- return PARSE_ERROR;
-
- rc_set = g_new (GtkRcSet, 1);
- rc_set->set = g_strdup (scanner->value.v_string);
-
token = g_scanner_get_next_token (scanner);
- if (token != TOKEN_STYLE)
+ if (token == GTK_RC_TOKEN_STYLE)
+ is_binding = FALSE;
+ else if (token == GTK_RC_TOKEN_BINDING)
{
- g_free (rc_set->set);
- g_free (rc_set);
- return PARSE_ERROR;
+ is_binding = TRUE;
+ if (g_scanner_peek_next_token (scanner) == ':')
+ {
+ token = gtk_rc_parse_priority (scanner, &priority);
+ if (token != G_TOKEN_NONE)
+ {
+ g_free (pattern);
+ return token;
+ }
+ }
}
-
- token = g_scanner_get_next_token (scanner);
- if (token != G_TOKEN_STRING)
+ else
{
- g_free (rc_set->set);
- g_free (rc_set);
- return PARSE_ERROR;
+ g_free (pattern);
+ return GTK_RC_TOKEN_STYLE;
}
- rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string);
- if (!rc_set->rc_style)
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_STRING)
{
- g_free (rc_set->set);
- g_free (rc_set);
- return PARSE_ERROR;
+ g_free (pattern);
+ return G_TOKEN_STRING;
}
-
- widget_class_sets = g_slist_append (widget_class_sets, rc_set);
-
- return PARSE_OK;
-}
-static char*
-gtk_rc_widget_path (GtkWidget *widget)
-{
- GtkWidget *tmp_widget;
- char *path;
- char *name;
- int pathlength;
- int namelength;
-
- path = NULL;
- pathlength = 0;
-
- tmp_widget = widget;
- while (tmp_widget)
+ if (is_binding)
{
- name = gtk_widget_get_name (tmp_widget);
- pathlength += strlen (name);
-
- tmp_widget = tmp_widget->parent;
-
- if (tmp_widget)
- pathlength += 1;
+ GtkBindingSet *binding;
+
+ binding = gtk_binding_set_find (scanner->value.v_string);
+ if (!binding)
+ {
+ g_free (pattern);
+ return G_TOKEN_STRING;
+ }
+ gtk_binding_set_add_path (binding, path_type, pattern, priority);
}
-
- path = g_new (char, pathlength + 1);
- path[pathlength] = '\0';
-
- tmp_widget = widget;
- while (tmp_widget)
+ else
{
- name = gtk_widget_get_name (tmp_widget);
- namelength = strlen (name);
-
- strncpy (&path[pathlength - namelength], name, namelength);
- pathlength -= namelength;
-
- tmp_widget = tmp_widget->parent;
+ GtkRcStyle *rc_style;
+ GtkRcSet *rc_set;
+
+ rc_style = gtk_rc_style_find (scanner->value.v_string);
- if (tmp_widget)
+ if (!rc_style)
{
- pathlength -= 1;
- path[pathlength] = '.';
+ g_free (pattern);
+ return G_TOKEN_STRING;
}
+
+ rc_set = g_new (GtkRcSet, 1);
+ gtk_pattern_spec_init (&rc_set->pspec, pattern);
+ rc_set->rc_style = rc_style;
+
+ if (path_type == GTK_PATH_WIDGET)
+ gtk_rc_sets_widget = g_slist_prepend (gtk_rc_sets_widget, rc_set);
+ else if (path_type == GTK_PATH_WIDGET_CLASS)
+ gtk_rc_sets_widget_class = g_slist_prepend (gtk_rc_sets_widget_class, rc_set);
+ else
+ gtk_rc_sets_class = g_slist_prepend (gtk_rc_sets_class, rc_set);
}
-
- return path;
+
+ g_free (pattern);
+ return G_TOKEN_NONE;
}
-static char*
-gtk_rc_widget_class_path (GtkWidget *widget)
+/*
+typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
+ GdkColormap *colormap,
+ GdkBitmap **mask,
+ GdkColor *transparent_color,
+ const gchar *filename);
+*/
+
+void
+gtk_rc_set_image_loader(GtkImageLoader loader)
{
- GtkWidget *tmp_widget;
- char *path;
- char *name;
- int pathlength;
- int namelength;
-
- path = NULL;
- pathlength = 0;
-
- tmp_widget = widget;
- while (tmp_widget)
- {
- name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
- pathlength += strlen (name);
-
- tmp_widget = tmp_widget->parent;
-
- if (tmp_widget)
- pathlength += 1;
- }
-
- path = g_new (char, pathlength + 1);
- path[pathlength] = '\0';
-
- tmp_widget = widget;
- while (tmp_widget)
- {
- name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
- namelength = strlen (name);
-
- strncpy (&path[pathlength - namelength], name, namelength);
- pathlength -= namelength;
-
- tmp_widget = tmp_widget->parent;
-
- if (tmp_widget)
- {
- pathlength -= 1;
- path[pathlength] = '.';
- }
- }
-
- return path;
+ image_loader = loader;
}
+