 2b2667e791
			
		
	
	2b2667e791
	
	
	
		
			
			* gtk/gtkrc.h (gtk_rc_parse_string): new function.
        * gtk/gtkrc.c: many functions adapted to use GScanner for scanning.
        (gtk_rc_parse): use gtk_rc_parse_any for parsing.
        (gtk_rc_parse_string): new function to support parsing from
        strings, just calls gtk_rc_parse_any.
        (gtk_rc_parse_any): new function using GScanner as lexer.
-timj
		
	
		
			
				
	
	
		
			1348 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1348 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GTK - The GIMP Toolkit
 | |
|  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Library General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 | |
|  * 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.
 | |
|  */
 | |
| #include <ctype.h>
 | |
| #include <unistd.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
 | |
| };
 | |
| 
 | |
| 
 | |
| typedef struct _GtkRcStyle  GtkRcStyle;
 | |
| typedef struct _GtkRcSet    GtkRcSet;
 | |
| 
 | |
| struct _GtkRcStyle
 | |
| {
 | |
|   int initialize;
 | |
|   char *name;
 | |
|   char *font_name;
 | |
|   char *fontset_name;
 | |
|   char *bg_pixmap_name[5];
 | |
|   GtkStyle *style;
 | |
| };
 | |
| 
 | |
| struct _GtkRcSet
 | |
| {
 | |
|   char *set;
 | |
|   GtkRcStyle *rc_style;
 | |
| };
 | |
| 
 | |
| 
 | |
| 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);
 | |
| 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,
 | |
| 						    GtkStyle	 *style);
 | |
| static gint	   gtk_rc_parse_bg		   (GScanner	 *scanner,
 | |
| 						    GtkStyle	 *style);
 | |
| static gint	   gtk_rc_parse_fg		   (GScanner	 *scanner,
 | |
| 						    GtkStyle	 *style);
 | |
| static gint	   gtk_rc_parse_bg_pixmap	   (GScanner	 *scanner,
 | |
| 						    GtkRcStyle	 *rc_style);
 | |
| static gint	   gtk_rc_parse_font		   (GScanner	 *scanner,
 | |
| 						    GtkRcStyle	 *rc_style);
 | |
| static gint	   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 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	GScannerConfig	gtk_rc_scanner_config =
 | |
| {
 | |
|   (
 | |
|    " \t\n"
 | |
|    )			/* cset_skip_characters */,
 | |
|   (
 | |
|    G_CSET_a_2_z
 | |
|    "_"
 | |
|    G_CSET_A_2_Z
 | |
|    )			/* cset_identifier_first */,
 | |
|   (
 | |
|    G_CSET_a_2_z
 | |
|    "_0123456789"
 | |
|    G_CSET_A_2_Z
 | |
|    G_CSET_LATINS
 | |
|    G_CSET_LATINC
 | |
|    )			/* cset_identifier_nth */,
 | |
|   ( "#\n" )		/* cpair_comment_single */,
 | |
|   
 | |
|   TRUE			/* case_sensitive */,
 | |
|   
 | |
|   TRUE			/* skip_comment_multi */,
 | |
|   TRUE			/* skip_comment_single */,
 | |
|   TRUE			/* scan_comment_multi */,
 | |
|   TRUE			/* scan_identifier */,
 | |
|   FALSE			/* scan_identifier_1char */,
 | |
|   FALSE			/* scan_identifier_NULL */,
 | |
|   TRUE			/* scan_symbols */,
 | |
|   TRUE			/* scan_binary */,
 | |
|   TRUE			/* scan_octal */,
 | |
|   TRUE			/* scan_float */,
 | |
|   TRUE			/* scan_hex */,
 | |
|   TRUE			/* scan_hex_dollar */,
 | |
|   FALSE			/* scan_string_sq */,
 | |
|   TRUE			/* scan_string_dq */,
 | |
|   TRUE			/* numbers_2_int */,
 | |
|   FALSE			/* int_2_float */,
 | |
|   TRUE			/* identifier_2_string */,
 | |
|   TRUE			/* char_2_token */,
 | |
|   TRUE			/* symbol_2_token */,
 | |
| };
 | |
| 
 | |
| 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;
 | |
| 
 | |
| static GHashTable *rc_style_ht = NULL;
 | |
| static GSList *widget_sets = NULL;
 | |
| static GSList *widget_class_sets = NULL;
 | |
| 
 | |
| #define GTK_RC_MAX_PIXMAP_PATHS 128
 | |
| static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
 | |
| 
 | |
| 
 | |
| void
 | |
| gtk_rc_init ()
 | |
| {
 | |
|   rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
 | |
| 				  (GCompareFunc) gtk_rc_style_compare);
 | |
| }
 | |
| 
 | |
| void
 | |
| gtk_rc_parse_string (const gchar *rc_string)
 | |
| {
 | |
|   g_return_if_fail (rc_string != NULL);
 | |
| 
 | |
|   gtk_rc_parse_any ("-", -1, rc_string);
 | |
| }
 | |
| 
 | |
| 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_any (filename, fd, NULL);
 | |
| 
 | |
|   close (fd);
 | |
| }
 | |
| 
 | |
| GtkStyle*
 | |
| gtk_rc_get_style (GtkWidget *widget)
 | |
| {
 | |
|   GtkRcStyle *rc_style;
 | |
|   char *path;
 | |
|   
 | |
|   if (widget_sets)
 | |
|     {
 | |
|       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;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|   
 | |
|   if (widget_class_sets)
 | |
|     {
 | |
|       path = gtk_rc_widget_class_path (widget);
 | |
|       if (path)
 | |
| 	{
 | |
| 	  rc_style = gtk_rc_styles_match (widget_class_sets, path);
 | |
| 	  g_free (path);
 | |
| 	  
 | |
| 	  if (rc_style)
 | |
| 	    {
 | |
| 	      gtk_rc_style_init (rc_style);
 | |
| 	      return rc_style->style;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|   
 | |
|   return widget->style;
 | |
| }
 | |
| 
 | |
| void
 | |
| gtk_rc_add_widget_name_style (GtkStyle	 *style,
 | |
| 			      const char *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_sets = g_slist_append (widget_sets, rc_set);
 | |
| }
 | |
| 
 | |
| void
 | |
| gtk_rc_add_widget_class_style (GtkStyle *style,
 | |
| 			       const char     *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);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gtk_rc_parse_any (const gchar  *input_name,
 | |
| 		  gint		input_fd,
 | |
| 		  const gchar  *input_string)
 | |
| {
 | |
|   GScanner *scanner;
 | |
|   guint	   i;
 | |
|   
 | |
|   scanner = g_scanner_new (>k_rc_scanner_config);
 | |
|   
 | |
|   if (input_fd >= 0)
 | |
|     {
 | |
|       g_assert (input_string == NULL);
 | |
|       
 | |
|       g_scanner_input_file (scanner, input_fd);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       g_assert (input_string != NULL);
 | |
|       
 | |
|       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);
 | |
|   
 | |
|   done = FALSE;
 | |
|   while (!done)
 | |
|     {
 | |
|       if (gtk_rc_parse_statement (scanner) != PARSE_OK)
 | |
| 	{
 | |
| 	  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);
 | |
| 	  
 | |
| 	  done = TRUE;
 | |
| 	}
 | |
|     }
 | |
|   g_scanner_destroy (scanner);
 | |
| }
 | |
| 
 | |
| static guint
 | |
| gtk_rc_style_hash (const char *name)
 | |
| {
 | |
|   guint result;
 | |
|   
 | |
|   result = 0;
 | |
|   while (*name)
 | |
|     result += (result << 3) + *name++;
 | |
|   
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_style_compare (const char *a,
 | |
| 		      const char *b)
 | |
| {
 | |
|   return (strcmp (a, b) == 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;
 | |
| }
 | |
| 
 | |
| static GtkRcStyle*
 | |
| gtk_rc_styles_match (GSList	  *sets,
 | |
| 		     const char	  *path)
 | |
| {
 | |
|   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;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_style_match (const char *set,
 | |
| 		    const char *path)
 | |
| {
 | |
|   char ch;
 | |
|   
 | |
|   while (1)
 | |
|     {
 | |
|       ch = *set++;
 | |
|       if (ch == '\0')
 | |
| 	return (*path == '\0');
 | |
|       
 | |
|       switch (ch)
 | |
| 	{
 | |
| 	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;
 | |
| 	  break;
 | |
| 	}
 | |
|     }
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gtk_rc_style_init (GtkRcStyle *rc_style)
 | |
| {
 | |
|   GdkFont *old_font;
 | |
|   gint i;
 | |
|   
 | |
|   if (rc_style->initialize)
 | |
|     {
 | |
|       rc_style->initialize = FALSE;
 | |
|       
 | |
|       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)
 | |
| 	    gdk_font_unref (old_font);
 | |
| 	  else
 | |
| 	    rc_style->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)
 | |
| 	    gdk_font_unref (old_font);
 | |
| 	  else
 | |
| 	    rc_style->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;
 | |
| 	    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]);
 | |
| 	  }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_statement (GScanner *scanner)
 | |
| {
 | |
|   gint token;
 | |
|   gint error;
 | |
|   
 | |
|   token = g_scanner_peek_next_token (scanner);
 | |
|   if (token == G_TOKEN_EOF)
 | |
|     {
 | |
|       done = TRUE;
 | |
|       return PARSE_OK;
 | |
|     }
 | |
|   
 | |
|   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
 | |
| gtk_rc_parse_style (GScanner *scanner)
 | |
| {
 | |
|   GtkRcStyle *rc_style;
 | |
|   GtkRcStyle *parent_style;
 | |
|   gint token;
 | |
|   gint error;
 | |
|   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);
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_STRING)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   insert = FALSE;
 | |
|   rc_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
 | |
|   
 | |
|   if (!rc_style)
 | |
|     {
 | |
|       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);
 | |
|     }
 | |
|   
 | |
|   token = g_scanner_peek_next_token (scanner);
 | |
|   if (token == G_TOKEN_EQUAL_SIGN)
 | |
|     {
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       if (token != G_TOKEN_STRING)
 | |
| 	{
 | |
| 	  if (insert)
 | |
| 	    {
 | |
| 	      gtk_style_unref (rc_style->style);
 | |
| 	      g_free (rc_style);
 | |
| 	    }
 | |
| 	  return PARSE_ERROR;
 | |
| 	}
 | |
|       
 | |
|       parent_style = g_hash_table_lookup (rc_style_ht, scanner->value.v_string);
 | |
|       if (parent_style)
 | |
| 	{
 | |
| 	  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->style->black = parent_style->style->black;
 | |
| 	  rc_style->style->white = parent_style->style->white;
 | |
| 	  
 | |
| 	  if (rc_style->fontset_name)
 | |
| 	    {
 | |
| 	      g_free (rc_style->fontset_name);
 | |
| 	      rc_style->fontset_name = g_strdup (parent_style->fontset_name);
 | |
| 	    }
 | |
| 	  else if (rc_style->font_name)
 | |
| 	    {
 | |
| 	      g_free (rc_style->font_name);
 | |
| 	      rc_style->font_name = g_strdup (parent_style->font_name);
 | |
| 	    }
 | |
| 	  
 | |
| 	  for (i = 0; i < 5; i++)
 | |
| 	    {
 | |
| 	      if (rc_style->bg_pixmap_name[i])
 | |
| 		g_free (rc_style->bg_pixmap_name[i]);
 | |
| 	      rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_LEFT_CURLY)
 | |
|     {
 | |
|       if (insert)
 | |
| 	{
 | |
| 	  gtk_style_unref (rc_style->style);
 | |
| 	  g_free (rc_style);
 | |
| 	}
 | |
|       return PARSE_ERROR;
 | |
|     }
 | |
|   
 | |
|   while (1)
 | |
|     {
 | |
|       error = gtk_rc_parse_style_option (scanner, rc_style);
 | |
|       if (error == PARSE_SYNTAX)
 | |
| 	break;
 | |
|       if (error == PARSE_ERROR)
 | |
| 	{
 | |
| 	  if (insert)
 | |
| 	    {
 | |
| 	      gtk_style_unref (rc_style->style);
 | |
| 	      g_free (rc_style);
 | |
| 	    }
 | |
| 	  return error;
 | |
| 	}
 | |
|     }
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_RIGHT_CURLY)
 | |
|     {
 | |
|       if (insert)
 | |
| 	{
 | |
| 	  if (rc_style->fontset_name)
 | |
| 	    g_free (rc_style->fontset_name);
 | |
| 	  else 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);
 | |
| 	  g_free (rc_style);
 | |
| 	}
 | |
|       return PARSE_ERROR;
 | |
|     }
 | |
|   
 | |
|   if (insert)
 | |
|     g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_style_option (GScanner   *scanner,
 | |
| 			   GtkRcStyle *rc_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;
 | |
|   
 | |
|   error = gtk_rc_parse_bg_pixmap (scanner, rc_style);
 | |
|   if (error != PARSE_SYNTAX)
 | |
|     return error;
 | |
|   
 | |
|   error = gtk_rc_parse_font (scanner, rc_style);
 | |
|   if (error != PARSE_SYNTAX)
 | |
|     return error;
 | |
|   
 | |
|   error = gtk_rc_parse_fontset (scanner, rc_style);
 | |
|   
 | |
|   return error;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_base (GScanner *scanner,
 | |
| 		   GtkStyle *style)
 | |
| {
 | |
|   GtkStateType state;
 | |
|   gint token;
 | |
|   gint error;
 | |
|   
 | |
|   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);
 | |
|   
 | |
|   error = gtk_rc_parse_state (scanner, &state);
 | |
|   if (error != PARSE_OK)
 | |
|     return error;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_EQUAL_SIGN)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   error = gtk_rc_parse_color (scanner, &style->base[state]);
 | |
|   
 | |
|   return error;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_bg (GScanner *scanner,
 | |
| 		 GtkStyle *style)
 | |
| {
 | |
|   GtkStateType state;
 | |
|   gint token;
 | |
|   gint error;
 | |
|   
 | |
|   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);
 | |
|   
 | |
|   error = gtk_rc_parse_state (scanner, &state);
 | |
|   if (error != PARSE_OK)
 | |
|     return error;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_EQUAL_SIGN)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   error = gtk_rc_parse_color (scanner, &style->bg[state]);
 | |
|   
 | |
|   return error;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_fg (GScanner *scanner,
 | |
| 		 GtkStyle *style)
 | |
| {
 | |
|   GtkStateType state;
 | |
|   gint token;
 | |
|   gint error;
 | |
|   
 | |
|   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);
 | |
|   
 | |
|   error = gtk_rc_parse_state (scanner, &state);
 | |
|   if (error != PARSE_OK)
 | |
|     return error;
 | |
|   
 | |
|   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 error;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_bg_pixmap (GScanner   *scanner,
 | |
| 			GtkRcStyle *rc_style)
 | |
| {
 | |
|   GtkStateType state;
 | |
|   gint token;
 | |
|   gint error;
 | |
|   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);
 | |
|   
 | |
|   error = gtk_rc_parse_state (scanner, &state);
 | |
|   if (error != PARSE_OK)
 | |
|     return error;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_EQUAL_SIGN)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_STRING)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   if (strcmp (scanner->value.v_string, "<parent>"))
 | |
|     pixmap_file = gtk_rc_find_pixmap_in_path (scanner, scanner->value.v_string);
 | |
|   else
 | |
|     pixmap_file = g_strdup (scanner->value.v_string);
 | |
|   
 | |
|   if (pixmap_file)
 | |
|     {
 | |
|       if (rc_style->bg_pixmap_name[state])
 | |
| 	g_free (rc_style->bg_pixmap_name[state]);
 | |
|       rc_style->bg_pixmap_name[state] = pixmap_file;
 | |
|     }
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static char*
 | |
| gtk_rc_find_pixmap_in_path (GScanner *scanner,
 | |
| 			    gchar    *pixmap_file)
 | |
| {
 | |
|   gint i;
 | |
|   gint fd;
 | |
|   gchar *buf;
 | |
|   
 | |
|   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);
 | |
|     }
 | |
|   
 | |
|   g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
 | |
| 	     pixmap_file, scanner->line);
 | |
|   
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_font (GScanner   *scanner,
 | |
| 		   GtkRcStyle *rc_style)
 | |
| {
 | |
|   gint 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);
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_EQUAL_SIGN)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_STRING)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   if (rc_style->font_name)
 | |
|     g_free (rc_style->font_name);
 | |
|   rc_style->font_name = g_strdup (scanner->value.v_string);
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_fontset (GScanner	 *scanner,
 | |
| 		      GtkRcStyle *rc_style)
 | |
| {
 | |
|   gint 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);
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_EQUAL_SIGN)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_STRING)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   if (rc_style->fontset_name)
 | |
|     g_free (rc_style->fontset_name);
 | |
|   rc_style->fontset_name = g_strdup (scanner->value.v_string);
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_state (GScanner	 *scanner,
 | |
| 		    GtkStateType *state)
 | |
| {
 | |
|   gint token;
 | |
|   
 | |
|   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);
 | |
|   
 | |
|   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;
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   if (token != G_TOKEN_RIGHT_BRACE)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| 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;
 | |
|   
 | |
|   switch (token)
 | |
|     {
 | |
|     case G_TOKEN_LEFT_CURLY:
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       
 | |
|       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;
 | |
|       color->red = CLAMP (token_int, 0, 65535);
 | |
|       
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       if (token != G_TOKEN_COMMA)
 | |
| 	return PARSE_ERROR;
 | |
|       
 | |
|       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;
 | |
|       color->green = CLAMP (token_int, 0, 65535);
 | |
|       
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       if (token != G_TOKEN_COMMA)
 | |
| 	return PARSE_ERROR;
 | |
|       
 | |
|       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;
 | |
|       color->blue = CLAMP (token_int, 0, 65535);
 | |
|       
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       if (token != G_TOKEN_RIGHT_CURLY)
 | |
| 	return PARSE_ERROR;
 | |
|       break;
 | |
|       
 | |
|     case G_TOKEN_STRING:
 | |
|       token = g_scanner_get_next_token (scanner);
 | |
|       
 | |
|       if (scanner->value.v_string[0] != '#')
 | |
| 	return PARSE_ERROR;
 | |
|       
 | |
|       length = strlen (scanner->value.v_string) - 1;
 | |
|       if (((length % 3) != 0) || (length > 12))
 | |
| 	return PARSE_ERROR;
 | |
|       length /= 3;
 | |
|       
 | |
|       for (i = 0, j = 1; i < length; i++, j++)
 | |
| 	buf[i] = scanner->value.v_string[j];
 | |
|       buf[i] = '\0';
 | |
|       
 | |
|       sscanf (buf, "%x", &temp);
 | |
|       color->red = temp;
 | |
|       
 | |
|       for (i = 0; i < length; i++, j++)
 | |
| 	buf[i] = scanner->value.v_string[j];
 | |
|       buf[i] = '\0';
 | |
|       
 | |
|       sscanf (buf, "%x", &temp);
 | |
|       color->green = temp;
 | |
|       
 | |
|       for (i = 0; i < length; i++, j++)
 | |
| 	buf[i] = scanner->value.v_string[j];
 | |
|       buf[i] = '\0';
 | |
|       
 | |
|       sscanf (buf, "%x", &temp);
 | |
|       color->blue = temp;
 | |
|       
 | |
|       if (length == 1)
 | |
| 	{
 | |
| 	  color->red *= 4369;
 | |
| 	  color->green *= 4369;
 | |
| 	  color->blue *= 4369;
 | |
| 	}
 | |
|       else if (length == 2)
 | |
| 	{
 | |
| 	  color->red *= 257;
 | |
| 	  color->green *= 257;
 | |
| 	  color->blue *= 257;
 | |
| 	}
 | |
|       else if (length == 3)
 | |
| 	{
 | |
| 	  color->red *= 16;
 | |
| 	  color->green *= 16;
 | |
| 	  color->blue *= 16;
 | |
| 	}
 | |
|       break;
 | |
|       
 | |
|     case G_TOKEN_ERROR:
 | |
|       return PARSE_ERROR;
 | |
|       
 | |
|     default:
 | |
|       return PARSE_SYNTAX;
 | |
|     }
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_pixmap_path (GScanner *scanner)
 | |
| {
 | |
|   gint 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);
 | |
|   
 | |
|   token = g_scanner_get_next_token (scanner);
 | |
|   
 | |
|   if (token != G_TOKEN_STRING)
 | |
|     return PARSE_ERROR;
 | |
|   
 | |
|   gtk_rc_parse_pixmap_path_string (scanner->value.v_string);
 | |
|   
 | |
|   return PARSE_OK;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gtk_rc_parse_pixmap_path_string (gchar *pix_path)
 | |
| {
 | |
|   gchar *buf;
 | |
|   gint end_offset;
 | |
|   gint start_offset = 0;
 | |
|   gint path_len;
 | |
|   gint path_num;
 | |
|   
 | |
|   /* free the old one, or just add to the old one ? */
 | |
|   for (path_num=0; pixmap_path[path_num]; path_num++)
 | |
|     {
 | |
|       g_free (pixmap_path[path_num]);
 | |
|       pixmap_path[path_num] = NULL;
 | |
|     }
 | |
|   
 | |
|   path_num = 0;
 | |
|   
 | |
|   path_len = strlen (pix_path);
 | |
|   
 | |
|   buf = g_strdup (pix_path);
 | |
|   
 | |
|   for (end_offset = 0; end_offset <= path_len; end_offset++)
 | |
|     {
 | |
|       if ((buf[end_offset] == ':') ||
 | |
| 	  (end_offset == path_len))
 | |
| 	{
 | |
| 	  buf[end_offset] = '\0';
 | |
| 	  pixmap_path[path_num] = g_strdup (buf + start_offset);
 | |
| 	  path_num++;
 | |
| 	  pixmap_path[path_num] = NULL;
 | |
| 	  start_offset = end_offset + 1;
 | |
| 	}
 | |
|     }
 | |
|   g_free (buf);
 | |
| }
 | |
| 
 | |
| static gint
 | |
| gtk_rc_parse_widget_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)
 | |
|     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)
 | |
|     {
 | |
|       g_free (rc_set->set);
 | |
|       g_free (rc_set);
 | |
|       return PARSE_ERROR;
 | |
|     }
 | |
|   
 | |
|   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;
 | |
| }
 | |
| 
 | |
| 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)
 | |
|     {
 | |
|       g_free (rc_set->set);
 | |
|       g_free (rc_set);
 | |
|       return PARSE_ERROR;
 | |
|     }
 | |
|   
 | |
|   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_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)
 | |
|     {
 | |
|       name = gtk_widget_get_name (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_widget_get_name (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;
 | |
| }
 | |
| 
 | |
| static char*
 | |
| gtk_rc_widget_class_path (GtkWidget *widget)
 | |
| {
 | |
|   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;
 | |
| }
 |