[murrine/gtk-style-context] Turn murrine into a GtkThemingEngine



commit 31e1a9ffc64e0620fb28d7ce25ca23ced365ab78
Author: Andrea Cimitan <andrea cimitan gmail com>
Date:   Thu Dec 9 14:47:55 2010 +0100

    Turn murrine into a GtkThemingEngine

 Makefile.am              |    6 +-
 src/murrine_draw.c       |    1 -
 src/murrine_draw_rgba.c  |    1 -
 src/murrine_engine.c     | 2668 ++++++++++++++++++++++++++++++++++++++++++++++
 src/murrine_engine.h     |  107 ++
 src/murrine_theme_main.c |   14 +-
 6 files changed, 2784 insertions(+), 13 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 5f02bf4..99d1af0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,10 +17,8 @@ libmurrine_la_SOURCES = \
 	./src/config.h \
 	./src/support.c \
 	./src/support.h \
-	./src/murrine_rc_style.c \
-	./src/murrine_rc_style.h \
-	./src/murrine_style.c \
-	./src/murrine_style.h \
+	./src/murrine_engine.c \
+	./src/murrine_engine.h \
 	./src/murrine_theme_main.c \
 	./src/murrine_draw.c \
 	./src/murrine_draw_rgba.c \
diff --git a/src/murrine_draw.c b/src/murrine_draw.c
index 01e1beb..b0d68d5 100644
--- a/src/murrine_draw.c
+++ b/src/murrine_draw.c
@@ -21,7 +21,6 @@
 #include <cairo.h>
 
 #include "murrine_draw.h"
-#include "murrine_style.h"
 #include "murrine_types.h"
 #include "support.h"
 #include "cairo-support.h"
diff --git a/src/murrine_draw_rgba.c b/src/murrine_draw_rgba.c
index 539e965..a7d3f47 100644
--- a/src/murrine_draw_rgba.c
+++ b/src/murrine_draw_rgba.c
@@ -21,7 +21,6 @@
 #include <cairo.h>
 
 #include "murrine_draw.h"
-#include "murrine_style.h"
 #include "murrine_types.h"
 #include "support.h"
 #include "cairo-support.h"
diff --git a/src/murrine_engine.c b/src/murrine_engine.c
new file mode 100644
index 0000000..20a5a02
--- /dev/null
+++ b/src/murrine_engine.c
@@ -0,0 +1,2668 @@
+/* Murrine theme engine
+ * Copyright (C) 2006-2007-2008-2009-2009 Andrea Cimitan
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <cairo.h>
+#include <math.h>
+#include <string.h>
+
+#include "murrine_engine.h"
+#include "murrine_draw.h"
+#include "support.h"
+#include "cairo-support.h"
+
+/* #define DEBUG 1 */
+
+#define SCALE_SIZE 5
+
+#define DETAIL(xx) ((detail) && (!strcmp(xx, detail)))
+
+#define DRAW_ARGS GtkStyle      *style, \
+                  cairo_t       *cr, \
+                  GtkStateType  state_type, \
+                  GtkShadowType shadow_type, \
+                  GtkWidget     *widget, \
+                  const gchar   *detail, \
+                  gint          x, \
+                  gint          y, \
+                  gint          width, \
+                  gint          height
+
+#define CHECK_ARGS \
+	g_return_if_fail (cr != NULL);			\
+	g_return_if_fail (style != NULL);                     \
+	cairo_set_line_width (cr, 1.0);
+
+#ifdef HAVE_ANIMATION
+#include "animation.h"
+#endif
+
+#define STYLE_FUNCTION(function) (MURRINE_ENGINE_GET_CLASS (style)->style_functions[params.style].function)
+
+#define PRINT_DETAIL(section,detail,widget) printf("%s: %s %s\n", section, detail, G_OBJECT_TYPE_NAME (widget));
+
+G_DEFINE_DYNAMIC_TYPE (MurrineEngine, murrine_engine, GTK_TYPE_THEMING_ENGINE)
+
+static
+boolean murrine_widget_is_rgba (GtkWidget *widget)
+{
+	boolean use_rgba = FALSE;
+	GdkScreen *screen;
+
+	if (widget)
+		screen = gtk_widget_get_screen (widget);
+	else
+		return use_rgba;
+
+#ifdef HAVE_RGBA
+	if (gdk_screen_is_composited(screen))
+	{
+		GdkVisual *visual;
+		guint32 red_mask;
+		guint32 green_mask;
+		guint32 blue_mask;
+
+		visual = gtk_widget_get_visual (widget);
+
+		gdk_visual_get_red_pixel_details (visual, &red_mask, NULL, NULL);
+		gdk_visual_get_green_pixel_details (visual, &green_mask, NULL, NULL);
+		gdk_visual_get_blue_pixel_details (visual, &blue_mask, NULL, NULL);
+
+		if (gdk_visual_get_depth (visual) == 32 && (red_mask == 0xff0000 &&
+		                                            green_mask == 0x00ff00 &&
+		                                            blue_mask  == 0x0000ff))
+			use_rgba = TRUE;
+	}
+#endif
+
+	return use_rgba;
+}
+
+static void
+murrine_set_widget_parameters (const GtkWidget  *widget,
+                               const GtkStyle   *style,
+                               GtkStateType     state_type,
+                               WidgetParameters *params)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+
+	params->active     = (state_type == GTK_STATE_ACTIVE);
+	params->prelight   = (state_type == GTK_STATE_PRELIGHT);
+	params->disabled   = (state_type == GTK_STATE_INSENSITIVE);
+	params->state_type = state_type;
+	params->corners    = MRN_CORNER_ALL;
+	params->ltr        = murrine_widget_is_ltr ((GtkWidget*)widget);
+	params->focus      = (MURRINE_STYLE (style)->focusstyle != 0) && widget && gtk_widget_has_focus ((GtkWidget *) widget);
+	params->is_default = widget && gtk_widget_has_default ((GtkWidget *) widget);
+
+	params->xthickness = style->xthickness;
+	params->ythickness = style->ythickness;
+
+	params->contrast          = murrine_style->contrast;
+	params->glazestyle        = murrine_style->glazestyle;
+	params->glow_shade        = murrine_style->glow_shade;
+	params->glowstyle         = murrine_style->glowstyle;
+	params->highlight_shade   = murrine_style->highlight_shade;
+	params->lightborder_shade = murrine_style->lightborder_shade;
+	params->lightborderstyle  = murrine_style->lightborderstyle;
+	params->reliefstyle       = murrine_style->reliefstyle;
+	params->roundness         = murrine_style->roundness;
+
+	MurrineGradients mrn_gradient;
+	mrn_gradient.border_shades[0] = murrine_style->border_shades[0];
+	mrn_gradient.border_shades[1] = murrine_style->border_shades[1];
+
+	mrn_gradient.gradient_shades[0] = murrine_style->gradient_shades[0];
+	mrn_gradient.gradient_shades[1] = murrine_style->gradient_shades[1];
+	mrn_gradient.gradient_shades[2] = murrine_style->gradient_shades[2];
+	mrn_gradient.gradient_shades[3] = murrine_style->gradient_shades[3];
+
+	if (murrine_style->has_gradient_colors && !params->disabled)
+	{
+		mrn_gradient.has_gradient_colors = TRUE;
+		murrine_gdk_color_to_rgb (&murrine_style->gradient_colors[0], &mrn_gradient.gradient_colors[0].r,
+		                                                              &mrn_gradient.gradient_colors[0].g,
+		                                                              &mrn_gradient.gradient_colors[0].b);
+		murrine_gdk_color_to_rgb (&murrine_style->gradient_colors[1], &mrn_gradient.gradient_colors[1].r,
+		                                                              &mrn_gradient.gradient_colors[1].g,
+		                                                              &mrn_gradient.gradient_colors[1].b);
+		murrine_gdk_color_to_rgb (&murrine_style->gradient_colors[2], &mrn_gradient.gradient_colors[2].r,
+		                                                              &mrn_gradient.gradient_colors[2].g,
+		                                                              &mrn_gradient.gradient_colors[2].b);
+		murrine_gdk_color_to_rgb (&murrine_style->gradient_colors[3], &mrn_gradient.gradient_colors[3].r,
+		                                                              &mrn_gradient.gradient_colors[3].g,
+		                                                              &mrn_gradient.gradient_colors[3].b);
+		if (params->prelight && !MRN_IS_PROGRESS_BAR(widget)) //progressbar is prelight, no change in shade
+		{
+			mrn_gradient.gradient_shades[0] *= murrine_style->prelight_shade;
+			mrn_gradient.gradient_shades[1] *= murrine_style->prelight_shade;
+			mrn_gradient.gradient_shades[2] *= murrine_style->prelight_shade;
+			mrn_gradient.gradient_shades[3] *= murrine_style->prelight_shade;
+		}
+	}
+	else
+		mrn_gradient.has_gradient_colors = FALSE;
+
+	if (murrine_style->has_border_colors && !params->disabled)
+	{
+		mrn_gradient.has_border_colors = TRUE;
+		murrine_gdk_color_to_rgb (&murrine_style->border_colors[0], &mrn_gradient.border_colors[0].r,
+	                                                                    &mrn_gradient.border_colors[0].g,
+	                                                                    &mrn_gradient.border_colors[0].b);
+		murrine_gdk_color_to_rgb (&murrine_style->border_colors[1], &mrn_gradient.border_colors[1].r,
+	                                                                    &mrn_gradient.border_colors[1].g,
+	                                                                    &mrn_gradient.border_colors[1].b);
+	}
+	else
+		mrn_gradient.has_border_colors = FALSE;
+
+	mrn_gradient.shadow_shades[0] = murrine_style->shadow_shades[0];
+	mrn_gradient.shadow_shades[1] = murrine_style->shadow_shades[1];
+	mrn_gradient.trough_border_shades[0] = murrine_style->trough_border_shades[0];
+	mrn_gradient.trough_border_shades[1] = murrine_style->trough_border_shades[1];
+	mrn_gradient.trough_shades[0] = murrine_style->trough_shades[0];
+	mrn_gradient.trough_shades[1] = murrine_style->trough_shades[1];
+
+	if (murrine_style->border_shades[0] != 1.0 ||
+	    murrine_style->border_shades[1] != 1.0 ||
+	    murrine_style->gradient_shades[0] != 1.0 ||
+	    murrine_style->gradient_shades[1] != 1.0 ||
+	    murrine_style->gradient_shades[2] != 1.0 ||
+	    murrine_style->gradient_shades[3] != 1.0 ||
+	    murrine_style->shadow_shades[0] != 1.0 ||
+	    murrine_style->shadow_shades[1] != 1.0 ||
+	    murrine_style->trough_border_shades[0] != 1.0 ||
+	    murrine_style->trough_border_shades[1] != 1.0 ||
+	    murrine_style->trough_shades[0] != 1.0 ||
+	    murrine_style->trough_shades[1] != 1.0)
+		mrn_gradient.gradients = TRUE;
+	else
+		mrn_gradient.gradients = FALSE;
+
+	mrn_gradient.use_rgba = (murrine_widget_is_rgba ((GtkWidget*) widget) &&
+	                         murrine_style->rgba);
+	mrn_gradient.rgba_opacity = GRADIENT_OPACITY;
+
+	MurrineStyles mrn_style = MRN_STYLE_MURRINE;
+	if (mrn_gradient.use_rgba)
+		mrn_style = MRN_STYLE_RGBA;
+
+	params->mrn_gradient = mrn_gradient;
+	params->style = mrn_style;
+	params->style_functions = &(MURRINE_STYLE_GET_CLASS (style)->style_functions[mrn_style]);
+
+	/* I want to avoid to have to do this. I need it for GtkEntry, unless I
+	   find out why it doesn't behave the way I expect it to. */
+	params->parentbg = MURRINE_STYLE (style)->colors.bg[state_type];
+	murrine_get_parent_bg (widget, &params->parentbg);
+}
+
+static void
+murrine_style_draw_flat_box (DRAW_ARGS)
+{
+	////printf( "draw_flat_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+	if (detail &&
+	    state_type == GTK_STATE_SELECTED && (
+	    !strncmp ("cell_even", detail, 9) ||
+	    !strncmp ("cell_odd", detail, 8)))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+
+		CHECK_ARGS
+
+		WidgetParameters params;
+		CellParameters cell;
+
+		cell.style = murrine_style->cellstyle;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_selected_cell) (cr, colors, &params, &cell, x, y, width, height);
+	}
+	else if (DETAIL ("tooltip"))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+
+		CHECK_ARGS
+
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		if (params.mrn_gradient.use_rgba)
+		{
+			params.mrn_gradient.rgba_opacity = TOOLTIP_OPACITY;
+		}
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_tooltip) (cr, colors, &params, x, y, width, height);
+	}
+	else if (DETAIL ("icon_view_item"))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+
+		CHECK_ARGS
+
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_iconview) (cr, colors, &params, x, y, width, height);	
+	}
+	else
+	{
+		if (DETAIL ("base") || DETAIL ("eventbox") || DETAIL ("entry_bg") || DETAIL ("trough"))
+		{
+			MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+			MurrineColors *colors = &murrine_style->colors;
+			boolean use_rgba = FALSE;
+
+			CHECK_ARGS
+
+			use_rgba = (murrine_widget_is_rgba (widget) && murrine_style->rgba);
+
+			if (!use_rgba)
+			{
+				GTK_STYLE_CLASS (murrine_style_parent_class)->draw_flat_box (style, cr, state_type,
+		                                                                             shadow_type,
+		                                                                             widget, detail,
+		                                                                             x, y, width, height);
+			}
+			else
+			{
+				if (DETAIL ("entry_bg"))
+				{
+					cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+					murrine_set_color_rgba (cr, &colors->base[state_type], ENTRY_OPACITY);
+					cairo_rectangle (cr, x, y, width, height);
+					cairo_fill (cr);
+				}
+				else if (DETAIL ("eventbox") || DETAIL ("trough"))
+				{
+					cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+					murrine_set_color_rgba (cr, &colors->bg[0], WINDOW_OPACITY);
+					cairo_rectangle (cr, x, y, width, height);
+					cairo_fill (cr);
+				}
+				else
+				{
+					cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+					cairo_pattern_t *pat;
+					pat = cairo_pattern_create_linear (0, 0, width, 0);
+					murrine_pattern_add_color_stop_rgba (pat, 0.0, &colors->bg[0], WINDOW_OPACITY);
+					murrine_pattern_add_color_stop_rgba (pat, 0.5, &colors->bg[0], (WINDOW_OPACITY-0.04));
+					murrine_pattern_add_color_stop_rgba (pat, 1.0, &colors->bg[0], WINDOW_OPACITY);
+					cairo_set_source (cr, pat);
+					cairo_rectangle  (cr, x, y, width, height);
+					cairo_fill       (cr);
+					cairo_pattern_destroy (pat);
+				}
+			}
+		}
+		else
+		{
+/*			printf( "draw_flat_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));*/
+				GTK_STYLE_CLASS (murrine_style_parent_class)->draw_flat_box (style, cr, state_type,
+		                                                                             shadow_type,
+		                                                                             widget, detail,
+		                                                                             x, y, width, height);
+		}
+	}
+
+	/* Dotted listview */
+	if (detail && (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		switch (murrine_style->listviewstyle)
+		{
+			default:
+			case 0:
+				break;
+			case 1:
+			{
+				MurrineColors *colors = &murrine_style->colors;
+
+				CHECK_ARGS
+
+				cairo_translate (cr, x, y);
+				int i;
+				int pos = murrine_style->listviewheaderstyle != 1 ? 2 : 1;
+
+				murrine_set_color_rgba (cr, &colors->text[GTK_STATE_NORMAL], 0.42);
+				for (i = 2; i < height; i+=4)
+				{
+					cairo_rectangle (cr, -pos, i, 1, 1);
+					cairo_fill (cr);
+				}
+				break;
+			}
+			case 2:
+			{
+				MurrineColors *colors = &murrine_style->colors;
+
+				CHECK_ARGS
+
+				cairo_translate (cr, murrine_style->listviewheaderstyle != 1 ? x-1 : x, y);
+
+				cairo_move_to (cr, -0.5, 0);
+				cairo_line_to (cr, -0.5, height);
+				murrine_set_color_rgba (cr, &colors->text[GTK_STATE_NORMAL], 0.2);
+				cairo_stroke (cr);
+				break;
+			}
+		}
+	}
+}
+
+static void
+murrine_style_draw_shadow (DRAW_ARGS)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("entry") && !(widget && gtk_widget_get_parent (widget) && MRN_IS_TREE_VIEW (gtk_widget_get_parent (widget))))
+	{
+		WidgetParameters params;
+		FocusParameters  focus;
+
+		/* Override the entries state type, because we are too lame to handle this via
+		 * the focus ring, and GtkEntry doesn't even set the INSENSITIVE state ... */
+		if (state_type == GTK_STATE_NORMAL && widget && MRN_IS_ENTRY (widget))
+			state_type = gtk_widget_get_state (widget);
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (widget && (MRN_IS_COMBO (gtk_widget_get_parent (widget)) ||
+		               MRN_IS_COMBO_BOX_ENTRY(gtk_widget_get_parent (widget)) ||
+		               MRN_IS_SPIN_BUTTON (widget)))
+		{
+			width += style->xthickness;
+			if (!params.ltr)
+				x -= style->xthickness;
+
+			if (params.ltr)
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+			else
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+		}
+
+		/* Fill the background as it is initilized to base[NORMAL].
+		 * Relevant GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=513471
+		 * The fill only happens if no hint has been added by some application
+		 * that is faking GTK+ widgets. */
+		if (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint"))
+		{
+			cairo_rectangle (cr, 0, 0, width, height);
+			if (!params.mrn_gradient.use_rgba)
+			{
+				murrine_set_color_rgb (cr, &params.parentbg);
+				cairo_fill(cr);
+			}
+			else
+			{
+				cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+				murrine_set_color_rgba (cr, &params.parentbg, WINDOW_OPACITY);
+				cairo_fill(cr);
+				cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+			}
+		}
+
+		/* Focus color */
+		if (murrine_style->has_focus_color)
+		{
+			murrine_gdk_color_to_rgb (&murrine_style->focus_color, &focus.color.r,
+			                                                       &focus.color.g,
+			                                                       &focus.color.b);
+			focus.has_color = TRUE;
+		}
+		else
+			focus.color = colors->spot[2];
+
+		STYLE_FUNCTION(draw_entry) (cr, &murrine_style->colors, &params, &focus,
+		                            x, y, width, height);
+	}
+	else if (DETAIL ("frame") && widget && MRN_IS_STATUSBAR (gtk_widget_get_parent (widget)))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (!params.mrn_gradient.use_rgba)
+		{
+			gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
+                                                            state_type, x, y, width, height);;
+		}
+
+		if (shadow_type != GTK_SHADOW_NONE)
+			STYLE_FUNCTION(draw_statusbar) (cr, colors, &params,
+			                                x, y, width, height);
+	}
+	else if (DETAIL ("frame") || DETAIL ("calendar"))
+	{
+		WidgetParameters params;
+		FrameParameters  frame;
+
+		frame.shadow  = shadow_type;
+		frame.gap_x   = -1; /* No gap will be drawn */
+		frame.border  = &colors->shade[4];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_NONE;
+
+		if (widget && !g_str_equal ("XfcePanelWindow", gtk_widget_get_name (gtk_widget_get_toplevel (widget))))
+			STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame, x, y, width, height);
+	}
+	else if (DETAIL ("scrolled_window") || DETAIL ("viewport") || detail == NULL)
+	{
+		cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+		murrine_set_color_rgb (cr, &colors->shade[5]);
+		cairo_stroke (cr);
+	}
+	else if (DETAIL ("pager") || DETAIL ("pager-frame"))
+	{
+		murrine_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1,
+		                           CLAMP (murrine_style->roundness, 0, 3),
+		                           MRN_CORNER_ALL);
+		murrine_set_color_rgb (cr, &colors->shade[5]);
+		cairo_stroke (cr);
+	}
+	else if ((DETAIL ("trough-upper") || DETAIL ("trough-lower")) && widget && (MRN_IS_VSCROLLBAR (widget) || MRN_IS_HSCROLLBAR (widget) || MRN_IS_SCROLLBAR (widget)))
+	{
+		WidgetParameters params;
+		ScrollBarParameters scrollbar;
+		boolean within_bevel = FALSE;
+
+		if (gtk_widget_get_parent (widget) && MRN_IS_SCROLLED_WINDOW (gtk_widget_get_parent (widget)))
+			gtk_widget_style_get (gtk_widget_get_parent (widget), "scrollbars-within-bevel", &within_bevel, NULL);
+
+		scrollbar.horizontal   = TRUE;
+		scrollbar.junction     = murrine_scrollbar_get_junction (widget);
+		scrollbar.stepperstyle = murrine_style->stepperstyle;
+		scrollbar.within_bevel = within_bevel;
+		scrollbar.trough_upper = DETAIL ("trough-upper");
+		gtk_widget_style_get (widget, "stepper-size", &scrollbar.steppersize, NULL);
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (within_bevel)
+			params.corners = MRN_CORNER_NONE;
+
+		scrollbar.horizontal = gtk_orientable_get_orientation ((GtkOrientable*)widget) == GTK_ORIENTATION_HORIZONTAL;
+
+		if (murrine_style->stepperstyle != 1 && murrine_style->stepperstyle != 3 && !params.mrn_gradient.use_rgba)
+		{
+			if (scrollbar.horizontal)
+			{
+				x += 2;
+				width -= 4;
+			}
+			else
+			{
+				y += 2;
+				height -= 4;
+			}
+		}
+
+		STYLE_FUNCTION(draw_scrollbar_trough) (cr, colors, &params, &scrollbar, x, y, width, height);
+	}
+	else
+	{
+		WidgetParameters params;
+		FrameParameters frame;
+
+		frame.shadow = shadow_type;
+		frame.gap_x  = -1; /* No gap will be drawn */
+		frame.border = &colors->shade[4];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (params.roundness < 2)
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame, x, y, width, height);
+	}
+}
+
+static void
+murrine_style_draw_box_gap (DRAW_ARGS,
+                            GtkPositionType gap_side,
+                            gint            gap_x,
+                            gint            gap_width)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("notebook"))
+	{
+		WidgetParameters params;
+		FrameParameters  frame;
+		gboolean start, end;
+
+		frame.shadow    = shadow_type;
+		frame.gap_side  = gap_side;
+		frame.gap_x     = gap_x;
+		frame.gap_width = gap_width;
+		frame.border    = &colors->shade[5];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		murrine_get_notebook_tab_position (widget, &start, &end);
+
+		switch (gap_side)
+		{
+			case GTK_POS_TOP:
+				if (murrine_widget_is_ltr (widget))
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_TOPLEFT;
+					if (end)
+						params.corners ^= MRN_CORNER_TOPRIGHT;
+				}
+				else
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_TOPRIGHT;
+					if (end)
+						params.corners ^= MRN_CORNER_TOPLEFT;
+				}
+				break;
+			case GTK_POS_BOTTOM:
+				if (murrine_widget_is_ltr (widget))
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_BOTTOMLEFT;
+					if (end)
+						params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+				}
+				else
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+					if (end)
+						params.corners ^= MRN_CORNER_BOTTOMLEFT;
+				}
+				break;
+			case GTK_POS_LEFT:
+				if (start)
+					params.corners ^= MRN_CORNER_TOPLEFT;
+				if (end)
+					params.corners ^= MRN_CORNER_BOTTOMLEFT;
+				break;
+			case GTK_POS_RIGHT:
+				if (start)
+					params.corners ^= MRN_CORNER_TOPRIGHT;
+				if (end)
+					params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+				break;
+		}
+		if (params.roundness < 2)
+			params.corners = MRN_CORNER_NONE;
+
+		/* Fill the background with bg[NORMAL] */
+		clearlooks_rounded_rectangle (cr, x, y, width, height, params.roundness, params.corners);
+
+		if (!params.mrn_gradient.use_rgba)
+		{
+			murrine_set_color_rgb (cr, &colors->bg[0]);
+			cairo_fill (cr);
+		}
+		else
+		{
+			cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+			murrine_set_color_rgba (cr, &colors->bg[0], NOTEBOOK_OPACITY);
+			cairo_fill(cr);
+			cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		}
+
+		STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame,
+		                            x, y, width, height);
+	}
+	else
+	{
+		//printf( "draw_box_gap: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+		GTK_STYLE_CLASS (murrine_style_parent_class)->draw_box_gap (style, cr, state_type, shadow_type,
+		                                                            widget, detail,
+		                                                            x, y, width, height,
+		                                                            gap_side, gap_x, gap_width);
+	}
+}
+
+static void
+murrine_style_draw_extension (DRAW_ARGS, GtkPositionType gap_side)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("tab"))
+	{
+		WidgetParameters params;
+		TabParameters    tab;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		tab.gap_side = (MurrineGapSide)gap_side;
+		switch (gap_side)
+		{
+			case MRN_GAP_TOP:
+				params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+				break;
+			case MRN_GAP_BOTTOM:
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+				break;
+			case MRN_GAP_LEFT:
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+				break;
+			case MRN_GAP_RIGHT:
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+				break;
+		}
+
+		STYLE_FUNCTION(draw_tab) (cr, colors, &params, &tab, x, y, width, height);
+	}
+	else
+	{
+		//printf( "draw_extension: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+		GTK_STYLE_CLASS (murrine_style_parent_class)->draw_extension (style, cr, state_type, shadow_type,
+		                                                              widget, detail, x, y, width, height, gap_side);
+	}
+}
+
+static void
+murrine_style_draw_handle (DRAW_ARGS, GtkOrientation orientation)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("handlebox"))
+	{
+		WidgetParameters params;
+		HandleParameters handle;
+
+		handle.type = MRN_HANDLE_TOOLBAR;
+		handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
+		handle.style = murrine_style->handlestyle;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+
+		STYLE_FUNCTION(draw_handle) (cr, colors, &params, &handle, x, y, width, height);
+	}
+	else if (DETAIL ("paned"))
+	{
+		WidgetParameters params;
+		HandleParameters handle;
+
+		handle.type = MRN_HANDLE_SPLITTER;
+		handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
+		handle.style = murrine_style->handlestyle;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_handle) (cr, colors, &params, &handle, x, y, width, height);
+	}
+	else
+	{
+		WidgetParameters params;
+		HandleParameters handle;
+
+		handle.type = MRN_HANDLE_TOOLBAR;
+		handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
+		handle.style = murrine_style->handlestyle;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_handle) (cr, colors, &params, &handle, x, y, width, height);
+	}
+}
+
+static void
+murrine_style_draw_box (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("menubar") &&
+	    !(widget && (murrine_is_panel_widget (gtk_widget_get_parent (widget)))))
+	{
+		WidgetParameters params;
+		gboolean horizontal;
+		int menubarstyle = murrine_style->menubarstyle;
+		int offset = 0;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (params.mrn_gradient.use_rgba)
+		{
+			params.mrn_gradient.rgba_opacity = MENUBAR_GLOSSY_OPACITY;
+			if (shadow_type == GTK_SHADOW_NONE)
+			{
+				offset = 1;
+				menubarstyle = 0;
+			}
+		}
+
+		horizontal = height < 2*width;
+		params.corners = MRN_CORNER_NONE;
+
+		/* This is not that great. Ideally we would have a nice vertical menubar. */
+		if (params.mrn_gradient.use_rgba ||
+		    ((shadow_type != GTK_SHADOW_NONE) && horizontal))
+			STYLE_FUNCTION(draw_menubar) (cr, colors, &params, x, y,
+			                              width, height+offset, menubarstyle);
+	}
+	else if (DETAIL ("button") && widget && gtk_widget_get_parent (widget) &&
+	         MRN_IS_TREE_VIEW (gtk_widget_get_parent (widget)))
+	{
+		WidgetParameters params;
+		ListViewHeaderParameters header;
+		header.style = murrine_style->listviewheaderstyle;
+
+		gint columns, column_index;
+		gboolean resizable = TRUE;
+
+		/* XXX: This makes unknown treeview header "middle", in need for something nicer */
+		columns = 3;
+		column_index = 1;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_NONE;
+
+		if (MRN_IS_TREE_VIEW (gtk_widget_get_parent (widget)))
+		{
+			murrine_gtk_treeview_get_header_index (GTK_TREE_VIEW(gtk_widget_get_parent (widget)),
+			                                       widget, &column_index, &columns,
+			                                       &resizable);
+		}
+
+		header.resizable = resizable;
+
+		header.order = 0;
+		if (column_index == 0)
+			header.order |= params.ltr ? MRN_ORDER_FIRST : MRN_ORDER_LAST;
+		if (column_index == columns-1)
+			header.order |= params.ltr ? MRN_ORDER_LAST : MRN_ORDER_FIRST;
+
+		gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget), state_type, x, y, width, height);
+
+		STYLE_FUNCTION(draw_list_view_header) (cr, colors, &params, &header, x, y, width, height);
+	}
+	else if (DETAIL ("buttondefault"))
+	{
+		/* We are already checking the default button with the
+		* "murrine_set_widget_parameters" function, so we may occur
+		* in drawing the button two times. Do nothing.
+		*/
+	}
+	else if (DETAIL ("button"))
+	{
+		WidgetParameters params;
+		ButtonParameters button;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.active = shadow_type == GTK_SHADOW_IN;
+
+		/* Default button color */
+		if (murrine_style->has_default_button_color)
+		{
+			murrine_gdk_color_to_rgb (&murrine_style->default_button_color, &button.default_button_color.r,
+				                                                        &button.default_button_color.g,
+				                                                        &button.default_button_color.b);
+			button.has_default_button_color = TRUE;
+		}
+		else
+			button.has_default_button_color = FALSE;
+
+		boolean horizontal = TRUE;
+		if (((float)width/height<0.5) ||
+		    (murrine_style->highlight_shade != 1.0 && murrine_style->glazestyle > 0 && width<height))
+			horizontal = FALSE;
+
+		if ((widget && (MRN_IS_COMBO_BOX_ENTRY (gtk_widget_get_parent (widget)) || MRN_IS_COMBO (gtk_widget_get_parent (widget)))))
+		{
+			if (murrine_style->roundness > 0)
+			{
+				if (params.ltr)
+				{
+					params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+					if (!horizontal)
+						params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+				}
+				else
+				{
+					params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+					if (!horizontal)
+						params.corners = MRN_CORNER_BOTTOMRIGHT | MRN_CORNER_BOTTOMLEFT;
+				}
+			}
+
+			if (params.xthickness > 1)
+			{
+				if (params.ltr)
+					x--;
+				width++;
+			}
+
+			if (murrine_style->reliefstyle > 1)
+				params.reliefstyle = 1;
+		}
+
+		/* Basic hack to theme the task list when x/y thickness == 0 */
+/*		if (gtk_widget_get_parent (widget) && widget->parent->parent && */
+/*                    MRN_IS_PANEL_APPLET(widget->parent->parent))*/
+/*		{*/
+/*			if (params.xthickness == 0 && params.ythickness == 0)*/
+/*			{*/
+/*				x--; width+=1;*/
+/*				y-=2; height+=4;*/
+/*				params.roundness = 0;*/
+/*			}		*/
+/*		}*/
+
+		if (!MRN_IS_COMBO_BOX(gtk_widget_get_parent (widget)) ||
+		     MRN_IS_COMBO_BOX_ENTRY (gtk_widget_get_parent (widget)) ||
+		     MRN_IS_COMBO (gtk_widget_get_parent (widget)))
+			STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, &params, &button, x, y, width, height, horizontal);
+		else
+		{
+			ComboBoxParameters combobox;
+			combobox.as_list = FALSE;
+			combobox.box_w = 24;
+			combobox.style = murrine_style->comboboxstyle;
+			combobox.prelight_shade = murrine_style->prelight_shade;
+
+			gtk_widget_style_get (gtk_widget_get_parent (widget), "appears-as-list", &combobox.as_list, NULL);
+
+			STYLE_FUNCTION(draw_combobox) (cr, murrine_style->colors, params, &combobox, x, y, width, height, horizontal);
+		}
+	}
+	else if (DETAIL ("spinbutton_up") || DETAIL ("spinbutton_down"))
+	{
+		if (state_type == GTK_STATE_ACTIVE)
+		{
+			WidgetParameters params;
+			murrine_set_widget_parameters (widget, style, state_type, &params);
+
+			if (style->xthickness > 1)
+			{
+				width++;
+				if (params.ltr)
+					x--;
+			}
+
+			if (DETAIL ("spinbutton_up"))
+			{
+				height+=2;
+				if (params.ltr)
+					params.corners = MRN_CORNER_TOPRIGHT;
+				else
+					params.corners = MRN_CORNER_TOPLEFT;
+			}
+			else
+			{
+				y--;
+				height++;
+				if (params.ltr)
+					params.corners = MRN_CORNER_BOTTOMRIGHT;
+				else
+					params.corners = MRN_CORNER_BOTTOMLEFT;
+			}
+
+			if (murrine_style->reliefstyle > 1)
+				params.reliefstyle = 1;
+
+			STYLE_FUNCTION(draw_spinbutton_down) (cr, &murrine_style->colors, &params, x, y, width, height);
+		}
+	}
+	else if (DETAIL ("spinbutton"))
+	{
+		WidgetParameters params;
+		SpinbuttonParameters spinbutton;
+
+		/* The "spinbutton" box is always drawn with state NORMAL, even if it is insensitive.
+		 * So work around this here. */
+		if (state_type == GTK_STATE_NORMAL && widget && MRN_IS_ENTRY (widget))
+			state_type = gtk_widget_get_state (widget);
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		spinbutton.style = murrine_style->spinbuttonstyle;
+
+		boolean horizontal = TRUE;
+		if (((float)width/height<0.5) ||
+		    (murrine_style->highlight_shade != 1.0 && murrine_style->glazestyle > 0 && width<height))
+			horizontal = FALSE;
+
+		if (murrine_style->roundness > 0)
+		{
+			if (params.ltr)
+			{
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+				if (!horizontal)
+					params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+			}
+			else
+			{
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+				if (!horizontal)
+					params.corners = MRN_CORNER_BOTTOMRIGHT | MRN_CORNER_BOTTOMLEFT;
+			}
+		}
+
+		if (style->xthickness > 1)
+		{
+			if (params.ltr)
+				x--;
+			width++;
+		}
+
+		if (murrine_style->reliefstyle > 1)
+			params.reliefstyle = 1;
+
+		if (!params.mrn_gradient.use_rgba)
+		{
+			cairo_rectangle (cr, x, y, width, height);
+			murrine_set_color_rgb (cr, &params.parentbg);
+			cairo_fill (cr);
+		}
+
+		STYLE_FUNCTION(draw_spinbutton) (cr, &murrine_style->colors, &params, &spinbutton, x, y, width, height, horizontal);
+	}
+	else if (detail && g_str_has_prefix (detail, "trough") && widget && MRN_IS_SCALE (widget))
+	{
+		WidgetParameters params;
+		SliderParameters slider;
+
+		slider.lower = DETAIL ("trough-lower");
+		slider.fill_level = DETAIL ("trough-fill-level") || DETAIL ("trough-fill-level-full");
+		slider.horizontal = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_ALL;
+
+		STYLE_FUNCTION(draw_scale_trough) (cr, &murrine_style->colors,
+		                                   &params, &slider,
+		                                   x, y, width, height);
+	}
+	else if (DETAIL ("trough") && widget && MRN_IS_PROGRESS_BAR (widget))
+	{
+		WidgetParameters params;
+		ProgressBarParameters progressbar;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		/* Fill the background as it is initilized to base[NORMAL].
+		 * Relevant GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=513471
+		 * The fill only happens if no hint has been added by some application
+		 * that is faking GTK+ widgets. */
+		if (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint"))
+		{
+			cairo_rectangle (cr, 0, 0, width, height);
+			if (!params.mrn_gradient.use_rgba)
+			{
+				murrine_set_color_rgb (cr, &params.parentbg);
+				cairo_fill(cr);
+			}
+			else
+			{
+				cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+				murrine_set_color_rgba (cr, &params.parentbg, WINDOW_OPACITY);
+				cairo_fill(cr);
+				cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+			}
+		}
+
+		if (widget && MRN_IS_PROGRESS_BAR (widget))
+		{			
+			if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL)
+			{
+				if (gtk_progress_bar_get_inverted (GTK_PROGRESS_BAR (widget)))
+					progressbar.orientation = MRN_ORIENTATION_RIGHT_TO_LEFT;
+				else
+					progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+			}
+			else
+			{
+				if (gtk_progress_bar_get_inverted (GTK_PROGRESS_BAR (widget)))
+					progressbar.orientation = MRN_ORIENTATION_BOTTOM_TO_TOP;
+				else
+					progressbar.orientation = MRN_ORIENTATION_TOP_TO_BOTTOM;
+			}	
+		}
+		else
+			progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+
+		if (!params.ltr)
+		{
+			if (progressbar.orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
+				progressbar.orientation = MRN_ORIENTATION_RIGHT_TO_LEFT;
+			else if (progressbar.orientation == MRN_ORIENTATION_RIGHT_TO_LEFT)
+				progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+		}
+
+		STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, &params, &progressbar, x, y, width, height);
+	}
+	else if (DETAIL ("bar"))
+	{
+		WidgetParameters      params;
+		ProgressBarParameters progressbar;
+		gdouble               elapsed = 0.0;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		progressbar.style = murrine_style->progressbarstyle;
+
+		if (widget && MRN_IS_PROGRESS_BAR (widget))
+		{			
+			if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL)
+			{
+				if (gtk_progress_bar_get_inverted (GTK_PROGRESS_BAR (widget)))
+					progressbar.orientation = MRN_ORIENTATION_RIGHT_TO_LEFT;
+				else
+					progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+/*				x-=1;*/
+/*				width+=2;*/
+			}
+			else
+			{
+				if (gtk_progress_bar_get_inverted (GTK_PROGRESS_BAR (widget)))
+					progressbar.orientation = MRN_ORIENTATION_BOTTOM_TO_TOP;
+				else
+					progressbar.orientation = MRN_ORIENTATION_TOP_TO_BOTTOM;
+
+/*				x-=1;*/
+/*				y-=2;*/
+/*				width+=2;*/
+/*				height+=4;*/
+			}	
+		}
+		else
+			progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+
+		if (!params.ltr)
+		{
+			if (progressbar.orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
+				progressbar.orientation = MRN_ORIENTATION_RIGHT_TO_LEFT;
+			else if (progressbar.orientation == MRN_ORIENTATION_RIGHT_TO_LEFT)
+				progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+		}
+
+#ifdef HAVE_ANIMATION
+		if(murrine_style->animation && MRN_IS_PROGRESS_BAR (widget))
+		{
+#warning Assuming non-pulsing progress bars because there is currently no way to query them in GTK+ 3.0.
+			murrine_animation_progressbar_add ((gpointer)widget);
+		}
+
+		elapsed = murrine_animation_elapsed (widget);
+#endif
+
+		/* The x-1 and width+2 are to make the fill cover the left and
+		 * right-hand sides of the trough box */
+
+#ifndef HAVE_ANIMATIONRTL
+		STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, &params, &progressbar,
+		                                       x-1, y, width+2, height,
+		                                       10-(int)(elapsed*10.0) % 10);
+#else
+		STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, &params, &progressbar,
+		                                       x-1, y, width+2, height,
+		                                       10+(int)(elapsed*10.0) % 10);
+#endif
+	}
+	else if (DETAIL ("entry-progress"))
+	{
+		WidgetParameters params;
+		EntryProgressParameters progress;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		progress.max_size_known = FALSE;
+		progress.max_size.x = 0;
+		progress.max_size.y = 0;
+		progress.max_size.width = 0;
+		progress.max_size.height = 0;
+		progress.border.left = style->xthickness;
+		progress.border.right = style->xthickness;
+		progress.border.top = style->ythickness;
+		progress.border.bottom = style->ythickness;
+
+		if (MRN_IS_ENTRY (widget))
+		{
+			GtkBorder *border;
+			/* Try to retrieve the style property. */
+			gtk_widget_style_get (widget,
+			                      "progress-border", &border,
+			                      NULL);
+
+			if (border)
+			{
+				progress.border = *border;
+				gtk_border_free (border);
+			}
+
+			/* We got an entry, but well, we may not be drawing to
+			 * this particular widget ... it may not even be realized.
+			 * Also, we need to be drawing on a window obviously ... */
+			if (gtk_widget_get_realized (widget) &&
+			    gdk_window_is_visible (gtk_widget_get_window (widget)))
+			{
+				/* Assumptions done by this code:
+				 *  - GtkEntry has some nested windows.
+				 *  - gtk_widget_get_window (widget) is the entries window
+				 *  - gtk_widget_get_window (widget) is the size of the entry part
+				 *    (and not larger)
+				 *  - only one layer of subwindows
+				 * These should be true with any GTK+ 2.x version.
+				 */
+
+	                        progress.max_size_known = TRUE;
+                                progress.max_size.width = gdk_window_get_width (gtk_widget_get_window (widget));
+                                progress.max_size.height = gdk_window_get_height (gtk_widget_get_window (widget));
+
+				/* Now, one more thing needs to be done. If interior-focus
+				 * is off, then the entry may be a bit smaller. */
+				if (progress.max_size_known && gtk_widget_has_focus (widget))
+				{
+					gboolean interior_focus = TRUE;
+					gint focus_line_width = 1;
+
+					gtk_widget_style_get (widget,
+					                      "interior-focus", &interior_focus,
+					                      "focus-line-width", &focus_line_width,
+					                      NULL);
+
+					if (!interior_focus)
+					{
+						progress.max_size.x += focus_line_width;
+						progress.max_size.y += focus_line_width;
+						progress.max_size.width -= 2*focus_line_width;
+						progress.max_size.height -= 2*focus_line_width;
+					}
+				}
+
+				if (progress.max_size_known)
+				{
+					progress.max_size.x += progress.border.left;
+					progress.max_size.y += progress.border.top;
+					progress.max_size.width -= progress.border.left + progress.border.right;
+					progress.max_size.height -= progress.border.top + progress.border.bottom;
+
+					/* Now test that max_size.height == height, if that
+					 * fails, something has gone wrong ... so then throw away
+					 * the max_size information. */
+					if (progress.max_size.height != height)
+					{
+						progress.max_size_known = FALSE;
+						progress.max_size.x = 0;
+						progress.max_size.y = 0;
+						progress.max_size.width = 0;
+						progress.max_size.height = 0;
+					}
+				}
+			}
+		}
+
+		STYLE_FUNCTION(draw_entry_progress) (cr, colors, &params, &progress,
+		                                     x, y, width, height);
+	}
+	else if (DETAIL ("hscale") || DETAIL ("vscale"))
+	{
+		WidgetParameters params;
+		SliderParameters slider; 
+		ButtonParameters button;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		button.has_default_button_color = FALSE;
+
+		boolean horizontal = TRUE;
+		/* Different heuristic:
+		 * if (DETAIL ("vscale"))
+		 *	horizontal = FALSE;
+		 */
+
+		slider.horizontal = TRUE;
+		if (DETAIL ("vscale"))
+			slider.horizontal = FALSE;
+
+		if (height > width)
+			horizontal = !horizontal;
+
+		/* Use reliefstyle to remove inset on disabled slider button */
+		if (params.disabled)
+			params.reliefstyle = 0;
+		
+		if (murrine_style->sliderstyle < 2)
+			STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, &params, &button, x, y, width, height, horizontal);
+		else
+			STYLE_FUNCTION(draw_slider) (cr, &murrine_style->colors, &params, &slider, x, y, width-1, height-1);
+
+		if (murrine_style->sliderstyle == 1 || murrine_style->sliderstyle == 3)
+		{
+			HandleParameters handle;
+			handle.style = murrine_style->handlestyle;
+
+			STYLE_FUNCTION(draw_slider_handle) (cr, &murrine_style->colors, &params, &handle, x, y, width, height, horizontal);
+		}
+	}
+	else if (DETAIL ("menuitem"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (widget && !(MRN_IS_MENU_BAR (gtk_widget_get_parent (widget)) && murrine_style->menubaritemstyle))
+		{
+			if (murrine_style->menustyle != 1 || (MRN_IS_MENU_BAR (gtk_widget_get_parent (widget)) && !murrine_style->menubaritemstyle))
+				STYLE_FUNCTION(draw_menuitem) (cr, colors, &params, x, y, width, height, murrine_style->menuitemstyle);
+			else
+				STYLE_FUNCTION(draw_menuitem) (cr, colors, &params, x+3, y, width-3, height, murrine_style->menuitemstyle);
+		}
+
+		if (widget && MRN_IS_MENU_BAR (gtk_widget_get_parent (widget)) && murrine_style->menubaritemstyle)
+		{
+			ButtonParameters button;
+			button.has_default_button_color = FALSE;
+
+			params.active = FALSE;
+			params.prelight = TRUE;
+			params.focus = TRUE;
+			params.state_type = GTK_STATE_SELECTED;
+			params.xthickness = 2;
+			params.ythickness = 2;
+			params.reliefstyle = 0;
+			params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_TOPLEFT;
+
+			STYLE_FUNCTION(draw_button) (cr, colors, &params, &button, x, y, width, height+1, TRUE);
+		}
+	}
+	else if (detail && (g_str_has_prefix (detail, "hscrollbar") || g_str_has_prefix (detail, "vscrollbar"))) /* This can't be "stepper" for scrollbars ... */
+	{
+		WidgetParameters    params;
+		ScrollBarParameters scrollbar;
+		boolean within_bevel = FALSE;
+
+		scrollbar.has_color      = FALSE;
+		scrollbar.horizontal     = TRUE;
+		scrollbar.junction       = murrine_scrollbar_get_junction (widget);
+		scrollbar.handlestyle    = murrine_style->handlestyle;
+		scrollbar.style          = murrine_style->scrollbarstyle;
+		scrollbar.stepperstyle   = murrine_style->stepperstyle;
+		scrollbar.prelight_shade = murrine_style->prelight_shade;
+		gtk_widget_style_get (widget, "stepper-size", &scrollbar.steppersize, NULL);
+
+		scrollbar.horizontal = g_str_has_prefix (detail, "hscrollbar");
+
+		if (murrine_style->colorize_scrollbar)
+		{
+			scrollbar.color = colors->spot[1];
+			scrollbar.has_color = TRUE;
+		}
+		else
+			scrollbar.color = colors->bg[0];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_NONE;
+
+		if (murrine_style->roundness > 1)
+		{
+			ScrollBarStepperParameters stepper;
+			GdkRectangle this_rectangle = { x, y, width, height };
+
+			if (g_str_equal(detail + 10, "_start"))
+				stepper.stepper = MRN_STEPPER_START;
+			else if (g_str_equal(detail + 10, "_end"))
+				stepper.stepper = MRN_STEPPER_END;
+			else if (g_str_equal(detail + 10, "_start_inner"))
+				stepper.stepper = MRN_STEPPER_START_INNER;
+			else if (g_str_equal(detail + 10, "_end_inner"))
+				stepper.stepper = MRN_STEPPER_END_INNER;
+			else
+				stepper.stepper = MRN_STEPPER_UNKNOWN;
+
+			/* XXX Check later for corners - might be OK 20101013 */
+
+			if (scrollbar.horizontal)
+			{
+				if (stepper.stepper == MRN_STEPPER_START)
+					params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+				else if (stepper.stepper == MRN_STEPPER_END)
+					params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+			}
+			else
+			{
+				if (stepper.stepper == MRN_STEPPER_START)
+					params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_TOPLEFT;
+				else if (stepper.stepper == MRN_STEPPER_END)
+					params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+			}
+		}
+		else if (murrine_style->roundness == 1)
+			params.corners = MRN_CORNER_ALL;
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		if (gtk_widget_get_parent (widget) && MRN_IS_SCROLLED_WINDOW (gtk_widget_get_parent (widget)))
+			gtk_widget_style_get (gtk_widget_get_parent (widget), "scrollbars-within-bevel", &within_bevel, NULL);
+
+		if (within_bevel)
+			params.corners = MRN_CORNER_NONE;
+
+		if (scrollbar.stepperstyle == 2)
+			params.corners = MRN_CORNER_NONE;
+
+		if (scrollbar.stepperstyle != 1 && scrollbar.stepperstyle != 3)
+			STYLE_FUNCTION(draw_scrollbar_stepper) (cr, colors, &params, &scrollbar, x, y, width, height);
+	}
+	else if (DETAIL ("toolbar") || DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin"))
+	{
+		WidgetParameters params;
+		ToolbarParameters toolbar;
+		gboolean horizontal;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		murrine_set_toolbar_parameters (&toolbar, widget, x, y);
+		toolbar.style = murrine_style->toolbarstyle;
+
+		if ((DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin")) && MRN_IS_BIN (widget))
+		{
+			GtkWidget* child = gtk_bin_get_child ((GtkBin*) widget);
+			/* This is to draw the correct shadow on the handlebox.
+			 * We need to draw it here, as otherwise the handle will not get the
+			 * background. */
+			if (MRN_IS_TOOLBAR (child))
+				gtk_widget_style_get (child, "shadow-type", &shadow_type, NULL);
+		}
+
+		horizontal = height < 2*width;
+		params.corners = MRN_CORNER_NONE;
+
+		/* This is not that great. Ideally we would have a nice vertical toolbar. */
+		if ((shadow_type != GTK_SHADOW_NONE) && horizontal)
+			STYLE_FUNCTION(draw_toolbar) (cr, colors, &params, &toolbar, x, y, width, height);
+	}
+	else if (DETAIL ("trough"))
+	{
+		/* Do nothing? */
+	}
+	else if (DETAIL ("menu"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_menu_frame) (cr, colors, &params, x, y, width, height, murrine_style->menustyle);
+	}
+	else if (DETAIL ("infobar") ||
+	         DETAIL ("infobar-error") ||
+	         DETAIL ("infobar-info") ||
+	         DETAIL ("infobar-question") ||
+	         DETAIL ("infobar-warning"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_tooltip) (cr, colors, &params, x, y, width, height);
+	}
+	else if (DETAIL ("hseparator") || DETAIL ("vseparator"))
+	{
+		gchar *new_detail = (gchar*) detail;
+		/* Draw a normal separator, we just use this because it gives more control
+		 * over sizing (currently). */
+
+		/* This isn't nice ... but it seems like the best cleanest way to me right now.
+		 * It will get slightly nicer in the future hopefully. */
+		if (MRN_IS_MENU_ITEM (widget))
+			new_detail = "menuitem";
+
+		if (DETAIL ("hseparator"))
+		{
+			gtk_paint_hline (style, cr, state_type, widget, new_detail,
+			                 x, x+width-1, y+height/2);
+		}
+		else
+			gtk_paint_vline (style, cr, state_type, widget, new_detail,
+			                 y, y+height-1, x+width/2);
+	}
+	else
+	{
+		//printf( "draw_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+		GTK_STYLE_CLASS (murrine_style_parent_class)->draw_box (style, cr, state_type, shadow_type,
+		                                                        widget, detail, x, y, width, height);
+	}
+}
+
+static void
+murrine_style_draw_slider (DRAW_ARGS, GtkOrientation orientation)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("hscale") || DETAIL ("vscale"))
+	{
+		murrine_style_draw_box (style, cr, state_type, shadow_type,
+		                        widget, detail, x, y, width, height);
+	}
+	else if (DETAIL ("slider"))
+	{
+		WidgetParameters    params;
+		ScrollBarParameters scrollbar;
+		boolean within_bevel = FALSE;
+
+		scrollbar.has_color      = FALSE;
+		scrollbar.horizontal     = (orientation == GTK_ORIENTATION_HORIZONTAL);
+		scrollbar.junction       = murrine_scrollbar_get_junction (widget);
+		scrollbar.handlestyle    = murrine_style->handlestyle;
+		scrollbar.style          = murrine_style->scrollbarstyle;
+		scrollbar.stepperstyle   = murrine_style->stepperstyle;
+		scrollbar.prelight_shade = murrine_style->prelight_shade;
+		gtk_widget_style_get (widget, "stepper-size", &scrollbar.steppersize, NULL);
+
+		if (murrine_style->colorize_scrollbar)
+		{
+			scrollbar.color = colors->spot[1];
+			scrollbar.has_color = TRUE;
+		}
+		else
+			scrollbar.color = colors->bg[0];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_NONE;
+
+		int trough_border = 0;
+		int trough_under_steppers = 1;
+
+		gtk_widget_style_get (widget,
+		                      "trough-border", &trough_border,
+		                      "trough-under-steppers", &trough_under_steppers,
+		                      NULL);
+
+		if (trough_border > 0 ||
+		    trough_under_steppers == 0 ||
+		    scrollbar.stepperstyle == 2 ||
+		    scrollbar.stepperstyle == 3 ||
+		    murrine_style->roundness == 1)
+			params.corners = MRN_CORNER_ALL;
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_scrollbar_slider) (cr, colors, &params, &scrollbar, x, y, width, height);
+	}
+	else
+		GTK_STYLE_CLASS (murrine_style_parent_class)->draw_slider (style, cr, state_type, shadow_type,
+		                                                           widget, detail, x, y, width, height, orientation);
+}
+
+static void
+murrine_style_draw_option (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	WidgetParameters params;
+	CheckboxParameters checkbox;
+
+	checkbox.shadow_type = shadow_type;
+	checkbox.in_cell = DETAIL ("cellradio");
+	checkbox.in_menu = (widget && gtk_widget_get_parent (widget) && GTK_IS_MENU(gtk_widget_get_parent (widget)));
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	double trans = 1.0;
+
+#ifdef HAVE_ANIMATION
+	if (murrine_style->animation)
+		murrine_animation_connect_checkbox (widget);
+
+	if (murrine_style->animation &&
+	    MRN_IS_CHECK_BUTTON (widget) &&
+	    murrine_animation_is_animated (widget) &&
+	    !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (widget)))
+	{
+		gfloat elapsed = murrine_animation_elapsed (widget);
+		trans = sqrt (sqrt (MIN (elapsed/CHECK_ANIMATION_TIME, 1.0)));
+	}
+#endif
+
+	STYLE_FUNCTION(draw_radiobutton) (cr, colors, &params, &checkbox, x, y, width, height, trans);
+}
+
+static void
+murrine_style_draw_check (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	WidgetParameters params;
+	CheckboxParameters checkbox;
+
+	checkbox.shadow_type = shadow_type;
+	checkbox.in_cell = DETAIL ("cellcheck");
+	checkbox.in_menu = (widget && gtk_widget_get_parent (widget) && GTK_IS_MENU(gtk_widget_get_parent (widget)));
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	double trans = 1.0;
+
+#ifdef HAVE_ANIMATION
+	if (murrine_style->animation)
+		murrine_animation_connect_checkbox (widget);
+
+	if (murrine_style->animation && MRN_IS_CHECK_BUTTON (widget) &&
+	    murrine_animation_is_animated (widget) &&
+	    !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (widget)))
+	{
+		gfloat elapsed = murrine_animation_elapsed (widget);
+		trans = sqrt (sqrt (MIN (elapsed/CHECK_ANIMATION_TIME, 1.0)));
+	}
+#endif
+
+	STYLE_FUNCTION(draw_checkbox) (cr, colors, &params, &checkbox, x, y, width, height, trans);
+}
+
+static void
+murrine_style_draw_tab (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	WidgetParameters params;
+	ArrowParameters  arrow;
+
+	arrow.type      = MRN_ARROW_COMBO;
+	arrow.direction = MRN_DIRECTION_DOWN;
+	arrow.style     = murrine_style->arrowstyle;
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	STYLE_FUNCTION(draw_arrow) (cr, colors, &params, &arrow, x, y, width, height);
+}
+
+static void
+murrine_style_draw_vline (GtkStyle     *style,
+                          cairo_t      *cr,
+                          GtkStateType  state_type,
+                          GtkWidget    *widget,
+                          const gchar  *detail,
+                          gint          y1,
+                          gint          y2,
+                          gint          x)
+{
+	/* Get toplevel window for this widget */
+	GtkWidget* toplevel = gtk_widget_get_toplevel (widget);
+
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	SeparatorParameters separator;
+	separator.horizontal = FALSE;
+	separator.style = murrine_style->separatorstyle;
+
+	WidgetParameters params;
+
+	params.contrast = murrine_style->contrast;
+	params.style = MRN_STYLE_MURRINE;
+	if (murrine_widget_is_rgba (toplevel))
+	{
+		params.style = MRN_STYLE_RGBA;
+	}
+
+	if (!(widget &&
+	    MRN_IS_HBOX (gtk_widget_get_parent (widget)) &&
+	    MRN_IS_TOGGLE_BUTTON (gtk_widget_get_parent (gtk_widget_get_parent (widget))) &&
+	    MRN_IS_COMBO_BOX (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (widget))))))
+	{
+		STYLE_FUNCTION(draw_separator) (cr, colors, &params, &separator, x, y1, 2, y2-y1);
+	}
+}
+
+static void
+murrine_style_draw_hline (GtkStyle     *style,
+                          cairo_t      *cr,
+                          GtkStateType  state_type,
+                          GtkWidget    *widget,
+                          const gchar  *detail,
+                          gint          x1,
+                          gint          x2,
+                          gint          y)
+{
+	/* Get toplevel window for this widget */
+	GtkWidget* toplevel = gtk_widget_get_toplevel (widget);
+
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	SeparatorParameters separator;
+	separator.horizontal = TRUE;
+	separator.style = murrine_style->separatorstyle;
+
+	WidgetParameters params;
+
+	params.contrast = murrine_style->contrast;
+	params.style = MRN_STYLE_MURRINE;
+	if (murrine_widget_is_rgba (toplevel))
+	{
+		params.style = MRN_STYLE_RGBA;
+	}
+
+	STYLE_FUNCTION(draw_separator) (cr, colors, &params, &separator, x1, y, x2-x1, 2);
+}
+
+static void
+murrine_style_draw_shadow_gap (DRAW_ARGS,
+                               GtkPositionType gap_side,
+                               gint            gap_x,
+                               gint            gap_width)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	const MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	if (DETAIL ("frame"))
+	{
+		WidgetParameters params;
+		FrameParameters  frame;
+
+		frame.shadow    = shadow_type;
+		frame.gap_side  = gap_side;
+		frame.gap_x     = gap_x;
+		frame.gap_width = gap_width;
+		frame.border    = (MurrineRGB*)&colors->shade[4];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (params.roundness < 2)
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame, x, y, width, height);
+	}
+	else
+	{
+		GTK_STYLE_CLASS (murrine_style_parent_class)->draw_shadow_gap (style, cr, state_type, shadow_type,
+		                                                               widget, detail, x, y, width, height,
+		                                                               gap_side, gap_x, gap_width);
+	}
+}
+
+static void
+murrine_style_draw_resize_grip (GtkStyle      *style,
+                                cairo_t       *cr,
+                                GtkStateType  state_type,
+                                GtkWidget     *widget,
+                                const gchar   *detail,
+                                GdkWindowEdge edge,
+                                gint          x,
+                                gint          y,
+                                gint          width,
+                                gint          height)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	WidgetParameters params;
+	ResizeGripParameters grip;
+	grip.edge = (MurrineWindowEdge)edge;
+
+	int lx, ly;
+
+	if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
+		return; /* sorry... need to work on this :P */
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	STYLE_FUNCTION(draw_resize_grip) (cr, colors, &params, &grip, x, y, width, height);
+
+	return;
+}
+
+static void
+murrine_style_draw_arrow (GtkStyle     *style,
+                          cairo_t      *cr,
+                          GtkStateType  state_type,
+                          GtkShadowType shadow,
+                          GtkWidget     *widget,
+                          const gchar   *detail,
+                          GtkArrowType  arrow_type,
+                          gboolean      fill,
+                          gint          x,
+                          gint          y,
+                          gint          width,
+                          gint          height)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	WidgetParameters params;
+	ArrowParameters  arrow;
+
+	if (arrow_type == GTK_ARROW_NONE)
+	{
+		return;
+	}
+
+	arrow.type = MRN_ARROW_NORMAL;
+	arrow.direction = (MurrineDirection)arrow_type;
+	arrow.style = murrine_style->arrowstyle;
+
+	if (MRN_IS_COMBO_BOX (widget) && !MRN_IS_COMBO_BOX_ENTRY (widget))
+	{
+		arrow.type = MRN_ARROW_COMBO;
+	}
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	if (arrow.style == 1 || arrow.style == 2)
+	{
+		if (DETAIL ("menuitem"))
+		{
+			if (arrow.direction == MRN_DIRECTION_UP || arrow.direction == MRN_DIRECTION_DOWN)
+			{
+				x = x + width / 2 - 2;
+				y = y + height / 2 - 2;
+				height = 4; width = 5;
+			}
+			else
+			{
+				x = x + width / 2 - 2;
+				y = y + height / 2 - 2;
+				height = 5; width = 4;
+			}
+		}
+		else if (g_str_has_prefix (detail, "hscrollbar") || g_str_has_prefix (detail, "vscrollbar"))
+		{
+			int steppersize;
+			gtk_widget_style_get (widget, "stepper-size", &steppersize, NULL);	
+
+			switch (arrow.direction)
+			{
+				case MRN_DIRECTION_UP:
+					x += width/2 - 2;
+					y += height/2 - steppersize % 2 == 0 ? 2 : 1;
+					height = 4; width = 5;
+					break;
+				case MRN_DIRECTION_DOWN:
+					x += width/2 - 2;
+					y += height/2 - 1;
+					height = 4; width = 5;
+					break;
+				case MRN_DIRECTION_LEFT:
+					x += width/2 - steppersize % 2 == 0 ? 2 : 1;
+					y += height/2 - 2;
+					height = 5; width = 4;
+					break;
+				case MRN_DIRECTION_RIGHT:
+					x += width/2 - 1;
+					y += height/2 - 2;
+					height = 5; width = 4;
+					break;
+			}
+			
+			if (arrow.style == 2)
+			{	
+				switch (arrow.direction)
+				{
+					case MRN_DIRECTION_UP:
+						y+=steppersize % 2 == 0 ? 1 : 2;
+						break;
+					case MRN_DIRECTION_DOWN:
+						y-=2;
+						break;
+					case MRN_DIRECTION_LEFT:
+						x+=steppersize % 2 == 0 ? 1 : 2;;
+						break;
+					case MRN_DIRECTION_RIGHT:
+						x--;
+						break;
+				}
+			}
+		}
+		else if (DETAIL ("spinbutton"))
+		{
+			x = x + width / 2 - 2;
+			y = y + height / 2 - 1;
+			height = 4; width = 5;
+
+			if (arrow.style == 2)
+			{
+				if (arrow.direction == MRN_DIRECTION_UP)
+					y++;
+				if (arrow.direction == MRN_DIRECTION_DOWN)
+					y-=2;
+			}
+			else
+			{
+				if (arrow.direction == MRN_DIRECTION_UP)
+					y--;
+			}
+		}
+		else if (arrow.direction == MRN_DIRECTION_UP || arrow.direction == MRN_DIRECTION_DOWN)
+		{
+			x = x + width / 2 - 3;
+			y = y + height / 2 - 2;
+			height = 6; width = 7;
+		}
+		else
+		{
+			x = x + width / 2 - 2;
+			y = y + height / 2 - 3;
+			height = 7; width = 6;
+		}
+	}
+
+	STYLE_FUNCTION(draw_arrow) (cr, colors, &params, &arrow, x, y, width, height);
+}
+
+static void
+murrine_style_draw_layout (GtkStyle     *style,
+                           cairo_t      *cr,
+                           GtkStateType state_type,
+                           gboolean     use_text,
+                           GtkWidget    *widget,
+                           const gchar  *detail, gint x, gint y,
+                           PangoLayout  *layout)
+{
+	CHECK_ARGS
+
+	murrine_transform_for_layout (cr, layout, x, y);
+
+	if (widget && (state_type == GTK_STATE_INSENSITIVE || 
+	    (MURRINE_STYLE (style)->textstyle != 0 &&
+	     state_type != GTK_STATE_PRELIGHT &&
+	     !(DETAIL ("cellrenderertext") && state_type == GTK_STATE_NORMAL))))
+	{
+		MurrineStyle *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+	
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		MurrineRGB temp;
+
+		double shade_level = murrine_style->text_shade;
+		double xos = 0;
+		double yos = 0;
+
+		switch (murrine_style->textstyle)
+		{
+			case 1:
+				yos = +0.5;
+				break;
+			case 2:
+				yos = -0.5;
+				break;
+			case 3:
+				xos = 0.5;
+				yos = 0.5;
+				break;
+			case 4:
+				xos = -0.5;
+				yos = -0.5;
+				break;
+		}
+
+		if (state_type == GTK_STATE_INSENSITIVE)
+		{
+			shade_level = 1.24;
+			xos = 0.5;
+			yos = 0.5;
+		}
+
+		if (!gtk_widget_get_has_window (widget))
+		{
+			boolean use_parentbg = TRUE;
+			while (gtk_widget_get_parent (widget))
+			{
+				if (MRN_IS_BUTTON(gtk_widget_get_parent (widget)) ||
+				    MRN_IS_TOGGLE_BUTTON(gtk_widget_get_parent (widget)) ||
+				    MRN_IS_COMBO_BOX(gtk_widget_get_parent (widget)) ||
+				    MRN_IS_COMBO_BOX_ENTRY(gtk_widget_get_parent (widget)) ||
+				    MRN_IS_COMBO(gtk_widget_get_parent (widget)) ||
+				    MRN_IS_NOTEBOOK(gtk_widget_get_parent (widget)))
+				{
+					GtkReliefStyle relief = GTK_RELIEF_NORMAL;
+					/* Check for the shadow type. */
+					if (MRN_IS_BUTTON (gtk_widget_get_parent (widget)))
+						g_object_get (G_OBJECT (gtk_widget_get_parent (widget)), "relief", &relief, NULL);
+
+					if (!MRN_IS_CHECK_BUTTON(gtk_widget_get_parent (widget)) &&
+					    !MRN_IS_RADIO_BUTTON(gtk_widget_get_parent (widget)) &&
+					    !(relief == GTK_RELIEF_NONE &&
+					      (state_type == GTK_STATE_NORMAL ||
+					       state_type == GTK_STATE_INSENSITIVE)))
+						use_parentbg = FALSE;
+
+					break;
+				}
+				widget = gtk_widget_get_parent (widget);
+			}
+
+			if (use_parentbg)
+				murrine_shade (&params.parentbg, shade_level, &temp);
+			else
+				murrine_shade (use_text ? &colors->base[state_type] : &colors->bg[state_type], shade_level, &temp);
+		}
+		else
+			murrine_shade (use_text ? &colors->base[state_type] : &colors->bg[state_type], shade_level, &temp);
+
+		cairo_save (cr);
+
+		/* XXX or cairo_move_to (cr, xos, yos); */
+		cairo_translate (cr, xos, yos); 
+		pango_cairo_layout_path (cr, layout);
+		murrine_set_color_rgba (cr, &temp, 0.5);
+		cairo_stroke (cr);
+
+		cairo_restore (cr);
+/*		printf( "draw_layout: %s %s\n", detail, G_OBJECT_TYPE_NAME (gtk_widget_get_parent (widget)));*/
+	}
+
+	if (DETAIL ("accellabel"))
+	{
+		MurrineStyle *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		MurrineRGB temp;
+
+		murrine_mix_color (&colors->fg[state_type], &params.parentbg, state_type != GTK_STATE_PRELIGHT ? 0.4 : 0.2, &temp);
+
+		murrine_set_color_rgb (cr, &temp);
+
+        	pango_cairo_show_layout (cr, layout);
+	}
+	else
+	{
+		gdk_cairo_set_source_color (cr, use_text ? &style->text[state_type] : &style->fg[state_type]);
+
+		pango_cairo_show_layout (cr, layout);
+	}
+}
+
+static void
+murrine_style_draw_expander (GtkStyle        *style,
+                             cairo_t         *cr,
+                             GtkStateType     state_type,
+                             GtkWidget       *widget,
+                             const gchar     *detail,
+                             gint             x,
+                             gint             y,
+                             GtkExpanderStyle expander_style)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	CHECK_ARGS
+
+	WidgetParameters params;
+	ExpanderParameters expander;
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	if (widget && gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget), "expander-size"))
+		gtk_widget_style_get (widget, "expander-size", &expander.size, NULL);
+	else
+		expander.size = 7;
+
+	expander.expander_style = expander_style;
+	expander.text_direction = murrine_get_direction (widget);
+	expander.arrowstyle = murrine_style->arrowstyle;
+	expander.style = murrine_style->expanderstyle;
+
+	STYLE_FUNCTION(draw_expander) (cr, colors, &params, &expander, x, y);
+}
+
+static void
+murrine_style_draw_focus (GtkStyle *style, cairo_t *cr, GtkStateType state_type,
+                          GtkWidget *widget, const gchar *detail,
+                          gint x, gint y, gint width, gint height)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	WidgetParameters params;
+	FocusParameters focus;
+	guint8* dash_list;
+
+	CHECK_ARGS
+
+	/* Just return if focus drawing is disabled. */
+	if (murrine_style->focusstyle == 0)
+		return;
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	/* Corners */
+	if (widget && gtk_widget_get_parent (widget) && MRN_IS_COMBO_BOX_ENTRY(gtk_widget_get_parent (widget)))
+	{
+		if (params.ltr)
+			params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+		else
+			params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+
+		if (params.xthickness > 2)
+		{
+			if (params.ltr)
+				x--;
+			width++;
+		}
+	}
+
+	focus.has_color = FALSE;
+	focus.interior = FALSE;
+	focus.line_width = 1;
+	focus.padding = 1;
+	focus.style = murrine_style->focusstyle;
+	dash_list = NULL;
+
+	if (widget)
+	{
+		gtk_widget_style_get (widget,
+		                      "focus-line-width", &focus.line_width,
+		                      "focus-line-pattern", &dash_list,
+		                      "focus-padding", &focus.padding,
+		                      "interior-focus", &focus.interior,
+		                      NULL);
+	}
+	if (dash_list)
+		focus.dash_list = dash_list;
+	else
+		focus.dash_list = (guint8*) g_strdup ("\1\1");
+
+	/* Focus type */
+	if (DETAIL("button"))
+	{
+		if (widget && gtk_widget_get_parent (widget) &&
+		    (MRN_IS_TREE_VIEW (gtk_widget_get_parent (widget))))
+		{
+			focus.type = MRN_FOCUS_TREEVIEW_HEADER;
+		}
+		else
+		{
+			GtkReliefStyle relief = GTK_RELIEF_NORMAL;
+			/* Check for the shadow type. */
+			if (widget && GTK_IS_BUTTON (widget))
+				g_object_get (G_OBJECT (widget), "relief", &relief, NULL);
+
+
+			if (relief == GTK_RELIEF_NORMAL)
+			{
+				if (widget && gtk_widget_has_default (widget))
+					focus.type = MRN_FOCUS_BUTTON_DEFAULT;
+				else
+					focus.type = MRN_FOCUS_BUTTON;
+			}
+			else
+				focus.type = MRN_FOCUS_BUTTON_FLAT;
+
+			/* Workaround for the panel. */
+			if (murrine_object_is_a (G_OBJECT (widget), "ButtonWidget"))
+				focus.type = MRN_FOCUS_LABEL;
+		}
+	}
+	else if (detail && g_str_has_prefix (detail, "treeview"))
+	{
+		/* Focus in a treeview, and that means a lot of different detail strings. */
+		if (g_str_has_prefix (detail, "treeview-drop-indicator"))
+			focus.type = MRN_FOCUS_TREEVIEW_DND;
+		else
+			focus.type = MRN_FOCUS_TREEVIEW_ROW;
+
+		if (g_str_has_suffix (detail, "left"))
+		{
+			focus.continue_side = MRN_CONT_RIGHT;
+		}
+		else if (g_str_has_suffix (detail, "right"))
+		{
+			focus.continue_side = MRN_CONT_LEFT;
+		}
+		else if (g_str_has_suffix (detail, "middle"))
+		{
+			focus.continue_side = MRN_CONT_LEFT | MRN_CONT_RIGHT;
+		}
+		else
+		{
+			/* This may either mean no continuation, or unknown ...
+			 * if it is unknown we assume it continues on both sides */
+			gboolean row_ending_details = FALSE;
+
+			/* Try to get the style property. */
+			if (widget)
+				gtk_widget_style_get (widget,
+				                      "row-ending-details", &row_ending_details,
+				                      NULL);
+
+			if (row_ending_details)
+				focus.continue_side = MRN_CONT_NONE;
+			else
+				focus.continue_side = MRN_CONT_LEFT | MRN_CONT_RIGHT;
+		}
+
+	}
+	else if (detail && g_str_has_prefix (detail, "trough") && MRN_IS_SCALE (widget))
+	{
+		focus.type = MRN_FOCUS_SCALE;
+	}
+	else if (DETAIL("tab"))
+	{
+		focus.type = MRN_FOCUS_TAB;
+	}
+	else if (detail && g_str_has_prefix (detail, "colorwheel"))
+	{
+		if (DETAIL ("colorwheel_dark"))
+			focus.type = MRN_FOCUS_COLOR_WHEEL_DARK;
+		else
+			focus.type = MRN_FOCUS_COLOR_WHEEL_LIGHT;
+	}
+	else if (DETAIL("checkbutton") || DETAIL("radiobutton") || DETAIL("expander"))
+	{
+		focus.type = MRN_FOCUS_LABEL; /* Let's call it "LABEL" :) */
+	}
+	else if (widget && MRN_IS_TREE_VIEW (widget))
+	{
+		focus.type = MRN_FOCUS_TREEVIEW; /* Treeview without content is focused. */
+	}
+	else if (DETAIL("icon_view"))
+	{
+		focus.type = MRN_FOCUS_ICONVIEW;
+	}
+	else
+	{
+		focus.type = MRN_FOCUS_UNKNOWN; /* Custom widgets (Beagle) and something unknown */
+	}
+
+	/* Focus color */
+	if (murrine_style->has_focus_color)
+	{
+		murrine_gdk_color_to_rgb (&murrine_style->focus_color, &focus.color.r,
+		                                                       &focus.color.g,
+		                                                       &focus.color.b);
+		focus.has_color = TRUE;
+	}
+	else
+		focus.color = colors->bg[GTK_STATE_SELECTED];
+
+	STYLE_FUNCTION(draw_focus) (cr, colors, &params, &focus, x, y, width, height);
+
+	g_free (focus.dash_list);
+}
+
+static void
+murrine_style_init_from_rc (GtkStyle   *style,
+                            GtkRcStyle *rc_style)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+
+	GTK_STYLE_CLASS (murrine_style_parent_class)->init_from_rc (style, rc_style);
+
+	/* Shades/Colors/Ratio */
+	murrine_style->border_shades[0]   = MURRINE_RC_STYLE (rc_style)->border_shades[0];
+	murrine_style->border_shades[1]   = MURRINE_RC_STYLE (rc_style)->border_shades[1];
+	murrine_style->glow_shade         = MURRINE_RC_STYLE (rc_style)->glow_shade;
+	murrine_style->highlight_shade    = MURRINE_RC_STYLE (rc_style)->highlight_shade;
+	murrine_style->gradient_shades[0] = MURRINE_RC_STYLE (rc_style)->gradient_shades[0];
+	murrine_style->gradient_shades[1] = MURRINE_RC_STYLE (rc_style)->gradient_shades[1];
+	murrine_style->gradient_shades[2] = MURRINE_RC_STYLE (rc_style)->gradient_shades[2];
+	murrine_style->gradient_shades[3] = MURRINE_RC_STYLE (rc_style)->gradient_shades[3];
+	/* This is required to avoid glitches on different glazestyles */
+	if (MURRINE_RC_STYLE (rc_style)->glazestyle != 0)
+	{
+		double gradient_stop_mid = ((murrine_style->gradient_shades[1])+
+		                            (murrine_style->gradient_shades[2]))/2.0;
+		murrine_style->gradient_shades[1] = gradient_stop_mid;
+		murrine_style->gradient_shades[2] = gradient_stop_mid;
+	}
+	/* Adjust lightborder_shade reading contrast */
+	murrine_style->lightborder_shade = murrine_get_contrast(MURRINE_RC_STYLE (rc_style)->lightborder_shade,
+	                                                        MURRINE_RC_STYLE (rc_style)->contrast);
+	murrine_style->shadow_shades[0]   = MURRINE_RC_STYLE (rc_style)->shadow_shades[0];
+	murrine_style->shadow_shades[1]   = MURRINE_RC_STYLE (rc_style)->shadow_shades[1];
+	murrine_style->trough_border_shades[0] = MURRINE_RC_STYLE (rc_style)->trough_border_shades[0];
+	murrine_style->trough_border_shades[1] = MURRINE_RC_STYLE (rc_style)->trough_border_shades[1];
+	murrine_style->trough_shades[0]   = MURRINE_RC_STYLE (rc_style)->trough_shades[0];
+	murrine_style->trough_shades[1]   = MURRINE_RC_STYLE (rc_style)->trough_shades[1];
+
+	/* Widget styles */
+	murrine_style->glazestyle         = MURRINE_RC_STYLE (rc_style)->glazestyle;
+	if (murrine_style->glazestyle == 2)
+	{
+		if (MURRINE_RC_STYLE (rc_style)->roundness > 0)
+			murrine_style->roundness = 1;
+		else
+			murrine_style->roundness = 0;
+	}
+	else
+		murrine_style->roundness = MURRINE_RC_STYLE (rc_style)->roundness;
+	murrine_style->animation           = MURRINE_RC_STYLE (rc_style)->animation;
+	murrine_style->arrowstyle          = MURRINE_RC_STYLE (rc_style)->arrowstyle;
+	murrine_style->cellstyle           = MURRINE_RC_STYLE (rc_style)->cellstyle;
+	murrine_style->comboboxstyle       = MURRINE_RC_STYLE (rc_style)->comboboxstyle;
+	murrine_style->contrast            = MURRINE_RC_STYLE (rc_style)->contrast;
+	murrine_style->colorize_scrollbar  = MURRINE_RC_STYLE (rc_style)->colorize_scrollbar;
+	murrine_style->expanderstyle       = MURRINE_RC_STYLE (rc_style)->expanderstyle;
+	murrine_style->focusstyle          = MURRINE_RC_STYLE (rc_style)->focusstyle;
+	murrine_style->glowstyle           = MURRINE_RC_STYLE (rc_style)->glowstyle;
+	murrine_style->has_border_colors   = MURRINE_RC_STYLE (rc_style)->has_border_colors;
+	murrine_style->has_default_button_color = MURRINE_RC_STYLE (rc_style)->flags & MRN_FLAG_DEFAULT_BUTTON_COLOR;
+	murrine_style->has_focus_color     = MURRINE_RC_STYLE (rc_style)->flags & MRN_FLAG_FOCUS_COLOR;
+	murrine_style->has_gradient_colors = MURRINE_RC_STYLE (rc_style)->has_gradient_colors;
+	murrine_style->handlestyle         = MURRINE_RC_STYLE (rc_style)->handlestyle;
+	murrine_style->lightborderstyle    = MURRINE_RC_STYLE (rc_style)->lightborderstyle;
+	murrine_style->listviewheaderstyle = MURRINE_RC_STYLE (rc_style)->listviewheaderstyle;
+	murrine_style->listviewstyle       = MURRINE_RC_STYLE (rc_style)->listviewstyle;
+	murrine_style->menubarstyle        = MURRINE_RC_STYLE (rc_style)->menubarstyle;
+	murrine_style->menubaritemstyle    = MURRINE_RC_STYLE (rc_style)->menubaritemstyle;
+	murrine_style->menuitemstyle       = MURRINE_RC_STYLE (rc_style)->menuitemstyle;
+	murrine_style->menustyle           = MURRINE_RC_STYLE (rc_style)->menustyle;
+	murrine_style->prelight_shade      = MURRINE_RC_STYLE (rc_style)->prelight_shade;
+	murrine_style->progressbarstyle    = MURRINE_RC_STYLE (rc_style)->progressbarstyle;
+	murrine_style->reliefstyle         = MURRINE_RC_STYLE (rc_style)->reliefstyle;
+	murrine_style->rgba                = MURRINE_RC_STYLE (rc_style)->rgba;
+	murrine_style->scrollbarstyle      = MURRINE_RC_STYLE (rc_style)->scrollbarstyle;
+	murrine_style->separatorstyle      = MURRINE_RC_STYLE (rc_style)->separatorstyle;
+	murrine_style->sliderstyle         = MURRINE_RC_STYLE (rc_style)->sliderstyle;
+	murrine_style->spinbuttonstyle     = MURRINE_RC_STYLE (rc_style)->spinbuttonstyle;
+	murrine_style->stepperstyle        = MURRINE_RC_STYLE (rc_style)->stepperstyle;
+	murrine_style->textstyle           = MURRINE_RC_STYLE (rc_style)->textstyle;
+	murrine_style->text_shade          = MURRINE_RC_STYLE (rc_style)->text_shade;
+	murrine_style->toolbarstyle        = MURRINE_RC_STYLE (rc_style)->toolbarstyle;
+
+	if (murrine_style->has_border_colors)
+	{
+		murrine_style->border_colors[0] = MURRINE_RC_STYLE (rc_style)->border_colors[0];
+		murrine_style->border_colors[1] = MURRINE_RC_STYLE (rc_style)->border_colors[1];
+	}
+	if (murrine_style->has_default_button_color)
+		murrine_style->default_button_color = MURRINE_RC_STYLE (rc_style)->default_button_color;
+	if (murrine_style->has_focus_color)
+		murrine_style->focus_color = MURRINE_RC_STYLE (rc_style)->focus_color;
+	if (murrine_style->has_gradient_colors)
+	{
+		murrine_style->gradient_colors[0] = MURRINE_RC_STYLE (rc_style)->gradient_colors[0];
+		murrine_style->gradient_colors[1] = MURRINE_RC_STYLE (rc_style)->gradient_colors[1];
+		murrine_style->gradient_colors[2] = MURRINE_RC_STYLE (rc_style)->gradient_colors[2];
+		murrine_style->gradient_colors[3] = MURRINE_RC_STYLE (rc_style)->gradient_colors[3];
+	}
+}
+
+static void
+murrine_style_realize (GtkStyle *style)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	double shades[] = {1.065, 0.95, 0.896, 0.82, 0.75, 0.665, 0.5, 0.45, 0.4};
+	double spots[] = {1.42, 1.00, 0.65};
+	MurrineRGB spot_color;
+	MurrineRGB bg_normal;
+	double contrast;
+	int i;
+
+	GTK_STYLE_CLASS (murrine_style_parent_class)->realize (style);
+
+	contrast = MURRINE_RC_STYLE (style->rc_style)->contrast;
+
+	murrine_gdk_color_to_murrinergb (&style->bg[GTK_STATE_NORMAL], &bg_normal);
+
+	/* (GtkWidget *) Apply contrast */
+	for (i = 0; i < 9; i++)
+	{
+		murrine_shade (&bg_normal,
+		               murrine_get_contrast(shades[i], contrast),
+		               &murrine_style->colors.shade[i]);
+	}
+	spots[2] = murrine_get_contrast(spots[2], contrast);
+
+	murrine_gdk_color_to_murrinergb (&style->bg[GTK_STATE_SELECTED], &spot_color);
+
+	murrine_shade (&spot_color, spots[0], &murrine_style->colors.spot[0]);
+	murrine_shade (&spot_color, spots[1], &murrine_style->colors.spot[1]);
+	murrine_shade (&spot_color, spots[2], &murrine_style->colors.spot[2]);
+
+	for (i=0; i<5; i++)
+	{
+		murrine_gdk_color_to_murrinergb (&style->bg[i], &murrine_style->colors.bg[i]);
+		murrine_gdk_color_to_murrinergb (&style->base[i], &murrine_style->colors.base[i]);
+		murrine_gdk_color_to_murrinergb (&style->text[i], &murrine_style->colors.text[i]);
+		murrine_gdk_color_to_murrinergb (&style->fg[i], &murrine_style->colors.fg[i]);
+	}
+}
+
+static void
+gdk_cairo_set_source_color_alpha (cairo_t  *cr,
+                                  GdkColor *color,
+                                  float    alpha)
+{
+	g_return_if_fail (cr != NULL);
+	g_return_if_fail (color != NULL);
+
+	cairo_set_source_rgba (cr,
+	                       color->red/65535.,
+	                       color->green/65535.,
+	                       color->blue/65535.,
+	                       alpha);
+}
+
+static void
+murrine_style_copy (GtkStyle *style, GtkStyle *src)
+{
+	MurrineStyle *mrn_style = MURRINE_STYLE (style);
+	MurrineStyle *mrn_src = MURRINE_STYLE (src);
+
+	mrn_style->animation           = mrn_src->animation;
+	mrn_style->arrowstyle          = mrn_src->arrowstyle;
+	mrn_style->border_colors[0]    = mrn_src->border_colors[0];
+	mrn_style->border_colors[1]    = mrn_src->border_colors[1];
+	mrn_style->border_shades[0]    = mrn_src->border_shades[0];
+	mrn_style->border_shades[1]    = mrn_src->border_shades[1];
+	mrn_style->cellstyle           = mrn_src->cellstyle;
+	mrn_style->colorize_scrollbar  = mrn_src->colorize_scrollbar;
+	mrn_style->colors              = mrn_src->colors;
+	mrn_style->comboboxstyle       = mrn_src->comboboxstyle;
+	mrn_style->contrast            = mrn_src->contrast;
+	mrn_style->default_button_color = mrn_src->default_button_color;
+	mrn_style->expanderstyle       = mrn_src->expanderstyle;
+	mrn_style->focusstyle          = mrn_src->focusstyle;
+	mrn_style->focus_color         = mrn_src->focus_color;
+	mrn_style->glazestyle          = mrn_src->glazestyle;
+	mrn_style->glow_shade          = mrn_src->glow_shade;
+	mrn_style->glowstyle           = mrn_src->glowstyle;
+	mrn_style->gradient_colors[0]  = mrn_src->gradient_colors[0];
+	mrn_style->gradient_colors[1]  = mrn_src->gradient_colors[1];
+	mrn_style->gradient_colors[2]  = mrn_src->gradient_colors[2];
+	mrn_style->gradient_colors[3]  = mrn_src->gradient_colors[3];
+	mrn_style->gradient_shades[0]  = mrn_src->gradient_shades[0];
+	mrn_style->gradient_shades[1]  = mrn_src->gradient_shades[1];
+	mrn_style->gradient_shades[2]  = mrn_src->gradient_shades[2];
+	mrn_style->gradient_shades[3]  = mrn_src->gradient_shades[3];
+	mrn_style->handlestyle         = mrn_src->handlestyle;
+	mrn_style->has_border_colors   = mrn_src->has_border_colors;
+	mrn_style->has_default_button_color = mrn_src->has_default_button_color;
+	mrn_style->has_focus_color     = mrn_src->has_focus_color;
+	mrn_style->has_gradient_colors = mrn_src->has_gradient_colors;
+	mrn_style->highlight_shade     = mrn_src->highlight_shade;
+	mrn_style->lightborder_shade   = mrn_src->lightborder_shade;
+	mrn_style->lightborderstyle    = mrn_src->lightborderstyle;
+	mrn_style->listviewheaderstyle = mrn_src->listviewheaderstyle;
+	mrn_style->listviewstyle       = mrn_src->listviewstyle;
+	mrn_style->menubaritemstyle    = mrn_src->menubaritemstyle;
+	mrn_style->menubarstyle        = mrn_src->menubarstyle;
+	mrn_style->menuitemstyle       = mrn_src->menuitemstyle;
+	mrn_style->menustyle           = mrn_src->menustyle;
+	mrn_style->prelight_shade      = mrn_src->prelight_shade;
+	mrn_style->progressbarstyle    = mrn_src->progressbarstyle;
+	mrn_style->reliefstyle         = mrn_src->reliefstyle;
+	mrn_style->rgba                = mrn_src->rgba;
+	mrn_style->roundness           = mrn_src->roundness;
+	mrn_style->scrollbarstyle      = mrn_src->scrollbarstyle;
+	mrn_style->separatorstyle      = mrn_src->separatorstyle;
+	mrn_style->shadow_shades[0]    = mrn_src->shadow_shades[0];
+	mrn_style->shadow_shades[1]    = mrn_src->shadow_shades[1];
+	mrn_style->sliderstyle 	       = mrn_src->sliderstyle;
+	mrn_style->spinbuttonstyle     = mrn_src->spinbuttonstyle;
+	mrn_style->stepperstyle        = mrn_src->stepperstyle;
+	mrn_style->textstyle           = mrn_src->textstyle;
+	mrn_style->text_shade          = mrn_src->text_shade;
+	mrn_style->toolbarstyle        = mrn_src->toolbarstyle;
+	mrn_style->trough_border_shades[0] = mrn_src->trough_border_shades[0];
+	mrn_style->trough_border_shades[1] = mrn_src->trough_border_shades[1];
+	mrn_style->trough_shades[0]    = mrn_src->trough_shades[0];
+	mrn_style->trough_shades[1]    = mrn_src->trough_shades[1];
+
+	GTK_STYLE_CLASS (murrine_style_parent_class)->copy (style, src);
+}
+
+static void
+murrine_style_unrealize (GtkStyle *style)
+{
+	GTK_STYLE_CLASS (murrine_style_parent_class)->unrealize (style);
+}
+
+static GdkPixbuf *
+set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
+{
+	GdkPixbuf *target;
+	guchar *data, *current;
+	guint x, y, rowstride, height, width;
+
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+	/* Returns a copy of pixbuf with it's non-completely-transparent pixels to
+	   have an alpha level "alpha_percent" of their original value. */
+
+	target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
+
+	if (alpha_percent == 1.0)
+		return target;
+	width = gdk_pixbuf_get_width (target);
+	height = gdk_pixbuf_get_height (target);
+	rowstride = gdk_pixbuf_get_rowstride (target);
+	data = gdk_pixbuf_get_pixels (target);
+
+	for (y = 0; y < height; y++)
+	{
+		for (x = 0; x < width; x++)
+		{
+			/* The "4" is the number of chars per pixel, in this case, RGBA,
+			   the 3 means "skip to the alpha" */
+			current = data+(y*rowstride)+(x*4)+3;
+			*(current) = (guchar) (*(current)*alpha_percent);
+		}
+	}
+
+	return target;
+}
+
+static GdkPixbuf*
+scale_or_ref (GdkPixbuf *src,
+              int       width,
+              int       height)
+{
+	if (width == gdk_pixbuf_get_width (src) &&
+	    height == gdk_pixbuf_get_height (src))
+	{
+		return g_object_ref (src);
+	}
+	else
+	{
+		return gdk_pixbuf_scale_simple (src, width, height, GDK_INTERP_BILINEAR);
+	}
+}
+
+static GdkPixbuf *
+murrine_style_draw_render_icon (GtkStyle            *style,
+                                const GtkIconSource *source,
+                                GtkTextDirection    direction,
+                                GtkStateType        state,
+                                GtkIconSize         size,
+                                GtkWidget           *widget,
+                                const char          *detail)
+{
+	int width = 1;
+	int height = 1;
+	GdkPixbuf *scaled;
+	GdkPixbuf *stated;
+	GdkPixbuf *base_pixbuf;
+	GdkScreen *screen;
+	GtkSettings *settings;
+
+	/* Oddly, style can be NULL in this function, because
+	 * GtkIconSet can be used without a style and if so
+	 * it uses this function.
+	 */
+
+	base_pixbuf = gtk_icon_source_get_pixbuf (source);
+
+	g_return_val_if_fail (base_pixbuf != NULL, NULL);
+
+	if (widget && gtk_widget_has_screen (widget))
+	{
+		screen = gtk_widget_get_screen (widget);
+		settings = gtk_settings_get_for_screen (screen);
+	}
+	else if (style->visual)
+	{
+		screen = gdk_visual_get_screen (style->visual);
+		settings = gtk_settings_get_for_screen (screen);
+	}
+	else
+	{
+		settings = gtk_settings_get_default ();
+		GTK_NOTE (MULTIHEAD,
+		g_warning ("Using the default screen for gtk_default_murrine_style_draw_render_icon()"));
+	}
+
+	if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
+	{
+		g_warning (G_STRLOC ": invalid icon size '%d'", size);
+		return NULL;
+	}
+
+	/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+	 * leave it alone.
+	 */
+	if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
+		scaled = scale_or_ref (base_pixbuf, width, height);
+	else
+		scaled = g_object_ref (base_pixbuf);
+
+	/* If the state was wildcarded, then generate a state. */
+	if (gtk_icon_source_get_state_wildcarded (source))
+	{
+		if (state == GTK_STATE_INSENSITIVE)
+		{
+			stated = set_transparency (scaled, 0.3);
+#if 0
+			stated =
+				gdk_pixbuf_composite_color_simple (scaled,
+				                                   gdk_pixbuf_get_width (scaled),
+				                                   gdk_pixbuf_get_height (scaled),
+				                                   GDK_INTERP_BILINEAR, 128,
+				                                   gdk_pixbuf_get_width (scaled),
+				                                   style->bg[state].pixel,
+				                                   style->bg[state].pixel);
+#endif
+			gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE);
+
+			g_object_unref (scaled);
+		}
+		else if (state == GTK_STATE_PRELIGHT)
+		{
+			stated = gdk_pixbuf_copy (scaled);
+
+			gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE);
+
+			g_object_unref (scaled);
+		}
+		else
+		{
+			stated = scaled;
+		}
+	}
+	else
+		stated = scaled;
+
+	return stated;
+}
+
+void
+murrine_engine_register_types (GTypeModule *module)
+{
+	murrine_engine_register_type (module);
+}
+
+
+static void
+murrine_style_init (MurrineStyle *style)
+{
+}
+
+static void
+murrine_engine_class_init (MurrineEngineClass *klass)
+{
+	GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
+
+	style_class->copy             = murrine_style_copy;
+	style_class->realize          = murrine_style_realize;
+	style_class->unrealize        = murrine_style_unrealize;
+	style_class->init_from_rc     = murrine_style_init_from_rc;
+	style_class->draw_arrow       = murrine_style_draw_arrow;
+	style_class->draw_layout      = murrine_style_draw_layout;
+	style_class->draw_box         = murrine_style_draw_box;
+	style_class->draw_box_gap     = murrine_style_draw_box_gap;
+	style_class->draw_check       = murrine_style_draw_check;
+	style_class->draw_expander    = murrine_style_draw_expander;
+	style_class->draw_extension   = murrine_style_draw_extension;
+	style_class->draw_flat_box    = murrine_style_draw_flat_box;
+	style_class->draw_focus       = murrine_style_draw_focus;
+	style_class->draw_handle      = murrine_style_draw_handle;
+	style_class->draw_hline       = murrine_style_draw_hline;
+	style_class->draw_option      = murrine_style_draw_option;
+	style_class->render_icon      = murrine_style_draw_render_icon;
+	style_class->draw_resize_grip = murrine_style_draw_resize_grip;
+	style_class->draw_shadow      = murrine_style_draw_shadow;
+	style_class->draw_shadow_gap  = murrine_style_draw_shadow_gap;
+	style_class->draw_slider      = murrine_style_draw_slider;
+	style_class->draw_tab         = murrine_style_draw_tab;
+	style_class->draw_vline       = murrine_style_draw_vline;
+
+	murrine_register_style_murrine (&klass->style_functions[MRN_STYLE_MURRINE]);
+	klass->style_functions[MRN_STYLE_RGBA] = klass->style_functions[MRN_STYLE_MURRINE];
+	murrine_register_style_rgba (&klass->style_functions[MRN_STYLE_RGBA]);
+}
+
+static void
+murrine_engine_class_finalize (MurrineEngineClass *klass)
+{
+}
diff --git a/src/murrine_engine.h b/src/murrine_engine.h
new file mode 100644
index 0000000..41db572
--- /dev/null
+++ b/src/murrine_engine.h
@@ -0,0 +1,107 @@
+/* Murrine theme engine
+ * Copyright (C) 2006-2007-2008-2009 Andrea Cimitan
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtk.h>
+
+#ifndef MURRINE_ENGINE_H
+#define MURRINE_ENGINE_H
+
+#include "animation.h"
+#include "murrine_types.h"
+
+typedef struct _MurrineEngine MurrineEngine;
+typedef struct _MurrineEngineClass MurrineEngineClass;
+
+#define MURRINE_TYPE_ENGINE              (murrine_engine_get_type())
+#define MURRINE_ENGINE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MURRINE_TYPE_ENGINE, MurrineEngine))
+#define MURRINE_ENGINE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MURRINE_TYPE_ENGINE, MurrineEngineClass))
+#define MURRINE_IS_ENGINE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MURRINE_TYPE_ENGINE))
+#define MURRINE_IS_ENGINE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MURRINE_TYPE_ENGINE))
+#define MURRINE_ENGINE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MURRINE_TYPE_ENGINE, MurrineEngineClass))
+
+struct _MurrineEngine
+{
+	GtkStyle parent_instance;
+
+	MurrineColors colors;
+
+	double   border_shades[2];
+	double   contrast;
+	double   glow_shade;
+	double   gradient_shades[4];
+	double   highlight_shade;
+	double   lightborder_shade;
+	double   prelight_shade;
+	double   shadow_shades[2];
+	double   text_shade;
+	double   trough_border_shades[2];
+	double   trough_shades[2];
+
+	guint8   arrowstyle;
+	guint8   cellstyle;
+	guint8   comboboxstyle;
+	guint8   expanderstyle;
+	guint8   focusstyle;
+	guint8   glazestyle;
+	guint8   glowstyle;
+	guint8   handlestyle;
+	guint8   lightborderstyle;
+	guint8   listviewheaderstyle;
+	guint8   listviewstyle;
+	guint8   menubaritemstyle;
+	guint8   menubarstyle;
+	guint8   menuitemstyle;
+	guint8   menustyle;
+	guint8   progressbarstyle;
+	guint8   reliefstyle;
+	guint8   roundness;
+	guint8   scrollbarstyle;
+	guint8   separatorstyle;
+	guint8   sliderstyle;
+	guint8   spinbuttonstyle;
+	guint8   stepperstyle;
+	guint8   textstyle;
+	guint8   toolbarstyle;
+
+	gboolean animation;
+	gboolean colorize_scrollbar;
+	gboolean has_border_colors;
+	gboolean has_default_button_color;
+	gboolean has_focus_color;
+	gboolean has_gradient_colors;
+	gboolean rgba;
+
+	GdkColor border_colors[2];
+	GdkColor default_button_color;
+	GdkColor focus_color;
+	GdkColor gradient_colors[4];
+};
+
+struct _MurrineEngineClass
+{
+	GtkThemingEngineClass parent_class;
+
+	MurrineStyleFunctions style_functions[MRN_NUM_DRAW_STYLES];
+};
+
+G_GNUC_INTERNAL void  murrine_engine_register_types (GTypeModule *module);
+G_GNUC_INTERNAL GType murrine_engine_get_type       (void);
+
+#endif /* MURRINE_ENGINE_H */
diff --git a/src/murrine_theme_main.c b/src/murrine_theme_main.c
index 8bc8a54..937804e 100644
--- a/src/murrine_theme_main.c
+++ b/src/murrine_theme_main.c
@@ -21,15 +21,13 @@
 #include <gmodule.h>
 #include <gtk/gtk.h>
 
-#include "murrine_style.h"
-#include "murrine_rc_style.h"
+#include "murrine_engine.h"
 
 G_MODULE_EXPORT void
 theme_init (GTypeModule *module)
 {
 //	printf ("Murrine 0.91.x Development Snapshot, Copyright Andrea Cimitan\n"); 
-	murrine_rc_style_register_types (module);
-	murrine_style_register_types (module);
+	murrine_engine_register_types (module);
 }
 
 G_MODULE_EXPORT void
@@ -37,10 +35,12 @@ theme_exit (void)
 {
 }
 
-G_MODULE_EXPORT GtkRcStyle *
-theme_create_rc_style (void)
+G_MODULE_EXPORT GtkThemingEngine *
+theme_create_engine (void)
 {
-	return GTK_RC_STYLE (g_object_new (MURRINE_TYPE_RC_STYLE, NULL));
+	return GTK_THEMING_ENGINE (g_object_new (MURRINE_TYPE_ENGINE,
+	                                         "name", "murrine",
+	                                         NULL));
 }
 
 /* The following function will be called by GTK+ when the module



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]