aboutsummaryrefslogtreecommitdiffstats
path: root/eazel-engine/src/eazel-theme-draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'eazel-engine/src/eazel-theme-draw.c')
-rw-r--r--eazel-engine/src/eazel-theme-draw.c2358
1 files changed, 2358 insertions, 0 deletions
diff --git a/eazel-engine/src/eazel-theme-draw.c b/eazel-engine/src/eazel-theme-draw.c
new file mode 100644
index 0000000..8098ef7
--- /dev/null
+++ b/eazel-engine/src/eazel-theme-draw.c
@@ -0,0 +1,2358 @@
+/* eazel-theme-draw.c -- replacement drawing `primitives'
+
+ Copyright (C) 2000 Eazel, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: eazel-theme-draw.c,v 1.21 2001/05/23 04:56:34 jsh Exp $
+
+ Authors: The Rasterman <raster@redhat.com>
+ Owen Taylor <otaylor@redhat.com>
+ John Harper <jsh@eazel.com> */
+
+/* Adapted from gtk-engines/notif/notif_theme_draw.c
+
+ Repeat after me: ``the implementation is unimportant, the only thing
+ that matters is the user-experience'' */
+
+#include "eazel-theme.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define DEBUG 0
+
+#define DETAIL(xx) ((detail) != 0 && strcmp (xx, detail) == 0)
+
+
+/* utility functions */
+
+static inline void
+debug (const char *fmt, ...)
+{
+ if (DEBUG)
+ {
+ va_list args;
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+/* adapted from nautilus-gdk-extensions.c */
+static void
+interpolate_color (GdkColor *dest, gdouble ratio,
+ GdkColor *start, GdkColor *end)
+{
+ g_return_if_fail (ratio >= 0.0);
+ g_return_if_fail (ratio <= 1.0);
+
+ dest->red = start->red * (1.0 - ratio) + (end->red & 0xFF) * ratio;
+ dest->green = start->green * (1.0 - ratio) + end->green * ratio;
+ dest->blue = start->blue * (1.0 - ratio) + end->blue * ratio;
+}
+
+static void
+paint_background_area (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ int x, int y, int width, int height)
+{
+ GdkGC *gc = style->bg_gc[GTK_STATE_NORMAL];
+
+ if (area != 0)
+ gdk_gc_set_clip_rectangle (gc, area);
+
+ gdk_draw_rectangle (window, gc, TRUE, x, y, width, height);
+
+ if (area != 0)
+ gdk_gc_set_clip_rectangle (gc, 0);
+}
+
+static void
+paint_stock_image (eazel_theme_data *theme_data,
+ eazel_engine_stock_image type,
+ gboolean scaled, gboolean setbg,
+ GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gint x, gint y, gint width, gint height)
+{
+ GdkPixmap *pixmap, *mask;
+
+ if (width == -1 || height == -1)
+ {
+ eazel_engine_stock_get_size (theme_data->stock, type,
+ width == -1 ? &width : 0,
+ height == -1 ? &height : 0);
+ }
+
+ if (scaled)
+ {
+ eazel_engine_stock_pixmap_and_mask_scaled (theme_data->stock, type,
+ width, height,
+ &pixmap, &mask);
+ }
+ else
+ eazel_engine_stock_pixmap_and_mask (theme_data->stock, type,
+ &pixmap, &mask);
+
+ if (gdk_window_get_type (window) == GDK_WINDOW_PIXMAP)
+ setbg = FALSE;
+
+ if (setbg)
+ {
+ gdk_draw_pixmap (window, style->fg_gc[state_type], pixmap,
+ 0, 0, x, y, width, height);
+ if (mask != 0)
+ gdk_window_shape_combine_mask (window, mask, 0, 0);
+ }
+ else
+ {
+ int xsrc = 0, ysrc = 0;
+
+ /* Install the mask before clipping.. */
+ if (mask != 0)
+ {
+ gdk_gc_set_clip_mask (style->fg_gc[state_type], mask);
+ gdk_gc_set_clip_origin (style->fg_gc[state_type], x, y);
+ }
+
+ if (area != 0)
+ {
+ /* clip by hand to leave gc's clipping for the possible mask */
+ GdkRectangle src = { x, y, width, height }, dest;
+
+ if (!gdk_rectangle_intersect (&src, area, &dest))
+ return;
+
+ xsrc -= x - dest.x;
+ ysrc -= y - dest.y;
+ x = dest.x;
+ y = dest.y;
+ width = dest.width;
+ height = dest.height;
+
+ }
+
+ if (width > 0 && height > 0)
+ {
+ gdk_draw_pixmap (window, style->fg_gc[state_type], pixmap,
+ xsrc, ysrc, x, y, width, height);
+ }
+
+ if (mask != 0)
+ {
+ gdk_gc_set_clip_mask (style->fg_gc[state_type], 0);
+ gdk_gc_set_clip_origin (style->fg_gc[state_type], 0, 0);
+ }
+ }
+
+ eazel_engine_stock_free_pixmaps (theme_data->stock, type, pixmap, mask);
+}
+
+static void
+paint_outline (GdkWindow *window, GdkGC *gc, gboolean rounded,
+ int x, int y, int width, int height)
+{
+ int corner = rounded ? 1 : 0;
+
+ /* left and top outermost */
+ gdk_draw_line (window, gc, x, y + corner,
+ x, y + height - (corner + 1));
+ gdk_draw_line (window, gc, x + corner, y, x + width - (corner + 1), y);
+
+ /* right and bottom outermost */
+ gdk_draw_line (window, gc, x + width - 1, y + corner,
+ x + width - 1, y + height - (corner + 1));
+ gdk_draw_line (window, gc, x + corner, y + height - 1,
+ x + width - (corner + 1), y + height - 1);
+}
+
+static void
+paint_shadow (GdkWindow *window, GdkGC *a, GdkGC *b, GdkGC *c, GdkGC *d,
+ gboolean rounded, int x, int y, int width, int height)
+{
+ int corner = rounded ? 1 : 0;
+
+ if (a != 0)
+ {
+ /* left and top outermost */
+ gdk_draw_line (window, a, x, y + corner,
+ x, y + height - (corner + 1));
+ gdk_draw_line (window, a, x + corner, y, x + width - (corner + 1), y);
+ }
+
+ if (d != 0)
+ {
+ /* right and bottom outermost */
+ gdk_draw_line (window, d, x + width - 1, y + corner,
+ x + width - 1, y + height - (corner + 1));
+ gdk_draw_line (window, d, x + corner, y + height - 1,
+ x + width - (corner + 1), y + height - 1);
+ }
+
+ if (b != 0)
+ {
+ /* left and top inner */
+ gdk_draw_line (window, b, x + 1, y + 2, x + 1, y + height - 2);
+ gdk_draw_line (window, b, x + 1, y + 1, x + width - 2, y + 1);
+ }
+
+ if (c != 0)
+ {
+ /* right and bottom outermost */
+ gdk_draw_line (window, c, x + width - 2, y + 1,
+ x + width - 2, y + height - 2);
+ gdk_draw_line (window, c, x + 1, y + height - 2,
+ x + width - 2, y + height - 2);
+ }
+}
+
+static void
+paint_entry_shadow (GdkWindow *window, GtkStyle *style,
+ GtkStateType state_type,
+ int x, int y, int width, int height)
+{
+ gdk_draw_rectangle (window, style->black_gc, FALSE,
+ x + 1, y + 1, width - 3, height - 3);
+
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x, y, x + width - 1, y);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x, y, x, y + height - 1);
+
+ gdk_draw_line (window, style->white_gc,
+ x + 1, y + height - 1, x + width - 1, y + height - 1);
+ gdk_draw_line (window, style->white_gc,
+ x + width - 1, y + 1, x + width - 1, y + height - 1);
+
+ gdk_draw_line (window, style->mid_gc[state_type],
+ x + 2, y + 2, x + width - 3, y + 2);
+ gdk_draw_line (window, style->mid_gc[state_type],
+ x + 2, y + 2, x + 2, y + height - 3);
+
+ gdk_draw_line (window, style->white_gc,
+ x + 2, y + height - 3, x + width - 3, y + height - 3);
+ gdk_draw_line (window, style->white_gc,
+ x + width - 3, y + 2, x + width - 3, y + height - 3);
+}
+
+static void
+paint_menuitem_shadow (GdkWindow *window, GtkStyle *style,
+ int x, int y, int width, int height)
+{
+ gdk_draw_rectangle (window, style->black_gc, FALSE,
+ x + 2, y + 1, width - 5, height - 3);
+
+ gdk_draw_line (window, style->dark_gc[GTK_STATE_NORMAL],
+ x + 1, y, x + width - 3, y);
+ gdk_draw_line (window, style->dark_gc[GTK_STATE_NORMAL],
+ x + 1, y, x + 1, y + height - 2);
+ gdk_draw_line (window, style->white_gc,
+ x + 2, y + height - 1, x + width - 2, y + height - 1);
+ gdk_draw_line (window, style->white_gc,
+ x + width - 2, y + 1, x + width - 2, y + height - 1);
+}
+
+static void
+paint_default_highlight (eazel_theme_data *theme_data,
+ GdkColor *hi_color, GdkColor *bg_color,
+ GdkWindow *window, GdkGC *gc, int x, int y)
+{
+ GdkColormap *sys_lut = gdk_colormap_get_system ();
+ GdkGCValues old_values;
+ GdkColor spectrum[6];
+ int i;
+
+ gdk_gc_get_values (gc, &old_values);
+
+ /* Calculate pixel colors */
+ for (i = 0; i < 6; i++)
+ {
+ interpolate_color (spectrum + i, 1.0 / 7 * i, hi_color, bg_color);
+ }
+
+#define COLOR(i) \
+ gdk_colormap_alloc_color (sys_lut, spectrum + i, FALSE, TRUE); \
+ gdk_gc_set_foreground (gc, spectrum + i);
+
+#define PIXEL(a,b) gdk_draw_point (window, gc, x + a, y + b)
+
+ COLOR (0); PIXEL (2, 2);
+ COLOR (1); PIXEL (3, 2); PIXEL (2, 3); PIXEL (4, 1); PIXEL (1, 4);
+ COLOR (2); PIXEL (5, 1); PIXEL (1, 5);
+ COLOR (3); PIXEL (6, 1); PIXEL (1, 6);
+ COLOR (4); PIXEL (7, 1); PIXEL (1, 7); PIXEL (4, 2); PIXEL (2, 4);
+ COLOR (5); PIXEL (8, 1); PIXEL (1, 8);
+
+#undef PIXEL
+#undef COLOR
+
+ gdk_gc_set_foreground (gc, &old_values.foreground);
+}
+
+static void
+paint_default (eazel_theme_data *theme_data,
+ GdkWindow *window, GdkGC *gc, GdkColor *bg,
+ gboolean rounded, gboolean rounded_inner, int thickness,
+ int x, int y, int width, int height)
+{
+ int corner = rounded ? ((thickness > 2) ? 3 : 1) : 0;
+ int window_width, window_height;
+ int i;
+
+ gdk_window_get_size (window, &window_width, &window_height);
+
+ /* If trying to draw a box that's too big for the dimensions of
+ the window, iteratively reduce the thickness until a value
+ is found that won't draw off the window edges */
+ while (x < 0 || y < 0 || x + width >= window_width
+ || y + height >= window_height)
+ {
+ if (thickness <= 0 || width <= 0 || height <= 0)
+ return;
+
+ thickness -= 1;
+ x += 1;
+ y += 1;
+ width -= 2;
+ height -= 2;
+ }
+
+ if (rounded)
+ {
+ /* XXX this doesn't work, the background of the window
+ XXX is white, not grey */
+ gdk_window_clear_area (window, x, y, 1, 1);
+ gdk_window_clear_area (window, x + width, y, 1, 1);
+ gdk_window_clear_area (window, x, y + height, 1, 1);
+ gdk_window_clear_area (window, x + width, y + height, 1, 1);
+ }
+
+ for (i = 0; i < thickness; i++)
+ {
+ int x_i = x + i;
+ int y_i = y + i;
+ int w_i = width - (i * 2);
+ int h_i = height - (i * 2);
+
+ int d_corner = (corner && i == 0) ? corner : 0;
+
+ gdk_draw_line (window, gc, x_i + d_corner, y_i,
+ x_i + w_i - d_corner , y_i);
+ gdk_draw_line (window, gc, x_i + w_i, y_i + d_corner,
+ x_i + w_i, y_i + h_i - d_corner);
+ gdk_draw_line (window, gc, x_i + w_i - d_corner, y_i + h_i,
+ x_i + d_corner, y_i + h_i);
+ gdk_draw_line (window, gc, x_i, y+i + h_i - d_corner,
+ x_i, y_i + d_corner);
+ }
+
+ if (rounded_inner)
+ {
+ gdk_draw_point (window, gc, x + thickness, y + thickness);
+ gdk_draw_point (window, gc, x + thickness, y + height - thickness);
+ gdk_draw_point (window, gc, x + width - thickness, y + thickness);
+ gdk_draw_point (window, gc, x + width - thickness, y + height - thickness);
+ }
+
+ if (thickness >= 3 && rounded)
+ {
+ GdkColor white = { 0, 65535, 65535, 65535 };
+ paint_default_highlight (theme_data, &white, bg, window, gc, x, y);
+ }
+}
+
+static void
+paint_default_box (eazel_theme_data *theme_data,
+ GdkWindow *window, GdkGC *gc,
+ gboolean rounded, gboolean rounded_inner, int thickness,
+ int x, int y, int width, int height)
+{
+ GdkColor black = { 0, 0, 0, 0 };
+ paint_default (theme_data, window, gc, &black,
+ rounded, rounded_inner, thickness,
+ x, y, width, height);
+}
+
+static void
+paint_focus_box (eazel_theme_data *theme_data, GdkWindow *window,
+ GdkGC *gc, gboolean rounded, gboolean rounded_inner,
+ int thickness, int x, int y, int width, int height)
+{
+ GdkColormap *sys_lut = gdk_colormap_get_system ();
+ GdkGCValues old_values;
+ GdkColor color;
+ gdk_gc_get_values (gc, &old_values);
+
+ color = theme_data->focus_color;
+ gdk_colormap_alloc_color (sys_lut, &color, FALSE, TRUE);
+ gdk_gc_set_foreground (gc, &color);
+
+ paint_default (theme_data, window, gc, &color, rounded,
+ rounded_inner, thickness, x, y, width, height);
+
+ gdk_gc_set_foreground (gc, &old_values.foreground);
+}
+
+static void
+paint_insensitive_box (eazel_theme_data *theme_data,
+ GdkWindow *window, GdkGC *gc, gboolean rounded,
+ int x, int y, int width, int height)
+{
+ GdkColormap *sys_lut = gdk_colormap_get_system ();
+ GdkGCValues old_values;
+ GdkColor color;
+ gdk_gc_get_values (gc, &old_values);
+
+ color = theme_data->insensitive_colors[1];
+ gdk_colormap_alloc_color (sys_lut, &color, FALSE, TRUE);
+ gdk_gc_set_foreground (gc, &color);
+ gdk_draw_rectangle (window, gc, TRUE, x, y, width, height);
+
+ color = theme_data->insensitive_colors[0];
+ gdk_colormap_alloc_color (sys_lut, &color, FALSE, TRUE);
+ gdk_gc_set_foreground (gc, &color);
+ paint_default (theme_data, window, gc, &color, rounded,
+ FALSE, 1, x, y, width - 1, height - 1);
+
+ gdk_gc_set_foreground (gc, &old_values.foreground);
+}
+
+static void
+paint_arrow (GdkWindow *window, GdkGC *gc, GtkArrowType arrow_type,
+ int x, int y, int width, int height)
+{
+ int half_width, half_height;
+ int center_x, center_y;
+
+ if ((width & 1) == 0)
+ width = width - 1;
+ if ((height & 1) == 0)
+ height = height - 1;
+
+ half_width = width / 2;
+ half_height = height / 2;
+
+ center_x = x + half_width;
+ center_y = y + half_height;
+
+ switch (arrow_type)
+ {
+ int i;
+ static int offset[5] = { 0, -1, -2, -3, -4 };
+ static int length[5] = { 0, 2, 4, 6, 8 };
+ static const int size = 4;
+
+ case GTK_ARROW_UP:
+ for (i = 0; i < size; i++)
+ {
+ gdk_draw_line (window, gc,
+ center_x + offset[i],
+ center_y - 2 + i,
+ center_x + offset[i] + length[i],
+ center_y - 2 + i);
+ }
+ break;
+
+ case GTK_ARROW_DOWN:
+ for (i = 0; i < size; i++)
+ {
+ gdk_draw_line (window, gc,
+ center_x + offset[i],
+ center_y + 2 - i,
+ center_x + offset[i] + length[i],
+ center_y + 2 - i);
+ }
+ break;
+
+ case GTK_ARROW_LEFT:
+ for (i = 0; i < size; i++)
+ {
+ gdk_draw_line (window, gc,
+ center_x - 2 + i,
+ center_y + offset[i],
+ center_x - 2 + i,
+ center_y + offset[i] + length[i]);
+ }
+ break;
+
+ case GTK_ARROW_RIGHT:
+ for (i = 0; i < size; i++)
+ {
+ gdk_draw_line (window, gc,
+ center_x + 2 - i,
+ center_y + offset[i],
+ center_x + 2 - i,
+ center_y + offset[i] + length[i]);
+ }
+ break;
+ }
+}
+
+static void
+paint_tick (GdkWindow *window, GdkGC *gc, int x, int y)
+{
+#define PIXEL(a,b) gdk_draw_point (window, gc, x + a, y + b)
+
+ PIXEL (4, -4);
+ PIXEL (3, -3); PIXEL (4, -3); PIXEL (5, -3);
+ PIXEL (-2, -2);
+ PIXEL (2, -2); PIXEL (3, -2); PIXEL (4, -2);
+ PIXEL (-3, -1); PIXEL (-2, -1); PIXEL (-1, -1);
+ PIXEL (1, -1); PIXEL (2, -1); PIXEL (3, -1);
+ PIXEL (-2, 0); PIXEL (-1, 0); PIXEL (0, 0); PIXEL (1, 0); PIXEL (2, 0);
+ PIXEL (-1, 1); PIXEL (0, 1); PIXEL (1, 1);
+ PIXEL (0, 2);
+
+#undef PIXEL
+}
+
+static void
+paint_bullet (GdkWindow *window, GdkGC *gc, int x, int y)
+{
+#define PIXEL(a, b) gdk_draw_point (window, gc, x + a, x + b)
+
+ PIXEL (0, 0); PIXEL (0, -1); PIXEL (-1, 0); PIXEL (-1, -1);
+ PIXEL (1, -1); PIXEL (2, -1); PIXEL (-1, 1); PIXEL (-1, 2);
+
+ PIXEL (0, -2); PIXEL (1, -2);
+ PIXEL (-2, 0); PIXEL (-2, 1);
+ PIXEL (1, 0); PIXEL (2, 0); PIXEL (3, 0);
+ PIXEL (0, 1); PIXEL (1, 1); PIXEL (2, 1); PIXEL (3, 1);
+ PIXEL (0, 2); PIXEL (1, 2); PIXEL (2, 2);
+ PIXEL (0, 3); PIXEL (1, 3);
+
+ PIXEL (-1, -2); PIXEL (-2, -1); PIXEL (2, -2); PIXEL (3, -1);
+ PIXEL (-2, 2); PIXEL (-1, 3); PIXEL (2, 3); PIXEL (3, 2);
+
+#undef PIXEL
+}
+
+
+/* style functions */
+
+static void
+draw_hline (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ gint x1, gint x2, gint y)
+{
+ gint thickness_light;
+ gint thickness_dark;
+ gint i;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_hline: detail=%s state=%d x1=%d x2=%d y=%d\n",
+ detail, state_type, x1, x2, y);
+
+ thickness_light = style->klass->ythickness / 2;
+ thickness_dark = style->klass->ythickness - thickness_light;
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+ }
+ for (i = 0; i < thickness_dark; i++)
+ {
+ gdk_draw_line (window, style->light_gc[state_type], x2 - i - 1,
+ y + i, x2, y + i);
+ gdk_draw_line (window, style->dark_gc[state_type], x1, y + i,
+ x2 - i - 1, y + i);
+ }
+
+ y += thickness_dark;
+ for (i = 0; i < thickness_light; i++)
+ {
+ gdk_draw_line (window, style->dark_gc[state_type], x1, y + i,
+ x1 + thickness_light - i - 1, y + i);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x1 + thickness_light - i - 1, y + i, x2, y + i);
+ }
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+ }
+}
+
+static void
+draw_vline (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget, gchar *detail, gint y1, gint y2, gint x)
+{
+ gint thickness_light;
+ gint thickness_dark;
+ gint i;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_vline: detail=%s state=%d x=%d y1=%d y2=%d\n",
+ detail, state_type, x, y1, y2);
+
+ thickness_light = style->klass->xthickness / 2;
+ thickness_dark = style->klass->xthickness - thickness_light;
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+ }
+ for (i = 0; i < thickness_dark; i++)
+ {
+ gdk_draw_line (window, style->light_gc[state_type], x + i,
+ y2 - i - 1, x + i, y2);
+ gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i,
+ y2 - i - 1);
+ }
+
+ x += thickness_dark;
+ for (i = 0; i < thickness_light; i++)
+ {
+ gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i,
+ y1 + thickness_light - i);
+ gdk_draw_line (window, style->light_gc[state_type], x + i,
+ y1 + thickness_light - i, x + i, y2);
+ }
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+ }
+}
+
+static void
+draw_shadow (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ GdkGC *gc1 = NULL;
+ GdkGC *gc2 = NULL;
+ GdkGC *gc3 = NULL;
+ GdkGC *gc4 = NULL;
+ GdkGC *gc_a, *gc_b, *gc_c, *gc_d;
+ gint thickness_light;
+ gint thickness_dark;
+ gboolean rounded = FALSE, rounded_inner = FALSE;
+ gboolean outline = TRUE;
+ gint i;
+
+ eazel_theme_data *theme_data;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ outline = theme_data->outline_shadow;
+
+ if (widget != 0 && !GTK_WIDGET_IS_SENSITIVE (widget))
+ state_type = GTK_STATE_INSENSITIVE;
+
+ debug ("draw_shadow: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ switch (shadow_type)
+ {
+ case GTK_SHADOW_NONE:
+ return;
+ case GTK_SHADOW_IN:
+ case GTK_SHADOW_ETCHED_IN:
+ if (theme_data->inverse_shadow)
+ goto out;
+ in:
+ gc1 = style->light_gc[state_type];
+ gc2 = style->dark_gc[state_type];
+ gc3 = style->mid_gc[state_type];
+ gc4 = style->bg_gc[state_type];
+ break;
+ case GTK_SHADOW_OUT:
+ case GTK_SHADOW_ETCHED_OUT:
+ if (theme_data->inverse_shadow)
+ goto in;
+ out:
+ gc1 = style->dark_gc[state_type];
+ gc2 = style->light_gc[state_type];
+ gc3 = style->mid_gc[state_type];
+ gc4 = style->bg_gc[state_type];
+ break;
+ }
+
+ gc_a = gc2;
+ gc_b = gc4;
+ gc_c = 0;
+ gc_d = gc1;
+
+ if (DETAIL ("button") || DETAIL ("optionmenu"))
+ {
+ /* Clist title buttons have square edges */
+ if (widget == 0 || !GTK_IS_CLIST (widget->parent))
+ rounded = rounded_inner = TRUE;
+ }
+ else if (DETAIL ("menuitem"))
+ {
+ paint_menuitem_shadow (window, style, x, y, width, height);
+ return;
+ }
+ else if (DETAIL ("entry") || DETAIL ("text"))
+ {
+ if (widget == 0 || GTK_WIDGET_IS_SENSITIVE (widget))
+ {
+ paint_entry_shadow (window, style, state_type,
+ x, y, width, height);
+ return;
+ }
+ }
+ else if (DETAIL ("spinbutton"))
+ {
+ gc_a = gc2;
+ gc_b = 0;
+ outline = FALSE;
+ }
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (gc1, area);
+ gdk_gc_set_clip_rectangle (gc2, area);
+ gdk_gc_set_clip_rectangle (gc3, area);
+ gdk_gc_set_clip_rectangle (gc4, area);
+ if ((shadow_type == GTK_SHADOW_IN) || (shadow_type == GTK_SHADOW_OUT))
+ {
+ gdk_gc_set_clip_rectangle (style->black_gc, area);
+ gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
+ }
+ }
+ switch (shadow_type)
+ {
+ case GTK_SHADOW_NONE:
+ break;
+
+ case GTK_SHADOW_IN:
+ case GTK_SHADOW_OUT:
+ if (state_type == GTK_STATE_INSENSITIVE)
+ {
+ paint_insensitive_box (theme_data, window,
+ style->bg_gc[state_type],
+ rounded, x, y, width, height);
+ }
+ else if (outline)
+ {
+ paint_outline (window, style->black_gc, rounded,
+ x, y, width, height);
+ if (!theme_data->no_shadow)
+ {
+ paint_shadow (window, gc_a, gc_b, gc_c, gc_d, rounded,
+ x + 1, y + 1, width - 2, height - 2);
+ }
+ }
+ else
+ {
+ if (!theme_data->no_shadow)
+ {
+ paint_shadow (window, gc_a, gc_b, gc_c, gc_d, rounded,
+ x, y, width, height);
+ }
+ }
+ break;
+
+ case GTK_SHADOW_ETCHED_IN:
+ case GTK_SHADOW_ETCHED_OUT:
+ thickness_light = 1;
+ thickness_dark = 1;
+
+ for (i = 0; i < thickness_dark; i++)
+ {
+ gdk_draw_line (window, gc1,
+ x + i,
+ y + height - i - 1,
+ x + width - i - 1, y + height - i - 1);
+ gdk_draw_line (window, gc1,
+ x + width - i - 1,
+ y + i, x + width - i - 1, y + height - i - 1);
+
+ gdk_draw_line (window, gc2,
+ x + i, y + i, x + width - i - 2, y + i);
+ gdk_draw_line (window, gc2,
+ x + i, y + i, x + i, y + height - i - 2);
+ }
+
+ for (i = 0; i < thickness_light; i++)
+ {
+ gdk_draw_line (window, gc1,
+ x + thickness_dark + i,
+ y + thickness_dark + i,
+ x + width - thickness_dark - i - 1,
+ y + thickness_dark + i);
+ gdk_draw_line (window, gc1,
+ x + thickness_dark + i,
+ y + thickness_dark + i,
+ x + thickness_dark + i,
+ y + height - thickness_dark - i - 1);
+
+ gdk_draw_line (window, gc2,
+ x + thickness_dark + i,
+ y + height - thickness_light - i - 1,
+ x + width - thickness_light - 1,
+ y + height - thickness_light - i - 1);
+ gdk_draw_line (window, gc2,
+ x + width - thickness_light - i - 1,
+ y + thickness_dark + i,
+ x + width - thickness_light - i - 1,
+ y + height - thickness_light - 1);
+ }
+ break;
+ }
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (gc1, NULL);
+ gdk_gc_set_clip_rectangle (gc2, NULL);
+ gdk_gc_set_clip_rectangle (gc3, NULL);
+ gdk_gc_set_clip_rectangle (gc4, NULL);
+ if ((shadow_type == GTK_SHADOW_IN) || (shadow_type == GTK_SHADOW_OUT))
+ {
+ gdk_gc_set_clip_rectangle (style->black_gc, NULL);
+ gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
+ }
+ }
+}
+
+static void
+draw_box (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ gboolean add_shadow = FALSE;
+ eazel_theme_data *theme_data;
+ gboolean set_bg = FALSE;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((width == -1) && (height == -1))
+ {
+ gdk_window_get_size (window, &width, &height);
+ if (gdk_window_get_type (window) != GDK_WINDOW_PIXMAP)
+ set_bg = TRUE;
+ }
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ if (widget != 0 && !GTK_WIDGET_IS_SENSITIVE (widget))
+ state_type = GTK_STATE_INSENSITIVE;
+
+ debug ("draw_box: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ if ((!style->bg_pixmap[state_type]) ||
+ (gdk_window_get_type (window) == GDK_WINDOW_PIXMAP))
+ {
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->black_gc, area);
+ }
+
+ if (DETAIL ("trough"))
+ {
+ if (GTK_IS_PROGRESS_BAR (widget))
+ {
+ if (state_type != GTK_STATE_INSENSITIVE)
+ {
+ paint_stock_image (theme_data,
+ EAZEL_ENGINE_PROGRESS_TROUGH,
+ TRUE, FALSE,
+ style, window, state_type, area,
+ widget, x, y, width, height);
+ }
+ else
+ {
+ paint_insensitive_box (theme_data, window,
+ style->fg_gc[state_type],
+ FALSE, x, y, width, height);
+ }
+ }
+ else if (GTK_IS_SCALE (widget))
+ {
+ gboolean focused = GTK_WIDGET_HAS_FOCUS (widget);
+ paint_background_area (style, window, state_type, area,
+ x, y, width, height);
+ paint_stock_image (theme_data,
+ width > height
+ ? (focused
+ ? EAZEL_ENGINE_H_SLIDER_TROUGH_ACTIVE
+ : EAZEL_ENGINE_H_SLIDER_TROUGH)
+ : (focused
+ ? EAZEL_ENGINE_V_SLIDER_TROUGH_ACTIVE
+ : EAZEL_ENGINE_V_SLIDER_TROUGH),
+ TRUE, FALSE, style, window, state_type,
+ area, widget, x, y, width, height);
+ }
+ else
+ {
+ paint_stock_image (theme_data,
+ width > height ? EAZEL_ENGINE_H_TROUGH
+ : EAZEL_ENGINE_V_TROUGH, TRUE, FALSE,
+ style, window, state_type, area,
+ widget, x, y, width, height);
+ }
+ }
+ else if (DETAIL ("slider"))
+ {
+ int thumb_x, thumb_y;
+ gboolean focused;
+
+ focused = eazel_engine_widget_in_focused_window_p (widget);
+
+ /* XXX could be a gradient? */
+ paint_stock_image (theme_data,
+ width > height
+ ? (state_type == GTK_STATE_PRELIGHT
+ ? EAZEL_ENGINE_H_SCROLLBAR_HI
+ : !focused
+ ? EAZEL_ENGINE_H_SCROLLBAR_INACTIVE
+ : EAZEL_ENGINE_H_SCROLLBAR)
+ : (state_type == GTK_STATE_PRELIGHT
+ ? EAZEL_ENGINE_V_SCROLLBAR_HI
+ : !focused
+ ? EAZEL_ENGINE_V_SCROLLBAR_INACTIVE
+ : EAZEL_ENGINE_V_SCROLLBAR),
+ TRUE, FALSE, style, window, state_type, area,
+ widget, x, y, width, height);
+ if (width > height)
+ {
+ /* XXX `4' is 1/2 width of thumb */
+ thumb_x = x + width / 2 - 4;
+ thumb_y = y;
+ }
+ else
+ {
+ thumb_x = x;
+ /* XXX `4' is 1/2 height of thumb */
+ thumb_y = y + height / 2 - 4;
+ }
+
+ paint_stock_image (theme_data,
+ width > height
+ ? (state_type == GTK_STATE_PRELIGHT
+ ? EAZEL_ENGINE_H_SCROLLBAR_THUMB_HI
+ : !focused
+ ? EAZEL_ENGINE_H_SCROLLBAR_THUMB_INACTIVE
+ : EAZEL_ENGINE_H_SCROLLBAR_THUMB)
+ : (state_type == GTK_STATE_PRELIGHT
+ ? EAZEL_ENGINE_V_SCROLLBAR_THUMB_HI
+ : !focused
+ ? EAZEL_ENGINE_V_SCROLLBAR_THUMB_INACTIVE
+ : EAZEL_ENGINE_V_SCROLLBAR_THUMB),
+ FALSE, FALSE, style, window, state_type, area,
+ widget, thumb_x, thumb_y, -1, -1);
+ }
+ else if (DETAIL ("vscrollbar"))
+ {
+ }
+ else if (DETAIL ("hscrollbar"))
+ {
+ }
+ else if (DETAIL ("bar"))
+ {
+ if (state_type != GTK_STATE_INSENSITIVE)
+ {
+ gboolean focused;
+ focused = eazel_engine_widget_in_focused_window_p (widget);
+ paint_stock_image (theme_data,
+ focused ? EAZEL_ENGINE_PROGRESS_BAR
+ : EAZEL_ENGINE_PROGRESS_BAR_INACTIVE,
+ TRUE, FALSE, style, window, state_type,
+ area, widget, x, y, width, height);
+ if (x > style->klass->xthickness)
+ {
+ paint_stock_image (theme_data,
+ EAZEL_ENGINE_PROGRESS_BAR_LEFT,
+ TRUE, FALSE, style, window, state_type,
+ area, widget, x - 2, y, -1, height);
+ }
+ if (widget != 0
+ && x + width < widget->allocation.width - style->klass->xthickness - 3)
+ {
+ paint_stock_image (theme_data,
+ EAZEL_ENGINE_PROGRESS_BAR_RIGHT,
+ TRUE, FALSE, style, window,
+ state_type, area, widget,
+ x + width, y, -1, height);
+ }
+ }
+ else
+ {
+ paint_insensitive_box (theme_data, window,
+ style->fg_gc[state_type],
+ FALSE, x, y, width, height);
+ }
+ }
+ else if (DETAIL ("optionmenutab"))
+ {
+ int real_width, real_height;
+ int y1, y2;
+ int center_x, center_y;
+
+ gdk_window_get_size (window, &real_width, &real_height);
+
+ y1 = style->klass->ythickness + 1;
+ y2 = real_height - style->klass->ythickness - 2;
+ gdk_draw_line (window, style->dark_gc[state_type]
+ , x, y1, x, y2);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + 1, y1, x +1, y2);
+
+ center_x = x + (real_width - x) / 2;
+ center_y = real_height / 2;
+
+ paint_arrow (window, style->fg_gc[state_type], GTK_ARROW_UP,
+ center_x - 4, center_y - 6, 7, 7);
+ paint_arrow (window, style->fg_gc[state_type], GTK_ARROW_DOWN,
+ center_x - 4, center_y - 1, 7, 7);
+ }
+ else if (DETAIL ("buttondefault"))
+ {
+ /* Don't draw default markings. */
+ }
+ else
+ {
+ GdkRectangle full;
+
+ eazel_engine_gradient *gradient = theme_data->gradients[state_type];
+ add_shadow = (shadow_type != GTK_SHADOW_NONE);
+
+ if (DETAIL ("button") && widget != 0
+ && GTK_WIDGET_HAS_FOCUS (widget)
+ && GTK_WIDGET_CAN_DEFAULT (widget))
+ {
+ x -= 1;
+ y -= 1;
+ width += 2;
+ height += 2;
+ }
+
+ full.x = x;
+ full.y = y;
+ full.width = width;
+ full.height = height;
+
+ if (DETAIL ("menuitem"))
+ {
+ full.x++; full.y++;
+ full.width -= 2; full.height -= 2;
+ }
+
+ if (gradient != NULL && gradient->direction != GRADIENT_NONE)
+ {
+ if (!set_bg)
+ {
+ eazel_engine_draw_gradient (window,
+ style->bg_gc[state_type],
+ &full, &full, gradient);
+ }
+ else
+ {
+ GdkRectangle dest;
+ if (area != 0)
+ gdk_rectangle_intersect (&full, area, &dest);
+ else
+ dest = full;
+ eazel_engine_set_bg_gradient (window, gradient);
+ gdk_window_clear_area (window, dest.x, dest.y,
+ dest.width, dest.height);
+ }
+ }
+ else
+ {
+ if (!set_bg)
+ {
+ gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE,
+ x, y, width, height);
+ }
+ else
+ {
+ GdkRectangle dest;
+ if (area != 0)
+ gdk_rectangle_intersect (&full, area, &dest);
+ else
+ dest = full;
+ gdk_window_set_background (window, &style->bg[state_type]);
+ gdk_window_clear_area (window, dest.x, dest.y,
+ dest.width, dest.height);
+ }
+ }
+
+ if (DETAIL ("button") && widget != 0
+ && GTK_WIDGET_HAS_DEFAULT (widget))
+ {
+ void (*fun) (eazel_theme_data *, GdkWindow *, GdkGC *, gboolean, gboolean, int, int, int, int, int) = paint_default_box;
+
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ fun = paint_focus_box;
+
+ fun (theme_data, window, style->black_gc, TRUE, TRUE,
+ theme_data->default_thickness,
+ x - (theme_data->default_thickness),
+ y - (theme_data->default_thickness),
+ width + theme_data->default_thickness * 2 - 1,
+ height + theme_data->default_thickness * 2 - 1);
+ }
+ }
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->black_gc, NULL);
+ }
+ }
+ else
+ {
+ gtk_style_apply_default_pixmap (style, window, state_type, area, x,
+ y, width, height);
+ }
+
+ if (add_shadow)
+ {
+ gtk_paint_shadow (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+ }
+}
+
+static void
+draw_polygon (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, GdkPoint *points, gint npoints, gint fill)
+{
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif /*
+ * M_PI
+ */
+#ifndef M_PI_4
+#define M_PI_4 0.78539816339744830962
+#endif /*
+ * M_PI_4
+ */
+
+ static const gdouble pi_over_4 = M_PI_4;
+ static const gdouble pi_3_over_4 = M_PI_4 * 3;
+
+ GdkGC *gc1;
+ GdkGC *gc2;
+ GdkGC *gc3;
+ GdkGC *gc4;
+ gdouble angle;
+ gint xadjust;
+ gint yadjust;
+ gint i;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (points != NULL);
+
+ debug ("draw_polygon: detail=%s state=%d shadow=%d\n",
+ detail, state_type, shadow_type);
+
+ switch (shadow_type)
+ {
+ case GTK_SHADOW_IN:
+ gc1 = style->light_gc[state_type];
+ gc2 = style->dark_gc[state_type];
+ gc3 = style->light_gc[state_type];
+ gc4 = style->dark_gc[state_type];
+ break;
+ case GTK_SHADOW_ETCHED_IN:
+ gc1 = style->light_gc[state_type];
+ gc2 = style->dark_gc[state_type];
+ gc3 = style->dark_gc[state_type];
+ gc4 = style->light_gc[state_type];
+ break;
+ case GTK_SHADOW_OUT:
+ gc1 = style->dark_gc[state_type];
+ gc2 = style->light_gc[state_type];
+ gc3 = style->dark_gc[state_type];
+ gc4 = style->light_gc[state_type];
+ break;
+ case GTK_SHADOW_ETCHED_OUT:
+ gc1 = style->dark_gc[state_type];
+ gc2 = style->light_gc[state_type];
+ gc3 = style->light_gc[state_type];
+ gc4 = style->dark_gc[state_type];
+ break;
+ default:
+ return;
+ }
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (gc1, area);
+ gdk_gc_set_clip_rectangle (gc2, area);
+ gdk_gc_set_clip_rectangle (gc3, area);
+ gdk_gc_set_clip_rectangle (gc4, area);
+ }
+
+ if (fill)
+ gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points,
+ npoints);
+
+ npoints--;
+
+ for (i = 0; i < npoints; i++)
+ {
+ if ((points[i].x == points[i + 1].x) &&
+ (points[i].y == points[i + 1].y))
+ {
+ angle = 0;
+ }
+ else
+ {
+ angle = atan2 (points[i + 1].y - points[i].y,
+ points[i + 1].x - points[i].x);
+ }
+
+ if ((angle > -pi_3_over_4) && (angle < pi_over_4))
+ {
+ if (angle > -pi_over_4)
+ {
+ xadjust = 0;
+ yadjust = 1;
+ }
+ else
+ {
+ xadjust = 1;
+ yadjust = 0;
+ }
+
+ gdk_draw_line (window, gc1,
+ points[i].x - xadjust, points[i].y - yadjust,
+ points[i + 1].x - xadjust,
+ points[i + 1].y - yadjust);
+ gdk_draw_line (window, gc3, points[i].x, points[i].y,
+ points[i + 1].x, points[i + 1].y);
+ }
+ else
+ {
+ if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
+ {
+ xadjust = 0;
+ yadjust = 1;
+ }
+ else
+ {
+ xadjust = 1;
+ yadjust = 0;
+ }
+
+ gdk_draw_line (window, gc4,
+ points[i].x + xadjust, points[i].y + yadjust,
+ points[i + 1].x + xadjust,
+ points[i + 1].y + yadjust);
+ gdk_draw_line (window, gc2, points[i].x, points[i].y,
+ points[i + 1].x, points[i + 1].y);
+ }
+ }
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (gc1, NULL);
+ gdk_gc_set_clip_rectangle (gc2, NULL);
+ gdk_gc_set_clip_rectangle (gc3, NULL);
+ gdk_gc_set_clip_rectangle (gc4, NULL);
+ }
+}
+
+static void
+draw_arrow (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ GtkArrowType arrow_type,
+ gint fill, gint x, gint y, gint width, gint height)
+{
+ eazel_theme_data *theme_data;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ debug ("draw_arrow: detail=%s state=%d shadow=%d arrow_type=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, arrow_type, x, y, width, height);
+
+ if (DETAIL ("vscrollbar") || DETAIL ("hscrollbar"))
+ {
+ int type;
+ switch (arrow_type)
+ {
+ case GTK_ARROW_UP:
+ type = EAZEL_ENGINE_ARROW_UP;
+ break;
+
+ case GTK_ARROW_DOWN:
+ type = EAZEL_ENGINE_ARROW_DOWN;
+ break;
+
+ case GTK_ARROW_LEFT:
+ type = EAZEL_ENGINE_ARROW_LEFT;
+ break;
+
+ case GTK_ARROW_RIGHT:
+ type = EAZEL_ENGINE_ARROW_RIGHT;
+ break;
+ }
+
+ type += (state_type == GTK_STATE_ACTIVE ? 2
+ : state_type == GTK_STATE_PRELIGHT ? 1 : 0);
+
+ paint_stock_image (theme_data, type, TRUE, FALSE,
+ style, window, state_type,
+ area, widget, x, y, width, height);
+ }
+ else if (DETAIL ("spinbutton"))
+ {
+ int window_width, window_height;
+ int tem_x, tem_y;
+
+ if (widget != 0 && !GTK_WIDGET_IS_SENSITIVE (widget))
+ state_type = GTK_STATE_INSENSITIVE;
+
+ gdk_window_get_size (window, &window_width, &window_height);
+
+ if (state_type != GTK_STATE_INSENSITIVE)
+ {
+ draw_box (style, window, state_type, shadow_type,
+ area, widget, detail,
+ x, y - (arrow_type == GTK_ARROW_DOWN),
+ width, height + 1);
+ }
+ else if (arrow_type == GTK_ARROW_UP)
+ {
+ /* XXX A hack, assumes that up arrow is drawn before
+ XXX down arrow. (Currently it is) */
+
+ draw_shadow (style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ NULL, widget, "entry", x - 2, 0,
+ width + 4, window_height);
+ }
+
+ tem_x = x + (width / 2);
+ tem_y = y + (height / 2);
+ if (arrow_type == GTK_ARROW_UP)
+ {
+ int i;
+ tem_y--;
+ for (i = 0; i < 4; i++)
+ {
+ gdk_draw_line (window, style->fg_gc[state_type],
+ tem_x - i, tem_y + i, tem_x + i, tem_y + i);
+ }
+ }
+ else
+ {
+ int i;
+ tem_y -= 3;
+ for (i = 0; i < 4; i++)
+ {
+ gdk_draw_line (window, style->fg_gc[state_type],
+ tem_x - i, tem_y + (4 - i),
+ tem_x + i, tem_y + (4 - i));
+ }
+ }
+
+ if (state_type != GTK_STATE_INSENSITIVE)
+ {
+ draw_shadow (style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ NULL, widget, "entry", x - 2, 0,
+ width + 4, window_height);
+ }
+ }
+ else
+ {
+ if (widget != 0 && !GTK_WIDGET_IS_SENSITIVE (widget))
+ state_type = GTK_STATE_INSENSITIVE;
+
+ paint_arrow (window, style->fg_gc[state_type],
+ arrow_type, x, y, width, height);
+ }
+}
+
+static void
+draw_diamond (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ gint half_width;
+ gint half_height;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_diamond: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ half_width = width / 2;
+ half_height = height / 2;
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->black_gc, area);
+ }
+ switch (shadow_type)
+ {
+ case GTK_SHADOW_IN:
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + 2, y + half_height,
+ x + half_width, y + height - 2);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + half_width, y + height - 2,
+ x + width - 2, y + half_height);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + 1, y + half_height,
+ x + half_width, y + height - 1);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + half_width, y + height - 1,
+ x + width - 1, y + half_height);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x, y + half_height, x + half_width, y + height);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + half_width, y + height,
+ x + width, y + half_height);
+
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + 2, y + half_height, x + half_width, y + 2);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + half_width, y + 2, x + width - 2, y + half_height);
+ gdk_draw_line (window, style->dark_gc[state_type], x + 1,
+ y + half_height, x + half_width, y + 1);
+ gdk_draw_line (window, style->dark_gc[state_type], x + half_width,
+ y + 1, x + width - 1, y + half_height);
+ gdk_draw_line (window, style->dark_gc[state_type], x,
+ y + half_height, x + half_width, y);
+ gdk_draw_line (window, style->dark_gc[state_type], x + half_width,
+ y, x + width, y + half_height);
+ break;
+ case GTK_SHADOW_OUT:
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + 2, y + half_height,
+ x + half_width, y + height - 2);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + half_width, y + height - 2,
+ x + width - 2, y + half_height);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + 1, y + half_height,
+ x + half_width, y + height - 1);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + half_width, y + height - 1,
+ x + width - 1, y + half_height);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x, y + half_height, x + half_width, y + height);
+ gdk_draw_line (window, style->dark_gc[state_type],
+ x + half_width, y + height,
+ x + width, y + half_height);
+
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + 2, y + half_height, x + half_width, y + 2);
+ gdk_draw_line (window, style->light_gc[state_type],
+ x + half_width, y + 2, x + width - 2, y + half_height);
+ gdk_draw_line (window, style->light_gc[state_type], x + 1,
+ y + half_height, x + half_width, y + 1);
+ gdk_draw_line (window, style->light_gc[state_type], x + half_width,
+ y + 1, x + width - 1, y + half_height);
+ gdk_draw_line (window, style->light_gc[state_type], x,
+ y + half_height, x + half_width, y);
+ gdk_draw_line (window, style->light_gc[state_type], x + half_width,
+ y, x + width, y + half_height);
+ break;
+ default:
+ break;
+ }
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->black_gc, NULL);
+ }
+}
+
+static void
+draw_oval (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+}
+
+static void
+draw_string (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, const gchar *string)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_string: detail=%s state=%d x=%d y=%d\n",
+ detail, state_type, x, y);
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->white_gc, area);
+ gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
+ }
+ if (state_type == GTK_STATE_INSENSITIVE)
+ gdk_draw_string (window, style->font, style->white_gc, x + 1, y + 1,
+ string);
+ gdk_draw_string (window, style->font, style->fg_gc[state_type], x, y,
+ string);
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->white_gc, NULL);
+ gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
+ }
+}
+
+static void
+draw_flat_box (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ GdkGC *gc1;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ debug ("draw_flat_box: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ gc1 = style->bg_gc[state_type];
+
+ if (DETAIL ("text") && (state_type == GTK_STATE_SELECTED))
+ gc1 = style->bg_gc[GTK_STATE_SELECTED];
+ else if (DETAIL ("viewportbin"))
+ gc1 = style->bg_gc[GTK_STATE_NORMAL];
+ else if (DETAIL ("entry_bg"))
+ gc1 = style->white_gc;
+
+ if ((!style->bg_pixmap[state_type])
+ || (gc1 != style->bg_gc[state_type])
+ || (gdk_window_get_type (window) == GDK_WINDOW_PIXMAP))
+ {
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (gc1, area);
+ }
+ gdk_draw_rectangle (window, gc1, TRUE, x, y, width, height);
+ if ((detail) && (!strcmp ("tooltip", detail)))
+ gdk_draw_rectangle (window, style->black_gc, FALSE,
+ x, y, width - 1, height - 1);
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (gc1, NULL);
+ }
+ }
+ else
+ gtk_style_apply_default_pixmap (style, window, state_type, area, x,
+ y, width, height);
+}
+
+static void
+paint_check (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height,
+ eazel_engine_stock_image stock_base)
+{
+ eazel_engine_stock_image type;
+ gboolean active = (shadow_type != GTK_SHADOW_OUT);
+ gboolean has_focus = (widget != 0 && GTK_WIDGET_HAS_FOCUS (widget));
+ gboolean menu_item = (widget != 0 && gtk_widget_get_ancestor (widget, GTK_TYPE_MENU_ITEM));
+
+ eazel_theme_data *theme_data;
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ if (DETAIL ("checkbutton") || DETAIL ("radiobutton"))
+ {
+ /* correct for braindeath in gtk_real_check_button_draw_indicator */
+ if (widget != 0 && GTK_IS_TOGGLE_BUTTON (widget))
+ active = GTK_TOGGLE_BUTTON (widget)->active;
+ if (widget != 0)
+ {
+ state_type = GTK_WIDGET_STATE (widget);
+ /* XXX the widget gives us no way to tell between
+ XXX checked, and checked-and-clicked states.. */
+ if (active && state_type == GTK_STATE_ACTIVE)
+ state_type = GTK_STATE_NORMAL;
+ }
+ }
+
+ if (!menu_item)
+ {
+ switch (state_type)
+ {
+ case GTK_STATE_INSENSITIVE:
+ type = (!active ? EAZEL_ENGINE_CHECK_DISABLED
+ : EAZEL_ENGINE_CHECK_ACTIVE_DISABLED);
+ break;
+
+ case GTK_STATE_PRELIGHT:
+ type = (active
+ ? (has_focus ? EAZEL_ENGINE_CHECK_ACTIVE_HI_FOCUS
+ : EAZEL_ENGINE_CHECK_ACTIVE_HI)
+ : (has_focus ? EAZEL_ENGINE_CHECK_HI_FOCUS
+ : EAZEL_ENGINE_CHECK_HI));
+ break;
+
+ case GTK_STATE_ACTIVE:
+ type = (active
+ ? (has_focus ? EAZEL_ENGINE_CHECK_ACTIVE_PRESSED_FOCUS
+ : EAZEL_ENGINE_CHECK_ACTIVE)
+ : (has_focus ? EAZEL_ENGINE_CHECK_PRESSED_FOCUS
+ : EAZEL_ENGINE_CHECK_PRESSED));
+ break;
+
+ default:
+ type = (active
+ ? (has_focus ? EAZEL_ENGINE_CHECK_ACTIVE_FOCUS
+ : EAZEL_ENGINE_CHECK_ACTIVE)
+ : (has_focus ? EAZEL_ENGINE_CHECK_FOCUS
+ : EAZEL_ENGINE_CHECK));
+ }
+
+ paint_stock_image (theme_data, type + stock_base,
+ FALSE, FALSE, style, window,
+ state_type, area, widget,
+ x-3, y-3, width+6, height+6);
+ }
+ else
+ {
+ if (!active)
+ return;
+
+ if (stock_base == EAZEL_ENGINE_CHECK)
+ {
+ paint_tick (window, style->fg_gc[state_type],
+ x + width / 2, y + width / 2);
+ }
+ else
+ {
+ paint_bullet (window, style->fg_gc[state_type],
+ x + width / 2, y + width / 2);
+ }
+ }
+}
+
+static void
+draw_check (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ paint_check (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height, EAZEL_ENGINE_CHECK);
+}
+
+static void
+draw_option (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ paint_check (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height, EAZEL_ENGINE_OPTION);
+}
+
+static void
+draw_cross (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+}
+
+static void
+draw_ramp (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+}
+
+static void
+draw_tab (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ gtk_paint_box (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+}
+
+static void
+draw_shadow_gap (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkPositionType gap_side, gint gap_x, gint gap_width)
+{
+ GdkRectangle rect;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_shadow_gap: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ gtk_paint_shadow (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+
+ switch (gap_side)
+ {
+ case GTK_POS_TOP:
+ rect.x = x + gap_x;
+ rect.y = y;
+ rect.width = gap_width;
+ rect.height = 2;
+ break;
+ case GTK_POS_BOTTOM:
+ rect.x = x + gap_x;
+ rect.y = y + height - 2;
+ rect.width = gap_width;
+ rect.height = 2;
+ break;
+ case GTK_POS_LEFT:
+ rect.x = x;
+ rect.y = y + gap_x;
+ rect.width = 2;
+ rect.height = gap_width;
+ break;
+ case GTK_POS_RIGHT:
+ rect.x = x + width - 2;
+ rect.y = y + gap_x;
+ rect.width = 2;
+ rect.height = gap_width;
+ break;
+ }
+
+ gtk_style_apply_default_pixmap (style, window, state_type, area,
+ rect.x, rect.y, rect.width, rect.height);
+}
+
+static void
+draw_box_gap (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkPositionType gap_side, gint gap_x, gint gap_width)
+{
+ GdkRectangle rect;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_box_gap: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ gtk_paint_box (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+
+ /* XXX Eavel hack to prevent a hole being draw when the
+ XXX active tab is on the far left */
+ if (gap_x < 1)
+ {
+ gap_width -= (1 - gap_x);
+ gap_x = 1;
+ }
+
+ switch (gap_side)
+ {
+ case GTK_POS_TOP:
+ rect.x = x + gap_x;
+ rect.y = y;
+ rect.width = gap_width;
+ rect.height = 2;
+ break;
+ case GTK_POS_BOTTOM:
+ rect.x = x + gap_x;
+ rect.y = y + height - 2;
+ rect.width = gap_width;
+ rect.height = 2;
+ break;
+ case GTK_POS_LEFT:
+ rect.x = x;
+ rect.y = y + gap_x;
+ rect.width = 2;
+ rect.height = gap_width;
+ break;
+ case GTK_POS_RIGHT:
+ rect.x = x + width - 2;
+ rect.y = y + gap_x;
+ rect.width = 2;
+ rect.height = gap_width;
+ break;
+ }
+
+ gtk_style_apply_default_pixmap (style, window, state_type, area,
+ rect.x, rect.y, rect.width, rect.height);
+}
+
+static void
+draw_extension (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ gint x,
+ gint y, gint width, gint height, GtkPositionType gap_side)
+{
+ GdkRectangle rect;
+
+ eazel_theme_data *theme_data;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ debug ("draw_extension: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+
+ if (DETAIL ("tab"))
+ {
+ eazel_engine_stock_image type = 0;
+ switch (gap_side)
+ {
+ case GTK_POS_TOP:
+ type = ((state_type != GTK_STATE_ACTIVE)
+ ? EAZEL_ENGINE_TAB_BOTTOM_ACTIVE
+ : (x < 10) ? EAZEL_ENGINE_TAB_BOTTOM_LEFT
+ : EAZEL_ENGINE_TAB_BOTTOM);
+ break;
+
+ case GTK_POS_BOTTOM:
+ type = ((state_type != GTK_STATE_ACTIVE)
+ ? EAZEL_ENGINE_TAB_TOP_ACTIVE
+ : (x < 10) ? EAZEL_ENGINE_TAB_TOP_LEFT
+ : EAZEL_ENGINE_TAB_TOP);
+ break;
+
+ default: /* gcc drugging */
+ }
+ paint_background_area (style, window, state_type, area,
+ x, y, width, height);
+ if (type != 0)
+ {
+ paint_stock_image (theme_data, type, TRUE, FALSE, style, window,
+ state_type, area, widget, x, y, width, height);
+ return;
+ }
+ }
+
+ gtk_paint_box (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+
+ switch (gap_side)
+ {
+ case GTK_POS_TOP:
+ rect.x = x + style->klass->xthickness;
+ rect.y = y;
+ rect.width = width - style->klass->xthickness * 2;
+ rect.height = style->klass->ythickness;
+ break;
+ case GTK_POS_BOTTOM:
+ rect.x = x + style->klass->xthickness;
+ rect.y = y + height - style->klass->ythickness;
+ rect.width = width - style->klass->xthickness * 2;
+ rect.height = style->klass->ythickness;
+ break;
+ case GTK_POS_LEFT:
+ rect.x = x;
+ rect.y = y + style->klass->ythickness;
+ rect.width = style->klass->xthickness;
+ rect.height = height - style->klass->ythickness * 2;
+ break;
+ case GTK_POS_RIGHT:
+ rect.x = x + width - style->klass->xthickness;
+ rect.y = y + style->klass->ythickness;
+ rect.width = style->klass->xthickness;
+ rect.height = height - style->klass->ythickness * 2;
+ break;
+ }
+
+ gtk_style_apply_default_pixmap (style, window, state_type, area,
+ rect.x, rect.y, rect.width, rect.height);
+}
+
+static void
+draw_focus (GtkStyle *style,
+ GdkWindow *window,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail, gint x, gint y, gint width, gint height)
+{
+ eazel_theme_data *theme_data;
+ gboolean rounded = TRUE, rounded_inner = TRUE;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ debug ("draw_focus: detail=%s x=%d y=%d w=%d h=%d\n",
+ detail, x, y, width, height);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((DETAIL ("button") && widget != 0
+ && GTK_IS_BUTTON (widget) && GTK_WIDGET_HAS_DEFAULT (widget))
+ || DETAIL ("checkbutton") || DETAIL ("option") || DETAIL ("slider")
+ || (widget != 0 && GTK_IS_SCALE (widget))
+ /* XXX reenable me */
+ || DETAIL ("tab"))
+ {
+ return;
+ }
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ if (area)
+ gdk_gc_set_clip_rectangle (style->black_gc, area);
+
+ if (DETAIL ("button"))
+ {
+ x--; y--;
+ width += 2; height += 2;
+ }
+ else if (DETAIL ("text") || DETAIL ("entry"))
+ {
+ rounded_inner = FALSE;
+ }
+
+ paint_focus_box (theme_data, window, style->black_gc,
+ rounded, rounded_inner, theme_data->focus_thickness,
+ x, y, width, height);
+
+ if (area)
+ gdk_gc_set_clip_rectangle (style->black_gc, NULL);
+}
+
+static void
+draw_slider (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ gint x,
+ gint y, gint width, gint height, GtkOrientation orientation)
+{
+ eazel_theme_data *theme_data;
+ gboolean focused;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ theme_data = STYLE_THEME_DATA (style);
+ g_assert (theme_data != NULL);
+
+ debug ("draw_slider: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ if (area)
+ gdk_gc_set_clip_rectangle (style->black_gc, area);
+
+ focused = (widget != 0) && eazel_engine_widget_in_focused_window_p (widget);
+ paint_stock_image (theme_data,
+ orientation == GTK_ORIENTATION_HORIZONTAL
+ ? (focused ? EAZEL_ENGINE_H_SLIDER_THUMB
+ : EAZEL_ENGINE_H_SLIDER_THUMB_INACTIVE)
+ : (focused ? EAZEL_ENGINE_V_SLIDER_THUMB
+ : EAZEL_ENGINE_V_SLIDER_THUMB_INACTIVE),
+ TRUE, TRUE, style, window, state_type,
+ area, widget, x, y, width, height);
+ if (area)
+ gdk_gc_set_clip_rectangle (style->black_gc, NULL);
+}
+
+static void
+draw_handle (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gchar *detail,
+ gint x,
+ gint y, gint width, gint height, GtkOrientation orientation)
+{
+ gint i, yy, xx;
+ gint xthick, ythick;
+ GdkGC *light_gc, *dark_gc;
+ GdkRectangle dest;
+
+ g_return_if_fail (style != NULL);
+ g_return_if_fail (window != NULL);
+
+ debug ("draw_handle: detail=%s state=%d shadow=%d x=%d y=%d w=%d h=%d\n",
+ detail, state_type, shadow_type, x, y, width, height);
+
+ /* Protection against broken GTK+ widgets */
+ g_return_if_fail (width < 32768);
+ g_return_if_fail (height < 32768);
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ if (DETAIL ("dockitem") && state_type == GTK_STATE_NORMAL)
+ state_type = GTK_STATE_ACTIVE;
+
+ gtk_paint_box (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+
+ light_gc = style->light_gc[state_type];
+ dark_gc = style->dark_gc[state_type];
+
+ xthick = style->klass->xthickness;
+ ythick = style->klass->ythickness;
+
+ dest.x = x + xthick;
+ dest.y = y + ythick;
+ dest.width = width - (xthick * 2);
+ dest.height = height - (ythick * 2);
+
+ gdk_gc_set_clip_rectangle (light_gc, &dest);
+ gdk_gc_set_clip_rectangle (dark_gc, &dest);
+
+ /* ORIENTATION parameters is unreliable */
+ if (height > width)
+ {
+ yy = y + height / 2 - 5;
+ for (i = 0; i < 10; i += 2)
+ {
+ gdk_draw_line (window, dark_gc, xthick, yy + i,
+ x + width - xthick, yy + i);
+ gdk_draw_line (window, light_gc, xthick, yy + i + 1,
+ x + width - xthick, yy + i + 1);
+ }
+ }
+ else
+ {
+ xx = x + width / 2 - 5;
+ for (i = 0; i < 10; i += 2)
+ {
+ gdk_draw_line (window, dark_gc, xx + i, ythick,
+ xx + i, y + height - ythick);
+ gdk_draw_line (window, light_gc, xx + i + 1, ythick,
+ xx + i + 1, y + height - ythick);
+ }
+ }
+
+ gdk_gc_set_clip_rectangle (light_gc, NULL);
+ gdk_gc_set_clip_rectangle (dark_gc, NULL);
+}
+
+
+/*
+ * class struct
+ */
+
+GtkStyleClass eazel_class_0 = {
+ 0, 0,
+ draw_hline,
+ draw_vline,
+ draw_shadow,
+ draw_polygon,
+ draw_arrow,
+ draw_diamond,
+ draw_oval,
+ draw_string,
+ draw_box,
+ draw_flat_box,
+ draw_check,
+ draw_option,
+ draw_cross,
+ draw_ramp,
+ draw_tab,
+ draw_shadow_gap,
+ draw_box_gap,
+ draw_extension,
+ draw_focus,
+ draw_slider,
+ draw_handle
+};
+
+GtkStyleClass eazel_class_1 = {
+ 1, 1,
+ draw_hline,
+ draw_vline,
+ draw_shadow,
+ draw_polygon,
+ draw_arrow,
+ draw_diamond,
+ draw_oval,
+ draw_string,
+ draw_box,
+ draw_flat_box,
+ draw_check,
+ draw_option,
+ draw_cross,
+ draw_ramp,
+ draw_tab,
+ draw_shadow_gap,
+ draw_box_gap,
+ draw_extension,
+ draw_focus,
+ draw_slider,
+ draw_handle
+};
+
+GtkStyleClass eazel_class_2 = {
+ 2, 2,
+ draw_hline,
+ draw_vline,
+ draw_shadow,
+ draw_polygon,
+ draw_arrow,
+ draw_diamond,
+ draw_oval,
+ draw_string,
+ draw_box,
+ draw_flat_box,
+ draw_check,
+ draw_option,
+ draw_cross,
+ draw_ramp,
+ draw_tab,
+ draw_shadow_gap,
+ draw_box_gap,
+ draw_extension,
+ draw_focus,
+ draw_slider,
+ draw_handle
+};
+
+GtkStyleClass eazel_class_3 = {
+ 3, 3,
+ draw_hline,
+ draw_vline,
+ draw_shadow,
+ draw_polygon,
+ draw_arrow,
+ draw_diamond,
+ draw_oval,
+ draw_string,
+ draw_box,
+ draw_flat_box,
+ draw_check,
+ draw_option,
+ draw_cross,
+ draw_ramp,
+ draw_tab,
+ draw_shadow_gap,
+ draw_box_gap,
+ draw_extension,
+ draw_focus,
+ draw_slider,
+ draw_handle
+};
+