Logo Search packages:      
Sourcecode: ia32-libs-gtk version File versions  Download package

industrial_style.c

/**************************************************************************
* GTK Industrial Theme
* Designed by Tigert and Jimmac
* Implemented by Christopher James Lahey
*
* Based on GTK Bluecurve Theme
* Designed by Garrett LeSage
* Implemented by Alexander Larsson
*
* Parts of the code based on Metal theme, Copyright:
* Randy Gordon, randy@integrand.com
* Owen Taylor <otaylor@redhat.com>
*
* License: GPL (Gnu Public License)
*
**************************************************************************/

#include "industrial_style_versioned_include.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define DETAIL(xx)   ((detail) && (!strcmp((xx), detail)))
#if INDUSTRIAL_GTK_VERSION == 2
#define WIDGET_TYPE_NAME(xx) (widget && !strcmp (g_type_name (G_TYPE_FROM_INSTANCE (widget)), (xx)))
#else
#define WIDGET_TYPE_NAME(xx) (FALSE)
#endif
/* #define DEBUG 1 */

static GtkStyleClass *parent_class;

static void
rgb_to_hls (gdouble *r,
            gdouble *g,
            gdouble *b)
{
  gdouble min;
  gdouble max;
  gdouble red;
  gdouble green;
  gdouble blue;
  gdouble h, l, s;
  gdouble delta;
  
  red = *r;
  green = *g;
  blue = *b;
  
  if (red > green)
    {
      if (red > blue)
        max = red;
      else
        max = blue;
      
      if (green < blue)
        min = green;
      else
        min = blue;
    }
  else
    {
      if (green > blue)
        max = green;
      else
        max = blue;
      
      if (red < blue)
        min = red;
      else
        min = blue;
    }
  
  l = (max + min) / 2;
  s = 0;
  h = 0;
  
  if (max != min)
    {
      if (l <= 0.5)
        s = (max - min) / (max + min);
      else
        s = (max - min) / (2 - max - min);
      
      delta = max -min;
      if (red == max)
        h = (green - blue) / delta;
      else if (green == max)
        h = 2 + (blue - red) / delta;
      else if (blue == max)
        h = 4 + (red - green) / delta;
      
      h *= 60;
      if (h < 0.0)
        h += 360;
    }
  
  *r = h;
  *g = l;
  *b = s;
}

static void
hls_to_rgb (gdouble *h,
            gdouble *l,
            gdouble *s)
{
  gdouble hue;
  gdouble lightness;
  gdouble saturation;
  gdouble m1, m2;
  gdouble r, g, b;
  
  lightness = *l;
  saturation = *s;
  
  if (lightness <= 0.5)
    m2 = lightness * (1 + saturation);
  else
    m2 = lightness + saturation - lightness * saturation;
  m1 = 2 * lightness - m2;
  
  if (saturation == 0)
    {
      *h = lightness;
      *l = lightness;
      *s = lightness;
    }
  else
    {
      hue = *h + 120;
      while (hue > 360)
        hue -= 360;
      while (hue < 0)
        hue += 360;
      
      if (hue < 60)
        r = m1 + (m2 - m1) * hue / 60;
      else if (hue < 180)
        r = m2;
      else if (hue < 240)
        r = m1 + (m2 - m1) * (240 - hue) / 60;
      else
        r = m1;
      
      hue = *h;
      while (hue > 360)
        hue -= 360;
      while (hue < 0)
        hue += 360;
      
      if (hue < 60)
        g = m1 + (m2 - m1) * hue / 60;
      else if (hue < 180)
        g = m2;
      else if (hue < 240)
        g = m1 + (m2 - m1) * (240 - hue) / 60;
      else
        g = m1;
      
      hue = *h - 120;
      while (hue > 360)
        hue -= 360;
      while (hue < 0)
        hue += 360;
      
      if (hue < 60)
        b = m1 + (m2 - m1) * hue / 60;
      else if (hue < 180)
        b = m2;
      else if (hue < 240)
        b = m1 + (m2 - m1) * (240 - hue) / 60;
      else
        b = m1;
      
      *h = r;
      *l = g;
      *s = b;
    }
}

static void
shade_doubles (double *red, double *green, double *blue, double *red_fg, double *green_fg, double *blue_fg, float k)
{
  rgb_to_hls (red, green, blue);
  rgb_to_hls (red_fg, green_fg, blue_fg);
  
  *green = (*green - *green_fg) * k + *green_fg;
  if (*green > 1.0)
    *green = 1.0;
  else if (*green < 0.0)
    *green = 0.0;

  /* Don't change saturation. */
#if 0
  *blue *= k;
  if (*blue > 1.0)
    *blue = 1.0;
  else if (*blue < 0.0)
    *blue = 0.0;
#endif
  
  hls_to_rgb (red, green, blue);
}

static void
shade_color (GdkColor * a, GdkColor *fg, GdkColor * b, float k)
{
  gdouble red;
  gdouble green;
  gdouble blue;

  gdouble red_fg;
  gdouble green_fg;
  gdouble blue_fg;
  
  red = (gdouble) a->red / 65535.0;
  green = (gdouble) a->green / 65535.0;
  blue = (gdouble) a->blue / 65535.0;

  red_fg = (gdouble) fg->red / 65535.0;
  green_fg = (gdouble) fg->green / 65535.0;
  blue_fg = (gdouble) fg->blue / 65535.0;

  shade_doubles (&red, &green, &blue, &red_fg, &green_fg, &blue_fg, k);
  
  b->red = red * 65535.0;
  b->green = green * 65535.0;
  b->blue = blue * 65535.0;
}

#define TOHEX(x) (CLAMP ((int) ((x) * 255.0), 0, 255))
#define FROMHEX(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : (tolower(x) - 'a' + 10))

static void
shade_hex (GdkColor * a, GdkColor *fg, char hex[6])
{
  gdouble red;
  gdouble green;
  gdouble blue;

  gdouble red_fg;
  gdouble green_fg;
  gdouble blue_fg;

  double k;
  
  k = FROMHEX (hex[0]) * 0x10 + FROMHEX(hex[1]);
  k /= 253.0;

  red = (gdouble) a->red / 65535.0;
  green = (gdouble) a->green / 65535.0;
  blue = (gdouble) a->blue / 65535.0;

  red_fg = (gdouble) fg->red / 65535.0;
  green_fg = (gdouble) fg->green / 65535.0;
  blue_fg = (gdouble) fg->blue / 65535.0;

  shade_doubles (&red, &green, &blue, &red_fg, &green_fg, &blue_fg, k);

  sprintf (hex, "%02x%02x%02x", TOHEX (red), TOHEX (green), TOHEX (blue));
}

static GdkGC *
realize_color (GtkStyle * style,
             GdkColor * color)
{
  GdkGCValues gc_values;

  gdk_colormap_alloc_color (style->colormap, color,
                      FALSE, TRUE);

  gc_values.foreground = *color;

  return gtk_gc_get (style->depth, style->colormap,
                 &gc_values, GDK_GC_FOREGROUND);
}

#define SHADE_FG   0 
#define SHADE_DARK 1 
#define SHADE_0x9E 2 
#define SHADE_0xB3 3 
#define SHADE_0xBB 4 
#define SHADE_0xBE 5 
#define SHADE_0xC7 6 
#define SHADE_0xC8 7 
#define SHADE_0xCA 8 
#define SHADE_0xD1 9 
#define SHADE_0xD5 10
#define SHADE_0xD9 11
#define SHADE_0xDA 12
#define SHADE_0xE7 13
#define SHADE_0xEA 14
#define SHADE_0xEB 15
#define SHADE_0xEC 16
#define SHADE_0xF2 17
#define SHADE_0xF3 18
#define SHADE_0xF4 19
#define SHADE_0xF6 20
#define SHADE_0xF7 21
#define SHADE_0xF8 22   
#define SHADE_0xFA 23   
#define SHADE_0xFB 24   
#define SHADE_0xFC 25
#define SHADE_0xFD 26
#define SHADE_0xFF 27
#define SHADE_HALF 28
#define SHADE_NEG  29

#define SHADE_COUNT 30
static const double shades[SHADE_COUNT] = { 0.0   / 253.0,   /* 0  - SHADE_FG   */
                                  100.0 / 253.0,   /* 1  - SHADE_DARK 0x64 */
                                  158.0 / 253.0,   /* 2  - SHADE_0x9E */
                                  179.0 / 253.0,   /* 3  - SHADE_0xB3 */
                                  187.0 / 253.0,   /* 4  - SHADE_0xBB */
                                  190.0 / 253.0,   /* 5  - SHADE_0xBE */
                                  199.0 / 253.0,   /* 6  - SHADE_0xC7 */
                                  200.0 / 253.0,   /* 7  - SHADE_0xC8 */
                                  202.0 / 253.0,   /* 8  - SHADE_0xCA */
                                  209.0 / 253.0,   /* 9  - SHADE_0xD1 */
                                  213.0 / 253.0,   /* 10 - SHADE_0xD5 */
                                  217.0 / 253.0,   /* 11 - SHADE_0xD9 */
                                  218.0 / 253.0,   /* 12 - SHADE_0xDA */
                                  231.0 / 253.0,   /* 13 - SHADE_0xE7 */
                                  234.0 / 253.0,   /* 14 - SHADE_0xEA */
                                  235.0 / 253.0,   /* 15 - SHADE_0xEB */
                                  236.0 / 253.0,   /* 16 - SHADE_0xEC */
                                  242.0 / 253.0,   /* 17 - SHADE_0xF2 */
                                  243.0 / 253.0,   /* 18 - SHADE_0xF3 */
                                  244.0 / 253.0,   /* 19 - SHADE_0xF4 */
                                  246.0 / 253.0,   /* 20 - SHADE_0xF6 */
                                  247.0 / 253.0,   /* 21 - SHADE_0xF7 */
                                  248.0 / 253.0,   /* 22 - SHADE_0xF8 */
                                  250.0 / 253.0,   /* 23 - SHADE_0xFA */
                                  251.0 / 253.0,   /* 24 - SHADE_0xFB */
                                  252.0 / 253.0,   /* 25 - SHADE_0xFC */
                                  253.0 / 253.0,   /* 26 - SHADE_0xFD */
                                  255.0 / 253.0,   /* 27 - SHADE_0xFF */
                                  50.0  / 100.0,   /* 28 - SHADE_HALF */ 
                                  52.0  / 83.0 }; /* 29 - SHADE_NEG 0x34 / 0x53 */
/* 135.0 /  83.0 26 - SHADE_NEG (0x53 + 0x34) / 0x53 */

#define MENUITEM_BORDER_SHADE SHADE_NEG

#define HANDLE_SHADE SHADE_0x9E
#define HANDLE_SHADOW_SHADE SHADE_0xDA
#define LINE_SHADE SHADE_0x9E
#define STANDARD_BORDER_SHADE SHADE_0x9E
#define STANDARD_BEVEL_TOP_SHADE SHADE_0xFF
#define STANDARD_BEVEL_BOTTOM_SHADE SHADE_0xF3
#define TROUGH_BORDER_SHADE SHADE_0xC7
#define TROUGH_BG_SHADE SHADE_0xD9

#define BUTTON_BORDER_SHADE SHADE_0x9E

#define MENUBAR_BORDER_SHADE SHADE_0xEA

#define BUTTON_DEPRESSED_SHADOW_SHADE_1 SHADE_0xDA
#define BUTTON_DEPRESSED_SHADOW_SHADE_2 SHADE_0xEC
#define BUTTON_DEPRESSED_SHADOW_SHADE_3 SHADE_0xF7

#define SHADE_BG SHADE_0xFD


#define PIXMAP_CHECK_ACTIVE 0
#define PIXMAP_CHECK_INACTIVE 1
#define PIXMAP_CHECK_MIXED 2
#define PIXMAP_MEDIUM_CHECK_ACTIVE 3
#define PIXMAP_MEDIUM_CHECK_INACTIVE 4
#define PIXMAP_MEDIUM_CHECK_MIXED 5
#define PIXMAP_SMALL_CHECK_ACTIVE 6
#define PIXMAP_SMALL_CHECK_INACTIVE 7
#define PIXMAP_SMALL_CHECK_MIXED 8
#define PIXMAP_RADIO_ACTIVE 9
#define PIXMAP_RADIO_INACTIVE 10
#define PIXMAP_RADIO_MIXED 11
#define PIXMAP_SMALL_RADIO_ACTIVE 12
#define PIXMAP_SMALL_RADIO_INACTIVE 13
#define PIXMAP_SMALL_RADIO_MIXED 14

#define PIXMAP_COUNT 15

#include "xpm/checkbox-on.xpm"
#include "xpm/checkbox-off.xpm"
#include "xpm/checkbox-mixed.xpm"
#include "xpm/table-checkbox-on.xpm"
#include "xpm/table-checkbox-off.xpm"
#include "xpm/table-checkbox-mixed.xpm"
#include "xpm/menu-checkbox-on.xpm"
#include "xpm/menu-checkbox-off.xpm"
#include "xpm/menu-checkbox-mixed.xpm"
#include "xpm/radio-on.xpm"
#include "xpm/radio-off.xpm"
#include "xpm/radio-mixed.xpm"
#include "xpm/menu-radio-on.xpm"
#include "xpm/menu-radio-off.xpm"
#include "xpm/menu-radio-mixed.xpm"

static char ** pixmaps[PIXMAP_COUNT] = { checkbox_on_xpm,
                               checkbox_off_xpm,
                               checkbox_mixed_xpm,
                               table_checkbox_on_xpm,
                               table_checkbox_off_xpm,
                               table_checkbox_mixed_xpm,
                               menu_checkbox_on_xpm,
                               menu_checkbox_off_xpm,
                               menu_checkbox_mixed_xpm,
                               radio_on_xpm,
                               radio_off_xpm,
                               radio_mixed_xpm,
                               menu_radio_on_xpm,
                               menu_radio_off_xpm,
                               menu_radio_mixed_xpm };

typedef struct {
  GdkColor bg_color;
  GdkColor fg_color;
  GdkColor colors[SHADE_COUNT];
  GdkGC *gcs[SHADE_COUNT];
  GdkPixmap *pixmaps[PIXMAP_COUNT];
  GdkBitmap *masks[PIXMAP_COUNT];
} Shading;

static guint
hash_colors (gconstpointer key)
{
  GdkColor **colors = (GdkColor **) key;
  return colors[0]->red ^ (colors[0]->green << 8) ^ (colors[0]->blue << 16) ^
    (colors[1]->red) << 12 ^ (colors[1]->green << 20) ^ (colors[1]->blue << 4);
}

static gboolean
equal_colors (gconstpointer key1, gconstpointer key2)
{
  GdkColor **colors1 = (GdkColor **) key1;
  GdkColor **colors2 = (GdkColor **) key2;

  return colors1[0]->red == colors2[0]->red &&
    colors1[0]->green == colors2[0]->green &&
    colors1[0]->blue == colors2[0]->blue &&
    colors1[1]->red == colors2[1]->red &&
    colors1[1]->green == colors2[1]->green &&
    colors1[1]->blue == colors2[1]->blue;
}

#if 0
static void
free_colors (gpointer data)
{
  GdkColor **colors = data;
  gdk_color_free (colors[0]);
  gdk_color_free (colors[1]);
  g_free (colors);
}

static void
free_shading (gpointer data)
{
  int i;
  Shading *shading = data;
  for (i = 0; i < SHADE_COUNT; i++) {
    if (shading->gcs[i])
      g_object_unref (shading->gcs[i]);
  }
  g_free (shading);
}
#endif

static Shading *
get_shading (GtkStyle *style, GdkColor *bg_color, GdkColor *fg_color)
{
  Shading *shading;
  GdkColor *colors[2] = {bg_color, fg_color};

  if (GET_SHADING_HASH (style) == NULL)
    GET_SHADING_HASH (style) = g_hash_table_new (hash_colors, equal_colors);

  shading = g_hash_table_lookup (GET_SHADING_HASH (style), colors);

  if (shading == NULL) {
    int i;
    GdkColor **colors = g_new (GdkColor *, 2);

    shading = g_new (Shading, 1);
    shading->bg_color = *bg_color;
    shading->fg_color = *fg_color;
    for (i = 0; i < SHADE_COUNT; i++) {
      shading->gcs[i] = NULL;
    }
    for (i = 0; i < PIXMAP_COUNT; i++) {
      shading->pixmaps[i] = NULL;
    }
    colors[0] = gdk_color_copy (bg_color);
    colors[1] = gdk_color_copy (fg_color);

    g_hash_table_insert (GET_SHADING_HASH (style), colors, shading);
  }

  return shading;
}

static void
ensure_shade (GtkStyle *style, Shading *shading, int shade)
{
  if (shading->gcs[shade] == NULL) {
    double contrast = GET_CONTRAST (style);
    double contrast_center = GET_CONTRAST_CENTER (style);
    if (shade == SHADE_HALF ||
      shade == SHADE_NEG) {
      shade_color (&shading->bg_color, &shading->fg_color, &shading->colors[shade], shades[shade]);
    } else {
      shade_color (&shading->bg_color, &shading->fg_color, &shading->colors[shade], CLAMP ((shades[shade]-contrast_center) * contrast + contrast_center, 0.0, 1.0));
    }
    shading->gcs[shade] = realize_color (style, &shading->colors[shade]);
  }
}

/* This isn't robust pixmap parsing code.  It'll crash at a moments
 * notice, but not with the 12 pixmaps provided. 
 **/

static void
ensure_pixmap (GtkStyle *style, GdkWindow *window, Shading *shading, int pixmap)
{
  if (shading->pixmaps[pixmap] == NULL) {
    char **first_line;
    char **xpm;
    char **xpm_copy;
    int colors;
    int height;
    int i;

    xpm = pixmaps[pixmap];
    first_line = g_strsplit (xpm[0], " ", 0);

    height = atoi (first_line[1]);
    colors = atoi (first_line[2]);

    g_strfreev (first_line);

    xpm_copy = g_new (char *, 1 + colors + height + 1);
    xpm_copy[0] = g_strdup (xpm[0]);

    for (i = 1; i < 1 + colors; i++) {
      char *color;

      xpm_copy[i] = g_strdup (xpm[i]);

      color = strstr (xpm_copy[i], " #");
      if (color) {
      color += 2;
      shade_hex (&shading->bg_color, &shading->fg_color, color);
      }
    }
    for (; i < 1 + colors + height; i++) {
      xpm_copy[i] = g_strdup (xpm[i]);
    }
    xpm_copy[i] = NULL;

    shading->pixmaps[pixmap] = gdk_pixmap_colormap_create_from_xpm_d (window, style->colormap, &shading->masks[pixmap], &style->bg[GTK_STATE_NORMAL], xpm_copy);

    g_strfreev (xpm_copy);
  }
}

static GdkPixmap *
get_pixmap (GtkStyle *style, GdkWindow *window, GdkColor *bg_color, GdkColor *fg_color, int pixmap)
{
  Shading *shading = get_shading (style, bg_color, fg_color);
  ensure_pixmap (style, window, shading, pixmap);
  return shading->pixmaps[pixmap];
}

static GdkBitmap *
get_mask (GtkStyle *style, GdkWindow *window, GdkColor *bg_color, GdkColor *fg_color, int pixmap)
{
  Shading *shading = get_shading (style, bg_color, fg_color);
  ensure_pixmap (style, window, shading, pixmap);
  return shading->masks[pixmap];
}

static GdkGC *
get_gc (GtkStyle *style, GdkColor *bg_color, GdkColor *fg_color, int shade)
{
  Shading *shading = get_shading (style, bg_color, fg_color);
  ensure_shade (style, shading, shade);
  return shading->gcs[shade];
}

static GdkColor *
get_color (GtkStyle *style, GdkColor *bg_color, GdkColor *fg_color, int shade)
{
  Shading *shading = get_shading (style, bg_color, fg_color);
  ensure_shade (style, shading, shade);
  return &shading->colors[shade];
}

static gboolean 
sanitize_size (GdkWindow      *window,
             gint           *width,
             gint           *height)
{
  gboolean set_bg = FALSE;

  if ((*width == -1) && (*height == -1))
    {
      set_bg = GDK_IS_WINDOW (window);
      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);

  return set_bg;
}
static void
kaleidoscope_point (GdkWindow *window,
                GdkGC *gc,
                GdkRectangle *area,
                gint x, gint y,
                gint width, gint height,
                gint offset_x, gint offset_y)
{
  if (!gc)
    return;
  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  /* No mirror */
  gdk_draw_point (window, gc, x + offset_x, y + offset_y);
  /* Mirror x */
  gdk_draw_point (window, gc, x + width - offset_x - 1, y + offset_y);
  /* Mirror y */
  gdk_draw_point (window, gc, x + offset_x, y + height - offset_y - 1);
  /* Mirror both */
  gdk_draw_point (window, gc, x + width - offset_x - 1, y + height - offset_y - 1);
  /* Mirror diagonal */
  if (offset_x != offset_y) {
    gdk_draw_point (window, gc, x + offset_y, y + offset_x);
    gdk_draw_point (window, gc, x + width - offset_y - 1, y + offset_x);
    gdk_draw_point (window, gc, x + offset_y, y + height - offset_x - 1);
    gdk_draw_point (window, gc, x + width - offset_y - 1, y + height - offset_x - 1);
  }
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

static void
kaleidoscope_line (GdkWindow *window,
                GdkGC *gc,
                GdkRectangle *area,
                gint x, gint y,
                gint width, gint height,
                gint edge_distance_offset, gint directional_offset)
{
  if (!gc)
    return;
  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  /* Top line */
  gdk_draw_line (window, gc,
             x + directional_offset,
             y + edge_distance_offset,
             x + width - directional_offset - 1,
             y + edge_distance_offset);

  /* Bottom line */
  gdk_draw_line (window, gc,
             x + directional_offset,
             y + height - edge_distance_offset - 1,
             x + width - directional_offset - 1,
             y + height - edge_distance_offset - 1);

  /* Left line */
  gdk_draw_line (window, gc,
             x + edge_distance_offset,
             y + directional_offset,
             x + edge_distance_offset,
             y + height - directional_offset - 1);

  /* Right line */
  gdk_draw_line (window, gc,
             x + width - edge_distance_offset - 1,
             y + directional_offset,
             x + width - edge_distance_offset - 1,
             y + height - directional_offset - 1);
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

typedef enum {
  ROTATION_CORNER_TL = 0,
  ROTATION_CORNER_TR = 1,
  ROTATION_CORNER_BR = 2,
  ROTATION_CORNER_BL = 3
} RotationCorner;

static void
rotate_point (GtkPositionType pos, 
            gint x, gint y,
            gint width, gint height,
            RotationCorner corner, /* if GTK_POS_TOP */
            gint offset_x, gint offset_y,
            gint *x_result, gint *y_result)
{
  int x_value, y_value;
  gboolean invert = 0;

  if (!x_result && !y_result)
    return;

  if (corner == ROTATION_CORNER_TR ||
      corner == ROTATION_CORNER_BL) {
    /* Swap values */
    offset_x ^= offset_y;
    offset_y ^= offset_x;
    offset_x ^= offset_y;
  }

  switch (pos) {
  case GTK_POS_TOP:
    /* corner += 0; */
    break;
  case GTK_POS_RIGHT:
    corner += 1;
    break;
  case GTK_POS_BOTTOM:
    corner = 3 - corner;
    invert = 1;
    break;
  case GTK_POS_LEFT:
    corner = 4 - corner;
    invert = 1;
    break;
  }
  corner %= 4;

  if (invert) {
    offset_x ^= offset_y;
    offset_y ^= offset_x;
    offset_x ^= offset_y;
  }

  switch (corner) {
  case ROTATION_CORNER_TL:
    x_value = x + offset_x;
    y_value = y + offset_y;
    break;
  case ROTATION_CORNER_TR:
    x_value = x + width - offset_y - 1;
    y_value = y + offset_x;
    break;
  case ROTATION_CORNER_BR:
    x_value = x + width - offset_x - 1;
    y_value = y + height - offset_y - 1;
    break;
  case ROTATION_CORNER_BL:
    x_value = x + offset_y;
    y_value = y + height - offset_x - 1;
    break;
  }

  if (x_result)
    *x_result = x_value;
  if (y_result)
    *y_result = y_value;
}

static void
draw_rotated_point (GdkWindow *window,
                GdkGC *gc,
                GdkRectangle *area,
                GtkPositionType pos, 
                gint x, gint y,
                gint width, gint height,
                RotationCorner corner,
                gint offset_x, gint offset_y)
{
  int x_result, y_result;
  rotate_point (pos, x, y, width, height, corner, offset_x, offset_y, &x_result, &y_result);
  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  /* No mirror */
  gdk_draw_point (window, gc, x_result, y_result);
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

static void
draw_rotated_line (GdkWindow *window,
               GdkGC *gc,
               GdkRectangle *area,
               GtkPositionType pos, 
               gint x, gint y,
               gint width, gint height,
               RotationCorner corner_1,
               gint offset_x_1, gint offset_y_1,
               RotationCorner corner_2,
               gint offset_x_2, gint offset_y_2)
{
  int x_result_1, y_result_1, x_result_2, y_result_2;
  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  rotate_point (pos, x, y, width, height, corner_1, offset_x_1, offset_y_1, &x_result_1, &y_result_1);
  rotate_point (pos, x, y, width, height, corner_2, offset_x_2, offset_y_2, &x_result_2, &y_result_2);
  /* No mirror */
  gdk_draw_line (window, gc, x_result_1, y_result_1, x_result_2, y_result_2);
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

static void
draw_rounded_rect_one_pixel (GdkWindow *window,
                       GdkGC *bg_gc,
                       GdkGC *fg_gc,
                       GdkGC *corner_gc,
                       GdkRectangle *area,
                       gint x, gint y,
                       gint width, gint height)
{
  /*
    ... ...
    .+@ @+.
    .@. .@.

    .@. .@.
    .+@ @+.
    ... ...

    The spaces indicate repeat the line on either side (if they don't match, it's a bug in the drawing.)
    Set of . around the edge not part of width & height.
  */

  if (bg_gc) {
    if (area)
      gdk_gc_set_clip_rectangle (bg_gc, area);
    gdk_draw_rectangle (window, bg_gc, TRUE, x, y, width, height);
    if (area)
      gdk_gc_set_clip_rectangle (bg_gc, NULL);
  }

  /* Draw @s */
  kaleidoscope_line (window, fg_gc, area, x, y, width, height, 0, 1);

  /* Draw +s */
  kaleidoscope_point (window, corner_gc, area, x, y, width, height, 0, 0);
}

static void
draw_rounded_rect_two_pixel (GdkWindow *window,
                       GdkGC *bg_gc,
                       GdkGC *fg_gc,
                       GdkGC *corner_gc,
                       GdkRectangle *area,
                       gint x, gint y,
                       gint width, gint height)
{
  /*
    .... ....
    ..+@ @+..
    .+@. .@+.
    .@.. ..@.

    .@.. ..@.
    .+@. .@+.
    ..+@ @+..
    .... ....

    The spaces indicate repeat the line on either side (if they don't match, it's a bug in the drawing.)
    Set of . around the edge not part of width & height.
  */

  if (bg_gc) {
    if (area)
      gdk_gc_set_clip_rectangle (bg_gc, area);
    gdk_draw_rectangle (window, bg_gc, TRUE, x + 1, y + 1, width - 2, height - 2);
    if (area)
      gdk_gc_set_clip_rectangle (bg_gc, NULL);
  }

  /* Draw @s */
  if (area)
    gdk_gc_set_clip_rectangle (fg_gc, area);
  kaleidoscope_line (window, fg_gc, NULL, x, y, width, height, 0, 2);
  kaleidoscope_point (window, fg_gc, NULL, x, y, width, height, 1, 1);
  if (area)
    gdk_gc_set_clip_rectangle (fg_gc, NULL);

  /* Draw +s */
  kaleidoscope_point (window, corner_gc, area, x, y, width, height, 0, 1);
}

  /* #define names assume vertical */
#define HANDLE_HEIGHT (4 * 4 + 1 + 2)
#define HANDLE_WIDTH (4 + 1 + 2)

static void
draw_grid (GdkWindow *window,
         GdkGC *gc1,
         GdkGC *gc2,
         gint x, gint y,
         gint width, gint height)
{
  int i, j, k, l;
  int i2, j2;
  int xoffset = 0;
  int yoffset = 0;
  struct {
    int xoff;
    int yoff;
    int color;
  } offsets[5] = {
    {0, 1, 0},
    {1, 0, 0},
    {2, 1, 0},
    {1, 2, 0},
    {1, 1, 1}
  };

  /*
    .............
    ..*...*...*..
    .*@*.*@*.*@*.
    ..*.*.*.*.*..
    ...*+*.*+*...
    ..*.*.*.*.*..
    .*@*.*@*.*@*.
    ..*.*.*.*.*..
    ...*+*.*+*...
    ..*.*.*.*.*..
    .*@*.*@*.*@*.
    ..*...*...*..
    .............

    Repeated pattern.

    + and @ are the same color.  They're just used in comments later.

    * is color 1.

    Possibly offset by -1 either up or to the left.

    Set of . around the edge not part of width & height.
  */

  if (width % 4 == 1)
    xoffset = -1;
  if (height % 4 == 1)
    yoffset = -1;
  for (l = 0; l < 5; l++) { /* Draw the pattern 5 times in different colors. */
    for (k = 0; k <= 2; k += 2) { /* draw @ -> k = 0 ... draw + -> k = 2 */
      for (i = k + offsets[l].xoff + xoffset, i2 = k + 1 + xoffset; i < width && i2 < width; i += 4, i2 += 4) {
      if (i < 0) continue;
      for (j = k + offsets[l].yoff + yoffset, j2 = k + 1 + yoffset; j < height && j2 < height; j += 4, j2 += 4) {
        if (j < 0) continue;
        gdk_draw_point (window, offsets[l].color ? gc1 : gc2, x + i, y + j);
      }
      }
    }
  }
}


/**************************************************************************/

static void
draw_hline (GtkStyle     *style,
          GdkWindow    *window,
          GtkStateType  state_type,
          GdkRectangle  *area,
          GtkWidget     *widget,
          INDUSTRIAL_CONST gchar   *detail,
          gint          x1,
          gint          x2,
          gint          y)
{
  GdkGC *gc;
  
#ifdef DEBUG
  printf ("draw_hline: %p %p %s %i %i %i\n", widget, window, detail, x1, x2,
        y);
#endif

  g_return_if_fail (GTK_IS_STYLE (style));
  g_return_if_fail (window != NULL);
  if (DETAIL("label")) {
    if (state_type == GTK_STATE_INSENSITIVE) {
      if (area)
      gdk_gc_set_clip_rectangle (style->white_gc, area);
      gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
      if (area)
      gdk_gc_set_clip_rectangle (style->white_gc, NULL);
    }
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_FG);
    if (area)
      gdk_gc_set_clip_rectangle (gc, area);
    gdk_draw_line (window, gc, x1, y, x2, y);
    if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);
  } else {
    if (DETAIL ("menuitem"))
      y++;

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], LINE_SHADE);

    if (area)
      gdk_gc_set_clip_rectangle (gc, area);

    gdk_draw_line (window, gc,
               x1, y, x2, y);

    if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);
  }
}

/**************************************************************************/

static void 
draw_handle (GtkStyle      *style,
           GdkWindow     *window,
           GtkStateType   state_type,
           GtkShadowType  shadow_type,
           GdkRectangle  *area,
           GtkWidget     *widget,
           INDUSTRIAL_CONST gchar   *detail,
           gint           x,
           gint           y,
           gint           width,
           gint           height,
           GtkOrientation orientation)
{
  GdkGC *gc1 = get_gc (style, &style->bg[state_type], &style->fg[state_type], HANDLE_SHADE);
  GdkGC *gc2 = get_gc (style, &style->bg[state_type], &style->fg[state_type], HANDLE_SHADOW_SHADE);
  int handle_width, handle_height, maxwidth, maxheight;

  g_return_if_fail (GTK_IS_STYLE (style));
  g_return_if_fail (window != NULL);
  
  sanitize_size (window, &width, &height);

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i  %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height, orientation);
#endif
  
  gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
                 detail, x, y, width, height);

  if (DETAIL ("paned")) {
#if 0
    x += 3;
    y += 3;
    width -= 5;
    height -= 5;
#endif
  } else {
    x += 2;
    y += 2;
    width -= 4;
    height -= 4;
  }

#if INDUSTRIAL_GTK_VERSION == 2
  if (DETAIL ("dockitem") ||
      WIDGET_TYPE_NAME ("PanelAppletFrame")) {
    if (orientation == GTK_ORIENTATION_HORIZONTAL)
      orientation = GTK_ORIENTATION_VERTICAL;
    else
      orientation = GTK_ORIENTATION_HORIZONTAL;
  }
#endif

  if (shadow_type == GTK_SHADOW_NONE) {
    maxwidth = width;
    maxheight = height;
  } else {
    maxwidth = width - 2;
    maxheight = height - 2;
  }

  if (orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      handle_width = MIN (maxwidth, HANDLE_HEIGHT);
      handle_height = MIN (maxheight, HANDLE_WIDTH);
    }
  else
    {
      handle_width = MIN (maxwidth, HANDLE_WIDTH);
      handle_height = MIN (maxheight, HANDLE_HEIGHT);
    }

  if (handle_width <= 0 || handle_height <= 0)
    return;

  x += (width - handle_width) / 2;
  y += (height - handle_height) / 2;

  if (area) {
    gdk_gc_set_clip_rectangle (gc1, area);
    gdk_gc_set_clip_rectangle (gc2, area);
  }

  draw_grid (window, gc1, gc2, x, y, handle_width, handle_height);

  if (area) {
    gdk_gc_set_clip_rectangle (gc1, NULL);
    gdk_gc_set_clip_rectangle (gc2, NULL);
  }
}

/**************************************************************************/

static void
draw_vline (GtkStyle     *style,
          GdkWindow    *window,
          GtkStateType  state_type,
          GdkRectangle  *area,
          GtkWidget     *widget,
          INDUSTRIAL_CONST gchar   *detail,
          gint          y1,
          gint          y2,
          gint          x)
{
  GdkGC *gc;

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i\n", __FUNCTION__, widget, window, detail, y1, y2,
        x);
#endif

  g_return_if_fail (GTK_IS_STYLE (style));
  g_return_if_fail (window != NULL);
  
  gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], LINE_SHADE);

  if (area) {
    gdk_gc_set_clip_rectangle (gc, area);
  }
  
  gdk_draw_line (window, gc, x, y1, x, y2 - 1);
  
  if (area) {
    gdk_gc_set_clip_rectangle (gc, NULL);
  }
}

/**************************************************************************/
static void
draw_slider (GtkStyle      *style,
           GdkWindow     *window,
           GtkStateType   state_type,
           GtkShadowType  shadow_type,
           GdkRectangle  *area,
           GtkWidget     *widget,
           INDUSTRIAL_CONST gchar   *detail,
           gint           x,
           gint           y,
           gint           width,
           gint           height,
           GtkOrientation orientation)
{
  int handle_width, handle_height;

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i  %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height, orientation);
#endif

  g_return_if_fail (GTK_IS_STYLE (style));
  g_return_if_fail (window != NULL);
  
  sanitize_size (window, &width, &height);

  if (widget && GTK_IS_SCROLLBAR (widget)) {
    GtkAdjustment *adjustment = GTK_RANGE (widget)->adjustment;
    if (adjustment->value ||  /* If all of these values are 0, don't do anything.  This fixes mozilla/galeon scrollbars. */
      adjustment->lower ||
      adjustment->upper ||
      adjustment->step_increment ||
      adjustment->page_increment ||
      adjustment->page_size) {
      if (adjustment->value <= adjustment->lower) {
      if (orientation == GTK_ORIENTATION_VERTICAL) {
        y --;
        height ++;
      } else {
        x --;
        width ++;
      }
      }
      if (adjustment->value >= adjustment->upper - adjustment->page_size) {
      if (orientation == GTK_ORIENTATION_VERTICAL) {
        height ++;
      } else {
        width ++;
      }
      }
    }
  }
  
  gtk_paint_box (style, window, state_type, shadow_type,
                 area, widget, detail, x, y, width, height);


  if (orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      handle_width = MIN (width - 2, HANDLE_HEIGHT);
      handle_height = MIN (height - 2, HANDLE_WIDTH);
    }
  else
    {
      handle_width = MIN (width - 2, HANDLE_WIDTH);
      handle_height = MIN (height - 2, HANDLE_HEIGHT);
    }

  if (handle_width > 0 && handle_height > 0) {
    GdkGC *gc1 = get_gc (style, &style->bg[state_type], &style->fg[state_type], HANDLE_SHADE);
    GdkGC *gc2 = get_gc (style, &style->bg[state_type], &style->fg[state_type], HANDLE_SHADOW_SHADE);

    if (area) {
      gdk_gc_set_clip_rectangle (gc1, area);
      gdk_gc_set_clip_rectangle (gc2, area);
    }
    x += (width - handle_width) / 2;
    y += (height - handle_height) / 2;
    draw_grid (window, gc1, gc2, x, y, handle_width, handle_height);
    if (area) {
      gdk_gc_set_clip_rectangle (gc1, NULL);
      gdk_gc_set_clip_rectangle (gc2, NULL);
    }
  }

}

static void
real_draw_box (GtkStyle      *style,
             GdkWindow     *window,
             GtkStateType   state_type,
             GtkShadowType  shadow_type,
             GdkRectangle  *area,
             GtkWidget     *widget,
             INDUSTRIAL_CONST gchar   *detail,
             gint           x,
             gint           y,
             gint           width,
             gint           height,
             gboolean       fill)
{
  g_return_if_fail (style != NULL);
  g_return_if_fail (window != NULL);

  sanitize_size (window, &width, &height);

  /* None of the drawing routines below are set up to handle SHADOW_TYPE_NONE,
   * so just fill in a blank box here.  Ideally everything in the theme
   * would be reworked to handle SHADOW_TYPE_NONE correctly */
  if (shadow_type == GTK_SHADOW_NONE) {
    if (!style->bg_pixmap[state_type] ||
      GDK_IS_PIXMAP (window)) {
      if (area)
        gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
      
      gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE,
                      x, y, width, height);
      if (area)
        gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
    }
    else
      gtk_style_apply_default_background (style, window,
                                widget && !GTK_WIDGET_NO_WINDOW (widget),
                                state_type, area, x, y, width, height);
    return;
  }

  if (DETAIL("button") ||
      DETAIL("togglebutton")) {
    /*
      .......... ...........
      ..+@@@@@@@ @@@@@@@@+..
      .+@....... ........@+.
      .@........ .......#.@.
      .@........ ......$%.@.
      .@........ .....$&%.@.
      .@........ ....*=&%.@.
      .@........ ...*#=&%.@.
      .@........ ..*$#=&%.@.
      .@........ .*-$#=&%.@.
             
      .@........ .*-$#=&%.@.
      .@.......* **-$#=&%.@.
      .@......*- --$$#=&%.@.
      .@.....*$$ $$$##=&%.@.
      .@....*### ####==&%.@.
      .@...$==== =====&&%.@.
      .@..$&&&&& &&&&&&%%.@.
      .@.#%%%%%% %%%%%%%#.@.
      .+@....... ........@+.
      ..+@@@@@@@ @@@@@@@@+..
      .......... ...........

      The spaces indicate repeat the line on either side (if they don't match, it's a bug in the drawing.)
      Set of . around the edge not part of width & height.
    */

    GdkGC *gc;
    GdkColor *color;

    if (! (GTK_WIDGET_HAS_DEFAULT (widget) &&
         GTK_IS_BUTTON (widget) && 
         GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL/* &&
                                                state_type != GTK_STATE_ACTIVE*/)) {
      /* if the button has default, we already drew the button shape and the background color */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_rectangle (window, gc, TRUE, x + 1, y + 1, width - 2, height - 2);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw @s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], BUTTON_BORDER_SHADE);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      if (GET_ROUNDED_BUTTONS (style)) {
      kaleidoscope_point (window, gc, NULL, x, y, width, height, 1, 1);
      kaleidoscope_line (window, gc, NULL, x, y, width, height, 0, 2);
      } else {
      kaleidoscope_line (window, gc, NULL, x, y, width, height, 0, 1);
      }
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw +s */
      color = get_color (style, &style->bg[state_type], &style->fg[state_type], BUTTON_BORDER_SHADE);
      gc = get_gc (style, &style->bg[state_type], color, SHADE_HALF);
      kaleidoscope_point (window, gc, area, x, y, width, height, 0, GET_ROUNDED_BUTTONS (style) ? 1 : 0);
    }

    /*
      Pushed button.
      ........... ..........
      ..+@@@@@@@@ @@@@@@@+..
      .+@'''''''' '''''''@+.
      .@'<<<<<<<< <<<<<<<<@.
      .@'<<"..... ....."<#@.
      .@'<"...... ......$%@.
      .@'<....... .....$&%@.
      .@'<....... ....*=&%@.
      .@'<....... ...*#=&%@.
      .@'<....... ..*$#=&%@.
      .@'<....... .*-$#=&%@.

      .@'<....... .*-$#=&%@.
      .@'<......* **-$#=&%@.
      .@'<.....*- --$$#=&%@.
      .@'<....*$$ $$$##=&%@.
      .@'<...*### ####==&%@.
      .@'<".$==== =====&&%@.
      .@'<<$&&&&& &&&&&&%%@.
      .+@<#%%%%%% %%%%%%%@+.
      ..+@@@@@@@@ @@@@@@@+.. 
      ......................
      The spaces indicate repeat the line on either side (if they don't match, it's a bug in the drawing.)
      Set of . around the edge not part of width & height.
    */
    if (state_type == GTK_STATE_ACTIVE) {
      /* Draw 's */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], BUTTON_DEPRESSED_SHADOW_SHADE_1);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      if (GET_ROUNDED_BUTTONS (style)) {
      gdk_draw_line (window, gc, x + 2, y + 1, x + width - 3, y + 1);
      gdk_draw_line (window, gc, x + 1, y + 2, x + 1, y + height - 3);
      } else {
      gdk_draw_line (window, gc, x + 1, y + 1, x + width - 2, y + 1);
      gdk_draw_line (window, gc, x + 1, y + 2, x + 1, y + height - 2);
      }
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw <s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], BUTTON_DEPRESSED_SHADOW_SHADE_2);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 2, y + 2, x + width - 2, y + 2);
      gdk_draw_line (window, gc, x + 2, y + 3, x + 2, y + height - 2);
      gdk_draw_point (window, gc, x + 3, y + 3);
      gdk_draw_point (window, gc, x + width - 3, y + 3);
      gdk_draw_point (window, gc, x + 3, y + height - 3);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw #s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], BUTTON_DEPRESSED_SHADOW_SHADE_3);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_point (window, gc, x + 3, y + 4);
      gdk_draw_point (window, gc, x + 4, y + 3);
      gdk_draw_point (window, gc, x + 3, y + height - 4);
      gdk_draw_point (window, gc, x + width - 4, y + 3);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);
    } else {
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF8);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_point (window, gc, x + width - 3, y + height - 3);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);
    }

    /* Only draw shadow if button is large enough to fit it. */
    if (width > 18 && height > 18) {

      /* Offset shadow if depressed. */
      if (state_type == GTK_STATE_ACTIVE) {
      x ++;
      y ++;
      }

      /* Draw *s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFC);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 8, y + height - 9, x + width - 9, y + height - 9);
      gdk_draw_line (window, gc, x + width - 9, y + 8, x + width - 9, y + height - 9);
      gdk_draw_point (window, gc, x + 5, y + height - 6);
      gdk_draw_point (window, gc, x + 6, y + height - 7);
      gdk_draw_point (window, gc, x + 7, y + height - 8);
      gdk_draw_point (window, gc, x + width - 6, y + 5);
      gdk_draw_point (window, gc, x + width - 7, y + 6);
      gdk_draw_point (window, gc, x + width - 8, y + 7);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw -s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFB);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 8, y + height - 8, x + width - 9, y + height - 8);
      gdk_draw_line (window, gc, x + width - 8, y + 8, x + width - 8, y + height - 9);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw $s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFA);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 7, y + height - 7, x + width - 8, y + height - 7);
      gdk_draw_line (window, gc, x + width - 7, y + 7, x + width - 7, y + height - 8);
      gdk_draw_point (window, gc, x + width - 8, y + height - 8);
      gdk_draw_point (window, gc, x + 3, y + height - 4);
      gdk_draw_point (window, gc, x + 4, y + height - 5);
      gdk_draw_point (window, gc, x + width - 4, y + 3);
      gdk_draw_point (window, gc, x + width - 5, y + 4);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw #s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF8);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 6, y + height - 6, x + width - 7, y + height - 6);
      gdk_draw_line (window, gc, x + width - 6, y + 6, x + width - 6, y + height - 7);
      gdk_draw_point (window, gc, x + width - 7, y + height - 7);
      gdk_draw_point (window, gc, x + 2, y + height - 3);
      gdk_draw_point (window, gc, x + width - 3, y + 2);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw =s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF6);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 5, y + height - 5, x + width - 6, y + height - 5);
      gdk_draw_line (window, gc, x + width - 5, y + 5, x + width - 5, y + height - 6);
      gdk_draw_point (window, gc, x + width - 6, y + height - 6);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw &s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF4);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      gdk_draw_line (window, gc, x + 4, y + height - 4, x + width - 5, y + height - 4);
      gdk_draw_line (window, gc, x + width - 4, y + 4, x + width - 4, y + height - 5);
      gdk_draw_point (window, gc, x + width - 5, y + height - 5);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

      /* Draw %s */
      gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF3);
      if (area)
      gdk_gc_set_clip_rectangle (gc, area);
      if (GET_ROUNDED_BUTTONS (style)) {
      gdk_draw_line (window, gc, x + 3, y + height - 3, x + width - 4, y + height - 3);
      gdk_draw_line (window, gc, x + width - 3, y + 3, x + width - 3, y + height - 4);
      } else {
      gdk_draw_line (window, gc, x + 3, y + height - 3, x + width - 3, y + height - 3);
      gdk_draw_line (window, gc, x + width - 3, y + 3, x + width - 3, y + height - 4);
      }
      gdk_draw_point (window, gc, x + width - 4, y + height - 4);
      if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);
    }
  } else if (DETAIL("buttondefault") ||
           DETAIL("togglebuttondefault")) {
    /*
      .     c #FDFDFD
      +     c #FCFCFC
      @     c #FBFBFB
      #     c #FAFAFA
      0     c #F8F8F8
      -     c #F7F7F7
      a     c #F2F2F2
      3     c #EBEBEB
      6     c #EAEAEA
      =     c #E7E7E7
      2     c #D9D9D9
      4     c #D1D1D1
      <     c #C8C8C8
      '     c #BEBEBE
      )     c #BBBBBB
      {     c #B3B3B3
      ]     c #000000
      ......... .........
      .....+@## ##@+.....
      ...+0a3== ==3a0+...
      ..+-62<') )'<26-+..
      ..064{]]] ]]]{460..
      .+a2{]... ...]{2a+.
      .@3<].... ....]<3@.
      .#='].... ....]'=#.
      .#=)].... ....])=#.
      
      .#=)].... ....])=#.
      .#='].... ....]'=#.
      .@3<].... ....]<3@.
      .+a2{]... ...]{2a+.
      ..064{]]] ]]]{460..
      ..+-62<') )'<26-+..
      ...+0a3== ==3a0+...
      .....+@## ##@+.....
      ......... .........
      The spaces indicate repeat the line on either side (if they don't match, it's a bug in the drawing.)
      Set of . around the edge not part of width & height.
    */
    GdkGC *gc;

    gc = get_gc (style, &style->bg[GTK_WIDGET_STATE (widget)], &style->fg[GTK_WIDGET_STATE (widget)], SHADE_BG);
    if (area)
      gdk_gc_set_clip_rectangle (gc, area);
    gdk_draw_rectangle (window, gc, TRUE, x + 4, y + 4, width - 8, height - 8);
    if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

    /* Draw ]s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_FG);
    if (area)
      gdk_gc_set_clip_rectangle (gc, area);
    kaleidoscope_point (window, gc, NULL, x, y, width, height, 4, 4);
    kaleidoscope_line (window, gc, NULL, x, y, width, height, 3, 5);
    if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

    /* Draw {s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xB3);
    kaleidoscope_point (window, gc, area, x, y, width, height, 3, 4);

#if 1
    /* Remove this to add the shadow back for depressed buttons. */
    if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
      return;
#endif

    /* Draw )s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xBB);
    kaleidoscope_line (window, gc, area, x, y, width, height, 2, 7);

    /* Draw 's */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xBE);
    kaleidoscope_point (window, gc, area, x, y, width, height, 2, 6);

    /* Draw <s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xC8);
    kaleidoscope_point (window, gc, area, x, y, width, height, 2, 5);

    /* Draw 4s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xD1);
    kaleidoscope_point (window, gc, area, x, y, width, height, 3, 3);

    /* Draw 2s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xD9);
    kaleidoscope_point (window, gc, area, x, y, width, height, 2, 4);

    /* Draw =s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xE7);
    kaleidoscope_line (window, gc, area, x, y, width, height, 1, 6);

    /* Draw 6s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xEA);
    kaleidoscope_point (window, gc, area, x, y, width, height, 2, 3);

    /* Draw 3s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xEB);
    kaleidoscope_point (window, gc, area, x, y, width, height, 1, 5);

    /* Draw as */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF2);
    kaleidoscope_point (window, gc, area, x, y, width, height, 1, 4);

    /* Draw -s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF7);
    kaleidoscope_point (window, gc, area, x, y, width, height, 2, 2);

    /* Draw 0s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF8);
    kaleidoscope_point (window, gc, area, x, y, width, height, 1, 3);

    /* Draw #s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFA);
    kaleidoscope_line (window, gc, area, x, y, width, height, 0, 6);

    /* Draw @s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFB);
    kaleidoscope_point (window, gc, area, x, y, width, height, 0, 5);

    /* Draw +s */
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFC);
    if (area)
      gdk_gc_set_clip_rectangle (gc, area);
    kaleidoscope_point (window, gc, NULL, x, y, width, height, 0, 4);
    kaleidoscope_point (window, gc, NULL, x, y, width, height, 1, 2);
    if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);

  } else if (DETAIL("menuitem")) {
    GdkGC *bg_gc = fill ? get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG) : NULL;
    GdkGC *fg_gc = get_gc (style, &style->bg[state_type], &style->fg[GTK_STATE_NORMAL], MENUITEM_BORDER_SHADE);
    GdkColor *fg_color = get_color (style, &style->bg[state_type], &style->fg[GTK_STATE_NORMAL], MENUITEM_BORDER_SHADE);
    GdkGC *corner_gc = get_gc (style, &style->bg[GTK_STATE_NORMAL], fg_color, SHADE_HALF);

    draw_rounded_rect_one_pixel (window, bg_gc, fg_gc, corner_gc,
                         area, x, y, width, height);
  } else if (DETAIL("trough") ||
           DETAIL("menu") ||
           DETAIL("dockitem_bin") ||
           DETAIL("handlebox_bin") ||
           DETAIL("toolbar") ||
           DETAIL("dockitem") ||
           WIDGET_TYPE_NAME("PanelAppletFrame")) {
    GdkGC *bg_gc = NULL;
    GdkGC *fg_gc;
    GdkColor *bg_color;
    GdkColor *fg_color;
    GdkGC *corner_gc;


    if (fill) {
      if (DETAIL("trough")) {
      if (state_type == GTK_STATE_ACTIVE)
        state_type = GTK_STATE_NORMAL;
      fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], TROUGH_BORDER_SHADE);
      bg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], TROUGH_BG_SHADE);
      corner_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);
      } else {
      fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], TROUGH_BORDER_SHADE);
      fg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], TROUGH_BORDER_SHADE);
      bg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);
      bg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);
      corner_gc = get_gc (style, bg_color, fg_color, SHADE_HALF);
      }
    }

    draw_rounded_rect_one_pixel (window, bg_gc, fg_gc, corner_gc,
                         area, x, y, width, height);
  } else if (DETAIL("menubar")) {
    GdkGC *bg_gc;
    GdkGC *fg_gc;
    GdkColor *bg_color;
    GdkColor *fg_color;
    GdkGC *corner_gc;

    bg_gc = fill ? get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG) : NULL;
    bg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);
    fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], MENUBAR_BORDER_SHADE);
    fg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], MENUBAR_BORDER_SHADE);
    corner_gc = get_gc (style, bg_color, fg_color, SHADE_HALF);

    draw_rounded_rect_one_pixel (window, bg_gc, fg_gc, corner_gc,
                         area, x, y, width, height);
  } else if (DETAIL("spinbutton_up") ||
           DETAIL("spinbutton_down")) {
    if (DETAIL("spinbutton_up")) {
      x += 1;
      y += 1;
      width -= 2;
      height -= 1;
    } else {
      x += 1;
      width -= 2;
      height -= 1;
    }

    parent_class->draw_flat_box (style, window, state_type, shadow_type, area,
                         widget, detail, x, y, width, height);
#if INDUSTRIAL_GTK_VERSION == 1
  } else if (DETAIL("slider")) {
    if (widget && GTK_IS_SCROLLBAR (widget)) {
      if (GTK_IS_VSCROLLBAR (widget))
      draw_slider (style, window, state_type, shadow_type, area, widget, "vscrollbar", x, y, width, height, GTK_ORIENTATION_VERTICAL);
      else
      draw_slider (style, window, state_type, shadow_type, area, widget, "hscrollbar", x, y, width, height, GTK_ORIENTATION_HORIZONTAL);
    } else {
      if (height > width)
      draw_slider (style, window, state_type, shadow_type, area, widget, "vscrollbar", x, y, width, height, GTK_ORIENTATION_VERTICAL);
      else
      draw_slider (style, window, state_type, shadow_type, area, widget, "hscrollbar", x, y, width, height, GTK_ORIENTATION_HORIZONTAL);
    }
#endif
  } else if (DETAIL ("slider") ||
           DETAIL ("stepper") ||
           DETAIL ("vscrollbar") ||
           DETAIL ("hscrollbar")) {
    GdkGC *bg_gc = fill ? get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG) : NULL;
    /* This is different to merge with the trough bg. */
    GdkColor *bg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], TROUGH_BORDER_SHADE); 
    GdkGC *fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
    GdkColor *fg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
    GdkGC *corner_gc = get_gc (style, bg_color, fg_color, SHADE_HALF);
    GdkGC *bevel_top_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BEVEL_TOP_SHADE);
    GdkGC *bevel_bottom_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BEVEL_BOTTOM_SHADE);

    draw_rounded_rect_two_pixel (window, bg_gc, fg_gc, corner_gc,
                         area, x, y, width, height);
    draw_rotated_line (window, bevel_bottom_gc, area, GTK_POS_TOP, x, y, width, height, ROTATION_CORNER_TR, 1, 2, ROTATION_CORNER_BR, 1, 2);
    draw_rotated_line (window, bevel_bottom_gc, area, GTK_POS_TOP, x, y, width, height, ROTATION_CORNER_BR, 2, 1, ROTATION_CORNER_BL, 2, 1);
    draw_rotated_line (window, bevel_top_gc, area, GTK_POS_TOP, x, y, width, height, ROTATION_CORNER_BL, 1, 2, ROTATION_CORNER_TL, 1, 2);
    draw_rotated_line (window, bevel_top_gc, area, GTK_POS_TOP, x, y, width, height, ROTATION_CORNER_TL, 2, 1, ROTATION_CORNER_TR, 2, 1);
  } else if (DETAIL("optionmenu")) {
    GdkGC *bg_gc = fill ? get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG) : NULL;
    GdkGC *fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
    GdkColor *fg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
    GdkGC *corner_gc = get_gc (style, &style->bg[state_type], fg_color, SHADE_HALF);
    int indicator_width, vline_x;

    draw_rounded_rect_two_pixel (window, bg_gc, fg_gc, corner_gc,
                         area, x, y, width, height);

    indicator_width = option_menu_get_indicator_width (widget);

    if ((!widget) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR))
      vline_x = x + width - indicator_width - GET_XTHICKNESS(style) + 1;
    else
      vline_x = x + indicator_width + GET_XTHICKNESS(style) - 1;
      
    gtk_paint_vline (style, window, state_type, area, widget,
                 detail,
                 y + GET_YTHICKNESS (style) + 4,
                 y + height - GET_YTHICKNESS(style) - 4,
                 vline_x);
  } else /* if (DETAIL("slider") ||
           DETAIL("stepper") ||
           DETAIL("vscrollbar") ||
           DETAIL("hscrollbar") ||
           DETAIL("vscale") ||
           DETAIL("hscale") ||
           DETAIL("optionmenu") ||
           DETAIL("notebook") ||
           DETAIL("text") ||
           DETAIL("entry") ||
           DETAIL("scrolled_window") ||
           DETAIL("frame") ||
           DETAIL("tab") ||
           DETAIL("spinbutton"))*/ {
    GdkGC *bg_gc = fill ? get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG) : NULL;
    GdkGC *fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
    GdkColor *fg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
    GdkGC *corner_gc = get_gc (style, &style->bg[state_type], fg_color, SHADE_HALF);

    draw_rounded_rect_one_pixel (window, bg_gc, fg_gc, corner_gc,
                         area, x, y, width, height);
  }
}

static void
draw_box (GtkStyle      *style,
        GdkWindow     *window,
        GtkStateType   state_type,
        GtkShadowType  shadow_type,
        GdkRectangle  *area,
        GtkWidget     *widget,
        INDUSTRIAL_CONST gchar   *detail,
        gint           x,
        gint           y,
        gint           width,
        gint           height)
{
#ifdef DEBUG
  printf ("draw_box: %p %p %s %i %i %i %i\n", widget, window, detail, x, y,
        width, height);
#endif

#if INDUSTRIAL_GTK_VERSION == 1
  if (DETAIL("hpaned")) {
    draw_handle (style, window, state_type, GTK_SHADOW_NONE, area, widget, "paned", x, y, width, height, GTK_ORIENTATION_VERTICAL);
  } else if (DETAIL("vpaned")) {
    draw_handle (style, window, state_type, GTK_SHADOW_NONE, area, widget, "paned", x, y, width, height, GTK_ORIENTATION_HORIZONTAL);
  } else {
#endif
    real_draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, TRUE);
#if INDUSTRIAL_GTK_VERSION == 1
  }
#endif
}

static void
draw_shadow (GtkStyle        *style,
           GdkWindow       *window,
           GtkStateType     state_type,
           GtkShadowType    shadow_type,
           GdkRectangle    *area,
           GtkWidget       *widget,
           INDUSTRIAL_CONST gchar     *detail,
           gint             x,
           gint             y,
           gint             width,
           gint             height)
{
#ifdef DEBUG
  printf ("draw_shadow: %p %p %s %i %i %i %i\n", widget, window, detail, x, y,
        width, height);
#endif

#if INDUSTRIAL_GTK_VERSION == 1
  if ((DETAIL ("entry") ||
       DETAIL ("text")) &&
      GTK_WIDGET_HAS_FOCUS (widget)) {
    x --;
    y --;
    width += 2;
    height += 2;
  }
#endif

  real_draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, FALSE);
}

/**************************************************************************/

static void 
real_draw_box_gap (GtkStyle       *style,
               GdkWindow      *window,
               GtkStateType    state_type,
               GtkShadowType   shadow_type,
               GdkRectangle   *area,
               GtkWidget      *widget,
               INDUSTRIAL_CONST gchar    *detail,
               gint            x,
               gint            y,
               gint            width,
               gint            height,
               GtkPositionType gap_side,
               gint            gap_x,
               gint            gap_width,
               gboolean        fill)
{
  GdkGC *gc;
  GdkColor *color;

  /*
    ... ...
    .+@ @+.
    .@. .@.

    .@. .@.
    .+@ @+.
    ... ...

    The spaces indicate repeat the line on either side (if they don't match, it's a bug in the drawing.)
    Set of . around the edge not part of width & height.
  */

  if (fill) {
    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);

    if (area)
      gdk_gc_set_clip_rectangle (gc, area);
    gdk_draw_rectangle (window, gc, TRUE, x + 1, y + 1, width - 2, height - 2);
    if (area)
      gdk_gc_set_clip_rectangle (gc, NULL);
  }

  /* Draw +s */
  color = get_color (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
  gc = get_gc (style, &style->bg[state_type], color, SHADE_HALF);
  kaleidoscope_point (window, gc, area, x, y, width, height, 0, 0);

  gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);

  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  draw_rotated_line (window, gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TL, MIN (gap_x, 1), 0, ROTATION_CORNER_TL, gap_x, 0);
  draw_rotated_line (window, gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TL, gap_x + gap_width - 1, 0, ROTATION_CORNER_TR, 1, 0);
  draw_rotated_line (window, gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TR, 0, 1, ROTATION_CORNER_BR, 0, 1);
  draw_rotated_line (window, gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BR, 1, 0, ROTATION_CORNER_BL, 1, 0);
  draw_rotated_line (window, gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BL, 0, 1, ROTATION_CORNER_TL, 0, 1);

  if (gap_width >= 3)
    draw_rotated_line (window, get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG),
                   area, gap_side, x, y, width, height, ROTATION_CORNER_TL, gap_x + 1, 0, ROTATION_CORNER_TL, gap_x + gap_width - 2, 0);

  draw_rotated_point (window, gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TL, gap_x + gap_width - 1, 0);
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);

  if (DETAIL("notebook"))
    draw_rotated_point (window, gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 0, 0);
}

static void 
draw_box_gap (GtkStyle       *style,
            GdkWindow      *window,
            GtkStateType    state_type,
            GtkShadowType   shadow_type,
            GdkRectangle   *area,
            GtkWidget      *widget,
            INDUSTRIAL_CONST gchar    *detail,
            gint            x,
            gint            y,
            gint            width,
            gint            height,
            GtkPositionType gap_side,
            gint            gap_x,
            gint            gap_width)
{
#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i  %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height, gap_side);
#endif

  if (shadow_type == GTK_SHADOW_NONE)
    return;

  real_draw_box_gap (style, window, state_type, shadow_type, area, widget, detail,
                 x, y, width, height, gap_side, gap_x, gap_width, TRUE);
#if 0
  /* Unused stripe code. */
  if (DETAIL("notebook")) {
    GdkGC *gc;
    int i;

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xD5);
    draw_rotated_point (window, gc, area, x, y, width, height, ROTATION_CORNER_TL, 0, 0);
    draw_rotated_point (window, gc, area, x, y, width, height, ROTATION_CORNER_TR, 0, 0);
    draw_rotated_point (window, gc, area, x, y, width, height, ROTATION_CORNER_TR, 1, 1);
    for (i = 3; i < gap_width; i += 2) {
      draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_TL, 1, i, ROTATION_CORNER_TR, i, 3);
    }

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xB3);
    draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_BL, 1, 0, ROTATION_CORNER_TL, 0, 1);
    draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_TL, 1, 0, ROTATION_CORNER_TR, 0, 1);
    draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_TR, 1, 0, ROTATION_CORNER_BR, 0, 1);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xE7);
    draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_TR, 2, 1, ROTATION_CORNER_BR, 0, 2);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xCA);
    draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_TL, 1, 1, ROTATION_CORNER_TR, 1, 3);
    for (i = 2; i < gap_width; i += 2) {
      draw_rotated_line (window, gc, area, x, y, width, height, ROTATION_CORNER_TL, 1, i, ROTATION_CORNER_TR, i, 3);
    }
  }
#endif
}

static void 
draw_shadow_gap (GtkStyle       *style,
             GdkWindow      *window,
             GtkStateType    state_type,
             GtkShadowType   shadow_type,
             GdkRectangle   *area,
             GtkWidget      *widget,
             INDUSTRIAL_CONST gchar    *detail,
             gint            x,
             gint            y,
             gint            width,
             gint            height,
             GtkPositionType gap_side,
             gint            gap_x,
             gint            gap_width)
{
#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i  %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height, gap_side);
#endif

  if (shadow_type == GTK_SHADOW_NONE)
    return;

  real_draw_box_gap (style, window, state_type, shadow_type, area, widget, detail,
                 x, y, width, height, gap_side, gap_x, gap_width, FALSE);
  draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
}

static void 
draw_extension (GtkStyle       *style,
            GdkWindow      *window,
            GtkStateType    state_type,
            GtkShadowType   shadow_type,
            GdkRectangle   *area,
            GtkWidget      *widget,
            INDUSTRIAL_CONST gchar    *detail,
            gint            x,
            gint            y,
            gint            width,
            gint            height,
            GtkPositionType gap_side)
{
  GdkGC *bg_gc;
  GdkGC *fg_gc;
  GdkColor *fg_color;
  GdkGC *corner_gc;

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i  %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height, gap_side);
#endif

  if (shadow_type == GTK_SHADOW_NONE)
    return;

  bg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_BG);
  fg_gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
  fg_color = get_color (style, &style->bg[state_type], &style->fg[state_type], STANDARD_BORDER_SHADE);
  corner_gc = get_gc (style, &style->bg[state_type], fg_color, SHADE_HALF);

  if (area) {
    gdk_gc_set_clip_rectangle (bg_gc, area);
    gdk_gc_set_clip_rectangle (fg_gc, area);
    gdk_gc_set_clip_rectangle (corner_gc, area);
  }

  gdk_draw_rectangle (window, bg_gc, TRUE, x + 1, y + 1, width - 1, height - 1);

  /* Draw @s */
  kaleidoscope_line  (window,     fg_gc, NULL, x, y, width, height, 0, 2);
  kaleidoscope_point (window, corner_gc, NULL, x, y, width, height, 0, 1);

  /* Draw shadow */
  if (state_type == GTK_STATE_ACTIVE) {
    GdkGC *gc;

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFB);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 6, ROTATION_CORNER_TR, 2, 6);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xFA);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 5, ROTATION_CORNER_TR, 2, 5);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF8);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 4, ROTATION_CORNER_TR, 2, 4);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF6);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 3, ROTATION_CORNER_TR, 2, 3);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TR, 1, 0, ROTATION_CORNER_BR, 1, 2);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF4);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 2, ROTATION_CORNER_TR, 2, 2);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF3);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 1, ROTATION_CORNER_TR, 2, 1);

    gc = get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_0xF2);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 2, 0, ROTATION_CORNER_TR, 2, 0);

    gc = get_gc (style, &style->bg[state_type], &style->bg[GTK_STATE_NORMAL], SHADE_HALF);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_BL, 2, 1, ROTATION_CORNER_BR, 2, 1);
    draw_rotated_line (window,     gc, area, gap_side, x, y, width, height, ROTATION_CORNER_TL, 1, 0, ROTATION_CORNER_BL, 1, 2);
  } else {
    draw_rotated_line (window,  bg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TL, 1, 0, ROTATION_CORNER_TR, 1, 0);
  }

  draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TL, 0, 0);
  draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TL, 0, 1);

  draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TR, 0, 0);
  draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_TR, 0, 1);

  draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BL, 1, 1);
  if (check_page (widget, x, y, width, height))
    draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BL, 1, 0);
  else 
    draw_rotated_point (window, corner_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BL, 1, 0);
  draw_rotated_point (window, corner_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BL, 0, 1);
  draw_rotated_point (window,     bg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BL, 0, 0);

  draw_rotated_point (window,     fg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BR, 1, 1);
  draw_rotated_point (window, corner_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BR, 1, 0);
  draw_rotated_point (window, corner_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BR, 0, 1);
  draw_rotated_point (window,     bg_gc, NULL, gap_side, x, y, width, height, ROTATION_CORNER_BR, 0, 0);
  if (area) {
    gdk_gc_set_clip_rectangle (bg_gc, NULL);
    gdk_gc_set_clip_rectangle (fg_gc, NULL);
    gdk_gc_set_clip_rectangle (corner_gc, NULL);
  }
}

#if INDUSTRIAL_GTK_VERSION == 1
static void
real_draw_arrow (GdkWindow     *window,
             GdkGC         *gc,
             GdkRectangle  *area,
             GtkArrowType   arrow_type,
             gint           x,
             gint           y,
             gint           width,
             gint           height)
{
  gint i, j;

  if (area)
    gdk_gc_set_clip_rectangle (gc, area);

  if (arrow_type == GTK_ARROW_DOWN)
    {
      for (i = 0, j = 0; i < height; i++, j++)
      gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
    }
  else if (arrow_type == GTK_ARROW_UP)
    {
      for (i = height - 1, j = 0; i >= 0; i--, j++)
      gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
    }
  else if (arrow_type == GTK_ARROW_LEFT)
    {
      for (i = width - 1, j = 0; i >= 0; i--, j++)
      gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
    }
  else if (arrow_type == GTK_ARROW_RIGHT)
    {
      for (i = 0, j = 0; i < width; i++, j++)
      gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
    }

  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

static void
calculate_arrow_geometry (GtkArrowType  arrow_type,
                    gint         *x,
                    gint         *y,
                    gint         *width,
                    gint         *height)
{
  gint w = *width;
  gint h = *height;
  
  switch (arrow_type)
    {
    case GTK_ARROW_UP:
    case GTK_ARROW_DOWN:
      w += (w % 2) - 1;
      h = (w / 2 + 1);
      
      if (h > *height)
      {
        h = *height;
        w = 2 * h - 1;
      }
      
      if (arrow_type == GTK_ARROW_DOWN)
      {
        if (*height % 2 == 1 || h % 2 == 0)
          *height += 1;
      }
      else
      {
        if (*height % 2 == 0 || h % 2 == 0)
          *height -= 1;
      }
      break;

    case GTK_ARROW_RIGHT:
    case GTK_ARROW_LEFT:
      h += (h % 2) - 1;
      w = (h / 2 + 1);
      
      if (w > *width)
      {
        w = *width;
        h = 2 * w - 1;
      }
      
      if (arrow_type == GTK_ARROW_RIGHT)
      {
        if (*width % 2 == 1 || w % 2 == 0)
          *width += 1;
      }
      else
      {
        if (*width % 2 == 0 || w % 2 == 0)
          *width -= 1;
      }
      break;
      
    default:
      /* should not be reached */
      break;
    }

  *x += (*width - w) / 2;
  *y += (*height - h) / 2;
  *height = h;
  *width = w;
}

/* Gtk 1 only.  A copy of the Gtk2 code. */
static void
draw_arrow (GtkStyle      *style,
          GdkWindow     *window,
          GtkStateType   state,
          GtkShadowType  shadow,
          GdkRectangle  *area,
          GtkWidget     *widget,
          gchar         *detail,
          GtkArrowType   arrow_type,
          gboolean       fill,
          gint           x,
          gint           y,
          gint           width,
          gint           height)
{
  gint original_width, original_x;

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height);
#endif

  sanitize_size (window, &width, &height);

  original_width = width;
  original_x = x;


  if (DETAIL ("vscrollbar") ||
      DETAIL ("hscrollbar")) {
    gtk_paint_box (style, window, state, shadow, area, widget, "stepper", x, y, width, height);

    width -= 6;
    height -= 6;
    x += 3;
    y += 3;
  } else if (DETAIL ("spinbutton_up") ||
           DETAIL ("spinbutton_down")) {
    width -= 4;
    height -= 4;
    x += 2;
    y += 2;
  } else {
    width -= 2;
    height -= 2;
    x++;
    y++;
  }

  calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
  
  if (DETAIL ("menuitem"))
    x = original_x + original_width - width;

  if (state == GTK_STATE_INSENSITIVE)
    real_draw_arrow (window, style->white_gc, area, arrow_type,
                 x + 1, y + 1, width, height);
  real_draw_arrow (window, get_gc (style, &style->bg[state], &style->fg[state], SHADE_FG),
               area, arrow_type,
               x, y, width, height);
}
#endif

static inline int
decode_shadow (GtkShadowType shadow_type)
{
  switch (shadow_type) {
  case GTK_SHADOW_IN:
    return 0;
  case GTK_SHADOW_ETCHED_IN:
    return 2;
  default:
    return 1;
  }
}

static void
draw_check (GtkStyle          *style,
          GdkWindow           *window,
          GtkStateType   state_type,
          GtkShadowType  shadow_type,
          GdkRectangle  *area,
          GtkWidget           *widget,
          INDUSTRIAL_CONST gchar          *detail,
          gint           x,
          gint           y,
          gint           width,
          gint           height)
{
  GdkPixmap *pixmap;
  GdkGC *gc;
  int src_width, src_height;
  int which;

  GdkColor *fg, *bg;

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height);
#endif

#if INDUSTRIAL_GTK_VERSION == 1
  fg = &style->text[GTK_STATE_NORMAL];
  bg = &style->base[GTK_STATE_NORMAL];
#else
  if (state_type == GTK_STATE_NORMAL) {
    fg = &style->text[GTK_STATE_NORMAL];
    bg = &style->base[GTK_STATE_NORMAL];
  } else {
    fg = &style->fg[state_type];
    bg = &style->bg[state_type];
  } 
#endif

  if (width <= 8)
    which = PIXMAP_SMALL_CHECK_ACTIVE;
  else if (width <= 11)
    which = PIXMAP_MEDIUM_CHECK_ACTIVE;
  else
    which = PIXMAP_CHECK_ACTIVE;

  pixmap = get_pixmap (style, window, bg, fg, which + decode_shadow (shadow_type));
  gc = style->text_gc[state_type];

  gdk_window_get_size (pixmap, &src_width, &src_height);

  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  gdk_gc_set_clip_mask (gc, get_mask (style, window, bg, fg, which + decode_shadow (shadow_type)));
  gdk_gc_set_clip_origin (gc, x, y);
  gdk_draw_pixmap (window, gc, pixmap, 0, 0, x, y, MIN (width, src_width), MIN (height, src_height));
  gdk_gc_set_clip_mask (gc, NULL);
  gdk_gc_set_clip_origin (gc, 0, 0);
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

static void
draw_option (GtkStyle         *style,
           GdkWindow          *window,
           GtkStateType  state_type,
           GtkShadowType       shadow_type,
           GdkRectangle *area,
           GtkWidget          *widget,
           INDUSTRIAL_CONST gchar   *detail,
           gint          x,
           gint          y,
           gint          width,
           gint          height)
{
  GdkPixmap *pixmap;
  GdkGC *gc;
  int src_width, src_height;
  int which;
  GdkColor *fg, *bg;

#ifdef DEBUG
  printf ("%s: %p %p %s %i %i %i %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height);
#endif

#if INDUSTRIAL_GTK_VERSION == 1
  fg = &style->text[GTK_STATE_NORMAL];
  bg = &style->base[GTK_STATE_NORMAL];
#else
  if (state_type == GTK_STATE_NORMAL) {
    fg = &style->text[GTK_STATE_NORMAL];
    bg = &style->base[GTK_STATE_NORMAL];
  } else {
    fg = &style->fg[state_type];
    bg = &style->bg[state_type];
  } 
#endif
  
  if (width < 13)
    which = PIXMAP_SMALL_RADIO_ACTIVE;
  else
    which = PIXMAP_RADIO_ACTIVE;

  pixmap = get_pixmap (style, window, bg, fg, which + decode_shadow (shadow_type));
  gc = style->text_gc[state_type];

  gdk_window_get_size (pixmap, &src_width, &src_height);

  if (area)
    gdk_gc_set_clip_rectangle (gc, area);
  gdk_gc_set_clip_mask (gc, get_mask (style, window, bg, fg, which + decode_shadow (shadow_type)));
  gdk_gc_set_clip_origin (gc, x, y);
  gdk_draw_pixmap (window, gc, pixmap, 0, 0, x, y, MIN (width, src_width), MIN (height, src_height));
  gdk_gc_set_clip_mask (gc, NULL);
  gdk_gc_set_clip_origin (gc, 0, 0);
  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);
}

#if INDUSTRIAL_GTK_VERSION == 1
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)
{
#define ARROW_SPACE 4
  gint arrow_height;

#if DEBUG
  printf ("%s: %p %p %s %i %i %i %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height);
#endif

#define INDICATOR_WIDTH 7
  arrow_height = INDICATOR_WIDTH / 2 + 1;

  x += (width - INDICATOR_WIDTH) / 2;
  y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;

  if (state_type == GTK_STATE_INSENSITIVE)
    {
      real_draw_arrow (window, style->white_gc, area,
                   GTK_ARROW_UP, x + 1, y + 1,
                   INDICATOR_WIDTH, arrow_height);
      
      real_draw_arrow (window, style->white_gc, area,
                   GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
                   INDICATOR_WIDTH, arrow_height);
    }
  
  real_draw_arrow (window, get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_FG),
               area, GTK_ARROW_UP, x, y,
               INDICATOR_WIDTH, arrow_height);

  real_draw_arrow (window, get_gc (style, &style->bg[state_type], &style->fg[state_type], SHADE_FG),
               area, GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
               INDICATOR_WIDTH, arrow_height);
}

static void 
draw_focus (GtkStyle      *style,
          GdkWindow     *window,
          GdkRectangle  *area,
          GtkWidget     *widget,
          gchar     *detail,
          gint           x,
          gint           y,
          gint           width,
          gint           height)
{
  GdkPoint points[5];
  GdkGC    *gc;
  gboolean free_dash_list = FALSE;
  gint line_width = 1;
  gchar *dash_list = "\1\1";
  gint dash_len;

#if DEBUG
  printf ("%s: %p %p %s %i %i %i %i\n", __FUNCTION__, widget, window, detail, x, y,
        width, height);
#endif

#if INDUSTRIAL_GTK_VERSION == 1
  if (DETAIL ("entry") ||
      DETAIL ("text"))
    return;
#endif

  gc = get_gc (style, &style->fg[GTK_STATE_NORMAL], &style->bg[GTK_STATE_NORMAL], STANDARD_BORDER_SHADE);

  sanitize_size (window, &width, &height);
  
  if (DETAIL ("treeitem") ||
      DETAIL ("add-mode") ||
      detail == NULL ||
      DETAIL ("tab")) {
    width += 1;
    height += 1;
  } else if (DETAIL ("checkbutton")) {
    if (widget && GTK_IS_RADIO_BUTTON (widget)) {
      /* y -= 1 to center */
      /* y += 1 to make smaller, along with height -= 2 */
      height -= 2;
    }
    y += 3;
    height -= 4;
  } else if ((DETAIL ("button") ||
            DETAIL ("togglebutton")) &&
           !(widget && GTK_WIDGET_CAN_DEFAULT (widget))){
    x += 4;
    y += 4;
    width -= 7;
    height -= 7;
  } else if (DETAIL ("trough")) {
    x += 1;
    y += 1;
    width -= 2;
    height -= 2;
  } else {
    x += 1;
    y += 1;
    width -= 1;
    height -= 1;
  }

#if 0
  if (widget)
    {
      gtk_widget_style_get (widget,
                      "focus-line-width", &line_width,
                      "focus-line-pattern", (gchar *)&dash_list,
                      NULL);

      free_dash_list = TRUE;
  }
#endif

  if (area)
    gdk_gc_set_clip_rectangle (gc, area);

  gdk_gc_set_line_attributes (gc, line_width,
                        dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
                        GDK_CAP_BUTT, GDK_JOIN_MITER);


  if (detail && !strcmp (detail, "add-mode"))
    {
      if (free_dash_list)
      g_free (dash_list);
      
      dash_list = "\4\4";
      free_dash_list = FALSE;
    }

  points[0].x = x + line_width / 2;
  points[0].y = y + line_width / 2;
  points[1].x = x + width - line_width + line_width / 2;
  points[1].y = y + line_width / 2;
  points[2].x = x + width - line_width + line_width / 2;
  points[2].y = y + height - line_width + line_width / 2;
  points[3].x = x + line_width / 2;
  points[3].y = y + height - line_width + line_width / 2;
  points[4] = points[0];

  if (!dash_list[0])
    {
      gdk_draw_lines (window, gc, points, 5);
    }
  else
    {
      /* We go through all the pain below because the X rasterization
       * rules don't really work right for dashed lines if you
       * want continuity in segments that go between top/right
       * and left/bottom. For instance, a top left corner
       * with a 1-1 dash is drawn as:
       *
       *  X X X 
       *  X
       *
       *  X
       *
       * This is because pixels on the top and left boundaries
       * of polygons are drawn, but not on the bottom and right.
       * So, if you have a line going up that turns the corner
       * and goes right, there is a one pixel shift in the pattern.
       *
       * So, to fix this, we drawn the top and right in one call,
       * then the left and bottom in another call, fixing up
       * the dash offset for the second call ourselves to get
       * continuity at the upper left.
       *
       * It's not perfect since we really should have a join at
       * the upper left and lower right instead of two intersecting
       * lines but that's only really apparent for no-dashes,
       * which (for this reason) are done as one polygon and
       * don't to through this code path.
       */
      
      dash_len = strlen (dash_list);
      
      if (dash_list[0])
      gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
      
      gdk_draw_lines (window, gc, points, 3);
      
      /* We draw this line one farther over than it is "supposed" to
       * because of another rasterization problem ... if two 1 pixel
       * unjoined lines meet at the lower right, there will be a missing
       * pixel.
       */
      points[2].x += 1;
      
      if (dash_list[0])
      {
        gint dash_pixels = 0;
        gint i;
        
        /* Adjust the dash offset for the bottom and left so we
         * match up at the upper left.
         */
        for (i = 0; i < dash_len; i++)
          dash_pixels += dash_list[i];
      
        if (dash_len % 2 == 1)
          dash_pixels *= 2;
        
        gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len);
      }
      
      gdk_draw_lines (window, gc, points + 2, 3);
    }

  gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);

  if (area)
    gdk_gc_set_clip_rectangle (gc, NULL);

  if (free_dash_list)
    g_free (dash_list);


#if 0
  static GdkPixmap *small_stipple = NULL;
  static GdkPixmap *large_stipple = NULL;
  GdkPixmap *stipple;

  GdkGC *fg_gc = get_gc (style, &style->bg[GTK_STATE_NORMAL], &style->fg[GTK_STATE_NORMAL], STANDARD_BORDER_SHADE);
  GdkColor *fg_color = get_color (style, &style->bg[GTK_STATE_NORMAL], &style->fg[GTK_STATE_NORMAL], STANDARD_BORDER_SHADE);
  GdkGC *corner_gc = get_gc (style, &style->bg[GTK_STATE_NORMAL], fg_color, SHADE_HALF);

  if (!DETAIL ("add-mode") && small_stipple == NULL) {
    small_stipple = gdk_bitmap_create_from_data (window,
                                     "\1\2", /* Checkerboard stipple */
                                     2,
                                     2);
    stipple = small_stipple;
  }

  if (DETAIL ("add-mode") && large_stipple == NULL) {
    large_stipple = gdk_bitmap_create_from_data (window,
                                     "\x0f\x0f\x0f\x0f"
                                     "\xf0\xf0\xf0\xf0", /* Large checkerboard stipple */
                                     8,
                                     8);
    stipple = large_stipple;
  }

  sanitize_size (window, &width, &height);
  
  gdk_gc_set_stipple (fg_gc, stipple);
  gdk_gc_set_stipple (corner_gc, stipple);

  draw_rounded_rect_one_pixel (window, NULL, fg_gc, corner_gc,
                         area, x, y, width, height);

  gdk_gc_set_stipple (fg_gc, NULL);
  gdk_gc_set_stipple (corner_gc, NULL);
#endif
}
#endif

#if INDUSTRIAL_GTK_VERSION == 2
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 *
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->colormap) {
            screen = gdk_colormap_get_screen (style->colormap);
            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_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;
}
#endif

#include "industrial_style_versioned_code.h"

Generated by  Doxygen 1.6.0   Back to index