/* $Id$ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) 1999-2004 Olivier Fourdan (fourdan@xfce.org) * * Portions based Thinice port by * Tim Gerla , * Tomas Ögren * Portions based on Smooth theme by * Andrew Johnson * Portions based on IceGradient theme by * Tim Gerla * Tomas Ă–gren * JM Perez * Portions based on Wonderland theme by * Garrett LeSage * Alexander Larsson * Owen Taylor * Portions based on Raleigh theme by * Owen Taylor * Portions based on Notif theme * Portions based on Notif2 theme * Portions based on original GTK theme */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "xfce_rc_style.h" #include "xfce_style.h" #define DEFAULT_SHADE_START 1.10 #define DEFAULT_SHADE_END 0.90 static void xfce_rc_style_init(XfceRcStyle * style); static void xfce_rc_style_class_init(XfceRcStyleClass * klass); static guint xfce_rc_style_parse(GtkRcStyle * rc_style, GtkSettings * settings, GScanner * scanner); static void xfce_rc_style_merge(GtkRcStyle * dest, GtkRcStyle * src); static struct { gchar *name; guint token; } theme_symbols[] = { { "smooth_edge", TOKEN_SMOOTHEDGE }, { "boxfill", TOKEN_BOXFILL }, { "fill_style", TOKEN_FILL_STYLE }, { "grip_style", TOKEN_GRIP_STYLE }, { "none", TOKEN_GRIP_NONE }, { "rough", TOKEN_GRIP_ROUGH }, { "slide", TOKEN_GRIP_SLIDE }, { "gradient", TOKEN_GRADIENT }, { "plain", TOKEN_PLAIN }, { "orientation", TOKEN_ORIENTATION }, { "auto", TOKEN_AUTO }, { "vertical", TOKEN_VERTICAL }, { "horizontal", TOKEN_HORIZONTAL }, { "northern_diagonal", TOKEN_NORTHERN_DIAGONAL }, { "southern_diagonal", TOKEN_SOUTHERN_DIAGONAL }, { "shade_start", TOKEN_SHADE_START }, { "shade_end", TOKEN_SHADE_END }, { "flat_border", TOKEN_FLATBORDER }, { "focus_color", TOKEN_FOCUSCOLOR }, { "true", TOKEN_TRUE}, { "TRUE", TOKEN_TRUE}, { "false", TOKEN_FALSE}, { "FALSE", TOKEN_FALSE} }; static guint n_theme_symbols = sizeof(theme_symbols) / sizeof(theme_symbols[0]); static GtkStyle *xfce_rc_style_create_style(GtkRcStyle * rc_style); static GtkRcStyleClass *parent_class; GType xfce_type_rc_style = 0; void xfce_rc_style_register_type(GTypeModule * module) { static const GTypeInfo object_info = { sizeof(XfceRcStyleClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) xfce_rc_style_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof(XfceRcStyle), 0, /* n_preallocs */ (GInstanceInitFunc) xfce_rc_style_init, }; xfce_type_rc_style = g_type_module_register_type(module, GTK_TYPE_RC_STYLE, "XfceRcStyle", &object_info, 0); } static void xfce_rc_style_init(XfceRcStyle * style) { style->flags = XFCE_RC_FLAGS_NONE; style->smooth_edge = FALSE; style->grip_style = XFCE_RC_GRIP_ROUGH; style->gradient = FALSE; style->gradient_style = XFCE_RC_GRADIENT_AUTO; style->shade_start = DEFAULT_SHADE_START; style->shade_end = DEFAULT_SHADE_END; style->flat_border = FALSE; } static void xfce_rc_style_class_init(XfceRcStyleClass * klass) { GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS(klass); parent_class = g_type_class_peek_parent(klass); rc_style_class->parse = xfce_rc_style_parse; rc_style_class->merge = xfce_rc_style_merge; rc_style_class->create_style = xfce_rc_style_create_style; } static guint theme_parse_boolean(GScanner * scanner, GTokenType wanted_token, gboolean * retval) { guint token; token = g_scanner_get_next_token(scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token(scanner); if(token != G_TOKEN_EQUAL_SIGN) { return G_TOKEN_EQUAL_SIGN; } token = g_scanner_get_next_token(scanner); if(token == TOKEN_TRUE) { *retval = TRUE; } else if(token == TOKEN_FALSE) { *retval = FALSE; } else { return TOKEN_TRUE; } return G_TOKEN_NONE; } static guint theme_parse_float (GScanner *scanner, GTokenType wanted_token, gfloat return_default, gfloat lower_limit, gfloat upper_limit, gfloat *retval) { guint token; token = g_scanner_get_next_token (scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token (scanner); if (token != G_TOKEN_EQUAL_SIGN) { return G_TOKEN_EQUAL_SIGN; } token = g_scanner_get_next_token (scanner); if (token != G_TOKEN_FLOAT) { *retval = return_default; } else { *retval = scanner->value.v_float; } if (*retval < lower_limit) { *retval = lower_limit; } if ((*retval > upper_limit) && (upper_limit > lower_limit)) { *retval = upper_limit; } return G_TOKEN_NONE; } static guint theme_parse_fillstyle (GScanner * scanner, GTokenType wanted_token, gboolean * retval) { guint token; token = g_scanner_get_next_token(scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token(scanner); if(token != G_TOKEN_EQUAL_SIGN) { return G_TOKEN_EQUAL_SIGN; } token = g_scanner_get_next_token(scanner); if(token == TOKEN_GRADIENT) { *retval = TRUE; } else if (token == TOKEN_PLAIN) { *retval = FALSE; } else { return TOKEN_PLAIN; } return G_TOKEN_NONE; } static guint theme_parse_orientation (GScanner * scanner, GTokenType wanted_token, XfceRcGradientType * retval) { guint token; token = g_scanner_get_next_token(scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token(scanner); if(token != G_TOKEN_EQUAL_SIGN) { return G_TOKEN_EQUAL_SIGN; } token = g_scanner_get_next_token(scanner); if(token == TOKEN_HORIZONTAL) { *retval = XFCE_RC_GRADIENT_HORIZONTAL; } else if(token == TOKEN_VERTICAL) { *retval = XFCE_RC_GRADIENT_VERTICAL; } else if(token == TOKEN_NORTHERN_DIAGONAL) { *retval = XFCE_RC_GRADIENT_NORTHERN_DIAGONAL; } else if(token == TOKEN_SOUTHERN_DIAGONAL) { *retval = XFCE_RC_GRADIENT_SOUTHERN_DIAGONAL; } else { *retval = XFCE_RC_GRADIENT_AUTO; } return G_TOKEN_NONE; } static guint theme_parse_boxfill (GScanner * scanner, GTokenType wanted_token, XfceRcStyle * retval) { guint token; gboolean b; gfloat f; XfceRcGradientType orientation; token = g_scanner_get_next_token(scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token(scanner); if(token != G_TOKEN_LEFT_CURLY) { return G_TOKEN_LEFT_CURLY; } token = g_scanner_peek_next_token(scanner); while (token != G_TOKEN_RIGHT_CURLY) { switch (token) { case TOKEN_FILL_STYLE: token = theme_parse_fillstyle(scanner, TOKEN_FILL_STYLE, &b); if(token != G_TOKEN_NONE) { break; } retval->gradient = b; break; case TOKEN_ORIENTATION: token = theme_parse_orientation(scanner, TOKEN_ORIENTATION, &orientation); if(token != G_TOKEN_NONE) { break; } retval->gradient_style = orientation; break; case TOKEN_SHADE_START: token = theme_parse_float (scanner, TOKEN_SHADE_START, DEFAULT_SHADE_START, 0.0, 2.0, &f); if(token != G_TOKEN_NONE) { break; } retval->shade_start = f; break; case TOKEN_SHADE_END: token = theme_parse_float (scanner, TOKEN_SHADE_END, DEFAULT_SHADE_END, 0.0, 2.0, &f); if(token != G_TOKEN_NONE) { break; } retval->shade_end = f; break; default: g_scanner_get_next_token(scanner); token = G_TOKEN_RIGHT_CURLY; break; } if (token != G_TOKEN_NONE) { return token; } token = g_scanner_peek_next_token(scanner); } g_scanner_get_next_token (scanner); return G_TOKEN_NONE; } static guint theme_parse_grip_style (GScanner * scanner, GTokenType wanted_token, XfceRcStyle * retval) { guint token; token = g_scanner_get_next_token(scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token(scanner); if(token != G_TOKEN_EQUAL_SIGN) { return G_TOKEN_EQUAL_SIGN; } token = g_scanner_get_next_token(scanner); if(token == TOKEN_GRIP_NONE) { retval->grip_style = XFCE_RC_HANDLER_NONE; } else if(token == TOKEN_GRIP_SLIDE) { retval->grip_style = XFCE_RC_GRIP_SLIDE; } else { retval->grip_style = XFCE_RC_GRIP_ROUGH; } return G_TOKEN_NONE; } static guint theme_parse_color (GScanner *scanner, GTokenType wanted_token, GtkRcStyle *style, GdkColor *retval) { guint token; token = g_scanner_get_next_token (scanner); if (token != wanted_token) { return wanted_token; } token = g_scanner_get_next_token (scanner); if (token != G_TOKEN_EQUAL_SIGN) { return G_TOKEN_EQUAL_SIGN; } return gtk_rc_parse_color_full (scanner, style, retval); } static guint xfce_rc_style_parse(GtkRcStyle * rc_style, GtkSettings * settings, GScanner * scanner) { static GQuark scope_id = 0; XfceRcStyle *theme_data = XFCE_RC_STYLE(rc_style); guint old_scope; guint token; guint i; gboolean b; GdkColor c; /* Set up a new scope in this scanner. */ if(!scope_id) { scope_id = g_quark_from_string("theme_engine"); } old_scope = g_scanner_set_scope(scanner, scope_id); if(!g_scanner_lookup_symbol(scanner, theme_symbols[0].name)) { for(i = 0; i < n_theme_symbols; i++) { g_scanner_scope_add_symbol(scanner, scope_id, theme_symbols[i].name, GINT_TO_POINTER(theme_symbols[i].token)); } } token = g_scanner_peek_next_token(scanner); while(token != G_TOKEN_RIGHT_CURLY) { switch (token) { case TOKEN_SMOOTHEDGE: token = theme_parse_boolean(scanner, TOKEN_SMOOTHEDGE, &b); if(token != G_TOKEN_NONE) { break; } theme_data->smooth_edge = b; break; case TOKEN_GRIP_STYLE: token = theme_parse_grip_style(scanner, TOKEN_GRIP_STYLE, theme_data); if(token != G_TOKEN_NONE) { break; } break; case TOKEN_BOXFILL: token = theme_parse_boxfill(scanner, TOKEN_BOXFILL, theme_data); if(token != G_TOKEN_NONE) { break; } break; case TOKEN_FLATBORDER: token = theme_parse_boolean(scanner, TOKEN_FLATBORDER, &b); if(token != G_TOKEN_NONE) { break; } theme_data->flat_border = b; break; case TOKEN_FOCUSCOLOR: token = theme_parse_color (scanner, TOKEN_FOCUSCOLOR, rc_style, &c); if(token != G_TOKEN_NONE) { break; } theme_data->focus_color = c; theme_data->flags |= XFCE_RC_FOCUS_COLOR; break; default: g_scanner_get_next_token(scanner); token = G_TOKEN_RIGHT_CURLY; break; } if(token != G_TOKEN_NONE) { return token; } token = g_scanner_peek_next_token(scanner); } g_scanner_get_next_token(scanner); g_scanner_set_scope(scanner, old_scope); return G_TOKEN_NONE; } static void xfce_rc_style_merge(GtkRcStyle * dest, GtkRcStyle * src) { XfceRcStyle *src_data, *dest_data; parent_class->merge(dest, src); if(!XFCE_IS_RC_STYLE(src)) { return; } src_data = XFCE_RC_STYLE(src); dest_data = XFCE_RC_STYLE(dest); dest_data->flags = src_data->flags; dest_data->smooth_edge = src_data->smooth_edge; dest_data->grip_style = src_data->grip_style; dest_data->gradient = src_data->gradient; dest_data->gradient_style = src_data->gradient_style; dest_data->shade_start = src_data->shade_start; dest_data->shade_end = src_data->shade_end; dest_data->flat_border = src_data->flat_border; dest_data->focus_color = src_data->focus_color; } /* Create an empty style suitable to this RC style */ static GtkStyle *xfce_rc_style_create_style(GtkRcStyle * rc_style) { void *ptr; ptr = GTK_STYLE(g_object_new(XFCE_TYPE_STYLE, NULL)); return (GtkStyle *) ptr; }