]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkstyle.c
style: Use gtk_widget_get_state() for the entry background
[~andy/gtk] / gtk / gtkstyle.c
index ac49234952e8cde35bfbf14f948352551da98b06..d4fa6594a90151851ccc6e897f0f5ba53bc32d87 100644 (file)
@@ -29,9 +29,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <gobject/gvaluecollector.h>
-#include "gtkgc.h"
 #include "gtkmarshalers.h"
-#undef GTK_DISABLE_DEPRECATED
+#include "gtkpango.h"
 #include "gtkrc.h"
 #include "gtkspinbutton.h"
 #include "gtkstyle.h"
 #include "gtkiconfactory.h"
 #include "gtksettings.h"       /* _gtk_settings_parse_convert() */
 #include "gtkintl.h"
-#include "gtkalias.h"
 #include "gtkspinner.h"
 
+
+/**
+ * SECTION:gtkstyle
+ * @Short_description: An object that hold style information for widgets
+ * @Title: GtkStyle
+ *
+ * A #GtkStyle object encapsulates the information that provides the look and
+ * feel for a widget. Each #GtkWidget has an associated #GTkStyle object that
+ * is used when rendering that widget. Also, a #GtkStyle holds information for
+ * the five possible widget states though not every widget supports all five
+ * states; see #GtkStateType.
+ *
+ * Usually the #GtkStyle for a widget is the same as the default style that is
+ * set by GTK+ and modified the theme engine.
+ *
+ * Usually applications should not need to use or modify the #GtkStyle of their
+ * widgets.
+ */
+
+
 #define LIGHTNESS_MULT  1.3
 #define DARKNESS_MULT   0.7
 
@@ -111,16 +129,6 @@ static void gtk_default_draw_shadow     (GtkStyle        *style,
                                         gint             y,
                                         gint             width,
                                         gint             height);
-static void gtk_default_draw_polygon    (GtkStyle        *style,
-                                        GdkWindow       *window,
-                                        GtkStateType     state_type,
-                                        GtkShadowType    shadow_type,
-                                        GdkRectangle    *area,
-                                        GtkWidget       *widget,
-                                        const gchar     *detail,
-                                        GdkPoint        *points,
-                                        gint             npoints,
-                                        gboolean         fill);
 static void gtk_default_draw_arrow      (GtkStyle        *style,
                                         GdkWindow       *window,
                                         GtkStateType     state_type,
@@ -145,15 +153,6 @@ static void gtk_default_draw_diamond    (GtkStyle        *style,
                                         gint             y,
                                         gint             width,
                                         gint             height);
-static void gtk_default_draw_string     (GtkStyle        *style,
-                                        GdkWindow       *window,
-                                        GtkStateType     state_type,
-                                        GdkRectangle    *area,
-                                        GtkWidget       *widget,
-                                        const gchar     *detail,
-                                        gint             x,
-                                        gint             y,
-                                        const gchar     *string);
 static void gtk_default_draw_box        (GtkStyle        *style,
                                         GdkWindow       *window,
                                         GtkStateType     state_type,
@@ -332,9 +331,7 @@ static void hls_to_rgb                      (gdouble         *h,
                                         gdouble         *l,
                                         gdouble         *s);
 
-static void style_unrealize_cursor_gcs (GtkStyle *style);
-
-static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
+static void style_unrealize_cursors     (GtkStyle *style);
 
 /*
  * Data for default check and radio buttons
@@ -435,9 +432,6 @@ gtk_style_init (GtkStyle *style)
   style->white.green = 65535;
   style->white.blue = 65535;
   
-  style->black_gc = NULL;
-  style->white_gc = NULL;
-  
   style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
   style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
   style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
@@ -468,18 +462,6 @@ gtk_style_init (GtkStyle *style)
   
   style->rc_style = NULL;
   
-  for (i = 0; i < 5; i++)
-    {
-      style->fg_gc[i] = NULL;
-      style->bg_gc[i] = NULL;
-      style->light_gc[i] = NULL;
-      style->dark_gc[i] = NULL;
-      style->mid_gc[i] = NULL;
-      style->text_gc[i] = NULL;
-      style->base_gc[i] = NULL;
-      style->text_aa_gc[i] = NULL;
-    }
-
   style->xthickness = 2;
   style->ythickness = 2;
 
@@ -504,10 +486,8 @@ gtk_style_class_init (GtkStyleClass *klass)
   klass->draw_hline = gtk_default_draw_hline;
   klass->draw_vline = gtk_default_draw_vline;
   klass->draw_shadow = gtk_default_draw_shadow;
-  klass->draw_polygon = gtk_default_draw_polygon;
   klass->draw_arrow = gtk_default_draw_arrow;
   klass->draw_diamond = gtk_default_draw_diamond;
-  klass->draw_string = gtk_default_draw_string;
   klass->draw_box = gtk_default_draw_box;
   klass->draw_flat_box = gtk_default_draw_flat_box;
   klass->draw_check = gtk_default_draw_check;
@@ -550,7 +530,7 @@ gtk_style_class_init (GtkStyleClass *klass)
    *
    * Emitted when the aspects of the style specific to a particular colormap
    * and depth are being cleaned up. A connection to this signal can be useful
-   * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
+   * if a widget wants to cache objects as object data on #GtkStyle.
    * This signal provides a convenient place to free such cached objects.
    *
    * Since: 2.4
@@ -624,9 +604,6 @@ gtk_style_finalize (GObject *object)
   g_slist_free (priv->color_hashes);
 
   pango_font_description_free (style->font_desc);
-  
-  if (style->private_font)
-    gdk_font_unref (style->private_font);
 
   if (style->private_font_desc)
     pango_font_description_free (style->private_font_desc);
@@ -765,12 +742,6 @@ gtk_style_attach (GtkStyle  *style,
   if (!new_style)
     {
       new_style = gtk_style_duplicate (style);
-      if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
-         new_style->private_font)
-       {
-         gdk_font_unref (new_style->private_font);
-         new_style->private_font = NULL;
-       }
       gtk_style_realize (new_style, colormap);
     }
 
@@ -814,12 +785,6 @@ gtk_style_detach (GtkStyle *style)
 
       if (style->private_font_desc)
        {
-         if (style->private_font)
-           {
-             gdk_font_unref (style->private_font);
-             style->private_font = NULL;
-           }
-         
          pango_font_description_free (style->private_font_desc);
          style->private_font_desc = NULL;
        }
@@ -919,68 +884,6 @@ gtk_style_lookup_color (GtkStyle   *style,
   return FALSE;
 }
 
-/**
- * gtk_draw_slider:
- * @style: a #GtkStyle
-  @window: a #GdkWindow
- * @state_type: a state
- * @shadow_type: a shadow
- * @x: the x origin of the rectangle in which to draw a slider
- * @y: the y origin of the rectangle in which to draw a slider
- * @width: the width of the rectangle in which to draw a slider
- * @height: the height of the rectangle in which to draw a slider
- * @orientation: the orientation to be used
- *
- * Draws a slider in the given rectangle on @window using the
- * given style and orientation.
- */
-void 
-gtk_draw_slider (GtkStyle      *style,
-                GdkWindow     *window,
-                GtkStateType   state_type,
-                GtkShadowType  shadow_type,
-                gint           x,
-                gint           y,
-                gint           width,
-                gint           height,
-                GtkOrientation orientation)
-{
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
-  
-  GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
-}
-
-/**
- * gtk_draw_layout:
- * @style: a #GtkStyle
- * @window: a #GdkWindow
- * @state_type: a state
- * @use_text: whether to use the text or foreground
- *            graphics context of @style
- * @x: x origin
- * @y: y origin
- * @layout: the layout to draw
- * 
- * Draws a layout on @window using the given parameters.
- */
-void
-gtk_draw_layout (GtkStyle        *style,
-                 GdkWindow       *window,
-                 GtkStateType     state_type,
-                gboolean         use_text,
-                 gint             x,
-                 gint             y,
-                 PangoLayout     *layout)
-{
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
-  
-  GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
-                                            NULL, NULL, NULL,
-                                            x, y, layout);
-}
-
 /**
  * gtk_style_set_background:
  * @style: a #GtkStyle
@@ -1030,12 +933,6 @@ gtk_style_real_copy (GtkStyle *style,
        g_object_ref (style->bg_pixmap[i]);
     }
 
-  if (style->private_font)
-    gdk_font_unref (style->private_font);
-  style->private_font = src->private_font;
-  if (style->private_font)
-    gdk_font_ref (style->private_font);
-
   if (style->font_desc)
     pango_font_description_free (style->font_desc);
   if (src->font_desc)
@@ -1351,18 +1248,39 @@ load_bg_image (GdkColormap *colormap,
     return (GdkPixmap*) GDK_PARENT_RELATIVE;
   else
     {
-      return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
-                                                 bg_color,
-                                                 filename);
+      GdkPixmap *pixmap;
+      GdkPixbuf *pixbuf;
+      cairo_t *cr;
+      GdkScreen *screen = gdk_colormap_get_screen (colormap);
+  
+      pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+      if (!pixbuf)
+        return NULL;
+
+      pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen),
+                               gdk_pixbuf_get_width (pixbuf),
+                               gdk_pixbuf_get_height (pixbuf),
+                               gdk_colormap_get_visual (colormap)->depth);
+      gdk_drawable_set_colormap (pixmap, colormap);
+  
+      cr = gdk_cairo_create (pixmap);
+
+      gdk_cairo_set_source_color (cr, bg_color);
+      cairo_paint (cr);
+
+      gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+      cairo_paint (cr);
+
+      cairo_destroy (cr);
+      g_object_unref (pixbuf);
+
+      return pixmap;
     }
 }
 
 static void
 gtk_style_real_realize (GtkStyle *style)
 {
-  GdkGCValues gc_values;
-  GdkGCValuesMask gc_values_mask;
-  
   gint i;
 
   for (i = 0; i < 5; i++)
@@ -1382,24 +1300,10 @@ gtk_style_real_realize (GtkStyle *style)
   style->black.red = 0x0000;
   style->black.green = 0x0000;
   style->black.blue = 0x0000;
-  gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
 
   style->white.red = 0xffff;
   style->white.green = 0xffff;
   style->white.blue = 0xffff;
-  gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
-
-  gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
-  
-  gc_values.foreground = style->black;
-  gc_values.background = style->white;
-  style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-  
-  gc_values.foreground = style->white;
-  gc_values.background = style->black;
-  style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-  
-  gc_values_mask = GDK_GC_FOREGROUND;
 
   for (i = 0; i < 5; i++)
     {
@@ -1407,55 +1311,6 @@ gtk_style_real_realize (GtkStyle *style)
        style->bg_pixmap[i] = load_bg_image (style->colormap,
                                             &style->bg[i],
                                             style->rc_style->bg_pixmap_name[i]);
-      
-      if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->fg[i].red, style->fg[i].green, style->fg[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->bg[i].red, style->bg[i].green, style->bg[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->light[i].red, style->light[i].green, style->light[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->dark[i].red, style->dark[i].green, style->dark[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->mid[i].red, style->mid[i].green, style->mid[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->text[i].red, style->text[i].green, style->text[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->base[i].red, style->base[i].green, style->base[i].blue);
-      if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
-        g_warning ("unable to allocate color: ( %d %d %d )",
-                   style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
-      
-      gc_values.foreground = style->fg[i];
-      style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-      
-      gc_values.foreground = style->bg[i];
-      style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-      
-      gc_values.foreground = style->light[i];
-      style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-      
-      gc_values.foreground = style->dark[i];
-      style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-      
-      gc_values.foreground = style->mid[i];
-      style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-      
-      gc_values.foreground = style->text[i];
-      style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-      
-      gc_values.foreground = style->base[i];
-      style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->text_aa[i];
-      style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
     }
 }
 
@@ -1464,20 +1319,8 @@ gtk_style_real_unrealize (GtkStyle *style)
 {
   int i;
 
-  gtk_gc_release (style->black_gc);
-  gtk_gc_release (style->white_gc);
-      
   for (i = 0; i < 5; i++)
     {
-      gtk_gc_release (style->fg_gc[i]);
-      gtk_gc_release (style->bg_gc[i]);
-      gtk_gc_release (style->light_gc[i]);
-      gtk_gc_release (style->dark_gc[i]);
-      gtk_gc_release (style->mid_gc[i]);
-      gtk_gc_release (style->text_gc[i]);
-      gtk_gc_release (style->base_gc[i]);
-      gtk_gc_release (style->text_aa_gc[i]);
-
       if (style->bg_pixmap[i] &&  style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
        {
          g_object_unref (style->bg_pixmap[i]);
@@ -1486,16 +1329,7 @@ gtk_style_real_unrealize (GtkStyle *style)
       
     }
   
-  gdk_colormap_free_colors (style->colormap, style->fg, 5);
-  gdk_colormap_free_colors (style->colormap, style->bg, 5);
-  gdk_colormap_free_colors (style->colormap, style->light, 5);
-  gdk_colormap_free_colors (style->colormap, style->dark, 5);
-  gdk_colormap_free_colors (style->colormap, style->mid, 5);
-  gdk_colormap_free_colors (style->colormap, style->text, 5);
-  gdk_colormap_free_colors (style->colormap, style->base, 5);
-  gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
-
-  style_unrealize_cursor_gcs (style);
+  style_unrealize_cursors (style);
 }
 
 static void
@@ -1613,18 +1447,20 @@ gtk_style_apply_default_background (GtkStyle          *style,
       GDK_IS_PIXMAP (window) ||
       (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
     {
-      GdkGC *gc = style->bg_gc[state_type];
-      
+      cairo_t *cr = gdk_cairo_create (window);
+
       if (style->bg_pixmap[state_type])
         {
-          gdk_gc_set_fill (gc, GDK_TILED);
-          gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
+          gdk_cairo_set_source_pixmap (cr, style->bg_pixmap[state_type], 0, 0);
+          cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
         }
-      
-      gdk_draw_rectangle (window, gc, TRUE, 
-                          new_rect.x, new_rect.y, new_rect.width, new_rect.height);
-      if (style->bg_pixmap[state_type])
-        gdk_gc_set_fill (gc, GDK_SOLID);
+      else
+        gdk_cairo_set_source_color (cr, &style->bg[state_type]);
+
+      gdk_cairo_rectangle (cr, &new_rect);
+      cairo_fill (cr);
+
+      cairo_destroy (cr);
     }
   else
     {
@@ -1773,6 +1609,60 @@ sanitize_size (GdkWindow *window,
     gdk_drawable_get_size (window, NULL, height);
 }
 
+static void
+_cairo_draw_line (cairo_t  *cr,
+                  GdkColor *color,
+                  gint      x1,
+                  gint      y1,
+                  gint      x2,
+                  gint      y2)
+{
+  cairo_save (cr);
+
+  gdk_cairo_set_source_color (cr, color);
+  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+
+  cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
+  cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
+
+static void
+_cairo_draw_rectangle (cairo_t *cr,
+                       GdkColor *color,
+                       gboolean filled,
+                       gint x,
+                       gint y,
+                       gint width,
+                       gint height)
+{
+  gdk_cairo_set_source_color (cr, color);
+
+  if (filled)
+    {
+      cairo_rectangle (cr, x, y, width, height);
+      cairo_fill (cr);
+    }
+  else
+    {
+      cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
+      cairo_stroke (cr);
+    }
+}
+
+static void
+_cairo_draw_point (cairo_t *cr,
+                   GdkColor *color,
+                   gint x,
+                   gint y)
+{
+  gdk_cairo_set_source_color (cr, color);
+  cairo_rectangle (cr, x, y, 1, 1);
+  cairo_fill (cr);
+}
+
 static void
 gtk_default_draw_hline (GtkStyle     *style,
                         GdkWindow    *window,
@@ -1784,6 +1674,7 @@ gtk_default_draw_hline (GtkStyle     *style,
                         gint          x2,
                         gint          y)
 {
+  cairo_t *cr;
   gint thickness_light;
   gint thickness_dark;
   gint i;
@@ -1791,39 +1682,38 @@ gtk_default_draw_hline (GtkStyle     *style,
   thickness_light = style->ythickness / 2;
   thickness_dark = style->ythickness - thickness_light;
   
+  cr = gdk_cairo_create (window);
+  cairo_set_line_width (cr, 1.0);
+
   if (area)
     {
-      gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
-      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
     }
   
   if (detail && !strcmp (detail, "label"))
     {
       if (state_type == GTK_STATE_INSENSITIVE)
-        gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);   
-      gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);     
+        _cairo_draw_line (cr, &style->white, x1 + 1, y + 1, x2 + 1, y + 1);
+      _cairo_draw_line (cr, &style->fg[state_type], x1, y, x2, y);
     }
   else
     {
       for (i = 0; i < thickness_dark; i++)
         {
-          gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
-          gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
+          _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x2 - i - 1, y + i);
+          _cairo_draw_line (cr, &style->light[state_type], x2 - i, y + i, x2, 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, y + i, x2, y + i);
+          _cairo_draw_line (cr, &style->dark[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
+          _cairo_draw_line (cr, &style->light[state_type], x1 + thickness_light - i, 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);
-    }
+
+  cairo_destroy (cr);
 }
 
 
@@ -1838,40 +1728,46 @@ gtk_default_draw_vline (GtkStyle     *style,
                         gint          y2,
                         gint          x)
 {
+  cairo_t *cr;
   gint thickness_light;
   gint thickness_dark;
   gint i;
   
   thickness_light = style->xthickness / 2;
   thickness_dark = style->xthickness - thickness_light;
-  
+
+  cr = gdk_cairo_create (window);
+  cairo_set_line_width (cr, 1.0);
+
   if (area)
     {
-      gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
-      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
     }
+
   for (i = 0; i < thickness_dark; i++)
     { 
-      gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
-      gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
+      _cairo_draw_line (cr, &style->dark[state_type],
+                        x + i, y1, x + i, y2 - i - 1);
+      _cairo_draw_line (cr, &style->light[state_type],
+                        x + i, y2 - i, x + i, y2);
     }
   
   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 - 1);
-      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);
+      _cairo_draw_line (cr, &style->dark[state_type],
+                        x + i, y1, x + i, y1 + thickness_light - i - 1);
+      _cairo_draw_line (cr, &style->light[state_type],
+                        x + i, y1 + thickness_light - i, x + i, y2);
     }
+
+  cairo_destroy (cr);
 }
 
 static void
 draw_thin_shadow (GtkStyle      *style,
-                 GdkWindow     *window,
+                 cairo_t       *cr,
                  GtkStateType   state,
                  GdkRectangle  *area,
                  gint           x,
@@ -1879,39 +1775,25 @@ draw_thin_shadow (GtkStyle      *style,
                  gint           width,
                  gint           height)
 {
-  GdkGC *gc1, *gc2;
+  GdkColor *gc1, *gc2;
 
-  sanitize_size (window, &width, &height);
-  
-  gc1 = style->light_gc[state];
-  gc2 = style->dark_gc[state];
-  
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (gc1, area);
-      gdk_gc_set_clip_rectangle (gc2, area);
-    }
-  
-  gdk_draw_line (window, gc1,
-                x, y + height - 1, x + width - 1, y + height - 1);
-  gdk_draw_line (window, gc1,
-                x + width - 1, y,  x + width - 1, y + height - 1);
-      
-  gdk_draw_line (window, gc2,
-                x, y, x + width - 2, y);
-  gdk_draw_line (window, gc2,
-                x, y, x, y + height - 2);
+  gc1 = &style->light[state];
+  gc2 = &style->dark[state];
 
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (gc1, NULL);
-      gdk_gc_set_clip_rectangle (gc2, NULL);
-    }
+  _cairo_draw_line (cr, gc1,
+                    x, y + height - 1, x + width - 1, y + height - 1);
+  _cairo_draw_line (cr, gc1,
+                    x + width - 1, y,  x + width - 1, y + height - 1);
+      
+  _cairo_draw_line (cr, gc2,
+                    x, y, x + width - 2, y);
+  _cairo_draw_line (cr, gc2,
+                    x, y, x, y + height - 2);
 }
 
 static void
 draw_spinbutton_shadow (GtkStyle        *style,
-                       GdkWindow       *window,
+                       cairo_t         *cr,
                        GtkStateType     state,
                        GtkTextDirection direction,
                        GdkRectangle    *area,
@@ -1920,63 +1802,46 @@ draw_spinbutton_shadow (GtkStyle        *style,
                        gint             width,
                        gint             height)
 {
-  sanitize_size (window, &width, &height);
-
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (style->black_gc, area);
-      gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
-      gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
-      gdk_gc_set_clip_rectangle (style->light_gc[state], area);
-    }
 
   if (direction == GTK_TEXT_DIR_LTR)
     {
-      gdk_draw_line (window, style->dark_gc[state],
-                    x, y, x + width - 1, y);
-      gdk_draw_line (window, style->black_gc,
-                    x, y + 1, x + width - 2, y + 1);
-      gdk_draw_line (window, style->black_gc,
-                    x + width - 2, y + 2, x + width - 2, y + height - 3);
-      gdk_draw_line (window, style->light_gc[state],
-                    x + width - 1, y + 1, x + width - 1, y + height - 2);
-      gdk_draw_line (window, style->light_gc[state],
-                    x, y + height - 1, x + width - 1, y + height - 1);
-      gdk_draw_line (window, style->bg_gc[state],
-                    x, y + height - 2, x + width - 2, y + height - 2);
-      gdk_draw_line (window, style->black_gc,
-                    x, y + 2, x, y + height - 3);
+      _cairo_draw_line (cr, &style->dark[state],
+                        x, y, x + width - 1, y);
+      _cairo_draw_line (cr, &style->black,
+                        x, y + 1, x + width - 2, y + 1);
+      _cairo_draw_line (cr, &style->black,
+                        x + width - 2, y + 2, x + width - 2, y + height - 3);
+      _cairo_draw_line (cr, &style->light[state],
+                        x + width - 1, y + 1, x + width - 1, y + height - 2);
+      _cairo_draw_line (cr, &style->light[state],
+                        x, y + height - 1, x + width - 1, y + height - 1);
+      _cairo_draw_line (cr, &style->bg[state],
+                        x, y + height - 2, x + width - 2, y + height - 2);
+      _cairo_draw_line (cr, &style->black,
+                        x, y + 2, x, y + height - 3);
     }
   else
     {
-      gdk_draw_line (window, style->dark_gc[state],
-                    x, y, x + width - 1, y);
-      gdk_draw_line (window, style->dark_gc[state],
-                    x, y + 1, x, y + height - 1);
-      gdk_draw_line (window, style->black_gc,
-                    x + 1, y + 1, x + width - 1, y + 1);
-      gdk_draw_line (window, style->black_gc,
-                    x + 1, y + 2, x + 1, y + height - 2);
-      gdk_draw_line (window, style->black_gc,
-                    x + width - 1, y + 2, x + width - 1, y + height - 3);
-      gdk_draw_line (window, style->light_gc[state],
-                    x + 1, y + height - 1, x + width - 1, y + height - 1);
-      gdk_draw_line (window, style->bg_gc[state],
-                    x + 2, y + height - 2, x + width - 1, y + height - 2);
-    }
-  
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (style->black_gc, NULL);
-      gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
-      gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
-      gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
+      _cairo_draw_line (cr, &style->dark[state],
+                        x, y, x + width - 1, y);
+      _cairo_draw_line (cr, &style->dark[state],
+                        x, y + 1, x, y + height - 1);
+      _cairo_draw_line (cr, &style->black,
+                        x + 1, y + 1, x + width - 1, y + 1);
+      _cairo_draw_line (cr, &style->black,
+                        x + 1, y + 2, x + 1, y + height - 2);
+      _cairo_draw_line (cr, &style->black,
+                        x + width - 1, y + 2, x + width - 1, y + height - 3);
+      _cairo_draw_line (cr, &style->light[state],
+                        x + 1, y + height - 1, x + width - 1, y + height - 1);
+      _cairo_draw_line (cr, &style->bg[state],
+                        x + 2, y + height - 2, x + width - 1, y + height - 2);
     }
 }
 
 static void
 draw_menu_shadow (GtkStyle        *style,
-                 GdkWindow       *window,
+                 cairo_t         *cr,
                  GtkStateType     state,
                  GdkRectangle    *area,
                  gint             x,
@@ -1988,15 +1853,16 @@ draw_menu_shadow (GtkStyle        *style,
     {
       if (style->ythickness > 1)
        {
-         gdk_draw_line (window, style->dark_gc[state],
-                        x + 1, y + height - 2, x + width - 2, y + height - 2);
-         gdk_draw_line (window, style->black_gc,
-                        x, y + height - 1, x + width - 1, y + height - 1);
+         _cairo_draw_line (cr, &style->dark[state],
+                            x + 1, y + height - 2,
+                            x + width - 2, y + height - 2);
+         _cairo_draw_line (cr, &style->black,
+                            x, y + height - 1, x + width - 1, y + height - 1);
        }
       else
        {
-         gdk_draw_line (window, style->dark_gc[state],
-                        x + 1, y + height - 1, x + width - 1, y + height - 1);
+         _cairo_draw_line (cr, &style->dark[state],
+                            x + 1, y + height - 1, x + width - 1, y + height - 1);
        }
     }
   
@@ -2004,34 +1870,35 @@ draw_menu_shadow (GtkStyle        *style,
     {
       if (style->xthickness > 1)
        {
-         gdk_draw_line (window, style->dark_gc[state],
-                        x + width - 2, y + 1, x + width - 2, y + height - 2);
-         
-         gdk_draw_line (window, style->black_gc,
-                        x + width - 1, y, x + width - 1, y + height - 1);
+         _cairo_draw_line (cr, &style->dark[state],
+                            x + width - 2, y + 1,
+                            x + width - 2, y + height - 2);
+
+         _cairo_draw_line (cr, &style->black,
+                            x + width - 1, y, x + width - 1, y + height - 1);
        }
       else
        {
-         gdk_draw_line (window, style->dark_gc[state],
-                        x + width - 1, y + 1, x + width - 1, y + height - 1);
+         _cairo_draw_line (cr, &style->dark[state],
+                            x + width - 1, y + 1, x + width - 1, y + height - 1);
        }
     }
   
   /* Light around top and left */
   
   if (style->ythickness > 0)
-    gdk_draw_line (window, style->black_gc,
+    _cairo_draw_line (cr, &style->black,
                   x, y, x + width - 2, y);
   if (style->xthickness > 0)
-    gdk_draw_line (window, style->black_gc,
-                  x, y, x, y + height - 2);
+    _cairo_draw_line (cr, &style->black,
+                      x, y, x, y + height - 2);
   
   if (style->ythickness > 1)
-    gdk_draw_line (window, style->light_gc[state],
-                  x + 1, y + 1, x + width - 3, y + 1);
+    _cairo_draw_line (cr, &style->light[state],
+                      x + 1, y + 1, x + width - 3, y + 1);
   if (style->xthickness > 1)
-    gdk_draw_line (window, style->light_gc[state],
-                  x + 1, y + 1, x + 1, y + height - 3);
+    _cairo_draw_line (cr, &style->light[state],
+                      x + 1, y + 1, x + 1, y + height - 3);
 }
 
 static GtkTextDirection
@@ -2061,75 +1928,77 @@ gtk_default_draw_shadow (GtkStyle      *style,
                          gint           width,
                          gint           height)
 {
-  GdkGC *gc1 = NULL;
-  GdkGC *gc2 = NULL;
+  cairo_t *cr;
+  GdkColor *gc1 = NULL;
+  GdkColor *gc2 = NULL;
   gint thickness_light;
   gint thickness_dark;
   gint i;
-  
+
+  sanitize_size (window, &width, &height);
+
+  cr = gdk_cairo_create (window);
+  cairo_set_line_width (cr, 1.0);
+
+  if (area)
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
+
   if (shadow_type == GTK_SHADOW_IN)
     {
       if (detail && strcmp (detail, "buttondefault") == 0)
        {
-         sanitize_size (window, &width, &height);
+          _cairo_draw_rectangle (cr, &style->black, FALSE,
+                                 x, y, width - 1, height - 1);
 
-         gdk_draw_rectangle (window, style->black_gc, FALSE,
-                             x, y, width - 1, height - 1);
-         
+          cairo_destroy (cr);
          return;
        }
       if (detail && strcmp (detail, "trough") == 0)
        {
-         draw_thin_shadow (style, window, state_type, area,
-                           x, y, width, height);
+          draw_thin_shadow (style, cr, state_type, area,
+                            x, y, width, height);
+
+          cairo_destroy (cr);
          return;
        }
       if (GTK_IS_SPIN_BUTTON (widget) &&
          detail && strcmp (detail, "spinbutton") == 0)
        {
-         draw_spinbutton_shadow (style, window, state_type, 
+         draw_spinbutton_shadow (style, cr, state_type, 
                                  get_direction (widget), area, x, y, width, height);
          
+         cairo_destroy (cr);
          return;
        }
     }
 
   if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
     {
-      draw_menu_shadow (style, window, state_type, area, x, y, width, height);
+      draw_menu_shadow (style, cr, state_type, area, x, y, width, height);
+      cairo_destroy (cr);
       return;
     }
   
-  sanitize_size (window, &width, &height);
-  
   switch (shadow_type)
     {
     case GTK_SHADOW_NONE:
+      cairo_destroy (cr);
       return;
     case GTK_SHADOW_IN:
     case GTK_SHADOW_ETCHED_IN:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->dark_gc[state_type];
+      gc1 = &style->light[state_type];
+      gc2 = &style->dark[state_type];
       break;
     case GTK_SHADOW_OUT:
     case GTK_SHADOW_ETCHED_OUT:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->light_gc[state_type];
+      gc1 = &style->dark[state_type];
+      gc2 = &style->light[state_type];
       break;
     }
   
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (gc1, area);
-      gdk_gc_set_clip_rectangle (gc2, 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:
@@ -2139,34 +2008,34 @@ gtk_default_draw_shadow (GtkStyle      *style,
       /* Light around right and bottom edge */
 
       if (style->ythickness > 0)
-        gdk_draw_line (window, gc1,
-                       x, y + height - 1, x + width - 1, y + height - 1);
+        _cairo_draw_line (cr, gc1,
+                          x, y + height - 1, x + width - 1, y + height - 1);
       if (style->xthickness > 0)
-        gdk_draw_line (window, gc1,
-                       x + width - 1, y, x + width - 1, y + height - 1);
+        _cairo_draw_line (cr, gc1,
+                          x + width - 1, y, x + width - 1, y + height - 1);
 
       if (style->ythickness > 1)
-        gdk_draw_line (window, style->bg_gc[state_type],
-                       x + 1, y + height - 2, x + width - 2, y + height - 2);
+        _cairo_draw_line (cr, &style->bg[state_type],
+                          x + 1, y + height - 2, x + width - 2, y + height - 2);
       if (style->xthickness > 1)
-        gdk_draw_line (window, style->bg_gc[state_type],
-                       x + width - 2, y + 1, x + width - 2, y + height - 2);
+        _cairo_draw_line (cr, &style->bg[state_type],
+                          x + width - 2, y + 1, x + width - 2, y + height - 2);
 
       /* Dark around left and top */
 
       if (style->ythickness > 1)
-        gdk_draw_line (window, style->black_gc,
-                       x + 1, y + 1, x + width - 2, y + 1);
+        _cairo_draw_line (cr, &style->black,
+                          x + 1, y + 1, x + width - 2, y + 1);
       if (style->xthickness > 1)
-        gdk_draw_line (window, style->black_gc,
-                       x + 1, y + 1, x + 1, y + height - 2);
+        _cairo_draw_line (cr, &style->black,
+                          x + 1, y + 1, x + 1, y + height - 2);
 
       if (style->ythickness > 0)
-        gdk_draw_line (window, gc2,
-                       x, y, x + width - 1, y);
+        _cairo_draw_line (cr, gc2,
+                          x, y, x + width - 1, y);
       if (style->xthickness > 0)
-        gdk_draw_line (window, gc2,
-                       x, y, x, y + height - 1);
+        _cairo_draw_line (cr, gc2,
+                          x, y, x, y + height - 1);
       break;
       
     case GTK_SHADOW_OUT:
@@ -2176,15 +2045,15 @@ gtk_default_draw_shadow (GtkStyle      *style,
         {
           if (style->ythickness > 1)
             {
-              gdk_draw_line (window, gc1,
-                             x + 1, y + height - 2, x + width - 2, y + height - 2);
-              gdk_draw_line (window, style->black_gc,
-                             x, y + height - 1, x + width - 1, y + height - 1);
+              _cairo_draw_line (cr, gc1,
+                                x + 1, y + height - 2, x + width - 2, y + height - 2);
+              _cairo_draw_line (cr, &style->black,
+                                x, y + height - 1, x + width - 1, y + height - 1);
             }
           else
             {
-              gdk_draw_line (window, gc1,
-                             x + 1, y + height - 1, x + width - 1, y + height - 1);
+              _cairo_draw_line (cr, gc1,
+                                x + 1, y + height - 1, x + width - 1, y + height - 1);
             }
         }
 
@@ -2192,34 +2061,34 @@ gtk_default_draw_shadow (GtkStyle      *style,
         {
           if (style->xthickness > 1)
             {
-              gdk_draw_line (window, gc1,
-                             x + width - 2, y + 1, x + width - 2, y + height - 2);
+              _cairo_draw_line (cr, gc1,
+                                x + width - 2, y + 1, x + width - 2, y + height - 2);
               
-              gdk_draw_line (window, style->black_gc,
-                             x + width - 1, y, x + width - 1, y + height - 1);
+              _cairo_draw_line (cr, &style->black,
+                                x + width - 1, y, x + width - 1, y + height - 1);
             }
           else
             {
-              gdk_draw_line (window, gc1,
-                             x + width - 1, y + 1, x + width - 1, y + height - 1);
+              _cairo_draw_line (cr, gc1,
+                                x + width - 1, y + 1, x + width - 1, y + height - 1);
             }
         }
       
       /* Light around top and left */
 
       if (style->ythickness > 0)
-        gdk_draw_line (window, gc2,
-                       x, y, x + width - 2, y);
+        _cairo_draw_line (cr, gc2,
+                          x, y, x + width - 2, y);
       if (style->xthickness > 0)
-        gdk_draw_line (window, gc2,
-                       x, y, x, y + height - 2);
+        _cairo_draw_line (cr, gc2,
+                          x, y, x, y + height - 2);
 
       if (style->ythickness > 1)
-        gdk_draw_line (window, style->bg_gc[state_type],
-                       x + 1, y + 1, x + width - 3, y + 1);
+        _cairo_draw_line (cr, &style->bg[state_type],
+                          x + 1, y + 1, x + width - 3, y + 1);
       if (style->xthickness > 1)
-        gdk_draw_line (window, style->bg_gc[state_type],
-                       x + 1, y + 1, x + 1, y + height - 3);
+        _cairo_draw_line (cr, &style->bg[state_type],
+                          x + 1, y + 1, x + 1, y + height - 3);
       break;
       
     case GTK_SHADOW_ETCHED_IN:
@@ -2233,40 +2102,40 @@ gtk_default_draw_shadow (GtkStyle      *style,
       
               for (i = 0; i < thickness_dark; i++)
                 {
-                  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 + i,
-                                 y + height - i - 2);
+                  _cairo_draw_line (cr, gc1,
+                                    x + width - i - 1,
+                                    y + i,
+                                    x + width - i - 1,
+                                    y + height - i - 1);
+                  _cairo_draw_line (cr, 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 + thickness_dark + i,
-                                 y + height - thickness_dark - 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);
+                  _cairo_draw_line (cr, gc1,
+                                    x + thickness_dark + i,
+                                    y + thickness_dark + i,
+                                    x + thickness_dark + i,
+                                    y + height - thickness_dark - i - 1);
+                  _cairo_draw_line (cr, gc2,
+                                    x + width - thickness_light - i - 1,
+                                    y + thickness_dark + i,
+                                    x + width - thickness_light - i - 1,
+                                    y + height - thickness_light - 1);
                 }
             }
           else
             {
-              gdk_draw_line (window, 
-                             style->dark_gc[state_type],
-                             x, y, x, y + height);                         
-              gdk_draw_line (window, 
-                             style->dark_gc[state_type],
-                             x + width, y, x + width, y + height);
+              _cairo_draw_line (cr,
+                                &style->dark[state_type],
+                                x, y, x, y + height);
+              _cairo_draw_line (cr,
+                                &style->dark[state_type],
+                                x + width, y, x + width, y + height);
             }
         }
 
@@ -2279,42 +2148,42 @@ gtk_default_draw_shadow (GtkStyle      *style,
       
               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);
+                  _cairo_draw_line (cr, gc1,
+                                    x + i,
+                                    y + height - i - 1,
+                                    x + width - i - 1,
+                                    y + height - i - 1);
           
-                  gdk_draw_line (window, gc2,
-                                 x + i,
-                                 y + i,
-                                 x + width - i - 2,
-                                 y + i);
+                  _cairo_draw_line (cr, gc2,
+                                    x + i,
+                                    y + i,
+                                    x + width - i - 2,
+                                    y + i);
                 }
       
               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 - 2,
-                                 y + thickness_dark + i);
+                  _cairo_draw_line (cr, gc1,
+                                    x + thickness_dark + i,
+                                    y + thickness_dark + i,
+                                    x + width - thickness_dark - i - 2,
+                                    y + thickness_dark + i);
           
-                  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);
+                  _cairo_draw_line (cr, gc2,
+                                    x + thickness_dark + i,
+                                    y + height - thickness_light - i - 1,
+                                    x + width - thickness_light - 1,
+                                    y + height - thickness_light - i - 1);
                 }
             }
           else
             {
-              gdk_draw_line (window, 
-                             style->dark_gc[state_type],
-                             x, y, x + width, y);
-              gdk_draw_line (window, 
-                             style->dark_gc[state_type],
-                             x, y + height, x + width, y + height);
+              _cairo_draw_line (cr,
+                                &style->dark[state_type],
+                                x, y, x + width, y);
+              _cairo_draw_line (cr,
+                                &style->dark[state_type],
+                                x, y + height, x + width, y + height);
             }
         }
       
@@ -2327,206 +2196,62 @@ gtk_default_draw_shadow (GtkStyle      *style,
     {
       if (get_direction (widget) == GTK_TEXT_DIR_LTR)
        {
-         gdk_draw_line (window,
-                        style->base_gc[state_type],
-                        x + width - 1, y + 2,
-                        x + width - 1, y + height - 3);
-         gdk_draw_line (window,
-                        style->base_gc[state_type],
-                        x + width - 2, y + 2,
-                        x + width - 2, y + height - 3);
-         gdk_draw_point (window,
-                         style->black_gc,
-                         x + width - 1, y + 1);
-         gdk_draw_point (window,
-                         style->bg_gc[state_type],
-                         x + width - 1, y + height - 2);
+          _cairo_draw_line (cr,
+                            &style->base[state_type],
+                            x + width - 1, y + 2,
+                            x + width - 1, y + height - 3);
+          _cairo_draw_line (cr,
+                            &style->base[state_type],
+                            x + width - 2, y + 2,
+                            x + width - 2, y + height - 3);
+          /* draw point */
+          _cairo_draw_point (cr,
+                             &style->black,
+                             x + width - 1, y + 1);
+          _cairo_draw_point (cr,
+                             &style->bg[state_type],
+                             x + width - 1, y + height - 2);
        }
       else
        {
-         gdk_draw_line (window,
-                        style->base_gc[state_type],
-                        x, y + 2,
-                        x, y + height - 3);
-         gdk_draw_line (window,
-                        style->base_gc[state_type],
-                        x + 1, y + 2,
-                        x + 1, y + height - 3);
-         gdk_draw_point (window,
-                         style->black_gc,
-                         x, y + 1);
-         gdk_draw_line (window,
-                        style->bg_gc[state_type],
-                        x, y + height - 2,
-                        x + 1, y + height - 2);
-         gdk_draw_point (window,
-                         style->light_gc[state_type],
-                         x, y + height - 1);
+          _cairo_draw_line (cr,
+                            &style->base[state_type],
+                            x, y + 2,
+                            x, y + height - 3);
+          _cairo_draw_line (cr,
+                            &style->base[state_type],
+                            x + 1, y + 2,
+                            x + 1, y + height - 3);
+
+          _cairo_draw_point (cr,
+                             &style->black,
+                             x, y + 1);
+
+          _cairo_draw_line (cr,
+                            &style->bg[state_type],
+                            x, y + height - 2,
+                            x + 1, y + height - 2);
+          _cairo_draw_point (cr,
+                             &style->light[state_type],
+                             x, y + height - 1);
        }
     }
 
 
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (gc1, NULL);
-      gdk_gc_set_clip_rectangle (gc2, 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
-gtk_default_draw_polygon (GtkStyle      *style,
-                          GdkWindow     *window,
-                          GtkStateType   state_type,
-                          GtkShadowType  shadow_type,
-                          GdkRectangle  *area,
-                          GtkWidget     *widget,
-                          const gchar   *detail,
-                          GdkPoint      *points,
-                          gint           npoints,
-                          gboolean       fill)
-{
-  static const gdouble pi_over_4 = G_PI_4;
-  static const gdouble pi_3_over_4 = G_PI_4 * 3;
-  GdkGC *gc1;
-  GdkGC *gc2;
-  GdkGC *gc3;
-  GdkGC *gc4;
-  gdouble angle;
-  gint xadjust;
-  gint yadjust;
-  gint i;
-  
-  switch (shadow_type)
-    {
-    case GTK_SHADOW_IN:
-      gc1 = style->bg_gc[state_type];
-      gc2 = style->dark_gc[state_type];
-      gc3 = style->light_gc[state_type];
-      gc4 = style->black_gc;
-      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->black_gc;
-      gc4 = style->bg_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);
-    }
+  cairo_destroy (cr);
 }
 
 static void
-draw_arrow (GdkWindow     *window,
+draw_arrow (cairo_t       *cr,
            GdkColor      *color,
-           GdkRectangle  *area,
            GtkArrowType   arrow_type,
            gint           x,
            gint           y,
            gint           width,
            gint           height)
 {
-  cairo_t *cr = gdk_cairo_create (window);
   gdk_cairo_set_source_color (cr, color);
-  
-  if (area)
-    {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
-    }
+  cairo_save (cr);
     
   if (arrow_type == GTK_ARROW_DOWN)
     {
@@ -2556,7 +2281,7 @@ draw_arrow (GdkWindow     *window,
   cairo_close_path (cr);
   cairo_fill (cr);
 
-  cairo_destroy (cr);
+  cairo_restore (cr);
 }
 
 static void
@@ -2643,6 +2368,8 @@ gtk_default_draw_arrow (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
+  cairo_t *cr;
+
   sanitize_size (window, &width, &height);
 
   calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
@@ -2650,11 +2377,21 @@ gtk_default_draw_arrow (GtkStyle      *style,
   if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
     y++;
 
+  cr = gdk_cairo_create (window);
+
+  if (area)
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
+
   if (state == GTK_STATE_INSENSITIVE)
-    draw_arrow (window, &style->white, area, arrow_type,
+    draw_arrow (cr, &style->white, arrow_type,
                x + 1, y + 1, width, height);
-  draw_arrow (window, &style->fg[state], area, arrow_type,
+  draw_arrow (cr, &style->fg[state], arrow_type,
              x, y, width, height);
+
+  cairo_destroy (cr);
 }
 
 static void
@@ -2672,68 +2409,61 @@ gtk_default_draw_diamond (GtkStyle      *style,
 {
   gint half_width;
   gint half_height;
-  GdkGC *outer_nw = NULL;
-  GdkGC *outer_ne = NULL;
-  GdkGC *outer_sw = NULL;
-  GdkGC *outer_se = NULL;
-  GdkGC *middle_nw = NULL;
-  GdkGC *middle_ne = NULL;
-  GdkGC *middle_sw = NULL;
-  GdkGC *middle_se = NULL;
-  GdkGC *inner_nw = NULL;
-  GdkGC *inner_ne = NULL;
-  GdkGC *inner_sw = NULL;
-  GdkGC *inner_se = NULL;
+  GdkColor *outer_nw = NULL;
+  GdkColor *outer_ne = NULL;
+  GdkColor *outer_sw = NULL;
+  GdkColor *outer_se = NULL;
+  GdkColor *middle_nw = NULL;
+  GdkColor *middle_ne = NULL;
+  GdkColor *middle_sw = NULL;
+  GdkColor *middle_se = NULL;
+  GdkColor *inner_nw = NULL;
+  GdkColor *inner_ne = NULL;
+  GdkColor *inner_sw = NULL;
+  GdkColor *inner_se = NULL;
+  cairo_t *cr;
   
   sanitize_size (window, &width, &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:
-      inner_sw = inner_se = style->bg_gc[state_type];
-      middle_sw = middle_se = style->light_gc[state_type];
-      outer_sw = outer_se = style->light_gc[state_type];
-      inner_nw = inner_ne = style->black_gc;
-      middle_nw = middle_ne = style->dark_gc[state_type];
-      outer_nw = outer_ne = style->dark_gc[state_type];
+      inner_sw = inner_se = &style->bg[state_type];
+      middle_sw = middle_se = &style->light[state_type];
+      outer_sw = outer_se = &style->light[state_type];
+      inner_nw = inner_ne = &style->black;
+      middle_nw = middle_ne = &style->dark[state_type];
+      outer_nw = outer_ne = &style->dark[state_type];
       break;
           
     case GTK_SHADOW_OUT:
-      inner_sw = inner_se = style->dark_gc[state_type];
-      middle_sw = middle_se = style->dark_gc[state_type];
-      outer_sw = outer_se = style->black_gc;
-      inner_nw = inner_ne = style->bg_gc[state_type];
-      middle_nw = middle_ne = style->light_gc[state_type];
-      outer_nw = outer_ne = style->light_gc[state_type];
+      inner_sw = inner_se = &style->dark[state_type];
+      middle_sw = middle_se = &style->dark[state_type];
+      outer_sw = outer_se = &style->black;
+      inner_nw = inner_ne = &style->bg[state_type];
+      middle_nw = middle_ne = &style->light[state_type];
+      outer_nw = outer_ne = &style->light[state_type];
       break;
 
     case GTK_SHADOW_ETCHED_IN:
-      inner_sw = inner_se = style->bg_gc[state_type];
-      middle_sw = middle_se = style->dark_gc[state_type];
-      outer_sw = outer_se = style->light_gc[state_type];
-      inner_nw = inner_ne = style->bg_gc[state_type];
-      middle_nw = middle_ne = style->light_gc[state_type];
-      outer_nw = outer_ne = style->dark_gc[state_type];
+      inner_sw = inner_se = &style->bg[state_type];
+      middle_sw = middle_se = &style->dark[state_type];
+      outer_sw = outer_se = &style->light[state_type];
+      inner_nw = inner_ne = &style->bg[state_type];
+      middle_nw = middle_ne = &style->light[state_type];
+      outer_nw = outer_ne = &style->dark[state_type];
       break;
 
     case GTK_SHADOW_ETCHED_OUT:
-      inner_sw = inner_se = style->bg_gc[state_type];
-      middle_sw = middle_se = style->light_gc[state_type];
-      outer_sw = outer_se = style->dark_gc[state_type];
-      inner_nw = inner_ne = style->bg_gc[state_type];
-      middle_nw = middle_ne = style->dark_gc[state_type];
-      outer_nw = outer_ne = style->light_gc[state_type];
+      inner_sw = inner_se = &style->bg[state_type];
+      middle_sw = middle_se = &style->light[state_type];
+      outer_sw = outer_se = &style->dark[state_type];
+      inner_nw = inner_ne = &style->bg[state_type];
+      middle_nw = middle_ne = &style->dark[state_type];
+      outer_nw = outer_ne = &style->light[state_type];
       break;
       
     default:
@@ -2741,87 +2471,55 @@ gtk_default_draw_diamond (GtkStyle      *style,
       break;
     }
 
-  if (inner_sw)
-    {
-      gdk_draw_line (window, inner_sw,
-                     x + 2, y + half_height,
-                     x + half_width, y + height - 2);
-      gdk_draw_line (window, inner_se,
-                     x + half_width, y + height - 2,
-                     x + width - 2, y + half_height);
-      gdk_draw_line (window, middle_sw,
-                     x + 1, y + half_height,
-                     x + half_width, y + height - 1);
-      gdk_draw_line (window, middle_se,
-                     x + half_width, y + height - 1,
-                     x + width - 1, y + half_height);
-      gdk_draw_line (window, outer_sw,
-                     x, y + half_height,
-                     x + half_width, y + height);
-      gdk_draw_line (window, outer_se,
-                     x + half_width, y + height,
-                     x + width, y + half_height);
-  
-      gdk_draw_line (window, inner_nw,
-                     x + 2, y + half_height,
-                     x + half_width, y + 2);
-      gdk_draw_line (window, inner_ne,
-                     x + half_width, y + 2,
-                     x + width - 2, y + half_height);
-      gdk_draw_line (window, middle_nw,
-                     x + 1, y + half_height,
-                     x + half_width, y + 1);
-      gdk_draw_line (window, middle_ne,
-                     x + half_width, y + 1,
-                     x + width - 1, y + half_height);
-      gdk_draw_line (window, outer_nw,
-                     x, y + half_height,
-                     x + half_width, y);
-      gdk_draw_line (window, outer_ne,
-                     x + half_width, y,
-                     x + width, y + half_height);
-    }
-  
-  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
-gtk_default_draw_string (GtkStyle      *style,
-                         GdkWindow     *window,
-                         GtkStateType   state_type,
-                         GdkRectangle  *area,
-                         GtkWidget     *widget,
-                         const gchar   *detail,
-                         gint           x,
-                         gint           y,
-                         const gchar   *string)
-{
+  cr = gdk_cairo_create (window);
   if (area)
     {
-      gdk_gc_set_clip_rectangle (style->white_gc, area);
-      gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
     }
-
-  if (state_type == GTK_STATE_INSENSITIVE)
-    gdk_draw_string (window,
-                    gtk_style_get_font_internal (style),
-                    style->white_gc, x + 1, y + 1, string);
-
-  gdk_draw_string (window,
-                  gtk_style_get_font_internal (style),
-                  style->fg_gc[state_type], x, y, string);
-
-  if (area)
+  
+  if (inner_sw)
     {
-      gdk_gc_set_clip_rectangle (style->white_gc, NULL);
-      gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
+      _cairo_draw_line (cr, inner_sw,
+                        x + 2, y + half_height,
+                        x + half_width, y + height - 2);
+      _cairo_draw_line (cr, inner_se,
+                        x + half_width, y + height - 2,
+                        x + width - 2, y + half_height);
+      _cairo_draw_line (cr, middle_sw,
+                        x + 1, y + half_height,
+                        x + half_width, y + height - 1);
+      _cairo_draw_line (cr, middle_se,
+                        x + half_width, y + height - 1,
+                        x + width - 1, y + half_height);
+      _cairo_draw_line (cr, outer_sw,
+                        x, y + half_height,
+                        x + half_width, y + height);
+      _cairo_draw_line (cr, outer_se,
+                        x + half_width, y + height,
+                        x + width, y + half_height);
+  
+      _cairo_draw_line (cr, inner_nw,
+                        x + 2, y + half_height,
+                        x + half_width, y + 2);
+      _cairo_draw_line (cr, inner_ne,
+                        x + half_width, y + 2,
+                        x + width - 2, y + half_height);
+      _cairo_draw_line (cr, middle_nw,
+                        x + 1, y + half_height,
+                        x + half_width, y + 1);
+      _cairo_draw_line (cr, middle_ne,
+                        x + half_width, y + 1,
+                        x + width - 1, y + half_height);
+      _cairo_draw_line (cr, outer_nw,
+                        x, y + half_height,
+                        x + half_width, y);
+      _cairo_draw_line (cr, outer_ne,
+                        x + half_width, y,
+                        x + width, y + half_height);
     }
+  
+  cairo_destroy (cr);
 }
 
 static void
@@ -2898,21 +2596,26 @@ gtk_default_draw_box (GtkStyle      *style,
   if (!style->bg_pixmap[state_type] || 
       GDK_IS_PIXMAP (window))
     {
-      GdkGC *gc = style->bg_gc[state_type];
-      
+      cairo_t *cr;
+      GdkColor *gc = &style->bg[state_type];
+
+      cr = gdk_cairo_create (window);
+
       if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
        {
          if (widget && !gtk_widget_has_focus (widget))
-           gc = style->base_gc[GTK_STATE_ACTIVE];
+           gc = &style->base[GTK_STATE_ACTIVE];
        }
 
       if (area)
-       gdk_gc_set_clip_rectangle (gc, area);
+        {
+          gdk_cairo_rectangle (cr, area);
+          cairo_clip (cr);
+        }
 
-      gdk_draw_rectangle (window, gc, TRUE,
-                          x, y, width, height);
-      if (area)
-       gdk_gc_set_clip_rectangle (gc, NULL);
+      _cairo_draw_rectangle (cr, gc, TRUE,
+                             x, y, width, height);
+      cairo_destroy (cr);
     }
   else
     gtk_style_apply_default_background (style, window,
@@ -2921,29 +2624,28 @@ gtk_default_draw_box (GtkStyle      *style,
 
   if (is_spinbutton_box)
     {
-      GdkGC *upper_gc;
-      GdkGC *lower_gc;
-      
-      lower_gc = style->dark_gc[state_type];
+      cairo_t *cr;
+      GdkColor *upper;
+      GdkColor *lower;
+
+      cr = gdk_cairo_create (window);
+
+      lower = &style->dark[state_type];
       if (shadow_type == GTK_SHADOW_OUT)
-       upper_gc = style->light_gc[state_type];
+       upper = &style->light[state_type];
       else
-       upper_gc = style->dark_gc[state_type];
+       upper = &style->dark[state_type];
 
       if (area)
        {
-         gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
-         gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
+          gdk_cairo_rectangle (cr, area);
+          cairo_clip (cr);
        }
       
-      gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
-      gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
+      _cairo_draw_line (cr, upper, x, y, x + width - 1, y);
+      _cairo_draw_line (cr, lower, x, y + height - 1, x + width - 1, y + height - 1);
 
-      if (area)
-       {
-         gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
-         gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
-       }
+      cairo_destroy (cr);
       return;
     }
 
@@ -2973,17 +2675,13 @@ gtk_default_draw_box (GtkStyle      *style,
     }
 }
 
-static GdkGC *
-get_darkened_gc (GdkWindow      *window,
-                 const GdkColor *color,
+static GdkColor *
+get_darkened (const GdkColor *color,
                  gint            darken_count)
 {
   GdkColor src = *color;
   GdkColor shaded = *color;
-  GdkGC *gc;
   
-  gc = gdk_gc_new (window);
-
   while (darken_count)
     {
       _gtk_style_shade (&src, &shaded, 0.93);
@@ -2991,9 +2689,7 @@ get_darkened_gc (GdkWindow      *window,
       --darken_count;
     }
    
-  gdk_gc_set_rgb_fg_color (gc, &shaded);
-
-  return gc;
+  return gdk_color_copy (&shaded);
 }
 
 static void 
@@ -3009,8 +2705,8 @@ gtk_default_draw_flat_box (GtkStyle      *style,
                            gint           width,
                            gint           height)
 {
-  GdkGC *gc1;
-  GdkGC *freeme = NULL;
+  GdkColor *gc1;
+  GdkColor *freeme = NULL;
   
   sanitize_size (window, &width, &height);
   
@@ -3019,7 +2715,7 @@ gtk_default_draw_flat_box (GtkStyle      *style,
       if (state_type == GTK_STATE_SELECTED)
         {
           if (!strcmp ("text", detail))
-            gc1 = style->bg_gc[GTK_STATE_SELECTED];
+            gc1 = &style->bg[GTK_STATE_SELECTED];
           else if (!strcmp ("cell_even", detail) ||
                    !strcmp ("cell_odd", detail) ||
                    !strcmp ("cell_even_ruled", detail) ||
@@ -3027,30 +2723,30 @@ gtk_default_draw_flat_box (GtkStyle      *style,
             {
              /* This has to be really broken; alex made me do it. -jrb */
              if (widget && gtk_widget_has_focus (widget))
-               gc1 = style->base_gc[state_type];
+               gc1 = &style->base[state_type];
              else
-               gc1 = style->base_gc[GTK_STATE_ACTIVE];
+               gc1 = &style->base[GTK_STATE_ACTIVE];
             }
          else if (!strcmp ("cell_odd_ruled", detail) ||
                   !strcmp ("cell_odd_ruled_sorted", detail))
            {
              if (widget && gtk_widget_has_focus (widget))
-               freeme = get_darkened_gc (window, &style->base[state_type], 1);
+               freeme = get_darkened (&style->base[state_type], 1);
              else
-               freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
+               freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
              gc1 = freeme;
            }
           else
             {
-              gc1 = style->bg_gc[state_type];
+              gc1 = &style->bg[state_type];
             }
         }
       else
         {
           if (!strcmp ("viewportbin", detail))
-            gc1 = style->bg_gc[GTK_STATE_NORMAL];
+            gc1 = &style->bg[GTK_STATE_NORMAL];
           else if (!strcmp ("entry_bg", detail))
-            gc1 = style->base_gc[state_type];
+            gc1 = &style->base[gtk_widget_get_state (widget)];
 
           /* For trees: even rows are base color, odd rows are a shade of
            * the base color, the sort column is a shade of the original color
@@ -3069,13 +2765,13 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
              if (color)
                {
-                 freeme = get_darkened_gc (window, color, 0);
+                 freeme = get_darkened (color, 0);
                  gc1 = freeme;
 
                  gdk_color_free (color);
                }
              else
-               gc1 = style->base_gc[state_type];
+               gc1 = &style->base[state_type];
             }
          else if (!strcmp ("cell_odd_ruled", detail))
            {
@@ -3087,7 +2783,7 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
              if (color)
                {
-                 freeme = get_darkened_gc (window, color, 0);
+                 freeme = get_darkened (color, 0);
                  gc1 = freeme;
 
                  gdk_color_free (color);
@@ -3100,11 +2796,11 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
                  if (color)
                    {
-                     freeme = get_darkened_gc (window, color, 1);
+                     freeme = get_darkened (color, 1);
                      gdk_color_free (color);
                    }
                  else
-                   freeme = get_darkened_gc (window, &style->base[state_type], 1);
+                   freeme = get_darkened (&style->base[state_type], 1);
                  gc1 = freeme;
                }
            }
@@ -3125,14 +2821,14 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
              if (color)
                {
-                 freeme = get_darkened_gc (window, color, 1);
+                 freeme = get_darkened (color, 1);
                  gc1 = freeme;
 
                  gdk_color_free (color);
                }
              else
                {
-                 freeme = get_darkened_gc (window, &style->base[state_type], 1);
+                 freeme = get_darkened (&style->base[state_type], 1);
                   gc1 = freeme;
                }
             }
@@ -3146,7 +2842,7 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
              if (color)
                {
-                 freeme = get_darkened_gc (window, color, 1);
+                 freeme = get_darkened (color, 1);
                  gc1 = freeme;
 
                  gdk_color_free (color);
@@ -3159,36 +2855,43 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
                  if (color)
                    {
-                     freeme = get_darkened_gc (window, color, 2);
+                     freeme = get_darkened (color, 2);
                      gdk_color_free (color);
                    }
                  else
-                    freeme = get_darkened_gc (window, &style->base[state_type], 2);
+                    freeme = get_darkened (&style->base[state_type], 2);
                   gc1 = freeme;
                }
             }
           else
-            gc1 = style->bg_gc[state_type];
+            gc1 = &style->bg[state_type];
         }
     }
   else
-    gc1 = style->bg_gc[state_type];
+    gc1 = &style->bg[state_type];
   
-  if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
+  if (!style->bg_pixmap[state_type] || gc1 != &style->bg[state_type] ||
       GDK_IS_PIXMAP (window))
     {
+      cairo_t *cr;
+
+      cr = gdk_cairo_create (window);
+      cairo_set_line_width (cr, 1.0);
+
       if (area)
-       gdk_gc_set_clip_rectangle (gc1, area);
+        {
+          gdk_cairo_rectangle (cr, area);
+          cairo_clip (cr);
+        }
 
-      gdk_draw_rectangle (window, gc1, TRUE,
-                          x, y, width, height);
+      _cairo_draw_rectangle (cr, 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);
+        _cairo_draw_rectangle (cr, &style->black, FALSE,
+                               x, y, width - 1, height - 1);
 
-      if (area)
-       gdk_gc_set_clip_rectangle (gc1, NULL);
+      cairo_destroy (cr);
     }
   else
     gtk_style_apply_default_background (style, window,
@@ -3197,7 +2900,7 @@ gtk_default_draw_flat_box (GtkStyle      *style,
 
 
   if (freeme)
-    g_object_unref (freeme);
+    gdk_color_free (freeme);
 }
 
 static void 
@@ -3460,10 +3163,19 @@ gtk_default_draw_tab (GtkStyle      *style,
 {
 #define ARROW_SPACE 4
 
+  cairo_t *cr;
   GtkRequisition indicator_size;
   GtkBorder indicator_spacing;
   gint arrow_height;
-  
+
+  cr = gdk_cairo_create (window);
+
+  if (area)
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
+
   option_menu_get_props (widget, &indicator_size, &indicator_spacing);
 
   indicator_size.width += (indicator_size.width % 2) - 1;
@@ -3474,23 +3186,25 @@ gtk_default_draw_tab (GtkStyle      *style,
 
   if (state_type == GTK_STATE_INSENSITIVE)
     {
-      draw_arrow (window, &style->white, area,
+      draw_arrow (cr, &style->white,
                  GTK_ARROW_UP, x + 1, y + 1,
                  indicator_size.width, arrow_height);
       
-      draw_arrow (window, &style->white, area,
+      draw_arrow (cr, &style->white,
                  GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
                  indicator_size.width, arrow_height);
     }
   
-  draw_arrow (window, &style->fg[state_type], area,
+  draw_arrow (cr, &style->fg[state_type],
              GTK_ARROW_UP, x, y,
              indicator_size.width, arrow_height);
   
   
-  draw_arrow (window, &style->fg[state_type], area,
+  draw_arrow (cr, &style->fg[state_type],
              GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
              indicator_size.width, arrow_height);
+
+  cairo_destroy (cr);
 }
 
 static void 
@@ -3509,48 +3223,50 @@ gtk_default_draw_shadow_gap (GtkStyle       *style,
                              gint            gap_x,
                              gint            gap_width)
 {
-  GdkGC *gc1 = NULL;
-  GdkGC *gc2 = NULL;
-  GdkGC *gc3 = NULL;
-  GdkGC *gc4 = NULL;
+  GdkColor *color1 = NULL;
+  GdkColor *color2 = NULL;
+  GdkColor *color3 = NULL;
+  GdkColor *color4 = NULL;
+  cairo_t *cr;
   
   sanitize_size (window, &width, &height);
   
   switch (shadow_type)
     {
     case GTK_SHADOW_NONE:
+    default:
       return;
     case GTK_SHADOW_IN:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->black_gc;
-      gc3 = style->bg_gc[state_type];
-      gc4 = style->light_gc[state_type];
+      color1 = &style->dark[state_type];
+      color2 = &style->black;
+      color3 = &style->bg[state_type];
+      color4 = &style->light[state_type];
       break;
     case GTK_SHADOW_ETCHED_IN:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->light_gc[state_type];
-      gc3 = style->dark_gc[state_type];
-      gc4 = style->light_gc[state_type];
+      color1 = &style->dark[state_type];
+      color2 = &style->light[state_type];
+      color3 = &style->dark[state_type];
+      color4 = &style->light[state_type];
       break;
     case GTK_SHADOW_OUT:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->bg_gc[state_type];
-      gc3 = style->dark_gc[state_type];
-      gc4 = style->black_gc;
+      color1 = &style->light[state_type];
+      color2 = &style->bg[state_type];
+      color3 = &style->dark[state_type];
+      color4 = &style->black;
       break;
     case GTK_SHADOW_ETCHED_OUT:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->dark_gc[state_type];
-      gc3 = style->light_gc[state_type];
-      gc4 = style->dark_gc[state_type];
+      color1 = &style->light[state_type];
+      color2 = &style->dark[state_type];
+      color3 = &style->light[state_type];
+      color4 = &style->dark[state_type];
       break;
     }
+
+  cr = gdk_cairo_create (window);
   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);
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
     }
   
   switch (shadow_type)
@@ -3563,147 +3279,141 @@ gtk_default_draw_shadow_gap (GtkStyle       *style,
       switch (gap_side)
         {
         case GTK_POS_TOP:
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y, x + 1, y + height - 2);
+          _cairo_draw_line (cr, color1,
+                            x, y, x, y + height - 1);
+          _cairo_draw_line (cr, color2,
+                            x + 1, y, x + 1, y + height - 2);
           
-          gdk_draw_line (window, gc3,
-                         x + 1, y + height - 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 1, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, color3,
+                            x + 1, y + height - 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, color3,
+                            x + width - 2, y, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, color4,
+                            x, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, color4,
+                            x + width - 1, y, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x, y, x + gap_x - 1, y);
-              gdk_draw_line (window, gc2,
-                             x + 1, y + 1, x + gap_x - 1, y + 1);
-              gdk_draw_line (window, gc2,
-                             x + gap_x, y, x + gap_x, y);
+              _cairo_draw_line (cr, color1,
+                                x, y, x + gap_x - 1, y);
+              _cairo_draw_line (cr, color2,
+                                x + 1, y + 1, x + gap_x - 1, y + 1);
+              _cairo_draw_line (cr, color2,
+                                x + gap_x, y, x + gap_x, y);
             }
           if ((width - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x + gap_x + gap_width, y, x + width - 2, y);
-              gdk_draw_line (window, gc2,
-                             x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
-              gdk_draw_line (window, gc2,
-                             x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
+              _cairo_draw_line (cr, color1,
+                                x + gap_x + gap_width, y, x + width - 2, y);
+              _cairo_draw_line (cr, color2,
+                                x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
+              _cairo_draw_line (cr, color2,
+                                x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
             }
           break;
         case GTK_POS_BOTTOM:
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 1, y);
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 2, y + 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + 1, y + height - 1);
+          _cairo_draw_line (cr, color1,
+                            x, y, x + width - 1, y);
+          _cairo_draw_line (cr, color1,
+                            x, y, x, y + height - 1);
+          _cairo_draw_line (cr, color2,
+                            x + 1, y + 1, x + width - 2, y + 1);
+          _cairo_draw_line (cr, color2,
+                            x + 1, y + 1, x + 1, y + height - 1);
           
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y + 1, x + width - 2, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, color3,
+                            x + width - 2, y + 1, x + width - 2, y + height - 1);
+          _cairo_draw_line (cr, color4,
+                            x + width - 1, y, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x, y + height - 1, x + gap_x - 1, y + height - 1);
-              gdk_draw_line (window, gc3,
-                             x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + gap_x, y + height - 1, x + gap_x, y + height - 1);
+              _cairo_draw_line (cr, color4,
+                                x, y + height - 1, x + gap_x - 1, y + height - 1);
+              _cairo_draw_line (cr, color3,
+                                x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
+              _cairo_draw_line (cr, color3,
+                                x + gap_x, y + height - 1, x + gap_x, y + height - 1);
             }
           if ((width - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
-              gdk_draw_line (window, gc3,
-                             x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
+              _cairo_draw_line (cr, color4,
+                                x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
+              _cairo_draw_line (cr, color3,
+                                x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
+              _cairo_draw_line (cr, color3,
+                                x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
             }
           break;
         case GTK_POS_LEFT:
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 1, y);
-          gdk_draw_line (window, gc2,
-                         x, y + 1, x + width - 2, y + 1);
+          _cairo_draw_line (cr, color1,
+                            x, y, x + width - 1, y);
+          _cairo_draw_line (cr, color2,
+                            x, y + 1, x + width - 2, y + 1);
           
-          gdk_draw_line (window, gc3,
-                         x, y + height - 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y + 1, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 1, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, color3,
+                            x, y + height - 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, color3,
+                            x + width - 2, y + 1, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, color4,
+                            x, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, color4,
+                            x + width - 1, y, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x, y, x, y + gap_x - 1);
-              gdk_draw_line (window, gc2,
-                             x + 1, y + 1, x + 1, y + gap_x - 1);
-              gdk_draw_line (window, gc2,
-                             x, y + gap_x, x, y + gap_x);
+              _cairo_draw_line (cr, color1,
+                                x, y, x, y + gap_x - 1);
+              _cairo_draw_line (cr, color2,
+                                x + 1, y + 1, x + 1, y + gap_x - 1);
+              _cairo_draw_line (cr, color2,
+                                x, y + gap_x, x, y + gap_x);
             }
           if ((width - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x, y + gap_x + gap_width, x, y + height - 2);
-              gdk_draw_line (window, gc2,
-                             x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
-              gdk_draw_line (window, gc2,
-                             x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
+              _cairo_draw_line (cr, color1,
+                                x, y + gap_x + gap_width, x, y + height - 2);
+              _cairo_draw_line (cr, color2,
+                                x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
+              _cairo_draw_line (cr, color2,
+                                x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
             }
           break;
         case GTK_POS_RIGHT:
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 1, y);
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 1, y + 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + 1, y + height - 2);
+          _cairo_draw_line (cr, color1,
+                            x, y, x + width - 1, y);
+          _cairo_draw_line (cr, color1,
+                            x, y, x, y + height - 1);
+          _cairo_draw_line (cr, color2,
+                            x + 1, y + 1, x + width - 1, y + 1);
+          _cairo_draw_line (cr, color2,
+                            x + 1, y + 1, x + 1, y + height - 2);
           
-          gdk_draw_line (window, gc3,
-                         x + 1, y + height - 2, x + width - 1, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, color3,
+                            x + 1, y + height - 2, x + width - 1, y + height - 2);
+          _cairo_draw_line (cr, color4,
+                            x, y + height - 1, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x + width - 1, y, x + width - 1, y + gap_x - 1);
-              gdk_draw_line (window, gc3,
-                             x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
-              gdk_draw_line (window, gc3,
-                             x + width - 1, y + gap_x, x + width - 1, y + gap_x);
+              _cairo_draw_line (cr, color4,
+                                x + width - 1, y, x + width - 1, y + gap_x - 1);
+              _cairo_draw_line (cr, color3,
+                                x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
+              _cairo_draw_line (cr, color3,
+                                x + width - 1, y + gap_x, x + width - 1, y + gap_x);
             }
           if ((width - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
+              _cairo_draw_line (cr, color4,
+                                x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
+              _cairo_draw_line (cr, color3,
+                                x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
+              _cairo_draw_line (cr, color3,
+                                x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 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);
-    }
+  cairo_destroy (cr);
 }
 
 static void 
@@ -3722,55 +3432,58 @@ gtk_default_draw_box_gap (GtkStyle       *style,
                           gint            gap_x,
                           gint            gap_width)
 {
-  GdkGC *gc1 = NULL;
-  GdkGC *gc2 = NULL;
-  GdkGC *gc3 = NULL;
-  GdkGC *gc4 = NULL;
+  cairo_t *cr;
+  GdkColor color1;
+  GdkColor color2;
+  GdkColor color3;
+  GdkColor color4;
   
+  sanitize_size (window, &width, &height);
+
   gtk_style_apply_default_background (style, window,
                                       widget && gtk_widget_get_has_window (widget),
                                       state_type, area, x, y, width, height);
-  
-  sanitize_size (window, &width, &height);
-  
+
+  cr = gdk_cairo_create (window);
+  if (area)
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
+
   switch (shadow_type)
     {
     case GTK_SHADOW_NONE:
+      cairo_destroy (cr);
       return;
     case GTK_SHADOW_IN:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->black_gc;
-      gc3 = style->bg_gc[state_type];
-      gc4 = style->light_gc[state_type];
+      color1 = style->dark[state_type];
+      color2 = style->black;
+      color3 = style->bg[state_type];
+      color4 = style->light[state_type];
       break;
     case GTK_SHADOW_ETCHED_IN:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->light_gc[state_type];
-      gc3 = style->dark_gc[state_type];
-      gc4 = style->light_gc[state_type];
+      color1 = style->dark[state_type];
+      color2 = style->light[state_type];
+      color3 = style->dark[state_type];
+      color4 = style->light[state_type];
       break;
     case GTK_SHADOW_OUT:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->bg_gc[state_type];
-      gc3 = style->dark_gc[state_type];
-      gc4 = style->black_gc;
+      color1 = style->light[state_type];
+      color2 = style->bg[state_type];
+      color3 = style->dark[state_type];
+      color4 = style->black;
       break;
     case GTK_SHADOW_ETCHED_OUT:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->dark_gc[state_type];
-      gc3 = style->light_gc[state_type];
-      gc4 = style->dark_gc[state_type];
+      color1 = style->light[state_type];
+      color2 = style->dark[state_type];
+      color3 = style->light[state_type];
+      color4 = style->dark[state_type];
       break;
     }
-
-  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);
-    }
   
+  cairo_set_line_width (cr, 1.0);
+
   switch (shadow_type)
     {
     case GTK_SHADOW_NONE:
@@ -3781,147 +3494,142 @@ gtk_default_draw_box_gap (GtkStyle       *style,
       switch (gap_side)
         {
         case GTK_POS_TOP:
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y, x + 1, y + height - 2);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x, y + height - 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y, x + 1, y + height - 2);
           
-          gdk_draw_line (window, gc3,
-                         x + 1, y + height - 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 1, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color3,
+                            x + 1, y + height - 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color3,
+                            x + width - 2, y, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color4,
+                            x, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color4,
+                            x + width - 1, y, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x, y, x + gap_x - 1, y);
-              gdk_draw_line (window, gc2,
-                             x + 1, y + 1, x + gap_x - 1, y + 1);
-              gdk_draw_line (window, gc2,
-                             x + gap_x, y, x + gap_x, y);
+              _cairo_draw_line (cr, &color1,
+                                x, y, x + gap_x - 1, y);
+              _cairo_draw_line (cr, &color2,
+                                x + 1, y + 1, x + gap_x - 1, y + 1);
+              _cairo_draw_line (cr, &color2,
+                                x + gap_x, y, x + gap_x, y);
             }
           if ((width - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x + gap_x + gap_width, y, x + width - 2, y);
-              gdk_draw_line (window, gc2,
-                             x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
-              gdk_draw_line (window, gc2,
-                             x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
+              _cairo_draw_line (cr, &color1,
+                                x + gap_x + gap_width, y, x + width - 2, y);
+              _cairo_draw_line (cr, &color2,
+                                x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
+              _cairo_draw_line (cr, &color2,
+                                x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
             }
           break;
         case  GTK_POS_BOTTOM:
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 1, y);
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 2, y + 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + 1, y + height - 1);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x + width - 1, y);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x, y + height - 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + width - 2, y + 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + 1, y + height - 1);
           
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y + 1, x + width - 2, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color3,
+                            x + width - 2, y + 1, x + width - 2, y + height - 1);
+          _cairo_draw_line (cr, &color4,
+                            x + width - 1, y, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x, y + height - 1, x + gap_x - 1, y + height - 1);
-              gdk_draw_line (window, gc3,
-                             x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + gap_x, y + height - 1, x + gap_x, y + height - 1);
+              _cairo_draw_line (cr, &color4,
+                                x, y + height - 1, x + gap_x - 1, y + height - 1);
+              _cairo_draw_line (cr, &color3,
+                                x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
+              _cairo_draw_line (cr, &color3,
+                                x + gap_x, y + height - 1, x + gap_x, y + height - 1);
             }
           if ((width - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
-              gdk_draw_line (window, gc3,
-                             x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
+              _cairo_draw_line (cr, &color4,
+                                x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
+              _cairo_draw_line (cr, &color3,
+                                x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
+              _cairo_draw_line (cr, &color3,
+                                x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
             }
           break;
         case GTK_POS_LEFT:
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 1, y);
-          gdk_draw_line (window, gc2,
-                         x, y + 1, x + width - 2, y + 1);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x + width - 1, y);
+          _cairo_draw_line (cr, &color2,
+                            x, y + 1, x + width - 2, y + 1);
           
-          gdk_draw_line (window, gc3,
-                         x, y + height - 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y + 1, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 1, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color3,
+                            x, y + height - 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color3,
+                            x + width - 2, y + 1, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color4,
+                            x, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color4,
+                            x + width - 1, y, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x, y, x, y + gap_x - 1);
-              gdk_draw_line (window, gc2,
-                             x + 1, y + 1, x + 1, y + gap_x - 1);
-              gdk_draw_line (window, gc2,
-                             x, y + gap_x, x, y + gap_x);
+              _cairo_draw_line (cr, &color1,
+                                x, y, x, y + gap_x - 1);
+              _cairo_draw_line (cr, &color2,
+                                x + 1, y + 1, x + 1, y + gap_x - 1);
+              _cairo_draw_line (cr, &color2,
+                                x, y + gap_x, x, y + gap_x);
             }
           if ((height - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc1,
-                             x, y + gap_x + gap_width, x, y + height - 2);
-              gdk_draw_line (window, gc2,
-                             x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
-              gdk_draw_line (window, gc2,
-                             x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
+              _cairo_draw_line (cr, &color1,
+                                x, y + gap_x + gap_width, x, y + height - 2);
+              _cairo_draw_line (cr, &color2,
+                                x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
+              _cairo_draw_line (cr, &color2,
+                                x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
             }
           break;
         case GTK_POS_RIGHT:
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 1, y);
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 1, y + 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + 1, y + height - 2);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x + width - 1, y);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x, y + height - 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + width - 1, y + 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + 1, y + height - 2);
           
-          gdk_draw_line (window, gc3,
-                         x + 1, y + height - 2, x + width - 1, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color3,
+                            x + 1, y + height - 2, x + width - 1, y + height - 2);
+          _cairo_draw_line (cr, &color4,
+                            x, y + height - 1, x + width - 1, y + height - 1);
           if (gap_x > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x + width - 1, y, x + width - 1, y + gap_x - 1);
-              gdk_draw_line (window, gc3,
-                             x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
-              gdk_draw_line (window, gc3,
-                             x + width - 1, y + gap_x, x + width - 1, y + gap_x);
+              _cairo_draw_line (cr, &color4,
+                                x + width - 1, y, x + width - 1, y + gap_x - 1);
+              _cairo_draw_line (cr, &color3,
+                                x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
+              _cairo_draw_line (cr, &color3,
+                                x + width - 1, y + gap_x, x + width - 1, y + gap_x);
             }
           if ((height - (gap_x + gap_width)) > 0)
             {
-              gdk_draw_line (window, gc4,
-                             x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
-              gdk_draw_line (window, gc3,
-                             x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
+              _cairo_draw_line (cr, &color4,
+                                x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
+              _cairo_draw_line (cr, &color3,
+                                x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
+              _cairo_draw_line (cr, &color3,
+                                x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 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);
-    }
+
+  cairo_destroy (cr);
 }
 
 static void 
@@ -3938,54 +3646,94 @@ gtk_default_draw_extension (GtkStyle       *style,
                             gint            height,
                             GtkPositionType gap_side)
 {
-  GdkGC *gc1 = NULL;
-  GdkGC *gc2 = NULL;
-  GdkGC *gc3 = NULL;
-  GdkGC *gc4 = NULL;
-  
-  gtk_style_apply_default_background (style, window,
-                                      widget && gtk_widget_get_has_window (widget),
-                                      GTK_STATE_NORMAL, area, x, y, width, height);
+  cairo_t *cr;
+  GdkColor color1;
+  GdkColor color2;
+  GdkColor color3;
+  GdkColor color4;
   
   sanitize_size (window, &width, &height);
+
+  switch (gap_side)
+    {
+    case GTK_POS_TOP:
+      gtk_style_apply_default_background (style, window,
+                                          widget && gtk_widget_get_has_window (widget),
+                                          state_type, area,
+                                          x + 1,
+                                          y,
+                                          width - 2,
+                                          height - 1);
+      break;
+    case GTK_POS_BOTTOM:
+      gtk_style_apply_default_background (style, window,
+                                          widget && gtk_widget_get_has_window (widget),
+                                          state_type, area,
+                                          x + 1,
+                                          y + 1,
+                                          width - 2,
+                                          height - 1);
+      break;
+    case GTK_POS_LEFT:
+      gtk_style_apply_default_background (style, window,
+                                          widget && gtk_widget_get_has_window (widget),
+                                          state_type, area,
+                                          x,
+                                          y + 1,
+                                          width - 1,
+                                          height - 2);
+      break;
+    case GTK_POS_RIGHT:
+      gtk_style_apply_default_background (style, window,
+                                          widget && gtk_widget_get_has_window (widget),
+                                          state_type, area,
+                                          x + 1,
+                                          y + 1,
+                                          width - 1,
+                                          height - 2);
+      break;
+    }
+
+
+  cr = gdk_cairo_create (window);
+  if (area)
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
   
   switch (shadow_type)
     {
     case GTK_SHADOW_NONE:
+      cairo_destroy (cr);
       return;
     case GTK_SHADOW_IN:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->black_gc;
-      gc3 = style->bg_gc[state_type];
-      gc4 = style->light_gc[state_type];
+      color1 = style->dark[state_type];
+      color2 = style->black;
+      color3 = style->bg[state_type];
+      color4 = style->light[state_type];
       break;
     case GTK_SHADOW_ETCHED_IN:
-      gc1 = style->dark_gc[state_type];
-      gc2 = style->light_gc[state_type];
-      gc3 = style->dark_gc[state_type];
-      gc4 = style->light_gc[state_type];
+      color1 = style->dark[state_type];
+      color2 = style->light[state_type];
+      color3 = style->dark[state_type];
+      color4 = style->light[state_type];
       break;
     case GTK_SHADOW_OUT:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->bg_gc[state_type];
-      gc3 = style->dark_gc[state_type];
-      gc4 = style->black_gc;
+      color1 = style->light[state_type];
+      color2 = style->bg[state_type];
+      color3 = style->dark[state_type];
+      color4 = style->black;
       break;
     case GTK_SHADOW_ETCHED_OUT:
-      gc1 = style->light_gc[state_type];
-      gc2 = style->dark_gc[state_type];
-      gc3 = style->light_gc[state_type];
-      gc4 = style->dark_gc[state_type];
+      color1 = style->light[state_type];
+      color2 = style->dark[state_type];
+      color3 = style->light[state_type];
+      color4 = style->dark[state_type];
       break;
     }
 
-  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);
-    }
+  cairo_set_line_width (cr, 1.0);
 
   switch (shadow_type)
     {
@@ -3997,103 +3745,69 @@ gtk_default_draw_extension (GtkStyle       *style,
       switch (gap_side)
         {
         case GTK_POS_TOP:
-          gtk_style_apply_default_background (style, window,
-                                              widget && gtk_widget_get_has_window (widget),
-                                              state_type, area,
-                                              x + style->xthickness, 
-                                              y, 
-                                              width - (2 * style->xthickness), 
-                                              height - (style->ythickness));
-          gdk_draw_line (window, gc1,
-                         x, y, x, y + height - 2);
-          gdk_draw_line (window, gc2,
-                         x + 1, y, x + 1, y + height - 2);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x, y + height - 2);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y, x + 1, y + height - 2);
           
-          gdk_draw_line (window, gc3,
-                         x + 2, y + height - 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x + 1, y + height - 1, x + width - 2, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y, x + width - 1, y + height - 2);
+          _cairo_draw_line (cr, &color3,
+                            x + 2, y + height - 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color3,
+                            x + width - 2, y, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color4,
+                            x + 1, y + height - 1, x + width - 2, y + height - 1);
+          _cairo_draw_line (cr, &color4,
+                            x + width - 1, y, x + width - 1, y + height - 2);
           break;
         case GTK_POS_BOTTOM:
-          gtk_style_apply_default_background (style, window,
-                                              widget && gtk_widget_get_has_window (widget),
-                                              state_type, area,
-                                              x + style->xthickness, 
-                                              y + style->ythickness, 
-                                              width - (2 * style->xthickness), 
-                                              height - (style->ythickness));
-          gdk_draw_line (window, gc1,
-                         x + 1, y, x + width - 2, y);
-          gdk_draw_line (window, gc1,
-                         x, y + 1, x, y + height - 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 2, y + 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + 1, y + height - 1);
+          _cairo_draw_line (cr, &color1,
+                            x + 1, y, x + width - 2, y);
+          _cairo_draw_line (cr, &color1,
+                            x, y + 1, x, y + height - 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + width - 2, y + 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + 1, y + height - 1);
           
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y + 2, x + width - 2, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y + 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color3,
+                            x + width - 2, y + 2, x + width - 2, y + height - 1);
+          _cairo_draw_line (cr, &color4,
+                            x + width - 1, y + 1, x + width - 1, y + height - 1);
           break;
         case GTK_POS_LEFT:
-          gtk_style_apply_default_background (style, window,
-                                              widget && gtk_widget_get_has_window (widget),
-                                              state_type, area,
-                                              x, 
-                                              y + style->ythickness, 
-                                              width - (style->xthickness), 
-                                              height - (2 * style->ythickness));
-          gdk_draw_line (window, gc1,
-                         x, y, x + width - 2, y);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 2, y + 1);
+          _cairo_draw_line (cr, &color1,
+                            x, y, x + width - 2, y);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + width - 2, y + 1);
           
-          gdk_draw_line (window, gc3,
-                         x, y + height - 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc3,
-                         x + width - 2, y + 2, x + width - 2, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x, y + height - 1, x + width - 2, y + height - 1);
-          gdk_draw_line (window, gc4,
-                         x + width - 1, y + 1, x + width - 1, y + height - 2);
+          _cairo_draw_line (cr, &color3,
+                            x, y + height - 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color3,
+                            x + width - 2, y + 2, x + width - 2, y + height - 2);
+          _cairo_draw_line (cr, &color4,
+                            x, y + height - 1, x + width - 2, y + height - 1);
+          _cairo_draw_line (cr, &color4,
+                            x + width - 1, y + 1, x + width - 1, y + height - 2);
           break;
         case GTK_POS_RIGHT:
-          gtk_style_apply_default_background (style, window,
-                                              widget && gtk_widget_get_has_window (widget),
-                                              state_type, area,
-                                              x + style->xthickness, 
-                                              y + style->ythickness, 
-                                              width - (style->xthickness), 
-                                              height - (2 * style->ythickness));
-          gdk_draw_line (window, gc1,
-                         x + 1, y, x + width - 1, y);
-          gdk_draw_line (window, gc1,
-                         x, y + 1, x, y + height - 2);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + width - 1, y + 1);
-          gdk_draw_line (window, gc2,
-                         x + 1, y + 1, x + 1, y + height - 2);
+          _cairo_draw_line (cr, &color1,
+                            x + 1, y, x + width - 1, y);
+          _cairo_draw_line (cr, &color1,
+                            x, y + 1, x, y + height - 2);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + width - 1, y + 1);
+          _cairo_draw_line (cr, &color2,
+                            x + 1, y + 1, x + 1, y + height - 2);
           
-          gdk_draw_line (window, gc3,
-                         x + 2, y + height - 2, x + width - 1, y + height - 2);
-          gdk_draw_line (window, gc4,
-                         x + 1, y + height - 1, x + width - 1, y + height - 1);
+          _cairo_draw_line (cr, &color3,
+                            x + 2, y + height - 2, x + width - 1, y + height - 2);
+          _cairo_draw_line (cr, &color4,
+                            x + 1, y + height - 1, x + width - 1, y + height - 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);
-    }
+  cairo_destroy (cr);
 }
 
 static void 
@@ -4225,28 +3939,28 @@ gtk_default_draw_slider (GtkStyle      *style,
 }
 
 static void
-draw_dot (GdkWindow    *window,
-         GdkGC        *light_gc,
-         GdkGC        *dark_gc,
-         gint          x,
-         gint          y,
-         gushort       size)
+draw_dot (cairo_t    *cr,
+         GdkColor   *light,
+         GdkColor   *dark,
+         gint        x,
+         gint        y,
+         gushort     size)
 {
   size = CLAMP (size, 2, 3);
 
   if (size == 2)
     {
-      gdk_draw_point (window, light_gc, x, y);
-      gdk_draw_point (window, light_gc, x+1, y+1);
+      _cairo_draw_point (cr, light, x, y);
+      _cairo_draw_point (cr, light, x+1, y+1);
     }
   else if (size == 3)
     {
-      gdk_draw_point (window, light_gc, x, y);
-      gdk_draw_point (window, light_gc, x+1, y);
-      gdk_draw_point (window, light_gc, x, y+1);
-      gdk_draw_point (window, dark_gc, x+1, y+2);
-      gdk_draw_point (window, dark_gc, x+2, y+1);
-      gdk_draw_point (window, dark_gc, x+2, y+2);
+      _cairo_draw_point (cr, light, x, y);
+      _cairo_draw_point (cr, light, x+1, y);
+      _cairo_draw_point (cr, light, x, y+1);
+      _cairo_draw_point (cr, dark, x+1, y+2);
+      _cairo_draw_point (cr, dark, x+2, y+1);
+      _cairo_draw_point (cr, dark, x+2, y+2);
     }
 }
 
@@ -4266,17 +3980,20 @@ gtk_default_draw_handle (GtkStyle      *style,
 {
   gint xx, yy;
   gint xthick, ythick;
-  GdkGC *light_gc, *dark_gc;
-  GdkGC *free_me = NULL;
-  GdkRectangle rect;
-  GdkRectangle dest;
-  gint intersect;
+  GdkColor light, dark;
+  cairo_t *cr;
   
   sanitize_size (window, &width, &height);
   
   gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
                  detail, x, y, width, height);
   
+  cr = gdk_cairo_create (window);
+  if (area)
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
   
   if (detail && !strcmp (detail, "paned"))
     {
@@ -4285,73 +4002,46 @@ gtk_default_draw_handle (GtkStyle      *style,
       ythick = 0;
 
       if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
-       {
-         GdkColor unfocused_light;
-
-         _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
+         _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
                             LIGHTNESS_MULT);
-
-         light_gc = free_me = gdk_gc_new (window);
-         gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
-       }
       else
-       light_gc = style->light_gc[state_type];
+       light = style->light[state_type];
 
-      dark_gc = style->black_gc;
+      dark = style->black;
     }
   else
     {
       xthick = style->xthickness;
       ythick = style->ythickness;
 
-      light_gc = style->light_gc[state_type];
-      dark_gc = style->dark_gc[state_type];
+      light = style->light[state_type];
+      dark = style->dark[state_type];
     }
   
-  rect.x = x + xthick;
-  rect.y = y + ythick;
-  rect.width = width - (xthick * 2);
-  rect.height = height - (ythick * 2);
-
-  if (area)
-    intersect = gdk_rectangle_intersect (area, &rect, &dest);
-  else
-    {
-      intersect = TRUE;
-      dest = rect;
-    }
-
-  if (!intersect)
-    goto out;
-
-  gdk_gc_set_clip_rectangle (light_gc, &dest);
-  gdk_gc_set_clip_rectangle (dark_gc, &dest);
+  cairo_rectangle(cr, x + xthick, y + ythick,
+                  width - (xthick * 2), height - (ythick * 2));
+  cairo_clip (cr);
 
   if (detail && !strcmp (detail, "paned"))
     {
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
        for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
-         draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
+         draw_dot (cr, &light, &dark, xx, y + height/2 - 1, 3);
       else
        for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
-         draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
+         draw_dot (cr, &light, &dark, x + width/2 - 1, yy, 3);
     }
   else
     {
       for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
        for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
          {
-           draw_dot (window, light_gc, dark_gc, xx, yy, 2);
-           draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
+           draw_dot (cr, &light, &dark, xx, yy, 2);
+           draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
          }
     }
 
-  gdk_gc_set_clip_rectangle (light_gc, NULL);
-  gdk_gc_set_clip_rectangle (dark_gc, NULL);
-
- out:
-  if (free_me)
-    g_object_unref (free_me);
+  cairo_destroy (cr);
 }
 
 static void
@@ -4488,156 +4178,6 @@ gtk_default_draw_expander (GtkStyle        *style,
   cairo_destroy (cr);
 }
 
-typedef struct _ByteRange ByteRange;
-
-struct _ByteRange
-{
-  guint start;
-  guint end;
-};
-
-static ByteRange*
-range_new (guint start,
-           guint end)
-{
-  ByteRange *br = g_new (ByteRange, 1);
-
-  br->start = start;
-  br->end = end;
-  
-  return br;
-}
-
-static PangoLayout*
-get_insensitive_layout (GdkDrawable *drawable,
-                       PangoLayout *layout)
-{
-  GSList *embossed_ranges = NULL;
-  GSList *stippled_ranges = NULL;
-  PangoLayoutIter *iter;
-  GSList *tmp_list = NULL;
-  PangoLayout *new_layout;
-  PangoAttrList *attrs;
-  GdkBitmap *stipple = NULL;
-  
-  iter = pango_layout_get_iter (layout);
-  
-  do
-    {
-      PangoLayoutRun *run;
-      PangoAttribute *attr;
-      gboolean need_stipple = FALSE;
-      ByteRange *br;
-      
-      run = pango_layout_iter_get_run_readonly (iter);
-
-      if (run)
-        {
-          tmp_list = run->item->analysis.extra_attrs;
-
-          while (tmp_list != NULL)
-            {
-              attr = tmp_list->data;
-              switch (attr->klass->type)
-                {
-                case PANGO_ATTR_FOREGROUND:
-                case PANGO_ATTR_BACKGROUND:
-                  need_stipple = TRUE;
-                  break;
-              
-                default:
-                  break;
-                }
-
-              if (need_stipple)
-                break;
-          
-              tmp_list = g_slist_next (tmp_list);
-            }
-
-          br = range_new (run->item->offset, run->item->offset + run->item->length);
-      
-          if (need_stipple)
-            stippled_ranges = g_slist_prepend (stippled_ranges, br);
-          else
-            embossed_ranges = g_slist_prepend (embossed_ranges, br);
-        }
-    }
-  while (pango_layout_iter_next_run (iter));
-
-  pango_layout_iter_free (iter);
-
-  new_layout = pango_layout_copy (layout);
-
-  attrs = pango_layout_get_attributes (new_layout);
-
-  if (attrs == NULL)
-    {
-      /* Create attr list if there wasn't one */
-      attrs = pango_attr_list_new ();
-      pango_layout_set_attributes (new_layout, attrs);
-      pango_attr_list_unref (attrs);
-    }
-  
-  tmp_list = embossed_ranges;
-  while (tmp_list != NULL)
-    {
-      PangoAttribute *attr;
-      ByteRange *br = tmp_list->data;
-
-      attr = gdk_pango_attr_embossed_new (TRUE);
-
-      attr->start_index = br->start;
-      attr->end_index = br->end;
-      
-      pango_attr_list_change (attrs, attr);
-
-      g_free (br);
-      
-      tmp_list = g_slist_next (tmp_list);
-    }
-
-  g_slist_free (embossed_ranges);
-  
-  tmp_list = stippled_ranges;
-  while (tmp_list != NULL)
-    {
-      PangoAttribute *attr;
-      ByteRange *br = tmp_list->data;
-
-      if (stipple == NULL)
-        {
-#define gray50_width 2
-#define gray50_height 2
-          static const char gray50_bits[] = {
-            0x02, 0x01
-          };
-
-          stipple = gdk_bitmap_create_from_data (drawable,
-                                                 gray50_bits, gray50_width,
-                                                 gray50_height);
-        }
-      
-      attr = gdk_pango_attr_stipple_new (stipple);
-
-      attr->start_index = br->start;
-      attr->end_index = br->end;
-      
-      pango_attr_list_change (attrs, attr);
-
-      g_free (br);
-      
-      tmp_list = g_slist_next (tmp_list);
-    }
-
-  g_slist_free (stippled_ranges);
-  
-  if (stipple)
-    g_object_unref (stipple);
-
-  return new_layout;
-}
-
 static void
 gtk_default_draw_layout (GtkStyle        *style,
                          GdkWindow       *window,
@@ -4650,30 +4190,59 @@ gtk_default_draw_layout (GtkStyle        *style,
                          gint             y,
                          PangoLayout     *layout)
 {
-  GdkGC *gc;
+  cairo_t *cr;
+  GdkColor *gc;
+  const PangoMatrix *matrix;
 
-  gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
-  
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
+  cr = gdk_cairo_create (window);
 
-  if (state_type == GTK_STATE_INSENSITIVE)
+  if (area)
     {
-      PangoLayout *ins;
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
 
-      ins = get_insensitive_layout (window, layout);
+  matrix = pango_context_get_matrix (pango_layout_get_context (layout));
+  if (matrix)
+    {
+      cairo_matrix_t cairo_matrix;
+      PangoMatrix tmp_matrix;
+      PangoRectangle rect;
       
-      gdk_draw_layout (window, gc, x, y, ins);
+      cairo_matrix_init (&cairo_matrix,
+                         matrix->xx, matrix->yx,
+                         matrix->xy, matrix->yy,
+                         matrix->x0, matrix->y0);
 
-      g_object_unref (ins);
+      pango_layout_get_extents (layout, NULL, &rect);
+      pango_matrix_transform_rectangle (matrix, &rect);
+      pango_extents_to_pixels (&rect, NULL);
+                                          
+      tmp_matrix = *matrix;
+      cairo_matrix.x0 += x - rect.x;
+      cairo_matrix.y0 += y - rect.y;
+
+      cairo_set_matrix (cr, &cairo_matrix);
     }
   else
+    cairo_translate (cr, x, y);
+
+  if (state_type == GTK_STATE_INSENSITIVE)
     {
-      gdk_draw_layout (window, gc, x, y, layout);
+      cairo_save (cr);
+      gdk_cairo_set_source_color (cr, &style->white);
+      cairo_move_to (cr, 1, 1);
+      _gtk_pango_fill_layout (cr, layout);
+      cairo_restore (cr);
     }
 
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
+  gc = use_text ? &style->text[state_type] : &style->fg[state_type];
+
+  gdk_cairo_set_source_color (cr, gc);
+
+  pango_cairo_show_layout (cr, layout);
+
+  cairo_destroy (cr);
 }
 
 static void
@@ -4689,16 +4258,20 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
                               gint            width,
                               gint            height)
 {
-  GdkPoint points[4];
-  gint i, j, skip;
+  gint skip;
+  cairo_t *cr;
 
+  cr = gdk_cairo_create (window);
+  cairo_rectangle (cr, x, y, width, height);
+  cairo_clip (cr);
   if (area)
     {
-      gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
-      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
-      gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
     }
-  
+
+  cairo_set_line_width (cr, 1.0);
+
   skip = -1;
   switch (edge)
     {
@@ -4773,20 +4346,6 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
     default:
       g_assert_not_reached ();
     }
-  /* Clear background */
-  j = 0;
-  for (i = 0; i < 4; i++)
-    {
-      if (skip != i)
-       {
-         points[j].x = (i == 0 || i == 3) ? x : x + width;
-         points[j].y = (i < 2) ? y : y + height;
-         j++;
-       }
-    }
-  
-  gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, 
-                   points, skip < 0 ? 4 : 3);
   
   switch (edge)
     {
@@ -4799,16 +4358,16 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
 
        while (xi < x + width)
          {
-           gdk_draw_line (window,
-                          style->light_gc[state_type],
-                          xi, y,
-                          xi, y + height);
+           _cairo_draw_line (cr,
+                             &style->light[state_type],
+                             xi, y,
+                             xi, y + height);
 
            xi++;
-           gdk_draw_line (window,
-                          style->dark_gc[state_type],
-                          xi, y,
-                          xi, y + height);
+           _cairo_draw_line (cr,
+                             &style->dark[state_type],
+                             xi, y,
+                             xi, y + height);
 
            xi += 2;
          }
@@ -4823,16 +4382,16 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
 
        while (yi < y + height)
          {
-           gdk_draw_line (window,
-                          style->light_gc[state_type],
-                          x, yi,
-                          x + width, yi);
+           _cairo_draw_line (cr,
+                             &style->light[state_type],
+                             x, yi,
+                             x + width, yi);
 
            yi++;
-           gdk_draw_line (window,
-                          style->dark_gc[state_type],
-                          x, yi,
-                          x + width, yi);
+           _cairo_draw_line (cr,
+                             &style->dark[state_type],
+                             x, yi,
+                             x + width, yi);
 
            yi+= 2;
          }
@@ -4847,26 +4406,26 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
 
        while (xi > x + 3)
          {
-           gdk_draw_line (window,
-                          style->dark_gc[state_type],
-                          xi, y,
-                          x, yi);
+           _cairo_draw_line (cr,
+                             &style->dark[state_type],
+                             xi, y,
+                             x, yi);
 
            --xi;
            --yi;
 
-           gdk_draw_line (window,
-                          style->dark_gc[state_type],
-                          xi, y,
-                          x, yi);
+           _cairo_draw_line (cr,
+                             &style->dark[state_type],
+                             xi, y,
+                             x, yi);
 
            --xi;
            --yi;
 
-           gdk_draw_line (window,
-                          style->light_gc[state_type],
-                          xi, y,
-                          x, yi);
+           _cairo_draw_line (cr,
+                             &style->light[state_type],
+                             xi, y,
+                             x, yi);
 
            xi -= 3;
            yi -= 3;
@@ -4883,26 +4442,26 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
 
         while (xi < (x + width - 3))
           {
-            gdk_draw_line (window,
-                           style->light_gc[state_type],
-                           xi, y,
-                           x + width, yi);                           
+            _cairo_draw_line (cr,
+                              &style->light[state_type],
+                              xi, y,
+                              x + width, yi);                           
 
             ++xi;
             --yi;
             
-            gdk_draw_line (window,
-                           style->dark_gc[state_type],
-                           xi, y,
-                           x + width, yi);                           
+            _cairo_draw_line (cr,
+                              &style->dark[state_type],
+                              xi, y,
+                              x + width, yi);                           
 
             ++xi;
             --yi;
             
-            gdk_draw_line (window,
-                           style->dark_gc[state_type],
-                           xi, y,
-                           x + width, yi);
+            _cairo_draw_line (cr,
+                              &style->dark[state_type],
+                              xi, y,
+                              x + width, yi);
 
             xi += 3;
             yi -= 3;
@@ -4918,26 +4477,26 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
 
        while (xi > x + 3)
          {
-           gdk_draw_line (window,
-                          style->dark_gc[state_type],
-                          x, yi,
-                          xi, y + height);
+           _cairo_draw_line (cr,
+                             &style->dark[state_type],
+                             x, yi,
+                             xi, y + height);
 
            --xi;
            ++yi;
 
-           gdk_draw_line (window,
-                          style->dark_gc[state_type],
-                          x, yi,
-                          xi, y + height);
+           _cairo_draw_line (cr,
+                             &style->dark[state_type],
+                             x, yi,
+                             xi, y + height);
 
            --xi;
            ++yi;
 
-           gdk_draw_line (window,
-                          style->light_gc[state_type],
-                          x, yi,
-                          xi, y + height);
+           _cairo_draw_line (cr,
+                             &style->light[state_type],
+                             x, yi,
+                             xi, y + height);
 
            xi -= 3;
            yi += 3;
@@ -4954,26 +4513,26 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
 
         while (xi < (x + width - 3))
           {
-            gdk_draw_line (window,
-                           style->light_gc[state_type],
-                           xi, y + height,
-                           x + width, yi);                           
+            _cairo_draw_line (cr,
+                              &style->light[state_type],
+                              xi, y + height,
+                              x + width, yi);                           
 
             ++xi;
             ++yi;
             
-            gdk_draw_line (window,
-                           style->dark_gc[state_type],
-                           xi, y + height,
-                           x + width, yi);                           
+            _cairo_draw_line (cr,
+                              &style->dark[state_type],
+                              xi, y + height,
+                              x + width, yi);                           
 
             ++xi;
             ++yi;
             
-            gdk_draw_line (window,
-                           style->dark_gc[state_type],
-                           xi, y + height,
-                           x + width, yi);
+            _cairo_draw_line (cr,
+                              &style->dark[state_type],
+                              xi, y + height,
+                              x + width, yi);
 
             xi += 3;
             yi += 3;
@@ -4985,12 +4544,7 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
       break;
     }
   
-  if (area)
-    {
-      gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
-      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
-      gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
-    }
+  cairo_destroy (cr);
 }
 
 static void
@@ -5367,43 +4921,6 @@ gtk_paint_shadow (GtkStyle           *style,
                                             x, y, width, height);
 }
 
-/**
- * gtk_paint_polygon:
- * @style: a #GtkStyle
- * @window: a #GdkWindow
- * @state_type: a state
- * @shadow_type: type of shadow to draw
- * @area: (allow-none): clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @points: an array of #GdkPoint<!-- -->s
- * @n_points: length of @points
- * @fill: %TRUE if the polygon should be filled
- *
- * Draws a polygon on @window with the given parameters.
- */ 
-void
-gtk_paint_polygon (GtkStyle           *style,
-                   GdkWindow          *window,
-                   GtkStateType        state_type,
-                   GtkShadowType       shadow_type,
-                   const GdkRectangle *area,
-                   GtkWidget          *widget,
-                   const gchar        *detail,
-                   const GdkPoint     *points,
-                   gint                n_points,
-                   gboolean            fill)
-{
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
-
-  GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type,
-                                             (GdkRectangle *) area, widget, detail,
-                                             (GdkPoint *) points, n_points, fill);
-}
-
 /**
  * gtk_paint_arrow:
  * @style: a #GtkStyle
@@ -6150,136 +5667,47 @@ gtk_border_free (GtkBorder *border)
   g_slice_free (GtkBorder, border);
 }
 
-GType
-gtk_border_get_type (void)
-{
-  static GType our_type = 0;
-  
-  if (our_type == 0)
-    our_type = g_boxed_type_register_static (I_("GtkBorder"),
-                                            (GBoxedCopyFunc) gtk_border_copy,
-                                            (GBoxedFreeFunc) gtk_border_free);
-
-  return our_type;
-}
-
-static GdkFont *
-gtk_style_get_font_internal (GtkStyle *style)
-{
-  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
-
-  if (style->private_font && style->private_font_desc)
-    {
-      if (!style->font_desc ||
-         !pango_font_description_equal (style->private_font_desc, style->font_desc))
-       {
-         gdk_font_unref (style->private_font);
-         style->private_font = NULL;
-         
-         if (style->private_font_desc)
-           {
-             pango_font_description_free (style->private_font_desc);
-             style->private_font_desc = NULL;
-           }
-       }
-    }
-  
-  if (!style->private_font)
-    {
-      GdkDisplay *display;
-
-      if (style->colormap)
-       {
-         display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
-       }
-      else
-       {
-         display = gdk_display_get_default ();
-         GTK_NOTE (MULTIHEAD,
-                   g_warning ("gtk_style_get_font() should not be called on an unattached style"));
-       }
-      
-      if (style->font_desc)
-       {
-         style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
-         style->private_font_desc = pango_font_description_copy (style->font_desc);
-       }
-
-      if (!style->private_font)
-       style->private_font = gdk_font_load_for_display (display, "fixed");
-      
-      if (!style->private_font) 
-       g_error ("Unable to load \"fixed\" font");
-    }
-
-  return style->private_font;
-}
+G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
+                     gtk_border_copy,
+                     gtk_border_free)
 
 typedef struct _CursorInfo CursorInfo;
 
 struct _CursorInfo
 {
   GType for_type;
-  GdkGC *primary_gc;
-  GdkGC *secondary_gc;
+  GdkColor primary;
+  GdkColor secondary;
 };
 
 static void
-style_unrealize_cursor_gcs (GtkStyle *style)
+style_unrealize_cursors (GtkStyle *style)
 {
   CursorInfo *
   
   cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
   if (cursor_info)
     {
-      if (cursor_info->primary_gc)
-       gtk_gc_release (cursor_info->primary_gc);
-
-      if (cursor_info->secondary_gc)
-       gtk_gc_release (cursor_info->secondary_gc);
-      
       g_free (cursor_info);
       g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
     }
 }
 
-static GdkGC *
-make_cursor_gc (GtkWidget      *widget,
-               const gchar    *property_name,
-               const GdkColor *fallback)
+static const GdkColor *
+get_insertion_cursor_color (GtkWidget *widget,
+                           gboolean   is_primary)
 {
-  GdkGCValues gc_values;
-  GdkGCValuesMask gc_values_mask;
+  CursorInfo *cursor_info;
+  GtkStyle *style;
   GdkColor *cursor_color;
 
-  gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
-  
-  gc_values_mask = GDK_GC_FOREGROUND;
-  if (cursor_color)
-    {
-      gc_values.foreground = *cursor_color;
-      gdk_color_free (cursor_color);
-    }
-  else
-    gc_values.foreground = *fallback;
-  
-  gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
-  return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
-}
-
-static GdkGC *
-get_insertion_cursor_gc (GtkWidget *widget,
-                        gboolean   is_primary)
-{
-  CursorInfo *cursor_info;
+  style = gtk_widget_get_style (widget);
 
-  cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
+  cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
   if (!cursor_info)
     {
-      cursor_info = g_new (CursorInfo, 1);
-      g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
-      cursor_info->primary_gc = NULL;
-      cursor_info->secondary_gc = NULL;
+      cursor_info = g_new0 (CursorInfo, 1);
+      g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), cursor_info);
       cursor_info->for_type = G_TYPE_INVALID;
     }
 
@@ -6292,48 +5720,38 @@ get_insertion_cursor_gc (GtkWidget *widget,
   if (cursor_info->for_type != G_OBJECT_TYPE (widget))
     {
       cursor_info->for_type = G_OBJECT_TYPE (widget);
-      if (cursor_info->primary_gc)
-       {
-         gtk_gc_release (cursor_info->primary_gc);
-         cursor_info->primary_gc = NULL;
-       }
-      if (cursor_info->secondary_gc)
-       {
-         gtk_gc_release (cursor_info->secondary_gc);
-         cursor_info->secondary_gc = NULL;
-       }
-    }
-
-  /* Cursors in text widgets are drawn only in NORMAL state,
-   * so we can use text[GTK_STATE_NORMAL] as text color here */
-  if (is_primary)
-    {
-      if (!cursor_info->primary_gc)
-       cursor_info->primary_gc = make_cursor_gc (widget,
-                                                 "cursor-color",
-                                                 &widget->style->text[GTK_STATE_NORMAL]);
 
-      return cursor_info->primary_gc;
-    }
-  else
-    {
-      if (!cursor_info->secondary_gc)
-       cursor_info->secondary_gc = make_cursor_gc (widget,
-                                                   "secondary-cursor-color",
-                                                   /* text_aa is the average of text and base colors,
-                                                    * in usual black-on-white case it's grey. */
-                                                   &widget->style->text_aa[GTK_STATE_NORMAL]);
+      /* Cursors in text widgets are drawn only in NORMAL state,
+       * so we can use text[GTK_STATE_NORMAL] as text color here */
+      gtk_widget_style_get (widget, "cursor-color", &cursor_color, NULL);
+      if (cursor_color)
+        {
+          cursor_info->primary = *cursor_color;
+          gdk_color_free (cursor_color);
+        }
+      else
+        {
+          cursor_info->primary = style->text[GTK_STATE_NORMAL];
+        }
 
-      return cursor_info->secondary_gc;
+      gtk_widget_style_get (widget, "secondary-cursor-color", &cursor_color, NULL);
+      if (cursor_color)
+        {
+          cursor_info->secondary = *cursor_color;
+          gdk_color_free (cursor_color);
+        }
+      else
+        {
+          /* text_aa is the average of text and base colors,
+           * in usual black-on-white case it's grey. */
+          cursor_info->secondary = style->text_aa[GTK_STATE_NORMAL];
+        }
     }
-}
 
-GdkGC *
-_gtk_widget_get_cursor_gc (GtkWidget *widget)
-{
-  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-  g_return_val_if_fail (gtk_widget_get_realized (widget), NULL);
-  return get_insertion_cursor_gc (widget, TRUE);
+  if (is_primary)
+    return &cursor_info->primary;
+  else
+    return &cursor_info->secondary;
 }
 
 void
@@ -6353,13 +5771,12 @@ _gtk_widget_get_cursor_color (GtkWidget *widget,
       gdk_color_free (style_color);
     }
   else
-    *color = widget->style->text[GTK_STATE_NORMAL];
+    *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
 }
 
 static void
 draw_insertion_cursor (GtkWidget          *widget,
-                      GdkDrawable        *drawable,
-                      GdkGC              *gc,
+                       cairo_t            *cr,
                       const GdkRectangle *location,
                       GtkTextDirection    direction,
                       gboolean            draw_arrow)
@@ -6367,7 +5784,6 @@ draw_insertion_cursor (GtkWidget          *widget,
   gint stem_width;
   gint arrow_width;
   gint x, y;
-  gint i;
   gfloat cursor_aspect_ratio;
   gint offset;
   
@@ -6386,10 +5802,10 @@ draw_insertion_cursor (GtkWidget          *widget,
   else
     offset = stem_width - stem_width / 2;
   
-  for (i = 0; i < stem_width; i++)
-    gdk_draw_line (drawable, gc,
-                  location->x + i - offset, location->y,
-                  location->x + i - offset, location->y + location->height - 1);
+  cairo_rectangle (cr, 
+                   location->x - offset, location->y,
+                   stem_width, location->height);
+  cairo_fill (cr);
 
   if (draw_arrow)
     {
@@ -6398,26 +5814,20 @@ draw_insertion_cursor (GtkWidget          *widget,
           x = location->x - offset - 1;
           y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
   
-          for (i = 0; i < arrow_width; i++)
-            {
-              gdk_draw_line (drawable, gc,
-                             x, y + i + 1,
-                             x, y + 2 * arrow_width - i - 1);
-              x --;
-            }
+          cairo_move_to (cr, x, y + 1);
+          cairo_line_to (cr, x - arrow_width, y + arrow_width);
+          cairo_line_to (cr, x, y + 2 * arrow_width);
+          cairo_fill (cr);
         }
       else if (direction == GTK_TEXT_DIR_LTR)
         {
           x = location->x + stem_width - offset;
           y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
   
-          for (i = 0; i < arrow_width; i++) 
-            {
-              gdk_draw_line (drawable, gc,
-                             x, y + i + 1,
-                             x, y + 2 * arrow_width - i - 1);
-              x++;
-            }
+          cairo_move_to (cr, x, y + 1);
+          cairo_line_to (cr, x + arrow_width, y + arrow_width);
+          cairo_line_to (cr, x, y + 2 * arrow_width);
+          cairo_fill (cr);
         }
     }
 }
@@ -6449,23 +5859,22 @@ gtk_draw_insertion_cursor (GtkWidget          *widget,
                           GtkTextDirection    direction,
                           gboolean            draw_arrow)
 {
-  GdkGC *gc;
+  cairo_t *cr;
 
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
   g_return_if_fail (location != NULL);
   g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
 
-  gc = get_insertion_cursor_gc (widget, is_primary);
+  cr = gdk_cairo_create (drawable);
   if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+    }
   
-  draw_insertion_cursor (widget, drawable, gc,
-                        location, direction, draw_arrow);
+  gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
+  draw_insertion_cursor (widget, cr, location, direction, draw_arrow);
   
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
+  cairo_destroy (cr);
 }
-
-#define __GTK_STYLE_C__
-#include "gtkaliasdef.c"