]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkstyle.c
Minor documentation improvements
[~andy/gtk] / gtk / gtkstyle.c
index 464b5420ff050e61217f668d3d9d6546a010afc5..cf88d1d07a601dd8a48a9d9a0f10301ed86d4261 100644 (file)
 #include "gtkrc.h"
 #include "gtkspinbutton.h"
 #include "gtkstyle.h"
+#include "gtkstylecontextprivate.h"
 #include "gtkwidget.h"
-#include "gtkthemes.h"
 #include "gtkiconfactory.h"
-#include "gtksettings.h"       /* _gtk_settings_parse_convert() */
 #include "gtkintl.h"
+#include "gtkdebug.h"
 #include "gtkspinner.h"
-
+#include "gtkborder.h"
 
 /**
  * SECTION:gtkstyle
- * @Short_description: An object that hold style information for widgets
+ * @Short_description: Deprecated object that holds 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
+ * feel for a widget.
+ *
+ * <warning>
+ * In GTK+ 3.0, GtkStyle has been deprecated and replaced by #GtkStyleContext.
+ * </warning>
+ *
+ * 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 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.
+ * Usually applications should not need to use or modify the #GtkStyle of
+ * their widgets.
  */
 
 
@@ -76,13 +83,27 @@ typedef struct {
 typedef struct _GtkStylePrivate GtkStylePrivate;
 
 struct _GtkStylePrivate {
-  GSList *color_hashes;
+  GtkStyleContext *context;
+  gulong context_changed_id;
+};
+
+enum {
+  PROP_0,
+  PROP_CONTEXT
 };
 
 /* --- prototypes --- */
 static void     gtk_style_finalize             (GObject        *object);
-static void     gtk_style_realize              (GtkStyle       *style,
-                                                GdkColormap    *colormap);
+static void     gtk_style_constructed          (GObject        *object);
+static void      gtk_style_set_property         (GObject        *object,
+                                                 guint           prop_id,
+                                                 const GValue   *value,
+                                                 GParamSpec     *pspec);
+static void      gtk_style_get_property         (GObject        *object,
+                                                 guint           prop_id,
+                                                 GValue         *value,
+                                                 GParamSpec     *pspec);
+
 static void      gtk_style_real_realize        (GtkStyle       *style);
 static void      gtk_style_real_unrealize      (GtkStyle       *style);
 static void      gtk_style_real_copy           (GtkStyle       *style,
@@ -311,7 +332,8 @@ static void hls_to_rgb                      (gdouble         *h,
                                         gdouble         *l,
                                         gdouble         *s);
 
-static void style_unrealize_cursors     (GtkStyle *style);
+static void transform_detail_string (const gchar     *detail,
+                                     GtkStyleContext *context);
 
 /*
  * Data for default check and radio buttons
@@ -352,57 +374,14 @@ G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
 
 /* --- functions --- */
 
-/**
- * _gtk_style_init_for_settings:
- * @style: a #GtkStyle
- * @settings: a #GtkSettings
- * 
- * Initializes the font description in @style according to the default
- * font name of @settings. This is called for gtk_style_new() with
- * the settings for the default screen (if any); if we are creating
- * a style for a particular screen, we then call it again in a
- * location where we know the correct settings.
- * The reason for this is that gtk_rc_style_create_style() doesn't
- * take the screen for an argument.
- **/
-void
-_gtk_style_init_for_settings (GtkStyle    *style,
-                             GtkSettings *settings)
-{
-  const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
-
-  if (style->font_desc)
-    pango_font_description_free (style->font_desc);
-  
-  style->font_desc = pango_font_description_from_string (font_name);
-      
-  if (!pango_font_description_get_family (style->font_desc))
-    {
-      g_warning ("Default font does not have a family set");
-      pango_font_description_set_family (style->font_desc, "Sans");
-    }
-  if (pango_font_description_get_size (style->font_desc) <= 0)
-    {
-      g_warning ("Default font does not have a positive size");
-      pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
-    }
-}
-
 static void
 gtk_style_init (GtkStyle *style)
 {
   gint i;
-  
-  GtkSettings *settings = gtk_settings_get_default ();
-  
-  if (settings)
-    _gtk_style_init_for_settings (style, settings);
-  else
-    style->font_desc = pango_font_description_from_string ("Sans 10");
-  
+
+  style->font_desc = pango_font_description_from_string ("Sans 10");
+
   style->attach_count = 0;
-  style->colormap = NULL;
-  style->depth = -1;
   
   style->black.red = 0;
   style->black.green = 0;
@@ -451,6 +430,9 @@ gtk_style_class_init (GtkStyleClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   
   object_class->finalize = gtk_style_finalize;
+  object_class->set_property = gtk_style_set_property;
+  object_class->get_property = gtk_style_get_property;
+  object_class->constructed = gtk_style_constructed;
 
   klass->clone = gtk_style_real_clone;
   klass->copy = gtk_style_real_copy;
@@ -483,12 +465,20 @@ gtk_style_class_init (GtkStyleClass *klass)
 
   g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
 
+  g_object_class_install_property (object_class,
+                                  PROP_CONTEXT,
+                                  g_param_spec_object ("context",
+                                                       P_("Style context"),
+                                                       P_("GtkStyleContext to get style from"),
+                                                        GTK_TYPE_STYLE_CONTEXT,
+                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
   /**
    * GtkStyle::realize:
    * @style: the object which received the signal
    *
    * Emitted when the style has been initialized for a particular
-   * colormap and depth. Connecting to this signal is probably seldom
+   * visual. Connecting to this signal is probably seldom
    * useful since most of the time applications and widgets only
    * deal with styles that have been already realized.
    *
@@ -505,8 +495,8 @@ gtk_style_class_init (GtkStyleClass *klass)
    * GtkStyle::unrealize:
    * @style: the object which received the signal
    *
-   * 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
+   * Emitted when the aspects of the style specific to a particular visual
+   * is being cleaned up. A connection to this signal can be useful
    * if a widget wants to cache objects as object data on #GtkStyle.
    * This signal provides a convenient place to free such cached objects.
    *
@@ -521,35 +511,15 @@ gtk_style_class_init (GtkStyleClass *klass)
                                   G_TYPE_NONE, 0);
 }
 
-static void
-clear_property_cache (GtkStyle *style)
-{
-  if (style->property_cache)
-    {
-      guint i;
-
-      for (i = 0; i < style->property_cache->len; i++)
-       {
-         PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
-
-         g_param_spec_unref (node->pspec);
-         g_value_unset (&node->value);
-       }
-      g_array_free (style->property_cache, TRUE);
-      style->property_cache = NULL;
-    }
-}
-
 static void
 gtk_style_finalize (GObject *object)
 {
   GtkStyle *style = GTK_STYLE (object);
   GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
+  gint i;
 
   g_return_if_fail (style->attach_count == 0);
 
-  clear_property_cache (style);
-  
   /* All the styles in the list have the same 
    * style->styles pointer. If we delete the 
    * *first* style from the list, we need to update
@@ -577,9 +547,6 @@ gtk_style_finalize (GObject *object)
   g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
   g_slist_free (style->icon_factories);
 
-  g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
-  g_slist_free (priv->color_hashes);
-
   pango_font_description_free (style->font_desc);
 
   if (style->private_font_desc)
@@ -588,9 +555,238 @@ gtk_style_finalize (GObject *object)
   if (style->rc_style)
     g_object_unref (style->rc_style);
 
+  if (priv->context)
+    {
+      if (priv->context_changed_id)
+        g_signal_handler_disconnect (priv->context, priv->context_changed_id);
+
+      g_object_unref (priv->context);
+    }
+
+  for (i = 0; i < 5; i++)
+    {
+      if (style->background[i])
+        cairo_pattern_destroy (style->background[i]);
+    }
+
   G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
 }
 
+static void
+gtk_style_set_property (GObject      *object,
+                        guint         prop_id,
+                        const GValue *value,
+                        GParamSpec   *pspec)
+{
+  GtkStylePrivate *priv;
+
+  priv = GTK_STYLE_GET_PRIVATE (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      priv->context = g_value_dup_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_style_get_property (GObject      *object,
+                        guint         prop_id,
+                        GValue       *value,
+                        GParamSpec   *pspec)
+{
+  GtkStylePrivate *priv;
+
+  priv = GTK_STYLE_GET_PRIVATE (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      g_value_set_object (value, priv->context);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+set_color (GtkStyle        *style,
+           GtkStyleContext *context,
+           GtkStateType     state,
+           GtkRcFlags       prop)
+{
+  GtkStateFlags flags;
+  GdkRGBA *color = NULL;
+  GdkColor *dest = { 0 }; /* Shut up gcc */
+
+  switch (state)
+    {
+    case GTK_STATE_ACTIVE:
+      flags = GTK_STATE_FLAG_ACTIVE;
+      break;
+    case GTK_STATE_PRELIGHT:
+      flags = GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags = GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags = GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      flags = 0;
+    }
+
+  switch (prop)
+    {
+    case GTK_RC_BG:
+      gtk_style_context_get (context, flags,
+                             "background-color", &color,
+                             NULL);
+      dest = &style->bg[state];
+      break;
+    case GTK_RC_FG:
+      gtk_style_context_get (context, flags,
+                             "color", &color,
+                             NULL);
+      dest = &style->fg[state];
+      break;
+    case GTK_RC_TEXT:
+      gtk_style_context_get (context, flags,
+                             "color", &color,
+                             NULL);
+      dest = &style->text[state];
+      break;
+    case GTK_RC_BASE:
+      gtk_style_context_get (context, flags,
+                             "background-color", &color,
+                             NULL);
+      dest = &style->base[state];
+      break;
+    }
+
+  if (color)
+    {
+      dest->pixel = 0;
+      dest->red = CLAMP ((guint) (color->red * 65535), 0, 65535);
+      dest->green = CLAMP ((guint) (color->green * 65535), 0, 65535);
+      dest->blue = CLAMP ((guint) (color->blue * 65535), 0, 65535);
+      gdk_rgba_free (color);
+    }
+}
+
+static void
+gtk_style_update_from_context (GtkStyle *style)
+{
+  GtkStylePrivate *priv;
+  GtkStateType state;
+  GtkBorder *padding;
+  gint i;
+
+  priv = GTK_STYLE_GET_PRIVATE (style);
+
+  for (state = GTK_STATE_NORMAL; state <= GTK_STATE_INSENSITIVE; state++)
+    {
+      if (gtk_style_context_has_class (priv->context, "entry"))
+        {
+          gtk_style_context_save (priv->context);
+          gtk_style_context_remove_class (priv->context, "entry");
+          set_color (style, priv->context, state, GTK_RC_BG);
+          set_color (style, priv->context, state, GTK_RC_FG);
+          gtk_style_context_restore (priv->context);
+
+          set_color (style, priv->context, state, GTK_RC_BASE);
+          set_color (style, priv->context, state, GTK_RC_TEXT);
+        }
+      else
+        {
+          gtk_style_context_save (priv->context);
+          gtk_style_context_add_class (priv->context, "entry");
+          set_color (style, priv->context, state, GTK_RC_BASE);
+          set_color (style, priv->context, state, GTK_RC_TEXT);
+          gtk_style_context_restore (priv->context);
+
+          set_color (style, priv->context, state, GTK_RC_BG);
+          set_color (style, priv->context, state, GTK_RC_FG);
+        }
+    }
+
+  if (style->font_desc)
+    pango_font_description_free (style->font_desc);
+
+  gtk_style_context_get (priv->context, 0,
+                         "font", &style->font_desc,
+                         "padding", &padding,
+                         NULL);
+
+  if (padding)
+    {
+      style->xthickness = padding->left;
+      style->ythickness = padding->top;
+
+      gtk_border_free (padding);
+    }
+
+  for (i = 0; i < 5; i++)
+    {
+      _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
+      _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
+
+      style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
+      style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
+      style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
+
+      style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
+      style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
+      style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
+    }
+
+  style->black.red = 0x0000;
+  style->black.green = 0x0000;
+  style->black.blue = 0x0000;
+
+  style->white.red = 0xffff;
+  style->white.green = 0xffff;
+  style->white.blue = 0xffff;
+
+  for (i = 0; i < 5; i++)
+    {
+      if (style->background[i])
+        cairo_pattern_destroy (style->background[i]);
+
+      style->background[i] = cairo_pattern_create_rgb (style->bg[i].red / 65535.0,
+                                                       style->bg[i].green / 65535.0,
+                                                       style->bg[i].blue / 65535.0);
+    }
+}
+
+static void
+style_context_changed (GtkStyleContext *context,
+                       gpointer         user_data)
+{
+  gtk_style_update_from_context (GTK_STYLE (user_data));
+}
+
+static void
+gtk_style_constructed (GObject *object)
+{
+  GtkStylePrivate *priv;
+
+  priv = GTK_STYLE_GET_PRIVATE (object);
+
+  if (priv->context)
+    {
+      gtk_style_update_from_context (GTK_STYLE (object));
+
+      priv->context_changed_id = g_signal_connect (priv->context, "changed",
+                                                   G_CALLBACK (style_context_changed), object);
+    }
+}
 
 /**
  * gtk_style_copy:
@@ -599,6 +795,8 @@ gtk_style_finalize (GObject *object)
  * Creates a copy of the passed in #GtkStyle object.
  *
  * Returns: (transfer full): a copy of @style
+ *
+ * Deprecated:3.0: Use #GtkStyleContext instead
  */
 GtkStyle*
 gtk_style_copy (GtkStyle *style)
@@ -613,24 +811,27 @@ gtk_style_copy (GtkStyle *style)
   return new_style;
 }
 
-static GtkStyle*
-gtk_style_duplicate (GtkStyle *style)
+GtkStyle*
+_gtk_style_new_for_path (GdkScreen     *screen,
+                         GtkWidgetPath *path)
 {
-  GtkStyle *new_style;
-  
-  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
-  
-  new_style = gtk_style_copy (style);
-  
-  /* All the styles in the list have the same 
-   * style->styles pointer. When we insert a new 
-   * style, we append it to the list to avoid having 
-   * to update the existing ones. 
-   */
-  style->styles = g_slist_append (style->styles, new_style);
-  new_style->styles = style->styles;  
-  
-  return new_style;
+  GtkStyleContext *context;
+  GtkStyle *style;
+
+  context = gtk_style_context_new ();
+
+  if (screen)
+    gtk_style_context_set_screen (context, screen);
+
+  gtk_style_context_set_path (context, path);
+
+  style = g_object_new (GTK_TYPE_STYLE,
+                        "context", context,
+                        NULL);
+
+  g_object_unref (context);
+
+  return style;
 }
 
 /**
@@ -638,27 +839,55 @@ gtk_style_duplicate (GtkStyle *style)
  * @returns: a new #GtkStyle.
  *
  * Creates a new #GtkStyle.
+ *
+ * Deprecated: 3.0: Use #GtkStyleContext
  **/
 GtkStyle*
 gtk_style_new (void)
 {
+  GtkWidgetPath *path;
   GtkStyle *style;
-  
-  style = g_object_new (GTK_TYPE_STYLE, NULL);
-  
+
+  path = gtk_widget_path_new ();
+  gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
+
+  style = _gtk_style_new_for_path (gdk_screen_get_default (), path);
+
+  gtk_widget_path_free (path);
+
   return style;
 }
 
 /**
- * gtk_style_attach:
+ * gtk_style_has_context:
+ * @style: a #GtkStyle
+ *
+ * Returns whether @style has an associated #GtkStyleContext.
+ *
+ * Returns: %TRUE if @style has a #GtkStyleContext
+ *
+ * Since: 3.0
+ */
+gboolean
+gtk_style_has_context (GtkStyle *style)
+{
+  GtkStylePrivate *priv;
+
+  priv = GTK_STYLE_GET_PRIVATE (style);
+
+  return priv->context != NULL;
+}
+
+/**
+ * gtk_style_attach: (skip)
  * @style: a #GtkStyle.
  * @window: a #GdkWindow.
  *
  * Attaches a style to a window; this process allocates the
  * colors and creates the GC's for the style - it specializes
- * it to a particular visual and colormap. The process may
- * involve the creation of a new style if the style has already
- * been attached to a window with a different style and colormap.
+ * it to a particular visual. The process may involve the creation
+ * of a new style if the style has already been attached to a
+ * window with a different style and visual.
  *
  * Since this function may return a new object, you have to use it
  * in the following way:
@@ -668,74 +897,17 @@ gtk_style_new (void)
  *   If the style is newly created, the style parameter
  *   will be unref'ed, and the new style will have
  *   a reference count belonging to the caller.
+ *
+ * Deprecated:3.0: Use gtk_widget_style_attach() instead
  */
 GtkStyle*
 gtk_style_attach (GtkStyle  *style,
                   GdkWindow *window)
 {
-  GSList *styles;
-  GtkStyle *new_style = NULL;
-  GdkColormap *colormap;
-  
   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
   g_return_val_if_fail (window != NULL, NULL);
-  
-  colormap = gdk_drawable_get_colormap (window);
-  
-  if (!style->styles)
-    style->styles = g_slist_append (NULL, style);
-  
-  styles = style->styles;
-  while (styles)
-    {
-      new_style = styles->data;
-      
-      if (new_style->colormap == colormap)
-        break;
-
-      new_style = NULL;
-      styles = styles->next;
-    }
-
-  if (!new_style)
-    {
-      styles = style->styles;
-      
-      while (styles)
-       {
-         new_style = styles->data;
-         
-         if (new_style->attach_count == 0)
-           {
-             gtk_style_realize (new_style, colormap);
-             break;
-           }
-         
-         new_style = NULL;
-         styles = styles->next;
-       }
-    }
-  
-  if (!new_style)
-    {
-      new_style = gtk_style_duplicate (style);
-      gtk_style_realize (new_style, colormap);
-    }
-
-  /* A style gets a refcount from being attached */
-  if (new_style->attach_count == 0)
-    g_object_ref (new_style);
 
-  /* Another refcount belongs to the parent */
-  if (style != new_style) 
-    {
-      g_object_unref (style);
-      g_object_ref (new_style);
-    }
-  
-  new_style->attach_count++;
-  
-  return new_style;
+  return style;
 }
 
 /**
@@ -744,40 +916,13 @@ gtk_style_attach (GtkStyle  *style,
  *
  * Detaches a style from a window. If the style is not attached
  * to any windows anymore, it is unrealized. See gtk_style_attach().
- * 
+ *
+ * Deprecated:3.0: Use #GtkStyleContext instead
  */
 void
 gtk_style_detach (GtkStyle *style)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (style->attach_count > 0);
-  
-  style->attach_count -= 1;
-  if (style->attach_count == 0)
-    {
-      g_signal_emit (style, unrealize_signal, 0);
-      
-      g_object_unref (style->colormap);
-      style->colormap = NULL;
-
-      if (style->private_font_desc)
-       {
-         pango_font_description_free (style->private_font_desc);
-         style->private_font_desc = NULL;
-       }
-
-      g_object_unref (style);
-    }
-}
-
-static void
-gtk_style_realize (GtkStyle    *style,
-                   GdkColormap *colormap)
-{
-  style->colormap = g_object_ref (colormap);
-  style->depth = gdk_colormap_get_visual (colormap)->depth;
-
-  g_signal_emit (style, realize_signal, 0);
 }
 
 /**
@@ -789,27 +934,23 @@ gtk_style_realize (GtkStyle    *style,
  * and the default icon factory, returning an icon set if found,
  * otherwise %NULL.
  *
- * Return value: icon set of @stock_id
+ * Return value: (transfer none): icon set of @stock_id
+ *
+ * Deprecated:3.0: Use gtk_style_context_lookup_icon_set() instead
  */
 GtkIconSet*
 gtk_style_lookup_icon_set (GtkStyle   *style,
                            const char *stock_id)
 {
-  GSList *iter;
+  GtkStylePrivate *priv;
 
   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
   g_return_val_if_fail (stock_id != NULL, NULL);
-  
-  iter = style->icon_factories;
-  while (iter != NULL)
-    {
-      GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
-                                                     stock_id);
-      if (icon_set)
-        return icon_set;
-      
-      iter = g_slist_next (iter);
-    }
+
+  priv = GTK_STYLE_GET_PRIVATE (style);
+
+  if (priv->context)
+    return gtk_style_context_lookup_icon_set (priv->context, stock_id);
 
   return gtk_icon_factory_lookup_default (stock_id);
 }
@@ -818,7 +959,7 @@ gtk_style_lookup_icon_set (GtkStyle   *style,
  * gtk_style_lookup_color:
  * @style: a #GtkStyle
  * @color_name: the name of the logical color to look up
- * @color: the #GdkColor to fill in
+ * @color: (out): the #GdkColor to fill in
  *
  * Looks up @color_name in the style's logical color mappings,
  * filling in @color and returning %TRUE if found, otherwise
@@ -829,6 +970,8 @@ gtk_style_lookup_icon_set (GtkStyle   *style,
  * Return value: %TRUE if the mapping was found.
  *
  * Since: 2.10
+ *
+ * Deprecated:3.0: Use gtk_style_context_lookup_color() instead
  **/
 gboolean
 gtk_style_lookup_color (GtkStyle   *style,
@@ -836,7 +979,8 @@ gtk_style_lookup_color (GtkStyle   *style,
                         GdkColor   *color)
 {
   GtkStylePrivate *priv;
-  GSList *iter;
+  gboolean result;
+  GdkRGBA rgba;
 
   g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
   g_return_val_if_fail (color_name != NULL, FALSE);
@@ -844,21 +988,20 @@ gtk_style_lookup_color (GtkStyle   *style,
 
   priv = GTK_STYLE_GET_PRIVATE (style);
 
-  for (iter = priv->color_hashes; iter != NULL; iter = iter->next)
-    {
-      GHashTable *hash    = iter->data;
-      GdkColor   *mapping = g_hash_table_lookup (hash, color_name);
+  if (!priv->context)
+    return FALSE;
 
-      if (mapping)
-        {
-          color->red = mapping->red;
-          color->green = mapping->green;
-          color->blue = mapping->blue;
-          return TRUE;
-        }
-    }
+  result = gtk_style_context_lookup_color (priv->context, color_name, &rgba);
 
-  return FALSE;
+  if (color)
+    {
+      color->red = (guint16) (rgba.red * 65535);
+      color->green = (guint16) (rgba.green * 65535);
+      color->blue = (guint16) (rgba.blue * 65535);
+      color->pixel = 0;
+    }
+
+  return result;
 }
 
 /**
@@ -869,6 +1012,8 @@ gtk_style_lookup_color (GtkStyle   *style,
  * 
  * Sets the background of @window to the background color or pixmap
  * specified by @style for the given state.
+ *
+ * Deprecated:3.0: Use gtk_style_context_set_background() instead
  */
 void
 gtk_style_set_background (GtkStyle    *style,
@@ -885,15 +1030,19 @@ gtk_style_set_background (GtkStyle    *style,
 static GtkStyle *
 gtk_style_real_clone (GtkStyle *style)
 {
-  return g_object_new (G_OBJECT_TYPE (style), NULL);
+  GtkStylePrivate *priv;
+
+  priv = GTK_STYLE_GET_PRIVATE (style);
+
+  return g_object_new (G_OBJECT_TYPE (style),
+                       "context", priv->context,
+                       NULL);
 }
 
 static void
 gtk_style_real_copy (GtkStyle *style,
                     GtkStyle *src)
 {
-  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
-  GtkStylePrivate *src_priv = GTK_STYLE_GET_PRIVATE (src);
   gint i;
   
   for (i = 0; i < 5; i++)
@@ -930,64 +1079,12 @@ gtk_style_real_copy (GtkStyle *style,
   g_slist_free (style->icon_factories);
   style->icon_factories = g_slist_copy (src->icon_factories);
   g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
-
-  g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
-  g_slist_free (priv->color_hashes);
-  priv->color_hashes = g_slist_copy (src_priv->color_hashes);
-  g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
-
-  /* don't copy, just clear cache */
-  clear_property_cache (style);
 }
 
 static void
 gtk_style_real_init_from_rc (GtkStyle   *style,
                             GtkRcStyle *rc_style)
 {
-  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
-  gint i;
-
-  /* cache _should_ be still empty */
-  clear_property_cache (style);
-
-  if (rc_style->font_desc)
-    pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
-    
-  for (i = 0; i < 5; i++)
-    {
-      if (rc_style->color_flags[i] & GTK_RC_FG)
-       style->fg[i] = rc_style->fg[i];
-      if (rc_style->color_flags[i] & GTK_RC_BG)
-       style->bg[i] = rc_style->bg[i];
-      if (rc_style->color_flags[i] & GTK_RC_TEXT)
-       style->text[i] = rc_style->text[i];
-      if (rc_style->color_flags[i] & GTK_RC_BASE)
-       style->base[i] = rc_style->base[i];
-    }
-
-  if (rc_style->xthickness >= 0)
-    style->xthickness = rc_style->xthickness;
-  if (rc_style->ythickness >= 0)
-    style->ythickness = rc_style->ythickness;
-
-  style->icon_factories = g_slist_copy (rc_style->icon_factories);
-  g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
-
-  priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
-  g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
-}
-
-static gint
-style_property_values_cmp (gconstpointer bsearch_node1,
-                          gconstpointer bsearch_node2)
-{
-  const PropertyValue *val1 = bsearch_node1;
-  const PropertyValue *val2 = bsearch_node2;
-
-  if (val1->widget_type == val2->widget_type)
-    return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
-  else
-    return val1->widget_type < val2->widget_type ? -1 : 1;
 }
 
 /**
@@ -1009,9 +1106,9 @@ gtk_style_get_style_property (GtkStyle     *style,
                               const gchar *property_name,
                               GValue      *value)
 {
+  GtkStylePrivate *priv;
   GtkWidgetClass *klass;
   GParamSpec *pspec;
-  GtkRcPropertyParser parser;
   const GValue *peek_value;
 
   klass = g_type_class_ref (widget_type);
@@ -1027,10 +1124,10 @@ gtk_style_get_style_property (GtkStyle     *style,
       return;
     }
 
-  parser = g_param_spec_get_qdata (pspec,
-                                   g_quark_from_static_string ("gtk-rc-property-parser"));
-
-  peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
+  priv = GTK_STYLE_GET_PRIVATE (style);
+  peek_value = _gtk_style_context_peek_style_property (priv->context,
+                                                       widget_type,
+                                                       0, pspec);
 
   if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
     g_value_copy (peek_value, value);
@@ -1063,6 +1160,7 @@ gtk_style_get_valist (GtkStyle    *style,
                       const gchar *first_property_name,
                       va_list      var_args)
 {
+  GtkStylePrivate *priv;
   const char *property_name;
   GtkWidgetClass *klass;
 
@@ -1070,11 +1168,11 @@ gtk_style_get_valist (GtkStyle    *style,
 
   klass = g_type_class_ref (widget_type);
 
+  priv = GTK_STYLE_GET_PRIVATE (style);
   property_name = first_property_name;
   while (property_name)
     {
       GParamSpec *pspec;
-      GtkRcPropertyParser parser;
       const GValue *peek_value;
       gchar *error;
 
@@ -1089,10 +1187,8 @@ gtk_style_get_valist (GtkStyle    *style,
           break;
         }
 
-      parser = g_param_spec_get_qdata (pspec,
-                                       g_quark_from_static_string ("gtk-rc-property-parser"));
-
-      peek_value = _gtk_style_peek_property_value (style, widget_type, pspec, parser);
+      peek_value = _gtk_style_context_peek_style_property (priv->context, widget_type,
+                                                           0, pspec);
       G_VALUE_LCOPY (peek_value, var_args, 0, &error);
       if (error)
         {
@@ -1134,195 +1230,14 @@ gtk_style_get (GtkStyle    *style,
   va_end (var_args);
 }
 
-const GValue*
-_gtk_style_peek_property_value (GtkStyle           *style,
-                               GType               widget_type,
-                               GParamSpec         *pspec,
-                               GtkRcPropertyParser parser)
-{
-  PropertyValue *pcache, key = { 0, NULL, { 0, } };
-  const GtkRcProperty *rcprop = NULL;
-  guint i;
-
-  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
-  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
-  g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
-  g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
-
-  key.widget_type = widget_type;
-  key.pspec = pspec;
-
-  /* need value cache array */
-  if (!style->property_cache)
-    style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
-  else
-    {
-      pcache = bsearch (&key,
-                       style->property_cache->data, style->property_cache->len,
-                       sizeof (PropertyValue), style_property_values_cmp);
-      if (pcache)
-       return &pcache->value;
-    }
-
-  i = 0;
-  while (i < style->property_cache->len &&
-        style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
-    i++;
-
-  g_array_insert_val (style->property_cache, i, key);
-  pcache = &g_array_index (style->property_cache, PropertyValue, i);
-
-  /* cache miss, initialize value type, then set contents */
-  g_param_spec_ref (pcache->pspec);
-  g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-
-  /* value provided by rc style? */
-  if (style->rc_style)
-    {
-      GQuark prop_quark = g_quark_from_string (pspec->name);
-
-      do
-       {
-         rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
-                                                    g_type_qname (widget_type),
-                                                    prop_quark);
-         if (rcprop)
-           break;
-         widget_type = g_type_parent (widget_type);
-       }
-      while (g_type_is_a (widget_type, pspec->owner_type));
-    }
-
-  /* when supplied by rc style, we need to convert */
-  if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
-                                             pspec, &pcache->value))
-    {
-      gchar *contents = g_strdup_value_contents (&rcprop->value);
-      
-      g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
-                rcprop->origin ? rcprop->origin : "(for origin information, set GTK_DEBUG)",
-                g_type_name (pspec->owner_type), pspec->name,
-                g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
-                contents,
-                G_VALUE_TYPE_NAME (&rcprop->value));
-      g_free (contents);
-      rcprop = NULL; /* needs default */
-    }
-  
-  /* not supplied by rc style (or conversion failed), revert to default */
-  if (!rcprop)
-    g_param_value_set_default (pspec, &pcache->value);
-
-  return &pcache->value;
-}
-
-static cairo_pattern_t *
-load_background (GdkColormap *colormap,
-                GdkColor    *bg_color,
-                const gchar *filename)
-{
-  if (filename == NULL)
-    {
-      return cairo_pattern_create_rgb (bg_color->red   / 65535.0,
-                                       bg_color->green / 65535.0,
-                                       bg_color->blue  / 65535.0);
-    }
-  if (strcmp (filename, "<parent>") == 0)
-    return NULL;
-  else
-    {
-      GdkPixbuf *pixbuf;
-      cairo_surface_t *surface;
-      cairo_pattern_t *pattern;
-      cairo_t *cr;
-      GdkScreen *screen = gdk_colormap_get_screen (colormap);
-  
-      pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
-      if (!pixbuf)
-        return NULL;
-
-      surface = gdk_window_create_similar_surface (gdk_screen_get_root_window (screen),
-                                                   CAIRO_CONTENT_COLOR,
-                                                   gdk_pixbuf_get_width (pixbuf),
-                                                   gdk_pixbuf_get_height (pixbuf));
-  
-      cr = cairo_create (surface);
-
-      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);
-
-      pattern = cairo_pattern_create_for_surface (surface);
-
-      cairo_surface_destroy (surface);
-
-      return pattern;
-    }
-}
-
 static void
 gtk_style_real_realize (GtkStyle *style)
 {
-  gint i;
-
-  for (i = 0; i < 5; i++)
-    {
-      _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
-      _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
-
-      style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
-      style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
-      style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
-
-      style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
-      style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
-      style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
-    }
-
-  style->black.red = 0x0000;
-  style->black.green = 0x0000;
-  style->black.blue = 0x0000;
-
-  style->white.red = 0xffff;
-  style->white.green = 0xffff;
-  style->white.blue = 0xffff;
-
-  for (i = 0; i < 5; i++)
-    {
-      const char *image_name;
-
-      if (style->rc_style)
-        image_name = style->rc_style->bg_pixmap_name[i];
-      else
-        image_name = NULL;
-
-      style->background[i] = load_background (style->colormap,
-                                             &style->bg[i],
-                                             image_name);
-    }
 }
 
 static void
 gtk_style_real_unrealize (GtkStyle *style)
 {
-  int i;
-
-  for (i = 0; i < 5; i++)
-    {
-      if (style->background[i])
-       {
-         cairo_pattern_destroy (style->background[i]);
-         style->background[i] = NULL;
-       }
-      
-    }
-  
-  style_unrealize_cursors (style);
 }
 
 static void
@@ -1351,6 +1266,8 @@ gtk_style_real_set_background (GtkStyle    *style,
  *
  * Return value: (transfer full): a newly-created #GdkPixbuf
  *     containing the rendered icon
+ *
+ * Deprecated:3.0: Use gtk_render_icon_pixbuf() instead
  */
 GdkPixbuf *
 gtk_style_render_icon (GtkStyle            *style,
@@ -1383,11 +1300,12 @@ gtk_style_render_icon (GtkStyle            *style,
  * @window:
  * @set_bg:
  * @state_type:
- * @area: (allow-none):
  * @x:
  * @y:
  * @width:
  * @height:
+ *
+ * Deprecated:3.0: Use #GtkStyleContext instead
  */
 void
 gtk_style_apply_default_background (GtkStyle          *style,
@@ -1429,54 +1347,6 @@ out:
   cairo_restore (cr);
 }
 
-static GdkPixbuf *
-scale_or_ref (GdkPixbuf *src,
-              gint       width,
-              gint       height)
-{
-  if (width == gdk_pixbuf_get_width (src) &&
-      height == gdk_pixbuf_get_height (src))
-    {
-      return g_object_ref (src);
-    }
-  else
-    {
-      return gdk_pixbuf_scale_simple (src,
-                                      width, height,
-                                      GDK_INTERP_BILINEAR);
-    }
-}
-
-static gboolean
-lookup_icon_size (GtkStyle    *style,
-                 GtkWidget   *widget,
-                 GtkIconSize  size,
-                 gint        *width,
-                 gint        *height)
-{
-  GdkScreen *screen;
-  GtkSettings *settings;
-
-  if (widget && gtk_widget_has_screen (widget))
-    {
-      screen = gtk_widget_get_screen (widget);
-      settings = gtk_settings_get_for_screen (screen);
-    }
-  else if (style && style->colormap)
-    {
-      screen = gdk_colormap_get_screen (style->colormap);
-      settings = gtk_settings_get_for_screen (screen);
-    }
-  else
-    {
-      settings = gtk_settings_get_default ();
-      GTK_NOTE (MULTIHEAD,
-               g_warning ("Using the default screen for gtk_default_render_icon()"));
-    }
-
-  return gtk_icon_size_lookup_for_settings (settings, size, width, height);
-}
-
 static GdkPixbuf *
 gtk_default_render_icon (GtkStyle            *style,
                          const GtkIconSource *source,
@@ -1486,78 +1356,46 @@ gtk_default_render_icon (GtkStyle            *style,
                          GtkWidget           *widget,
                          const gchar         *detail)
 {
-  gint width = 1;
-  gint height = 1;
-  GdkPixbuf *scaled;
-  GdkPixbuf *stated;
-  GdkPixbuf *base_pixbuf;
-
-  /* Oddly, style can be NULL in this function, because
-   * GtkIconSet can be used without a style and if so
-   * it uses this function.
-   */
-
-  base_pixbuf = gtk_icon_source_get_pixbuf (source);
-
-  g_return_val_if_fail (base_pixbuf != NULL, NULL);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+  GdkPixbuf *pixbuf;
 
-  if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      g_warning (G_STRLOC ": invalid icon size '%d'", size);
-      return NULL;
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
 
-  /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
-   * leave it alone.
-   */
-  if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
-    scaled = scale_or_ref (base_pixbuf, width, height);
-  else
-    scaled = g_object_ref (base_pixbuf);
+  if (!context)
+    return NULL;
 
-  /* If the state was wildcarded, then generate a state. */
-  if (gtk_icon_source_get_state_wildcarded (source))
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state)
     {
-      if (state == GTK_STATE_INSENSITIVE)
-        {
-          stated = gdk_pixbuf_copy (scaled);      
-          
-          gdk_pixbuf_saturate_and_pixelate (scaled, stated,
-                                            0.8, TRUE);
-          
-          g_object_unref (scaled);
-        }
-      else if (state == GTK_STATE_PRELIGHT)
-        {
-          stated = gdk_pixbuf_copy (scaled);      
-          
-          gdk_pixbuf_saturate_and_pixelate (scaled, stated,
-                                            1.2, FALSE);
-          
-          g_object_unref (scaled);
-        }
-      else
-        {
-          stated = scaled;
-        }
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      break;
     }
-  else
-    stated = scaled;
-  
-  return stated;
-}
 
-static void
-sanitize_size (GdkWindow *window,
-              gint      *width,
-              gint      *height)
-{
-  if ((*width == -1) && (*height == -1))
-    gdk_drawable_get_size (window, width, height);
-  else if (*width == -1)
-    gdk_drawable_get_size (window, width, NULL);
-  else if (*height == -1)
-    gdk_drawable_get_size (window, NULL, height);
+  gtk_style_context_set_state (context, flags);
+
+  pixbuf = gtk_render_icon_pixbuf (context, source, size);
+
+  gtk_style_context_restore (context);
+
+  return pixbuf;
 }
 
 static void
@@ -1581,41 +1419,168 @@ _cairo_draw_line (cairo_t  *cr,
 }
 
 static void
-_cairo_draw_rectangle (cairo_t *cr,
-                       GdkColor *color,
-                       gboolean filled,
-                       gint x,
-                       gint y,
-                       gint width,
-                       gint height)
+transform_detail_string (const gchar     *detail,
+                        GtkStyleContext *context)
 {
-  gdk_cairo_set_source_color (cr, color);
+  if (!detail)
+    return;
 
-  if (filled)
+  if (strcmp (detail, "arrow") == 0)
+    gtk_style_context_add_class (context, "arrow");
+  else if (strcmp (detail, "button") == 0)
+    gtk_style_context_add_class (context, "button");
+  else if (strcmp (detail, "buttondefault") == 0)
     {
-      cairo_rectangle (cr, x, y, width, height);
-      cairo_fill (cr);
+      gtk_style_context_add_class (context, "button");
+      gtk_style_context_add_class (context, "default");
     }
-  else
+  else if (strcmp (detail, "calendar") == 0)
+    gtk_style_context_add_class (context, "calendar");
+  else if (strcmp (detail, "cellcheck") == 0)
     {
-      cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
-      cairo_stroke (cr);
+      gtk_style_context_add_class (context, "cell");
+      gtk_style_context_add_class (context, "check");
     }
-}
+  else if (strcmp (detail, "cellradio") == 0)
+    {
+      gtk_style_context_add_class (context, "cell");
+      gtk_style_context_add_class (context, "radio");
+    }
+  else if (strcmp (detail, "checkbutton") == 0)
+    gtk_style_context_add_class (context, "check");
+  else if (strcmp (detail, "check") == 0)
+    {
+      gtk_style_context_add_class (context, "check");
+      gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "radiobutton") == 0)
+    {
+      gtk_style_context_add_class (context, "radio");
+    }
+  else if (strcmp (detail, "option") == 0)
+    {
+      gtk_style_context_add_class (context, "radio");
+      gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "entry") == 0 ||
+           strcmp (detail, "entry_bg") == 0)
+    gtk_style_context_add_class (context, "entry");
+  else if (strcmp (detail, "expander") == 0)
+    gtk_style_context_add_class (context, "expander");
+  else if (strcmp (detail, "tooltip") == 0)
+    gtk_style_context_add_class (context, "tooltip");
+  else if (strcmp (detail, "frame") == 0)
+    gtk_style_context_add_class (context, "frame");
+  else if (strcmp (detail, "scrolled_window") == 0)
+    gtk_style_context_add_class (context, "scrolled-window");
+  else if (strcmp (detail, "viewport") == 0 ||
+          strcmp (detail, "viewportbin") == 0)
+    gtk_style_context_add_class (context, "viewport");
+  else if (strncmp (detail, "trough", 6) == 0)
+    gtk_style_context_add_class (context, "trough");
+  else if (strcmp (detail, "spinbutton") == 0)
+    gtk_style_context_add_class (context, "spinbutton");
+  else if (strcmp (detail, "spinbutton_up") == 0)
+    {
+      gtk_style_context_add_class (context, "spinbutton");
+      gtk_style_context_add_class (context, "button");
+      gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
+    }
+  else if (strcmp (detail, "spinbutton_down") == 0)
+    {
+      gtk_style_context_add_class (context, "spinbutton");
+      gtk_style_context_add_class (context, "button");
+      gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+    }
+  else if ((detail[0] == 'h' || detail[0] == 'v') &&
+           strncmp (&detail[1], "scrollbar_", 10) == 0)
+    {
+      gtk_style_context_add_class (context, "button");
+      gtk_style_context_add_class (context, "scrollbar");
+    }
+  else if (strcmp (detail, "slider") == 0)
+    {
+      gtk_style_context_add_class (context, "slider");
+      gtk_style_context_add_class (context, "scrollbar");
+    }
+  else if (strcmp (detail, "vscale") == 0 ||
+           strcmp (detail, "hscale") == 0)
+    {
+      gtk_style_context_add_class (context, "slider");
+      gtk_style_context_add_class (context, "scale");
+    }
+  else if (strcmp (detail, "menuitem") == 0)
+    {
+      gtk_style_context_add_class (context, "menuitem");
+      gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "menu") == 0)
+    {
+      gtk_style_context_add_class (context, "popup");
+      gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "accellabel") == 0)
+    gtk_style_context_add_class (context, "accelerator");
+  else if (strcmp (detail, "menubar") == 0)
+    gtk_style_context_add_class (context, "menubar");
+  else if (strcmp (detail, "base") == 0)
+    gtk_style_context_add_class (context, "background");
+  else if (strcmp (detail, "bar") == 0 ||
+           strcmp (detail, "progressbar") == 0)
+    gtk_style_context_add_class (context, "progressbar");
+  else if (strcmp (detail, "toolbar") == 0)
+    gtk_style_context_add_class (context, "toolbar");
+  else if (strcmp (detail, "handlebox_bin") == 0)
+    gtk_style_context_add_class (context, "dock");
+  else if (strcmp (detail, "notebook") == 0)
+    gtk_style_context_add_class (context, "notebook");
+  else if (strcmp (detail, "tab") == 0)
+    {
+      gtk_style_context_add_class (context, "notebook");
+      gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, 0);
+    }
+  else if (g_str_has_prefix (detail, "cell"))
+    {
+      GtkRegionFlags row, col;
+      gboolean ruled = FALSE;
+      GStrv tokens;
+      guint i;
 
-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);
+      tokens = g_strsplit (detail, "_", -1);
+      row = col = 0;
+      i = 0;
+
+      while (tokens[i])
+        {
+          if (strcmp (tokens[i], "even") == 0)
+            row |= GTK_REGION_EVEN;
+          else if (strcmp (tokens[i], "odd") == 0)
+            row |= GTK_REGION_ODD;
+          else if (strcmp (tokens[i], "start") == 0)
+            col |= GTK_REGION_FIRST;
+          else if (strcmp (tokens[i], "end") == 0)
+            col |= GTK_REGION_LAST;
+          else if (strcmp (tokens[i], "ruled") == 0)
+            ruled = TRUE;
+          else if (strcmp (tokens[i], "sorted") == 0)
+            col |= GTK_REGION_SORTED;
+
+          i++;
+        }
+
+      if (!ruled)
+        row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
+
+      gtk_style_context_add_class (context, "cell");
+      gtk_style_context_add_region (context, "row", row);
+      gtk_style_context_add_region (context, "column", col);
+
+      g_strfreev (tokens);
+    }
 }
 
 static void
-gtk_default_draw_hline (GtkStyle      *style,
+gtk_default_draw_hline (GtkStyle     *style,
                         cairo_t       *cr,
                         GtkStateType  state_type,
                         GtkWidget     *widget,
@@ -1624,36 +1589,30 @@ gtk_default_draw_hline (GtkStyle      *style,
                         gint          x2,
                         gint          y)
 {
-  gint thickness_light;
-  gint thickness_dark;
-  gint i;
-  
-  thickness_light = style->ythickness / 2;
-  thickness_dark = style->ythickness - thickness_light;
-  
-  cairo_set_line_width (cr, 1.0);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
 
-  if (detail && !strcmp (detail, "label"))
-    {
-      if (state_type == GTK_STATE_INSENSITIVE)
-        _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);
-    }
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
   else
     {
-      for (i = 0; i < thickness_dark; 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++)
-        {
-          _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);
-        }
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
+
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  cairo_save (cr);
+
+  gtk_render_line (context, cr,
+                   x1, y, x2, y);
+
+  cairo_restore (cr);
+
+  gtk_style_context_restore (context);
 }
 
 
@@ -1667,180 +1626,31 @@ gtk_default_draw_vline (GtkStyle      *style,
                         gint          y2,
                         gint          x)
 {
-  gint thickness_light;
-  gint thickness_dark;
-  gint i;
-  
-  thickness_light = style->xthickness / 2;
-  thickness_dark = style->xthickness - thickness_light;
-
-  cairo_set_line_width (cr, 1.0);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
 
-  for (i = 0; i < thickness_dark; i++)
-    { 
-      _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++)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      _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);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
-}
 
-static void
-draw_thin_shadow (GtkStyle      *style,
-                 cairo_t       *cr,
-                 GtkStateType   state,
-                 gint           x,
-                 gint           y,
-                 gint           width,
-                 gint           height)
-{
-  GdkColor *gc1, *gc2;
+  gtk_style_context_save (context);
 
-  gc1 = &style->light[state];
-  gc2 = &style->dark[state];
+  if (detail)
+    transform_detail_string (detail, context);
 
-  _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);
+  cairo_save (cr);
+
+  gtk_render_line (context, cr,
+                   x, y1, x, y2);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
-static void
-draw_spinbutton_shadow (GtkStyle        *style,
-                       cairo_t         *cr,
-                       GtkStateType     state,
-                       GtkTextDirection direction,
-                       gint             x,
-                       gint             y,
-                       gint             width,
-                       gint             height)
-{
-
-  if (direction == GTK_TEXT_DIR_LTR)
-    {
-      _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
-    {
-      _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,
-                 cairo_t         *cr,
-                 GtkStateType     state,
-                 gint             x,
-                 gint             y,
-                 gint             width,
-                 gint             height)
-{
-  if (style->ythickness > 0)
-    {
-      if (style->ythickness > 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
-       {
-         _cairo_draw_line (cr, &style->dark[state],
-                            x + 1, y + height - 1, x + width - 1, y + height - 1);
-       }
-    }
-  
-  if (style->xthickness > 0)
-    {
-      if (style->xthickness > 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
-       {
-         _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)
-    _cairo_draw_line (cr, &style->black,
-                  x, y, x + width - 2, y);
-  if (style->xthickness > 0)
-    _cairo_draw_line (cr, &style->black,
-                      x, y, x, y + height - 2);
-  
-  if (style->ythickness > 1)
-    _cairo_draw_line (cr, &style->light[state],
-                      x + 1, y + 1, x + width - 3, y + 1);
-  if (style->xthickness > 1)
-    _cairo_draw_line (cr, &style->light[state],
-                      x + 1, y + 1, x + 1, y + height - 3);
-}
-
-static GtkTextDirection
-get_direction (GtkWidget *widget)
-{
-  GtkTextDirection dir;
-  
-  if (widget)
-    dir = gtk_widget_get_direction (widget);
-  else
-    dir = GTK_TEXT_DIR_LTR;
-  
-  return dir;
-}
-
-
 static void
 gtk_default_draw_shadow (GtkStyle      *style,
                          cairo_t       *cr,
@@ -1853,299 +1663,35 @@ gtk_default_draw_shadow (GtkStyle      *style,
                          gint           width,
                          gint           height)
 {
-  GdkColor *gc1 = NULL;
-  GdkColor *gc2 = NULL;
-  gint thickness_light;
-  gint thickness_dark;
-  gint i;
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
 
-  cairo_set_line_width (cr, 1.0);
+  if (shadow_type == GTK_SHADOW_NONE)
+    return;
 
-  if (shadow_type == GTK_SHADOW_IN)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      if (detail && strcmp (detail, "buttondefault") == 0)
-       {
-          _cairo_draw_rectangle (cr, &style->black, FALSE,
-                                 x, y, width - 1, height - 1);
-
-         return;
-       }
-      if (detail && strcmp (detail, "trough") == 0)
-       {
-          draw_thin_shadow (style, cr, state_type,
-                            x, y, width, height);
-
-         return;
-       }
-      if (GTK_IS_SPIN_BUTTON (widget) &&
-         detail && strcmp (detail, "spinbutton") == 0)
-       {
-         draw_spinbutton_shadow (style, cr, state_type, 
-                                 get_direction (widget), x, y, width, height);
-         
-         return;
-       }
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
 
-  if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
-    {
-      draw_menu_shadow (style, cr, state_type, x, y, width, height);
-      return;
-    }
-  
-  switch (shadow_type)
-    {
-    case GTK_SHADOW_NONE:
-      return;
-    case GTK_SHADOW_IN:
-    case GTK_SHADOW_ETCHED_IN:
-      gc1 = &style->light[state_type];
-      gc2 = &style->dark[state_type];
-      break;
-    case GTK_SHADOW_OUT:
-    case GTK_SHADOW_ETCHED_OUT:
-      gc1 = &style->dark[state_type];
-      gc2 = &style->light[state_type];
-      break;
-    }
-  
-  switch (shadow_type)
-    {
-    case GTK_SHADOW_NONE:
-      break;
-      
-    case GTK_SHADOW_IN:
-      /* Light around right and bottom edge */
-
-      if (style->ythickness > 0)
-        _cairo_draw_line (cr, gc1,
-                          x, y + height - 1, x + width - 1, y + height - 1);
-      if (style->xthickness > 0)
-        _cairo_draw_line (cr, gc1,
-                          x + width - 1, y, x + width - 1, y + height - 1);
-
-      if (style->ythickness > 1)
-        _cairo_draw_line (cr, &style->bg[state_type],
-                          x + 1, y + height - 2, x + width - 2, y + height - 2);
-      if (style->xthickness > 1)
-        _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)
-        _cairo_draw_line (cr, &style->black,
-                          x + 1, y + 1, x + width - 2, y + 1);
-      if (style->xthickness > 1)
-        _cairo_draw_line (cr, &style->black,
-                          x + 1, y + 1, x + 1, y + height - 2);
-
-      if (style->ythickness > 0)
-        _cairo_draw_line (cr, gc2,
-                          x, y, x + width - 1, y);
-      if (style->xthickness > 0)
-        _cairo_draw_line (cr, gc2,
-                          x, y, x, y + height - 1);
-      break;
-      
-    case GTK_SHADOW_OUT:
-      /* Dark around right and bottom edge */
+  gtk_style_context_save (context);
 
-      if (style->ythickness > 0)
-        {
-          if (style->ythickness > 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
-            {
-              _cairo_draw_line (cr, gc1,
-                                x + 1, y + height - 1, x + width - 1, y + height - 1);
-            }
-        }
+  if (detail)
+    transform_detail_string (detail, context);
 
-      if (style->xthickness > 0)
-        {
-          if (style->xthickness > 1)
-            {
-              _cairo_draw_line (cr, gc1,
-                                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
-            {
-              _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)
-        _cairo_draw_line (cr, gc2,
-                          x, y, x + width - 2, y);
-      if (style->xthickness > 0)
-        _cairo_draw_line (cr, gc2,
-                          x, y, x, y + height - 2);
-
-      if (style->ythickness > 1)
-        _cairo_draw_line (cr, &style->bg[state_type],
-                          x + 1, y + 1, x + width - 3, y + 1);
-      if (style->xthickness > 1)
-        _cairo_draw_line (cr, &style->bg[state_type],
-                          x + 1, y + 1, x + 1, y + height - 3);
-      break;
-      
-    case GTK_SHADOW_ETCHED_IN:
-    case GTK_SHADOW_ETCHED_OUT:
-      if (style->xthickness > 0)
-        {
-          if (style->xthickness > 1)
-            {
-              thickness_light = 1;
-              thickness_dark = 1;
-      
-              for (i = 0; i < thickness_dark; i++)
-                {
-                  _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++)
-                {
-                  _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
-            {
-              _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);
-            }
-        }
+  cairo_save (cr);
 
-      if (style->ythickness > 0)
-        {
-          if (style->ythickness > 1)
-            {
-              thickness_light = 1;
-              thickness_dark = 1;
-      
-              for (i = 0; i < thickness_dark; i++)
-                {
-                  _cairo_draw_line (cr, gc1,
-                                    x + i,
-                                    y + height - i - 1,
-                                    x + width - i - 1,
-                                    y + height - i - 1);
-          
-                  _cairo_draw_line (cr, gc2,
-                                    x + i,
-                                    y + i,
-                                    x + width - i - 2,
-                                    y + i);
-                }
-      
-              for (i = 0; i < thickness_light; i++)
-                {
-                  _cairo_draw_line (cr, gc1,
-                                    x + thickness_dark + i,
-                                    y + thickness_dark + i,
-                                    x + width - thickness_dark - i - 2,
-                                    y + thickness_dark + i);
-          
-                  _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
-            {
-              _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);
-            }
-        }
-      
-      break;
-    }
+  gtk_render_frame (context, cr,
+                    (gdouble) x,
+                    (gdouble) y,
+                    (gdouble) width,
+                    (gdouble) height);
 
-  if (shadow_type == GTK_SHADOW_IN &&
-      GTK_IS_SPIN_BUTTON (widget) &&
-      detail && strcmp (detail, "entry") == 0)
-    {
-      if (get_direction (widget) == GTK_TEXT_DIR_LTR)
-       {
-          _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
-       {
-          _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);
-       }
-    }
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -2191,75 +1737,6 @@ draw_arrow (cairo_t       *cr,
   cairo_restore (cr);
 }
 
-static void
-calculate_arrow_geometry (GtkArrowType  arrow_type,
-                         gint         *x,
-                         gint         *y,
-                         gint         *width,
-                         gint         *height)
-{
-  gint w = *width;
-  gint h = *height;
-  
-  switch (arrow_type)
-    {
-    case GTK_ARROW_UP:
-    case GTK_ARROW_DOWN:
-      w += (w % 2) - 1;
-      h = (w / 2 + 1);
-      
-      if (h > *height)
-       {
-         h = *height;
-         w = 2 * h - 1;
-       }
-      
-      if (arrow_type == GTK_ARROW_DOWN)
-       {
-         if (*height % 2 == 1 || h % 2 == 0)
-           *height += 1;
-       }
-      else
-       {
-         if (*height % 2 == 0 || h % 2 == 0)
-           *height -= 1;
-       }
-      break;
-
-    case GTK_ARROW_RIGHT:
-    case GTK_ARROW_LEFT:
-      h += (h % 2) - 1;
-      w = (h / 2 + 1);
-      
-      if (w > *width)
-       {
-         w = *width;
-         h = 2 * w - 1;
-       }
-      
-      if (arrow_type == GTK_ARROW_RIGHT)
-       {
-         if (*width % 2 == 1 || w % 2 == 0)
-           *width += 1;
-       }
-      else
-       {
-         if (*width % 2 == 0 || w % 2 == 0)
-           *width -= 1;
-       }
-      break;
-      
-    default:
-      /* should not be reached */
-      break;
-    }
-
-  *x += (*width - w) / 2;
-  *y += (*height - h) / 2;
-  *height = h;
-  *width = w;
-}
-
 static void
 gtk_default_draw_arrow (GtkStyle      *style,
                        cairo_t       *cr,
@@ -2274,16 +1751,79 @@ gtk_default_draw_arrow (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+  gdouble angle, size;
+
+  if (arrow_type == GTK_ARROW_NONE)
+    return;
+
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
+    {
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
+    }
+
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (arrow_type)
+    {
+    case GTK_ARROW_UP:
+      angle = 0;
+      size = width;
+      break;
+    case GTK_ARROW_RIGHT:
+      angle = G_PI / 2;
+      size = height;
+      break;
+    case GTK_ARROW_DOWN:
+      angle = G_PI;
+      size = width;
+      break;
+    case GTK_ARROW_LEFT:
+      angle = 3 * (G_PI / 2);
+      size = height;
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+
+  switch (state)
+    {
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    case GTK_STATE_ACTIVE:
+      flags |= GTK_STATE_FLAG_ACTIVE;
+      break;
+    default:
+      break;
+    }
+
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
 
-  if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
-    y++;
+  gtk_render_arrow (context,
+                    cr, angle,
+                    (gdouble) x,
+                    (gdouble) y,
+                    size);
 
-  if (state == GTK_STATE_INSENSITIVE)
-    draw_arrow (cr, &style->white, arrow_type,
-               x + 1, y + 1, width, height);
-  draw_arrow (cr, &style->fg[state], arrow_type,
-             x, y, width, height);
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -2426,16 +1966,6 @@ option_menu_get_props (GtkWidget      *widget,
     *indicator_spacing = default_option_indicator_spacing;
 }
 
-static gboolean
-background_is_solid (GtkStyle     *style,
-                     GtkStateType  type)
-{
-  if (style->background[type] == NULL)
-    return FALSE;
-
-  return cairo_pattern_get_type (style->background[type]) == CAIRO_PATTERN_TYPE_SOLID;
-}
-
 static void 
 gtk_default_draw_box (GtkStyle      *style,
                      cairo_t       *cr,
@@ -2448,111 +1978,60 @@ gtk_default_draw_box (GtkStyle      *style,
                      gint           width,
                      gint           height)
 {
-  gboolean is_spinbutton_box = FALSE;
-  
-  if (GTK_IS_SPIN_BUTTON (widget) && detail)
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      if (strcmp (detail, "spinbutton_up") == 0)
-       {
-         y += 2;
-         width -= 3;
-         height -= 2;
-
-         if (get_direction (widget) == GTK_TEXT_DIR_RTL)
-           x += 2;
-         else
-           x += 1;
-
-         is_spinbutton_box = TRUE;
-       }
-      else if (strcmp (detail, "spinbutton_down") == 0)
-       {
-         width -= 3;
-         height -= 2;
-
-         if (get_direction (widget) == GTK_TEXT_DIR_RTL)
-           x += 2;
-         else
-           x += 1;
-
-         is_spinbutton_box = TRUE;
-       }
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
-  
-  if (background_is_solid (style, state_type))
-    {
-      GdkColor *gc = &style->bg[state_type];
 
-      if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
-       {
-         if (widget && !gtk_widget_has_focus (widget))
-           gc = &style->base[GTK_STATE_ACTIVE];
-       }
-
-      _cairo_draw_rectangle (cr, gc, TRUE,
-                             x, y, width, height);
-    }
-  else
-    gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
-                                        state_type, x, y, width, height);
+  gtk_style_context_save (context);
 
+  if (detail)
+    transform_detail_string (detail, context);
 
-  if (is_spinbutton_box)
+  switch (state_type)
     {
-      GdkColor *upper;
-      GdkColor *lower;
-
-      lower = &style->dark[state_type];
-      if (shadow_type == GTK_SHADOW_OUT)
-       upper = &style->light[state_type];
-      else
-       upper = &style->dark[state_type];
+    case GTK_STATE_ACTIVE:
+      flags |= GTK_STATE_FLAG_ACTIVE;
+      break;
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      break;
+    }
 
-      _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 (shadow_type == GTK_SHADOW_IN)
+    flags |= GTK_STATE_FLAG_ACTIVE;
 
-      return;
-    }
+  gtk_style_context_set_state (context, flags);
 
-  gtk_cairo_paint_shadow (style, cr, state_type, shadow_type, widget, detail,
-                          x, y, width, height);
+  cairo_save (cr);
 
-  if (detail && strcmp (detail, "optionmenu") == 0)
+  if (gtk_style_context_has_class (context, GTK_STYLE_CLASS_PROGRESSBAR))
+    gtk_render_activity (context, cr, x, y, width, height);
+  else
     {
-      GtkRequisition indicator_size;
-      GtkBorder indicator_spacing;
-      gint vline_x;
-
-      option_menu_get_props (widget, &indicator_size, &indicator_spacing);
-
-      if (get_direction (widget) == GTK_TEXT_DIR_RTL)
-       vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
-      else 
-       vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
-
-      gtk_cairo_paint_vline (style, cr, state_type, widget,
-                             detail,
-                             y + style->ythickness + 1,
-                             y + height - style->ythickness - 3,
-                             vline_x);
-    }
-}
+      gtk_render_background (context, cr, x, y, width, height);
 
-static GdkColor *
-get_darkened (const GdkColor *color,
-                 gint            darken_count)
-{
-  GdkColor src = *color;
-  GdkColor shaded = *color;
-  
-  while (darken_count)
-    {
-      _gtk_style_shade (&src, &shaded, 0.93);
-      src = shaded;
-      --darken_count;
+      if (shadow_type != GTK_SHADOW_NONE)
+       gtk_render_frame (context, cr, x, y, width, height);
     }
-   
-  return gdk_color_copy (&shaded);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -2567,198 +2046,56 @@ gtk_default_draw_flat_box (GtkStyle      *style,
                            gint           width,
                            gint           height)
 {
-  GdkColor *gc1;
-  GdkColor *freeme = NULL;
-  
-  cairo_set_line_width (cr, 1.0);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-  if (detail)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      int trimmed_len = strlen (detail);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
+    }
 
-      if (g_str_has_prefix (detail, "cell_"))
-        {
-          if (g_str_has_suffix (detail, "_start"))
-            trimmed_len -= 6;
-          else if (g_str_has_suffix (detail, "_middle"))
-            trimmed_len -= 7;
-          else if (g_str_has_suffix (detail, "_end"))
-            trimmed_len -= 4;
-        }
+  gtk_style_context_save (context);
 
-      if (state_type == GTK_STATE_SELECTED)
-        {
-          if (!strcmp ("text", detail))
-            gc1 = &style->bg[GTK_STATE_SELECTED];
-          else if (!strncmp ("cell_even", detail, trimmed_len) ||
-                   !strncmp ("cell_odd", detail, trimmed_len) ||
-                   !strncmp ("cell_even_ruled", detail, trimmed_len) ||
-                  !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
-            {
-             /* This has to be really broken; alex made me do it. -jrb */
-             if (widget && gtk_widget_has_focus (widget))
-               gc1 = &style->base[state_type];
-             else
-               gc1 = &style->base[GTK_STATE_ACTIVE];
-            }
-         else if (!strncmp ("cell_odd_ruled", detail, trimmed_len) ||
-                  !strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
-           {
-             if (widget && gtk_widget_has_focus (widget))
-               freeme = get_darkened (&style->base[state_type], 1);
-             else
-               freeme = get_darkened (&style->base[GTK_STATE_ACTIVE], 1);
-             gc1 = freeme;
-           }
-          else
-            {
-              gc1 = &style->bg[state_type];
-            }
-        }
-      else
-        {
-          if (!strcmp ("viewportbin", detail))
-            gc1 = &style->bg[GTK_STATE_NORMAL];
-          else if (!strcmp ("entry_bg", detail))
-            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
-           * for that row.
-           */
-
-          else if (!strncmp ("cell_even", detail, trimmed_len) ||
-                   !strncmp ("cell_odd", detail, trimmed_len) ||
-                   !strncmp ("cell_even_ruled", detail, trimmed_len))
-            {
-             GdkColor *color = NULL;
+  if (detail)
+    transform_detail_string (detail, context);
 
-             gtk_widget_style_get (widget,
-                                   "even-row-color", &color,
-                                   NULL);
+  switch (state_type)
+    {
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    case GTK_STATE_ACTIVE:
+      flags |= GTK_STATE_FLAG_ACTIVE;
+      break;
+    case GTK_STATE_FOCUSED:
+      flags |= GTK_STATE_FLAG_FOCUSED;
+      break;
+    default:
+      break;
+    }
 
-             if (color)
-               {
-                 freeme = get_darkened (color, 0);
-                 gc1 = freeme;
+  gtk_style_context_set_state (context, flags);
 
-                 gdk_color_free (color);
-               }
-             else
-               gc1 = &style->base[state_type];
-            }
-         else if (!strncmp ("cell_odd_ruled", detail, trimmed_len))
-           {
-             GdkColor *color = NULL;
-
-             gtk_widget_style_get (widget,
-                                   "odd-row-color", &color,
-                                   NULL);
-
-             if (color)
-               {
-                 freeme = get_darkened (color, 0);
-                 gc1 = freeme;
-
-                 gdk_color_free (color);
-               }
-             else
-               {
-                 gtk_widget_style_get (widget,
-                                       "even-row-color", &color,
-                                       NULL);
-
-                 if (color)
-                   {
-                     freeme = get_darkened (color, 1);
-                     gdk_color_free (color);
-                   }
-                 else
-                   freeme = get_darkened (&style->base[state_type], 1);
-                 gc1 = freeme;
-               }
-           }
-          else if (!strncmp ("cell_even_sorted", detail, trimmed_len) ||
-                   !strncmp ("cell_odd_sorted", detail, trimmed_len) ||
-                   !strncmp ("cell_even_ruled_sorted", detail, trimmed_len))
-            {
-             GdkColor *color = NULL;
-
-             if (!strncmp ("cell_odd_sorted", detail, trimmed_len))
-               gtk_widget_style_get (widget,
-                                     "odd-row-color", &color,
-                                     NULL);
-             else
-               gtk_widget_style_get (widget,
-                                     "even-row-color", &color,
-                                     NULL);
-
-             if (color)
-               {
-                 freeme = get_darkened (color, 1);
-                 gc1 = freeme;
-
-                 gdk_color_free (color);
-               }
-             else
-               {
-                 freeme = get_darkened (&style->base[state_type], 1);
-                  gc1 = freeme;
-               }
-            }
-          else if (!strncmp ("cell_odd_ruled_sorted", detail, trimmed_len))
-            {
-             GdkColor *color = NULL;
-
-             gtk_widget_style_get (widget,
-                                   "odd-row-color", &color,
-                                   NULL);
-
-             if (color)
-               {
-                 freeme = get_darkened (color, 1);
-                 gc1 = freeme;
-
-                 gdk_color_free (color);
-               }
-             else
-               {
-                 gtk_widget_style_get (widget,
-                                       "even-row-color", &color,
-                                       NULL);
-
-                 if (color)
-                   {
-                     freeme = get_darkened (color, 2);
-                     gdk_color_free (color);
-                   }
-                 else
-                    freeme = get_darkened (&style->base[state_type], 2);
-                  gc1 = freeme;
-               }
-            }
-          else
-            gc1 = &style->bg[state_type];
-        }
-    }
-  else
-    gc1 = &style->bg[state_type];
-  
-  if (background_is_solid (style, state_type) || gc1 != &style->bg[state_type])
-    {
-      _cairo_draw_rectangle (cr, gc1, TRUE,
-                             x, y, width, height);
+  cairo_save (cr);
 
-      if (detail && !strcmp ("tooltip", detail))
-        _cairo_draw_rectangle (cr, &style->black, FALSE,
-                               x, y, width - 1, height - 1);
-    }
-  else
-    gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
-                                        state_type, x, y, width, height);
+  gtk_render_background (context, cr,
+                         (gdouble) x,
+                         (gdouble) y,
+                         (gdouble) width,
+                         (gdouble) height);
 
-  if (freeme)
-    gdk_color_free (freeme);
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -2773,107 +2110,53 @@ gtk_default_draw_check (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  enum { BUTTON, MENU, CELL } type = BUTTON;
-  int exterior_size;
-  int interior_size;
-  int pad;
-  
-  if (detail)
-    {
-      if (strcmp (detail, "cellcheck") == 0)
-       type = CELL;
-      else if (strcmp (detail, "check") == 0)
-       type = MENU;
-    }
-      
-  exterior_size = MIN (width, height);
-  if (exterior_size % 2 == 0) /* Ensure odd */
-    exterior_size -= 1;
-
-  pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
-  interior_size = MAX (1, exterior_size - 2 * pad);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-  if (interior_size < 7)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      interior_size = 7;
-      pad = MAX (0, (exterior_size - interior_size) / 2);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
 
-  x -= (1 + exterior_size - width) / 2;
-  y -= (1 + exterior_size - height) / 2;
+  gtk_style_context_save (context);
 
-  switch (type)
-    {
-    case BUTTON:
-    case CELL:
-      if (type == BUTTON)
-       gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-      else
-       gdk_cairo_set_source_color (cr, &style->text[state_type]);
-       
-      cairo_set_line_width (cr, 1.0);
-      cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
-      cairo_stroke (cr);
+  if (detail)
+    transform_detail_string (detail, context);
 
-      gdk_cairo_set_source_color (cr, &style->base[state_type]);
-      cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
-      cairo_fill (cr);
+  switch (state_type)
+    {
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
       break;
-
-    case MENU:
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
       break;
-    }
-      
-  switch (type)
-    {
-    case BUTTON:
-    case CELL:
-      gdk_cairo_set_source_color (cr, &style->text[state_type]);
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
       break;
-    case MENU:
-      gdk_cairo_set_source_color (cr, &style->fg[state_type]);
+    default:
       break;
     }
 
   if (shadow_type == GTK_SHADOW_IN)
-    {
-      cairo_translate (cr,
-                      x + pad, y + pad);
-      
-      cairo_scale (cr, interior_size / 7., interior_size / 7.);
-      
-      cairo_move_to  (cr, 7.0, 0.0);
-      cairo_line_to  (cr, 7.5, 1.0);
-      cairo_curve_to (cr, 5.3, 2.0,
-                     4.3, 4.0,
-                     3.5, 7.0);
-      cairo_curve_to (cr, 3.0, 5.7,
-                     1.3, 4.7,
-                     0.0, 4.7);
-      cairo_line_to  (cr, 0.2, 3.5);
-      cairo_curve_to (cr, 1.1, 3.5,
-                     2.3, 4.3,
-                     3.0, 5.0);
-      cairo_curve_to (cr, 1.0, 3.9,
-                     2.4, 4.1,
-                     3.2, 4.9);
-      cairo_curve_to (cr, 3.5, 3.1,
-                     5.2, 2.0,
-                     7.0, 0.0);
-      
-      cairo_fill (cr);
-    }
-  else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
-    {
-      int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
-
-      cairo_rectangle (cr,
-                      x + pad,
-                      y + pad + (1 + interior_size - line_thickness) / 2,
-                      interior_size,
-                      line_thickness);
-      cairo_fill (cr);
-    }
+    flags |= GTK_STATE_FLAG_ACTIVE;
+  else if (shadow_type == GTK_SHADOW_ETCHED_IN)
+    flags |= GTK_STATE_FLAG_INCONSISTENT;
+
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
+
+  gtk_render_check (context,
+                    cr, x, y,
+                    width, height);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -2888,102 +2171,54 @@ gtk_default_draw_option (GtkStyle      *style,
                         gint           width,
                         gint           height)
 {
-  enum { BUTTON, MENU, CELL } type = BUTTON;
-  int exterior_size;
-  
-  if (detail)
-    {
-      if (strcmp (detail, "radio") == 0)
-       type = CELL;
-      else if (strcmp (detail, "option") == 0)
-       type = MENU;
-    }
-      
-  exterior_size = MIN (width, height);
-  if (exterior_size % 2 == 0) /* Ensure odd */
-    exterior_size -= 1;
-  
-  x -= (1 + exterior_size - width) / 2;
-  y -= (1 + exterior_size - height) / 2;
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-  switch (type)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-    case BUTTON:
-    case CELL:
-      gdk_cairo_set_source_color (cr, &style->base[state_type]);
-      
-      cairo_arc (cr,
-                x + exterior_size / 2.,
-                y + exterior_size / 2.,
-                (exterior_size - 1) / 2.,
-                0, 2 * G_PI);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
+    }
 
-      cairo_fill_preserve (cr);
+  gtk_style_context_save (context);
 
-      if (type == BUTTON)
-       gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-      else
-       gdk_cairo_set_source_color (cr, &style->text[state_type]);
-       
-      cairo_set_line_width (cr, 1.);
-      cairo_stroke (cr);
-      break;
+  if (detail)
+    transform_detail_string (detail, context);
 
-    case MENU:
-      break;
-    }
-      
-  switch (type)
+  switch (state_type)
     {
-    case BUTTON:
-      gdk_cairo_set_source_color (cr, &style->text[state_type]);
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
       break;
-    case CELL:
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
       break;
-    case MENU:
-      gdk_cairo_set_source_color (cr, &style->fg[state_type]);
+    default:
       break;
     }
 
   if (shadow_type == GTK_SHADOW_IN)
-    {
-      int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
-      int interior_size = MAX (1, exterior_size - 2 * pad);
-
-      if (interior_size < 5)
-       {
-         interior_size = 7;
-         pad = MAX (0, (exterior_size - interior_size) / 2);
-       }
-
-      cairo_arc (cr,
-                x + pad + interior_size / 2.,
-                y + pad + interior_size / 2.,
-                interior_size / 2.,
-                0, 2 * G_PI);
-      cairo_fill (cr);
-    }
-  else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
-    {
-      int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
-      int interior_size = MAX (1, exterior_size - 2 * pad);
-      int line_thickness;
-
-      if (interior_size < 7)
-       {
-         interior_size = 7;
-         pad = MAX (0, (exterior_size - interior_size) / 2);
-       }
-
-      line_thickness = MAX (1, (3 + interior_size * 2) / 7);
-
-      cairo_rectangle (cr,
-                      x + pad,
-                      y + pad + (interior_size - line_thickness) / 2.,
-                      interior_size,
-                      line_thickness);
-      cairo_fill (cr);
-    }
+    flags |= GTK_STATE_FLAG_ACTIVE;
+  else if (shadow_type == GTK_SHADOW_ETCHED_IN)
+    flags |= GTK_STATE_FLAG_INCONSISTENT;
+
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
+  gtk_render_option (context, cr,
+                     (gdouble) x,
+                     (gdouble) y,
+                     (gdouble) width,
+                     (gdouble) height);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -3048,185 +2283,58 @@ gtk_default_draw_shadow_gap (GtkStyle       *style,
                              gint            gap_x,
                              gint            gap_width)
 {
-  GdkColor *color1 = NULL;
-  GdkColor *color2 = NULL;
-  GdkColor *color3 = NULL;
-  GdkColor *color4 = NULL;
-  
-  switch (shadow_type)
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+
+  if (shadow_type == GTK_SHADOW_NONE)
+    return;
+
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-    case GTK_SHADOW_NONE:
-    default:
-      return;
-    case GTK_SHADOW_IN:
-      color1 = &style->dark[state_type];
-      color2 = &style->black;
-      color3 = &style->bg[state_type];
-      color4 = &style->light[state_type];
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
+    }
+
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state_type)
+    {
+    case GTK_STATE_ACTIVE:
+      flags |= GTK_STATE_FLAG_ACTIVE;
       break;
-    case GTK_SHADOW_ETCHED_IN:
-      color1 = &style->dark[state_type];
-      color2 = &style->light[state_type];
-      color3 = &style->dark[state_type];
-      color4 = &style->light[state_type];
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
       break;
-    case GTK_SHADOW_OUT:
-      color1 = &style->light[state_type];
-      color2 = &style->bg[state_type];
-      color3 = &style->dark[state_type];
-      color4 = &style->black;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
       break;
-    case GTK_SHADOW_ETCHED_OUT:
-      color1 = &style->light[state_type];
-      color2 = &style->dark[state_type];
-      color3 = &style->light[state_type];
-      color4 = &style->dark[state_type];
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
       break;
     }
 
-  switch (shadow_type)
-    {
-    case GTK_SHADOW_NONE:
-    case GTK_SHADOW_IN:
-    case GTK_SHADOW_OUT:
-    case GTK_SHADOW_ETCHED_IN:
-    case GTK_SHADOW_ETCHED_OUT:
-      switch (gap_side)
-        {
-        case GTK_POS_TOP:
-          _cairo_draw_line (cr, color1,
-                            x, y, x, y + height - 1);
-          _cairo_draw_line (cr, color2,
-                            x + 1, y, x + 1, y + height - 2);
-          
-          _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)
-            {
-              _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)
-            {
-              _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:
-          _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);
-          
-          _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)
-            {
-              _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)
-            {
-              _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:
-          _cairo_draw_line (cr, color1,
-                            x, y, x + width - 1, y);
-          _cairo_draw_line (cr, color2,
-                            x, y + 1, x + width - 2, y + 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)
-            {
-              _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)
-            {
-              _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:
-          _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);
-          
-          _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)
-            {
-              _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)
-            {
-              _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;
-        }
-    }
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
+  gtk_render_frame_gap (context, cr,
+                        (gdouble) x,
+                        (gdouble) y,
+                        (gdouble) width,
+                        (gdouble) height,
+                        gap_side,
+                        (gdouble) gap_x,
+                        (gdouble) gap_x + gap_width);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -3244,189 +2352,63 @@ gtk_default_draw_box_gap (GtkStyle       *style,
                           gint            gap_x,
                           gint            gap_width)
 {
-  GdkColor color1;
-  GdkColor color2;
-  GdkColor color3;
-  GdkColor color4;
-  
-  gtk_style_apply_default_background (style, cr, gtk_widget_get_window (widget),
-                                      state_type, x, y, width, height);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-  switch (shadow_type)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-    case GTK_SHADOW_NONE:
-      return;
-    case GTK_SHADOW_IN:
-      color1 = style->dark[state_type];
-      color2 = style->black;
-      color3 = style->bg[state_type];
-      color4 = style->light[state_type];
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
+    }
+
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state_type)
+    {
+    case GTK_STATE_ACTIVE:
+      flags |= GTK_STATE_FLAG_ACTIVE;
       break;
-    case GTK_SHADOW_ETCHED_IN:
-      color1 = style->dark[state_type];
-      color2 = style->light[state_type];
-      color3 = style->dark[state_type];
-      color4 = style->light[state_type];
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
       break;
-    case GTK_SHADOW_OUT:
-      color1 = style->light[state_type];
-      color2 = style->bg[state_type];
-      color3 = style->dark[state_type];
-      color4 = style->black;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
       break;
-    case GTK_SHADOW_ETCHED_OUT:
-      color1 = style->light[state_type];
-      color2 = style->dark[state_type];
-      color3 = style->light[state_type];
-      color4 = style->dark[state_type];
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
       break;
     }
-  
-  cairo_set_line_width (cr, 1.0);
 
-  switch (shadow_type)
-    {
-    case GTK_SHADOW_NONE:
-    case GTK_SHADOW_IN:
-    case GTK_SHADOW_OUT:
-    case GTK_SHADOW_ETCHED_IN:
-    case GTK_SHADOW_ETCHED_OUT:
-      switch (gap_side)
-        {
-        case GTK_POS_TOP:
-          _cairo_draw_line (cr, &color1,
-                            x, y, x, y + height - 1);
-          _cairo_draw_line (cr, &color2,
-                            x + 1, y, x + 1, y + height - 2);
-          
-          _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)
-            {
-              _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)
-            {
-              _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:
-          _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);
-          
-          _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)
-            {
-              _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)
-            {
-              _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:
-          _cairo_draw_line (cr, &color1,
-                            x, y, x + width - 1, y);
-          _cairo_draw_line (cr, &color2,
-                            x, y + 1, x + width - 2, y + 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)
-            {
-              _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)
-            {
-              _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:
-          _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);
-          
-          _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)
-            {
-              _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)
-            {
-              _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;
-        }
-    }
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
+  gtk_render_background (context, cr,
+                         (gdouble) x,
+                         (gdouble) y,
+                         (gdouble) width,
+                         (gdouble) height);
+
+
+  if (shadow_type != GTK_SHADOW_NONE)
+    gtk_render_frame_gap (context, cr,
+                         (gdouble) x,
+                         (gdouble) y,
+                         (gdouble) width,
+                         (gdouble) height,
+                         gap_side,
+                         (gdouble) gap_x,
+                         (gdouble) gap_x + gap_width);
+  
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -3442,151 +2424,54 @@ gtk_default_draw_extension (GtkStyle       *style,
                             gint            height,
                             GtkPositionType gap_side)
 {
-  GdkWindow *window = gtk_widget_get_window (widget);
-  GdkColor color1;
-  GdkColor color2;
-  GdkColor color3;
-  GdkColor color4;
-  
-  switch (gap_side)
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-    case GTK_POS_TOP:
-      gtk_style_apply_default_background (style, cr, window,
-                                          state_type,
-                                          x + 1,
-                                          y,
-                                          width - 2,
-                                          height - 1);
-      break;
-    case GTK_POS_BOTTOM:
-      gtk_style_apply_default_background (style, cr, window,
-                                          state_type,
-                                          x + 1,
-                                          y + 1,
-                                          width - 2,
-                                          height - 1);
-      break;
-    case GTK_POS_LEFT:
-      gtk_style_apply_default_background (style, cr, window,
-                                          state_type,
-                                          x,
-                                          y + 1,
-                                          width - 1,
-                                          height - 2);
-      break;
-    case GTK_POS_RIGHT:
-      gtk_style_apply_default_background (style, cr, window,
-                                          state_type,
-                                          x + 1,
-                                          y + 1,
-                                          width - 1,
-                                          height - 2);
-      break;
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
 
-  switch (shadow_type)
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state_type)
     {
-    case GTK_SHADOW_NONE:
-      return;
-    case GTK_SHADOW_IN:
-      color1 = style->dark[state_type];
-      color2 = style->black;
-      color3 = style->bg[state_type];
-      color4 = style->light[state_type];
+    case GTK_STATE_ACTIVE:
+      flags |= GTK_STATE_FLAG_ACTIVE;
       break;
-    case GTK_SHADOW_ETCHED_IN:
-      color1 = style->dark[state_type];
-      color2 = style->light[state_type];
-      color3 = style->dark[state_type];
-      color4 = style->light[state_type];
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
       break;
-    case GTK_SHADOW_OUT:
-      color1 = style->light[state_type];
-      color2 = style->bg[state_type];
-      color3 = style->dark[state_type];
-      color4 = style->black;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
       break;
-    case GTK_SHADOW_ETCHED_OUT:
-      color1 = style->light[state_type];
-      color2 = style->dark[state_type];
-      color3 = style->light[state_type];
-      color4 = style->dark[state_type];
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
       break;
     }
 
-  cairo_set_line_width (cr, 1.0);
+  gtk_style_context_set_state (context, flags);
 
-  switch (shadow_type)
-    {
-    case GTK_SHADOW_NONE:
-    case GTK_SHADOW_IN:
-    case GTK_SHADOW_OUT:
-    case GTK_SHADOW_ETCHED_IN:
-    case GTK_SHADOW_ETCHED_OUT:
-      switch (gap_side)
-        {
-        case GTK_POS_TOP:
-          _cairo_draw_line (cr, &color1,
-                            x, y, x, y + height - 2);
-          _cairo_draw_line (cr, &color2,
-                            x + 1, y, x + 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:
-          _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);
-          
-          _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:
-          _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);
-          
-          _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:
-          _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);
-          
-          _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;
-        }
-    }
+  cairo_save (cr);
+
+  gtk_render_extension (context, cr,
+                        (gdouble) x,
+                        (gdouble) y,
+                        (gdouble) width,
+                        (gdouble) height,
+                        gap_side);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -3600,74 +2485,32 @@ gtk_default_draw_focus (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  gboolean free_dash_list = FALSE;
-  gint line_width = 1;
-  gint8 *dash_list = (gint8 *) "\1\1";
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
 
   if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      gtk_widget_style_get (widget,
-                           "focus-line-width", &line_width,
-                           "focus-line-pattern", (gchar *)&dash_list,
-                           NULL);
-
-      free_dash_list = TRUE;
-  }
-
-  if (detail && !strcmp (detail, "add-mode"))
-    {
-      if (free_dash_list)
-       g_free (dash_list);
-
-      dash_list = (gint8 *) "\4\4";
-      free_dash_list = FALSE;
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
 
-  if (detail && !strcmp (detail, "colorwheel_light"))
-    cairo_set_source_rgb (cr, 0., 0., 0.);
-  else if (detail && !strcmp (detail, "colorwheel_dark"))
-    cairo_set_source_rgb (cr, 1., 1., 1.);
-  else
-    gdk_cairo_set_source_color (cr, &style->fg[state_type]);
+  gtk_style_context_save (context);
 
-  cairo_set_line_width (cr, line_width);
+  if (detail)
+    transform_detail_string (detail, context);
 
-  if (dash_list[0])
-    {
-      gint n_dashes = strlen ((const gchar *) dash_list);
-      gdouble *dashes = g_new (gdouble, n_dashes);
-      gdouble total_length = 0;
-      gdouble dash_offset;
-      gint i;
-
-      for (i = 0; i < n_dashes; i++)
-       {
-         dashes[i] = dash_list[i];
-         total_length += dash_list[i];
-       }
-
-      /* The dash offset here aligns the pattern to integer pixels
-       * by starting the dash at the right side of the left border
-       * Negative dash offsets in cairo don't work
-       * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
-       */
-      dash_offset = - line_width / 2.;
-      while (dash_offset < 0)
-       dash_offset += total_length;
-      
-      cairo_set_dash (cr, dashes, n_dashes, dash_offset);
-      g_free (dashes);
-    }
+  cairo_save (cr);
 
-  cairo_rectangle (cr,
-                  x + line_width / 2.,
-                  y + line_width / 2.,
-                  width - line_width,
-                  height - line_width);
-  cairo_stroke (cr);
+  gtk_render_focus (context, cr,
+                    (gdouble) x,
+                    (gdouble) y,
+                    (gdouble) width,
+                    (gdouble) height);
 
-  if (free_dash_list)
-    g_free (dash_list);
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -3683,48 +2526,46 @@ gtk_default_draw_slider (GtkStyle      *style,
                          gint           height,
                          GtkOrientation orientation)
 {
-  gtk_cairo_paint_box (style, cr, state_type, shadow_type,
-                       widget, detail, x, y, width, height);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-  if (detail &&
-      (strcmp ("hscale", detail) == 0 ||
-       strcmp ("vscale", detail) == 0))
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      if (orientation == GTK_ORIENTATION_HORIZONTAL)
-        gtk_cairo_paint_vline (style, cr, state_type, widget, detail, 
-                               y + style->ythickness, 
-                               y + height - style->ythickness - 1, x + width / 2);
-      else
-        gtk_cairo_paint_hline (style, cr, state_type, widget, detail, 
-                               x + style->xthickness, 
-                               x + width - style->xthickness - 1, y + height / 2);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
-}
 
-static void
-draw_dot (cairo_t    *cr,
-         GdkColor   *light,
-         GdkColor   *dark,
-         gint        x,
-         gint        y,
-         gushort     size)
-{
-  size = CLAMP (size, 2, 3);
+  gtk_style_context_save (context);
 
-  if (size == 2)
-    {
-      _cairo_draw_point (cr, light, x, y);
-      _cairo_draw_point (cr, light, x+1, y+1);
-    }
-  else if (size == 3)
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state_type)
     {
-      _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);
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      break;
     }
+
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
+
+  gtk_render_slider (context, cr,  x, y, width, height, orientation);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void 
@@ -3740,58 +2581,50 @@ gtk_default_draw_handle (GtkStyle      *style,
                         gint           height,
                         GtkOrientation orientation)
 {
-  gint xx, yy;
-  gint xthick, ythick;
-  GdkColor light, dark;
-  
-  gtk_cairo_paint_box (style, cr, state_type, shadow_type, widget, 
-                       detail, x, y, width, height);
-  
-  if (detail && !strcmp (detail, "paned"))
-    {
-      /* we want to ignore the shadow border in paned widgets */
-      xthick = 0;
-      ythick = 0;
-
-      if (state_type == GTK_STATE_SELECTED && widget && !gtk_widget_has_focus (widget))
-         _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &light,
-                            LIGHTNESS_MULT);
-      else
-       light = style->light[state_type];
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-      dark = style->black;
-    }
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
   else
     {
-      xthick = style->xthickness;
-      ythick = style->ythickness;
-
-      light = style->light[state_type];
-      dark = style->dark[state_type];
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
-  
-  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 (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 (cr, &light, &dark, x + width/2 - 1, yy, 3);
-    }
-  else
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state_type)
     {
-      for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
-       for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
-         {
-           draw_dot (cr, &light, &dark, xx, yy, 2);
-           draw_dot (cr, &light, &dark, xx + 3, yy + 1, 2);
-         }
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      break;
     }
+
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
+
+  gtk_render_handle (context, cr,
+                     (gdouble) x,
+                     (gdouble) y,
+                     (gdouble) width,
+                     (gdouble) height);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -3804,117 +2637,63 @@ gtk_default_draw_expander (GtkStyle        *style,
                            gint             y,
                           GtkExpanderStyle expander_style)
 {
-#define DEFAULT_EXPANDER_SIZE 12
-
-  gint expander_size;
-  gint line_width;
-  double vertical_overshoot;
-  int diameter;
-  double radius;
-  double interp;               /* interpolation factor for center position */
-  double x_double_horz, y_double_horz;
-  double x_double_vert, y_double_vert;
-  double x_double, y_double;
-  gint degrees = 0;
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+  gint size;
 
-  if (widget &&
-      gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
-                                           "expander-size"))
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      gtk_widget_style_get (widget,
-                           "expander-size", &expander_size,
-                           NULL);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
-  else
-    expander_size = DEFAULT_EXPANDER_SIZE;
-    
-  line_width = MAX (1, expander_size/9);
 
-  switch (expander_style)
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  gtk_style_context_add_class (context, "expander");
+
+  switch (state_type)
     {
-    case GTK_EXPANDER_COLLAPSED:
-      degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
-      interp = 0.0;
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
       break;
-    case GTK_EXPANDER_SEMI_COLLAPSED:
-      degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
-      interp = 0.25;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
       break;
-    case GTK_EXPANDER_SEMI_EXPANDED:
-      degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
-      interp = 0.75;
-      break;
-    case GTK_EXPANDER_EXPANDED:
-      degrees = 90;
-      interp = 1.0;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
       break;
     default:
-      g_assert_not_reached ();
+      break;
     }
 
-  /* Compute distance that the stroke extends beyonds the end
-   * of the triangle we draw.
-   */
-  vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
-
-  /* For odd line widths, we end the vertical line of the triangle
-   * at a half pixel, so we round differently.
-   */
-  if (line_width % 2 == 1)
-    vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
+  if (widget &&
+      gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
+                                            "expander-size"))
+    gtk_widget_style_get (widget, "expander-size", &size, NULL);
   else
-    vertical_overshoot = ceil (vertical_overshoot);
+    size = 12;
 
-  /* Adjust the size of the triangle we draw so that the entire stroke fits
-   */
-  diameter = MAX (3, expander_size - 2 * vertical_overshoot);
-
-  /* If the line width is odd, we want the diameter to be even,
-   * and vice versa, so force the sum to be odd. This relationship
-   * makes the point of the triangle look right.
-   */
-  diameter -= (1 - (diameter + line_width) % 2);
-  
-  radius = diameter / 2.;
+  if (expander_style == GTK_EXPANDER_EXPANDED)
+    flags |= GTK_STATE_FLAG_ACTIVE;
 
-  /* Adjust the center so that the stroke is properly aligned with
-   * the pixel grid. The center adjustment is different for the
-   * horizontal and vertical orientations. For intermediate positions
-   * we interpolate between the two.
-   */
-  x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
-  y_double_vert = y - 0.5;
+  gtk_style_context_set_state (context, flags);
 
-  x_double_horz = x - 0.5;
-  y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
+  cairo_save (cr);
 
-  x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
-  y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
-  
-  cairo_translate (cr, x_double, y_double);
-  cairo_rotate (cr, degrees * G_PI / 180);
+  gtk_render_expander (context, cr,
+                       (gdouble) x - (size / 2),
+                       (gdouble) y - (size / 2),
+                       (gdouble) size,
+                       (gdouble) size);
 
-  cairo_move_to (cr, - radius / 2., - radius);
-  cairo_line_to (cr,   radius / 2.,   0);
-  cairo_line_to (cr, - radius / 2.,   radius);
-  cairo_close_path (cr);
-  
-  cairo_set_line_width (cr, line_width);
-
-  if (state_type == GTK_STATE_PRELIGHT)
-    gdk_cairo_set_source_color (cr,
-                               &style->fg[GTK_STATE_PRELIGHT]);
-  else if (state_type == GTK_STATE_ACTIVE)
-    gdk_cairo_set_source_color (cr,
-                               &style->light[GTK_STATE_ACTIVE]);
-  else
-    gdk_cairo_set_source_color (cr,
-                               &style->base[GTK_STATE_NORMAL]);
-  
-  cairo_fill_preserve (cr);
-  
-  gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-  cairo_stroke (cr);
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -3928,49 +2707,49 @@ gtk_default_draw_layout (GtkStyle        *style,
                          gint             y,
                          PangoLayout     *layout)
 {
-  GdkColor *gc;
-  const PangoMatrix *matrix;
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
 
-  matrix = pango_context_get_matrix (pango_layout_get_context (layout));
-  if (matrix)
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      cairo_matrix_t cairo_matrix;
-      PangoMatrix tmp_matrix;
-      PangoRectangle rect;
-      
-      cairo_matrix_init (&cairo_matrix,
-                         matrix->xx, matrix->yx,
-                         matrix->xy, matrix->yy,
-                         matrix->x0, matrix->y0);
-
-      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);
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
-  else
-    cairo_translate (cr, x, y);
 
-  cairo_new_path (cr);
+  gtk_style_context_save (context);
 
-  if (state_type == GTK_STATE_INSENSITIVE)
+  if (detail)
+    transform_detail_string (detail, context);
+
+  switch (state_type)
     {
-      gdk_cairo_set_source_color (cr, &style->white);
-      cairo_move_to (cr, 1, 1);
-      _gtk_pango_fill_layout (cr, layout);
-      cairo_new_path (cr);
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      break;
     }
 
-  gc = use_text ? &style->text[state_type] : &style->fg[state_type];
+  gtk_style_context_set_state (context, flags);
+
+  cairo_save (cr);
 
-  gdk_cairo_set_source_color (cr, gc);
+  gtk_render_layout (context, cr,
+                     (gdouble) x,
+                     (gdouble) y,
+                     layout);
 
-  pango_cairo_show_layout (cr, layout);
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -3985,284 +2764,83 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
                               gint            width,
                               gint            height)
 {
-  gint skip;
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GtkStateFlags flags = 0;
+  GtkJunctionSides sides = 0;
 
-  cairo_rectangle (cr, x, y, width, height);
-  cairo_clip (cr);
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
+    {
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
+    }
+
+  gtk_style_context_save (context);
 
-  cairo_set_line_width (cr, 1.0);
+  if (detail)
+    transform_detail_string (detail, context);
+
+  gtk_style_context_add_class (context, "grip");
+
+  switch (state_type)
+    {
+    case GTK_STATE_PRELIGHT:
+      flags |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      flags |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      flags |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    default:
+      break;
+    }
+
+  gtk_style_context_set_state (context, flags);
 
-  skip = -1;
   switch (edge)
     {
     case GDK_WINDOW_EDGE_NORTH_WEST:
-      /* make it square */
-      if (width < height)
-       height = width;
-      else if (height < width)
-       width = height;
-      skip = 2;
+      sides = GTK_JUNCTION_CORNER_TOPLEFT;
       break;
     case GDK_WINDOW_EDGE_NORTH:
-      if (width < height)
-       height = width;
+      sides = GTK_JUNCTION_TOP;
       break;
     case GDK_WINDOW_EDGE_NORTH_EAST:
-      /* make it square, aligning to top right */
-      if (width < height)
-       height = width;
-      else if (height < width)
-       {
-         x += (width - height);
-         width = height;
-       }
-      skip = 3;
+      sides = GTK_JUNCTION_CORNER_TOPRIGHT;
       break;
     case GDK_WINDOW_EDGE_WEST:
-      if (height < width)
-       width = height;
+      sides = GTK_JUNCTION_LEFT;
       break;
     case GDK_WINDOW_EDGE_EAST:
-      /* aligning to right */
-      if (height < width)
-       {
-         x += (width - height);
-         width = height;
-       }
+      sides = GTK_JUNCTION_RIGHT;
       break;
     case GDK_WINDOW_EDGE_SOUTH_WEST:
-      /* make it square, aligning to bottom left */
-      if (width < height)
-       {
-         y += (height - width);
-         height = width;
-       }
-      else if (height < width)
-       width = height;
-      skip = 1;
-      break;
-    case GDK_WINDOW_EDGE_SOUTH:
-      /* align to bottom */
-      if (width < height)
-       {
-         y += (height - width);
-         height = width;
-       }
-      break;
-    case GDK_WINDOW_EDGE_SOUTH_EAST:
-      /* make it square, aligning to bottom right */
-      if (width < height)
-       {
-         y += (height - width);
-         height = width;
-       }
-      else if (height < width)
-       {
-         x += (width - height);
-         width = height;
-       }
-      skip = 0;
-      break;
-    default:
-      g_assert_not_reached ();
-    }
-  
-  switch (edge)
-    {
-    case GDK_WINDOW_EDGE_WEST:
-    case GDK_WINDOW_EDGE_EAST:
-      {
-       gint xi;
-
-       xi = x;
-
-       while (xi < x + width)
-         {
-           _cairo_draw_line (cr,
-                             &style->light[state_type],
-                             xi, y,
-                             xi, y + height);
-
-           xi++;
-           _cairo_draw_line (cr,
-                             &style->dark[state_type],
-                             xi, y,
-                             xi, y + height);
-
-           xi += 2;
-         }
-      }
+      sides = GTK_JUNCTION_CORNER_BOTTOMLEFT;
       break;
-    case GDK_WINDOW_EDGE_NORTH:
     case GDK_WINDOW_EDGE_SOUTH:
-      {
-       gint yi;
-
-       yi = y;
-
-       while (yi < y + height)
-         {
-           _cairo_draw_line (cr,
-                             &style->light[state_type],
-                             x, yi,
-                             x + width, yi);
-
-           yi++;
-           _cairo_draw_line (cr,
-                             &style->dark[state_type],
-                             x, yi,
-                             x + width, yi);
-
-           yi+= 2;
-         }
-      }
-      break;
-    case GDK_WINDOW_EDGE_NORTH_WEST:
-      {
-       gint xi, yi;
-
-       xi = x + width;
-       yi = y + height;
-
-       while (xi > x + 3)
-         {
-           _cairo_draw_line (cr,
-                             &style->dark[state_type],
-                             xi, y,
-                             x, yi);
-
-           --xi;
-           --yi;
-
-           _cairo_draw_line (cr,
-                             &style->dark[state_type],
-                             xi, y,
-                             x, yi);
-
-           --xi;
-           --yi;
-
-           _cairo_draw_line (cr,
-                             &style->light[state_type],
-                             xi, y,
-                             x, yi);
-
-           xi -= 3;
-           yi -= 3;
-           
-         }
-      }
-      break;
-    case GDK_WINDOW_EDGE_NORTH_EAST:
-      {
-        gint xi, yi;
-
-        xi = x;
-        yi = y + height;
-
-        while (xi < (x + width - 3))
-          {
-            _cairo_draw_line (cr,
-                              &style->light[state_type],
-                              xi, y,
-                              x + width, yi);                           
-
-            ++xi;
-            --yi;
-            
-            _cairo_draw_line (cr,
-                              &style->dark[state_type],
-                              xi, y,
-                              x + width, yi);                           
-
-            ++xi;
-            --yi;
-            
-            _cairo_draw_line (cr,
-                              &style->dark[state_type],
-                              xi, y,
-                              x + width, yi);
-
-            xi += 3;
-            yi -= 3;
-          }
-      }
-      break;
-    case GDK_WINDOW_EDGE_SOUTH_WEST:
-      {
-       gint xi, yi;
-
-       xi = x + width;
-       yi = y;
-
-       while (xi > x + 3)
-         {
-           _cairo_draw_line (cr,
-                             &style->dark[state_type],
-                             x, yi,
-                             xi, y + height);
-
-           --xi;
-           ++yi;
-
-           _cairo_draw_line (cr,
-                             &style->dark[state_type],
-                             x, yi,
-                             xi, y + height);
-
-           --xi;
-           ++yi;
-
-           _cairo_draw_line (cr,
-                             &style->light[state_type],
-                             x, yi,
-                             xi, y + height);
-
-           xi -= 3;
-           yi += 3;
-           
-         }
-      }
+      sides = GTK_JUNCTION_BOTTOM;
       break;
     case GDK_WINDOW_EDGE_SOUTH_EAST:
-      {
-        gint xi, yi;
-
-        xi = x;
-        yi = y;
-
-        while (xi < (x + width - 3))
-          {
-            _cairo_draw_line (cr,
-                              &style->light[state_type],
-                              xi, y + height,
-                              x + width, yi);                           
-
-            ++xi;
-            ++yi;
-            
-            _cairo_draw_line (cr,
-                              &style->dark[state_type],
-                              xi, y + height,
-                              x + width, yi);                           
-
-            ++xi;
-            ++yi;
-            
-            _cairo_draw_line (cr,
-                              &style->dark[state_type],
-                              xi, y + height,
-                              x + width, yi);
-
-            xi += 3;
-            yi += 3;
-          }
-      }
-      break;
-    default:
-      g_assert_not_reached ();
+      sides = GTK_JUNCTION_CORNER_BOTTOMRIGHT;
       break;
     }
+
+  gtk_style_context_set_junction_sides (context, sides);
+
+  cairo_save (cr);
+
+  gtk_render_handle (context, cr,
+                     (gdouble) x,
+                     (gdouble) y,
+                     (gdouble) width,
+                     (gdouble) height);
+
+  cairo_restore (cr);
+  gtk_style_context_restore (context);
 }
 
 static void
@@ -4285,9 +2863,7 @@ gtk_default_draw_spinner (GtkStyle     *style,
   gint i;
   guint real_step;
 
-  gtk_style_get (style, GTK_TYPE_SPINNER,
-                 "num-steps", &num_steps,
-                 NULL);
+  num_steps = 12;
   real_step = step % num_steps;
 
   /* set a clip region for the expose event */
@@ -4519,86 +3095,31 @@ hls_to_rgb (gdouble *h,
 }
 
 
-static cairo_t *
-gtk_style_cairo_create (GdkWindow *window, const GdkRectangle *area)
-{
-  cairo_t *cr;
-
-  cr = gdk_cairo_create (window);
-
-  if (area)
-    {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
-    }
-
-  return cr;
-}
-
 /**
  * gtk_paint_hline:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #caio_t
  * @state_type: a state
- * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
- *        output should not be clipped
  * @widget: (allow-none): the widget
  * @detail: (allow-none): a style detail
  * @x1: the starting x coordinate
  * @x2: the ending x coordinate
  * @y: the y coordinate
  *
- * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
+ * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
  * using the given style and state.
- **/ 
-void 
+ *
+ * Deprecated:3.0: Use gtk_render_line() instead
+ **/
+void
 gtk_paint_hline (GtkStyle           *style,
-                 GdkWindow          *window,
+                 cairo_t            *cr,
                  GtkStateType        state_type,
-                 const GdkRectangle *area,
                  GtkWidget          *widget,
                  const gchar        *detail,
                  gint                x1,
                  gint                x2,
                  gint                y)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_hline (style, cr, state_type,
-                         widget, detail,
-                         x1, x2, y);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_hline:
- * @style: a #GtkStyle
- * @cr: a #caio_t
- * @state_type: a state
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x1: the starting x coordinate
- * @x2: the ending x coordinate
- * @y: the y coordinate
- *
- * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
- * using the given style and state.
- **/ 
-void 
-gtk_cairo_paint_hline (GtkStyle           *style,
-                       cairo_t            *cr,
-                       GtkStateType        state_type,
-                       GtkWidget          *widget,
-                       const gchar        *detail,
-                       gint                x1,
-                       gint                x2,
-                       gint                y)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (cr != NULL);
@@ -4606,56 +3127,15 @@ gtk_cairo_paint_hline (GtkStyle           *style,
 
   cairo_save (cr);
 
-  GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
-                                           widget, detail,
-                                           x1, x2, y);
-
-  cairo_restore (cr);
-}
-
-/**
- * gtk_paint_vline:
- * @style: a #GtkStyle
- * @window: a #GdkWindow
- * @state_type: a state
- * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
- *        output should not be clipped
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @y1_: the starting y coordinate
- * @y2_: the ending y coordinate
- * @x: the x coordinate
- *
- * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
- * using the given style and state.
- */
-void
-gtk_paint_vline (GtkStyle           *style,
-                 GdkWindow          *window,
-                 GtkStateType        state_type,
-                 const GdkRectangle *area,
-                 GtkWidget          *widget,
-                 const gchar        *detail,
-                 gint                y1_,
-                 gint                y2_,
-                 gint                x)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
+  GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
                                            widget, detail,
-                                           y1_, y2_, x);
+                                           x1, x2, y);
 
-  cairo_destroy (cr);
+  cairo_restore (cr);
 }
 
 /**
- * gtk_cairo_paint_vline:
+ * gtk_paint_vline:
  * @style: a #GtkStyle
  * @cr: a #cairo_t
  * @state_type: a state
@@ -4667,16 +3147,18 @@ gtk_paint_vline (GtkStyle           *style,
  *
  * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
  * using the given style and state.
+ *
+ * Deprecated:3.0: Use gtk_render_line() instead
  */
 void
-gtk_cairo_paint_vline (GtkStyle           *style,
-                       cairo_t            *cr,
-                       GtkStateType        state_type,
-                       GtkWidget          *widget,
-                       const gchar        *detail,
-                       gint                y1_,
-                       gint                y2_,
-                       gint                x)
+gtk_paint_vline (GtkStyle           *style,
+                 cairo_t            *cr,
+                 GtkStateType        state_type,
+                 GtkWidget          *widget,
+                 const gchar        *detail,
+                 gint                y1_,
+                 gint                y2_,
+                 gint                x)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (cr != NULL);
@@ -4694,11 +3176,9 @@ gtk_cairo_paint_vline (GtkStyle           *style,
 /**
  * gtk_paint_shadow:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @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
  * @x: x origin of the rectangle
@@ -4706,65 +3186,22 @@ gtk_cairo_paint_vline (GtkStyle           *style,
  * @width: width of the rectangle
  * @height: width of the rectangle
  *
- * Draws a shadow around the given rectangle in @window 
+ * Draws a shadow around the given rectangle in @cr
  * using the given style and state and shadow type.
+ *
+ * Deprecated:3.0: Use gtk_render_frame() instead
  */
 void
 gtk_paint_shadow (GtkStyle           *style,
-                  GdkWindow          *window,
+                  cairo_t            *cr,
                   GtkStateType        state_type,
                   GtkShadowType       shadow_type,
-                  const GdkRectangle *area,
                   GtkWidget          *widget,
                   const gchar        *detail,
                   gint                x,
                   gint                y,
                   gint                width,
                   gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_shadow (style, cr, state_type, shadow_type,
-                          widget, detail,
-                          x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_shadow:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the rectangle
- * @y: y origin of the rectangle
- * @width: width of the rectangle
- * @height: width of the rectangle
- *
- * Draws a shadow around the given rectangle in @cr 
- * using the given style and state and shadow type.
- */
-void
-gtk_cairo_paint_shadow (GtkStyle           *style,
-                        cairo_t            *cr,
-                        GtkStateType        state_type,
-                        GtkShadowType       shadow_type,
-                        GtkWidget          *widget,
-                        const gchar        *detail,
-                        gint                x,
-                        gint                y,
-                        gint                width,
-                        gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
@@ -4784,11 +3221,9 @@ gtk_cairo_paint_shadow (GtkStyle           *style,
 /**
  * gtk_paint_arrow:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the 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
  * @arrow_type: the type of arrow to draw
@@ -4797,16 +3232,17 @@ gtk_cairo_paint_shadow (GtkStyle           *style,
  * @y: y origin of the rectangle to draw the arrow in
  * @width: width of the rectangle to draw the arrow in
  * @height: height of the rectangle to draw the arrow in
- * 
- * Draws an arrow in the given rectangle on @window using the given 
+ *
+ * Draws an arrow in the given rectangle on @cr using the given
  * parameters. @arrow_type determines the direction of the arrow.
+ *
+ * Deprecated:3.0: Use gtk_render_arrow() instead
  */
 void
 gtk_paint_arrow (GtkStyle           *style,
-                 GdkWindow          *window,
+                 cairo_t            *cr,
                  GtkStateType        state_type,
                  GtkShadowType       shadow_type,
-                 const GdkRectangle *area,
                  GtkWidget          *widget,
                  const gchar        *detail,
                  GtkArrowType        arrow_type,
@@ -4815,54 +3251,6 @@ gtk_paint_arrow (GtkStyle           *style,
                  gint                y,
                  gint                width,
                  gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_arrow (style, cr, state_type, shadow_type,
-                         widget, detail,
-                         arrow_type, fill, x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_arrow:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: the type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @arrow_type: the type of arrow to draw
- * @fill: %TRUE if the arrow tip should be filled
- * @x: x origin of the rectangle to draw the arrow in
- * @y: y origin of the rectangle to draw the arrow in
- * @width: width of the rectangle to draw the arrow in
- * @height: height of the rectangle to draw the arrow in
- * 
- * Draws an arrow in the given rectangle on @cr using the given 
- * parameters. @arrow_type determines the direction of the arrow.
- */
-void
-gtk_cairo_paint_arrow (GtkStyle           *style,
-                       cairo_t            *cr,
-                       GtkStateType        state_type,
-                       GtkShadowType       shadow_type,
-                       GtkWidget          *widget,
-                       const gchar        *detail,
-                       GtkArrowType        arrow_type,
-                       gboolean            fill,
-                       gint                x,
-                       gint                y,
-                       gint                width,
-                       gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
@@ -4882,11 +3270,9 @@ gtk_cairo_paint_arrow (GtkStyle           *style,
 /**
  * gtk_paint_diamond:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the 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
  * @x: x origin of the rectangle to draw the diamond in
@@ -4896,63 +3282,20 @@ gtk_cairo_paint_arrow (GtkStyle           *style,
  *
  * Draws a diamond in the given rectangle on @window using the given
  * parameters.
+ *
+ * Deprecated:3.0: Use cairo instead
  */
 void
 gtk_paint_diamond (GtkStyle           *style,
-                   GdkWindow          *window,
+                   cairo_t            *cr,
                    GtkStateType        state_type,
                    GtkShadowType       shadow_type,
-                   const GdkRectangle *area,
                    GtkWidget          *widget,
                    const gchar        *detail,
                    gint                x,
                    gint                y,
                    gint                width,
                    gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
-
-  sanitize_size (window, &width, &height);
-  
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_diamond (style, cr, state_type, shadow_type,
-                           widget, detail,
-                           x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_diamond:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: the type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the rectangle to draw the diamond in
- * @y: y origin of the rectangle to draw the diamond in
- * @width: width of the rectangle to draw the diamond in
- * @height: height of the rectangle to draw the diamond in
- *
- * Draws a diamond in the given rectangle on @window using the given
- * parameters.
- */
-void
-gtk_cairo_paint_diamond (GtkStyle           *style,
-                         cairo_t            *cr,
-                         GtkStateType        state_type,
-                         GtkShadowType       shadow_type,
-                         GtkWidget          *widget,
-                         const gchar        *detail,
-                         gint                x,
-                         gint                y,
-                         gint                width,
-                         gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
@@ -4972,75 +3315,31 @@ gtk_cairo_paint_diamond (GtkStyle           *style,
 /**
  * gtk_paint_box:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the 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
  * @x: x origin of the box
  * @y: y origin of the box
  * @width: the width of the box
  * @height: the height of the box
- * 
- * Draws a box on @window with the given parameters.
+ *
+ * Draws a box on @cr with the given parameters.
+ *
+ * Deprecated:3.0: Use gtk_render_frame() and gtk_render_background() instead
  */
 void
 gtk_paint_box (GtkStyle           *style,
-               GdkWindow          *window,
+               cairo_t            *cr,
                GtkStateType        state_type,
                GtkShadowType       shadow_type,
-               const GdkRectangle *area,
                GtkWidget          *widget,
                const gchar        *detail,
                gint                x,
                gint                y,
                gint                width,
                gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_box (style, cr, state_type, shadow_type,
-                       widget, detail,
-                       x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_box:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: the type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the box
- * @y: y origin of the box
- * @width: the width of the box
- * @height: the height of the box
- * 
- * Draws a box on @cr with the given parameters.
- */
-void
-gtk_cairo_paint_box (GtkStyle           *style,
-                     cairo_t            *cr,
-                     GtkStateType        state_type,
-                     GtkShadowType       shadow_type,
-                     GtkWidget          *widget,
-                     const gchar        *detail,
-                     gint                x,
-                     gint                y,
-                     gint                width,
-                     gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
@@ -5058,77 +3357,31 @@ gtk_cairo_paint_box (GtkStyle           *style,
 /**
  * gtk_paint_flat_box:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the 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
  * @x: x origin of the box
  * @y: y origin of the box
  * @width: the width of the box
  * @height: the height of the box
- * 
- * Draws a flat box on @window with the given parameters.
+ *
+ * Draws a flat box on @cr with the given parameters.
+ *
+ * Deprecated:3.0: Use gtk_render_frame() and gtk_render_background() instead
  */
 void
 gtk_paint_flat_box (GtkStyle           *style,
-                    GdkWindow          *window,
+                    cairo_t            *cr,
                     GtkStateType        state_type,
                     GtkShadowType       shadow_type,
-                    const GdkRectangle *area,
                     GtkWidget          *widget,
                     const gchar        *detail,
                     gint                x,
                     gint                y,
                     gint                width,
                     gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_flat_box (style, cr, state_type, shadow_type,
-                            widget, detail,
-                            x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_flat_box:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: the 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
- * @x: x origin of the box
- * @y: y origin of the box
- * @width: the width of the box
- * @height: the height of the box
- * 
- * Draws a flat box on @cr with the given parameters.
- */
-void
-gtk_cairo_paint_flat_box (GtkStyle           *style,
-                          cairo_t            *cr,
-                          GtkStateType        state_type,
-                          GtkShadowType       shadow_type,
-                          GtkWidget          *widget,
-                          const gchar        *detail,
-                          gint                x,
-                          gint                y,
-                          gint                width,
-                          gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
@@ -5148,75 +3401,32 @@ gtk_cairo_paint_flat_box (GtkStyle           *style,
 /**
  * gtk_paint_check:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the 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
  * @x: x origin of the rectangle to draw the check in
  * @y: y origin of the rectangle to draw the check in
  * @width: the width of the rectangle to draw the check in
  * @height: the height of the rectangle to draw the check in
- * 
- * Draws a check button indicator in the given rectangle on @window with 
+ *
+ * Draws a check button indicator in the given rectangle on @cr with
  * the given parameters.
+ *
+ * Deprecated:3.0: Use gtk_render_check() instead
  */
 void
 gtk_paint_check (GtkStyle           *style,
-                 GdkWindow          *window,
+                 cairo_t            *cr,
                  GtkStateType        state_type,
                  GtkShadowType       shadow_type,
-                 const GdkRectangle *area,
                  GtkWidget          *widget,
                  const gchar        *detail,
                  gint                x,
                  gint                y,
                  gint                width,
                  gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_check (style, cr, state_type, shadow_type,
-                         widget, detail,
-                         x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_check:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: the type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the rectangle to draw the check in
- * @y: y origin of the rectangle to draw the check in
- * @width: the width of the rectangle to draw the check in
- * @height: the height of the rectangle to draw the check in
- * 
- * Draws a check button indicator in the given rectangle on @cr with 
- * the given parameters.
- */
-void
-gtk_cairo_paint_check (GtkStyle           *style,
-                       cairo_t            *cr,
-                       GtkStateType        state_type,
-                       GtkShadowType       shadow_type,
-                       GtkWidget          *widget,
-                       const gchar        *detail,
-                       gint                x,
-                       gint                y,
-                       gint                width,
-                       gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
@@ -5234,51 +3444,6 @@ gtk_cairo_paint_check (GtkStyle           *style,
 /**
  * gtk_paint_option:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
- * @state_type: a state
- * @shadow_type: the 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
- * @x: x origin of the rectangle to draw the option in
- * @y: y origin of the rectangle to draw the option in
- * @width: the width of the rectangle to draw the option in
- * @height: the height of the rectangle to draw the option in
- *
- * Draws a radio button indicator in the given rectangle on @window with 
- * the given parameters.
- */
-void
-gtk_paint_option (GtkStyle           *style,
-                  GdkWindow          *window,
-                  GtkStateType        state_type,
-                  GtkShadowType       shadow_type,
-                  const GdkRectangle *area,
-                  GtkWidget          *widget,
-                  const gchar        *detail,
-                  gint                x,
-                  gint                y,
-                  gint                width,
-                  gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_option (style, cr, state_type, shadow_type,
-                          widget, detail,
-                          x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_option:
- * @style: a #GtkStyle
  * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
@@ -5289,20 +3454,22 @@ gtk_paint_option (GtkStyle           *style,
  * @width: the width of the rectangle to draw the option in
  * @height: the height of the rectangle to draw the option in
  *
- * Draws a radio button indicator in the given rectangle on @cr with 
+ * Draws a radio button indicator in the given rectangle on @cr with
  * the given parameters.
+ *
+ * Deprecated:3.0: Use gtk_render_option() instead
  */
 void
-gtk_cairo_paint_option (GtkStyle           *style,
-                        cairo_t            *cr,
-                        GtkStateType        state_type,
-                        GtkShadowType       shadow_type,
-                        GtkWidget          *widget,
-                        const gchar        *detail,
-                        gint                x,
-                        gint                y,
-                        gint                width,
-                        gint                height)
+gtk_paint_option (GtkStyle           *style,
+                  cairo_t            *cr,
+                  GtkStateType        state_type,
+                  GtkShadowType       shadow_type,
+                  GtkWidget          *widget,
+                  const gchar        *detail,
+                  gint                x,
+                  gint                y,
+                  gint                width,
+                  gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
@@ -5320,11 +3487,9 @@ gtk_cairo_paint_option (GtkStyle           *style,
 /**
  * gtk_paint_tab:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: the 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
  * @x: x origin of the rectangle to draw the tab in
@@ -5333,62 +3498,21 @@ gtk_cairo_paint_option (GtkStyle           *style,
  * @height: the height of the rectangle to draw the tab in
  *
  * Draws an option menu tab (i.e. the up and down pointing arrows)
- * in the given rectangle on @window using the given parameters.
- */ 
+ * in the given rectangle on @cr using the given parameters.
+ *
+ * Deprecated:3.0: Use cairo instead
+ */
 void
 gtk_paint_tab (GtkStyle           *style,
-               GdkWindow          *window,
+               cairo_t            *cr,
                GtkStateType        state_type,
                GtkShadowType       shadow_type,
-               const GdkRectangle *area,
                GtkWidget          *widget,
                const gchar        *detail,
                gint                x,
                gint                y,
                gint                width,
                gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_tab (style, cr, state_type, shadow_type,
-                       widget, detail,
-                       x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_tab:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: the type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the rectangle to draw the tab in
- * @y: y origin of the rectangle to draw the tab in
- * @width: the width of the rectangle to draw the tab in
- * @height: the height of the rectangle to draw the tab in
- *
- * Draws an option menu tab (i.e. the up and down pointing arrows)
- * in the given rectangle on @cr using the given parameters.
- */ 
-void
-gtk_cairo_paint_tab (GtkStyle           *style,
-                     cairo_t            *cr,
-                     GtkStateType        state_type,
-                     GtkShadowType       shadow_type,
-                     GtkWidget          *widget,
-                     const gchar        *detail,
-                     gint                x,
-                     gint                y,
-                     gint                width,
-                     gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
@@ -5406,11 +3530,9 @@ gtk_cairo_paint_tab (GtkStyle           *style,
 /**
  * gtk_paint_shadow_gap:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @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
  * @x: x origin of the rectangle
@@ -5421,16 +3543,17 @@ gtk_cairo_paint_tab (GtkStyle           *style,
  * @gap_x: starting position of the gap
  * @gap_width: width of the gap
  *
- * Draws a shadow around the given rectangle in @window 
- * using the given style and state and shadow type, leaving a 
+ * Draws a shadow around the given rectangle in @cr
+ * using the given style and state and shadow type, leaving a
  * gap in one side.
-*/
+ *
+ * Deprecated:3.0: Use gtk_render_frame_gap() instead
+ */
 void
 gtk_paint_shadow_gap (GtkStyle           *style,
-                      GdkWindow          *window,
+                      cairo_t            *cr,
                       GtkStateType        state_type,
                       GtkShadowType       shadow_type,
-                      const GdkRectangle *area,
                       GtkWidget          *widget,
                       const gchar        *detail,
                       gint                x,
@@ -5440,58 +3563,6 @@ gtk_paint_shadow_gap (GtkStyle           *style,
                       GtkPositionType     gap_side,
                       gint                gap_x,
                       gint                gap_width)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
-
-  sanitize_size (window, &width, &height);
-  
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_shadow_gap (style, cr, state_type, shadow_type,
-                              widget, detail,
-                              x, y, width, height, gap_side, gap_x, gap_width);
-
-  cairo_destroy (cr);
-}
-
-
-/**
- * gtk_cairo_paint_shadow_gap:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the rectangle
- * @y: y origin of the rectangle
- * @width: width of the rectangle
- * @height: width of the rectangle
- * @gap_side: side in which to leave the gap
- * @gap_x: starting position of the gap
- * @gap_width: width of the gap
- *
- * Draws a shadow around the given rectangle in @cr
- * using the given style and state and shadow type, leaving a 
- * gap in one side.
-*/
-void
-gtk_cairo_paint_shadow_gap (GtkStyle           *style,
-                            cairo_t            *cr,
-                            GtkStateType        state_type,
-                            GtkShadowType       shadow_type,
-                            GtkWidget          *widget,
-                            const gchar        *detail,
-                            gint                x,
-                            gint                y,
-                            gint                width,
-                            gint                height,
-                            GtkPositionType     gap_side,
-                            gint                gap_x,
-                            gint                gap_width)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
@@ -5508,15 +3579,12 @@ gtk_cairo_paint_shadow_gap (GtkStyle           *style,
   cairo_restore (cr);
 }
 
-
 /**
  * gtk_paint_box_gap:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @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
  * @x: x origin of the rectangle
@@ -5527,15 +3595,16 @@ gtk_cairo_paint_shadow_gap (GtkStyle           *style,
  * @gap_x: starting position of the gap
  * @gap_width: width of the gap
  *
- * Draws a box in @window using the given style and state and shadow type, 
+ * Draws a box in @cr using the given style and state and shadow type,
  * leaving a gap in one side.
+ *
+ * Deprecated:3.0: Use gtk_render_frame_gap() instead
  */
 void
 gtk_paint_box_gap (GtkStyle           *style,
-                   GdkWindow          *window,
+                   cairo_t            *cr,
                    GtkStateType        state_type,
                    GtkShadowType       shadow_type,
-                   const GdkRectangle *area,
                    GtkWidget          *widget,
                    const gchar        *detail,
                    gint                x,
@@ -5545,56 +3614,6 @@ gtk_paint_box_gap (GtkStyle           *style,
                    GtkPositionType     gap_side,
                    gint                gap_x,
                    gint                gap_width)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_box_gap (style, cr, state_type, shadow_type,
-                           widget, detail,
-                           x, y, width, height, gap_side, gap_x, gap_width);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_box_gap:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the rectangle
- * @y: y origin of the rectangle
- * @width: width of the rectangle
- * @height: width of the rectangle
- * @gap_side: side in which to leave the gap
- * @gap_x: starting position of the gap
- * @gap_width: width of the gap
- *
- * Draws a box in @cr using the given style and state and shadow type, 
- * leaving a gap in one side.
- */
-void
-gtk_cairo_paint_box_gap (GtkStyle           *style,
-                         cairo_t            *cr,
-                         GtkStateType        state_type,
-                         GtkShadowType       shadow_type,
-                         GtkWidget          *widget,
-                         const gchar        *detail,
-                         gint                x,
-                         gint                y,
-                         gint                width,
-                         gint                height,
-                         GtkPositionType     gap_side,
-                         gint                gap_x,
-                         gint                gap_width)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
@@ -5612,13 +3631,11 @@ gtk_cairo_paint_box_gap (GtkStyle           *style,
 }
 
 /**
- * gtk_paint_extension: 
+ * gtk_paint_extension:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @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
  * @x: x origin of the extension
@@ -5626,15 +3643,16 @@ gtk_cairo_paint_box_gap (GtkStyle           *style,
  * @width: width of the extension
  * @height: width of the extension
  * @gap_side: the side on to which the extension is attached
- * 
+ *
  * Draws an extension, i.e. a notebook tab.
+ *
+ * Deprecated:3.0: Use gtk_render_extension() instead
  **/
 void
 gtk_paint_extension (GtkStyle           *style,
-                     GdkWindow          *window,
+                     cairo_t            *cr,
                      GtkStateType        state_type,
                      GtkShadowType       shadow_type,
-                     const GdkRectangle *area,
                      GtkWidget          *widget,
                      const gchar        *detail,
                      gint                x,
@@ -5642,51 +3660,6 @@ gtk_paint_extension (GtkStyle           *style,
                      gint                width,
                      gint                height,
                      GtkPositionType     gap_side)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_extension (style, cr, state_type, shadow_type,
-                             widget, detail,
-                             x, y, width, height, gap_side);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_extension: 
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: type of shadow to draw
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin of the extension
- * @y: y origin of the extension
- * @width: width of the extension
- * @height: width of the extension
- * @gap_side: the side on to which the extension is attached
- * 
- * Draws an extension, i.e. a notebook tab.
- **/
-void
-gtk_cairo_paint_extension (GtkStyle           *style,
-                           cairo_t            *cr,
-                           GtkStateType        state_type,
-                           GtkShadowType       shadow_type,
-                           GtkWidget          *widget,
-                           const gchar        *detail,
-                           gint                x,
-                           gint                y,
-                           gint                width,
-                           gint                height,
-                           GtkPositionType     gap_side)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
@@ -5706,10 +3679,8 @@ gtk_cairo_paint_extension (GtkStyle           *style,
 /**
  * gtk_paint_focus:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
- * @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
  * @x: the x origin of the rectangle around which to draw a focus indicator
@@ -5717,62 +3688,21 @@ gtk_cairo_paint_extension (GtkStyle           *style,
  * @width: the width of the rectangle around which to draw a focus indicator
  * @height: the height of the rectangle around which to draw a focus indicator
  *
- * Draws a focus indicator around the given rectangle on @window using the
+ * Draws a focus indicator around the given rectangle on @cr using the
  * given style.
+ *
+ * Deprecated:3.0: Use gtk_render_focus() instead
  */
 void
 gtk_paint_focus (GtkStyle           *style,
-                 GdkWindow          *window,
-                GtkStateType        state_type,
-                 const GdkRectangle *area,
+                 cairo_t            *cr,
+                 GtkStateType        state_type,
                  GtkWidget          *widget,
                  const gchar        *detail,
                  gint                x,
                  gint                y,
                  gint                width,
                  gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_focus (style, cr, state_type,
-                         widget, detail,
-                         x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_focus:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: the x origin of the rectangle around which to draw a focus indicator
- * @y: the y origin of the rectangle around which to draw a focus indicator
- * @width: the width of the rectangle around which to draw a focus indicator
- * @height: the height of the rectangle around which to draw a focus indicator
- *
- * Draws a focus indicator around the given rectangle on @cr using the
- * given style.
- */
-void
-gtk_cairo_paint_focus (GtkStyle           *style,
-                       cairo_t            *cr,
-                       GtkStateType        state_type,
-                       GtkWidget          *widget,
-                       const gchar        *detail,
-                       gint                x,
-                       gint                y,
-                       gint                width,
-                       gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
@@ -5792,11 +3722,9 @@ gtk_cairo_paint_focus (GtkStyle           *style,
 /**
  * gtk_paint_slider:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: a shadow
- * @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
  * @x: the x origin of the rectangle in which to draw a slider
@@ -5805,15 +3733,16 @@ gtk_cairo_paint_focus (GtkStyle           *style,
  * @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
+ * Draws a slider in the given rectangle on @cr using the
  * given style and orientation.
+ *
+ * Deprecated:3.0: Use gtk_render_slider() instead
  **/
 void
 gtk_paint_slider (GtkStyle           *style,
-                  GdkWindow          *window,
+                  cairo_t            *cr,
                   GtkStateType        state_type,
                   GtkShadowType       shadow_type,
-                  const GdkRectangle *area,
                   GtkWidget          *widget,
                   const gchar        *detail,
                   gint                x,
@@ -5821,52 +3750,6 @@ gtk_paint_slider (GtkStyle           *style,
                   gint                width,
                   gint                height,
                   GtkOrientation      orientation)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
-                                            widget, detail,
-                                            x, y, width, height, orientation);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_slider:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @shadow_type: a shadow
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @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 @cr using the
- * given style and orientation.
- **/
-void
-gtk_cairo_paint_slider (GtkStyle           *style,
-                        cairo_t            *cr,
-                        GtkStateType        state_type,
-                        GtkShadowType       shadow_type,
-                        GtkWidget          *widget,
-                        const gchar        *detail,
-                        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);
@@ -5886,54 +3769,6 @@ gtk_cairo_paint_slider (GtkStyle           *style,
 /**
  * gtk_paint_handle:
  * @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
- * @x: x origin of the handle
- * @y: y origin of the handle
- * @width: with of the handle
- * @height: height of the handle
- * @orientation: the orientation of the handle
- * 
- * Draws a handle as used in #GtkHandleBox and #GtkPaned.
- **/
-void
-gtk_paint_handle (GtkStyle           *style,
-                  GdkWindow          *window,
-                  GtkStateType        state_type,
-                  GtkShadowType       shadow_type,
-                  const GdkRectangle *area,
-                  GtkWidget          *widget,
-                  const gchar        *detail,
-                  gint                x,
-                  gint                y,
-                  gint                width,
-                  gint                height,
-                  GtkOrientation      orientation)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
-
-  sanitize_size (window, &width, &height);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_handle (style, cr, state_type, shadow_type,
-                          widget, detail,
-                          x, y, width, height, orientation);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_handle:
- * @style: a #GtkStyle
  * @cr: a #cairo_t
  * @state_type: a state
  * @shadow_type: type of shadow to draw
@@ -5944,21 +3779,23 @@ gtk_paint_handle (GtkStyle           *style,
  * @width: with of the handle
  * @height: height of the handle
  * @orientation: the orientation of the handle
- * 
+ *
  * Draws a handle as used in #GtkHandleBox and #GtkPaned.
+ *
+ * Deprecated:3.0: Use gtk_render_handle() instead
  **/
 void
-gtk_cairo_paint_handle (GtkStyle           *style,
-                        cairo_t            *cr,
-                        GtkStateType        state_type,
-                        GtkShadowType       shadow_type,
-                        GtkWidget          *widget,
-                        const gchar        *detail,
-                        gint                x,
-                        gint                y,
-                        gint                width,
-                        gint                height,
-                        GtkOrientation      orientation)
+gtk_paint_handle (GtkStyle           *style,
+                  cairo_t            *cr,
+                  GtkStateType        state_type,
+                  GtkShadowType       shadow_type,
+                  GtkWidget          *widget,
+                  const gchar        *detail,
+                  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_handle != NULL);
@@ -5978,10 +3815,8 @@ gtk_cairo_paint_handle (GtkStyle           *style,
 /**
  * gtk_paint_expander:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
- * @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
  * @x: the x position to draw the expander at
@@ -5989,7 +3824,7 @@ gtk_cairo_paint_handle (GtkStyle           *style,
  * @expander_style: the style to draw the expander in; determines
  *   whether the expander is collapsed, expanded, or in an
  *   intermediate state.
- * 
+ *
  * Draws an expander as used in #GtkTreeView. @x and @y specify the
  * center the expander. The size of the expander is determined by the
  * "expander-size" style property of @widget.  (If widget is not
@@ -5999,64 +3834,18 @@ gtk_cairo_paint_handle (GtkStyle           *style,
  * likely not useful.) The expander is expander_size pixels tall
  * in the collapsed position and expander_size pixels wide in the
  * expanded position.
+ *
+ * Deprecated:3.0: Use gtk_render_expander() instead
  **/
 void
 gtk_paint_expander (GtkStyle           *style,
-                    GdkWindow          *window,
+                    cairo_t            *cr,
                     GtkStateType        state_type,
-                    const GdkRectangle *area,
                     GtkWidget          *widget,
                     const gchar        *detail,
                     gint                x,
                     gint                y,
-                   GtkExpanderStyle    expander_style)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_expander (style, cr, state_type,
-                            widget, detail,
-                            x, y, expander_style);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_expander:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: the x position to draw the expander at
- * @y: the y position to draw the expander at
- * @expander_style: the style to draw the expander in; determines
- *   whether the expander is collapsed, expanded, or in an
- *   intermediate state.
- * 
- * Draws an expander as used in #GtkTreeView. @x and @y specify the
- * center the expander. The size of the expander is determined by the
- * "expander-size" style property of @widget.  (If widget is not
- * specified or doesn't have an "expander-size" property, an
- * unspecified default size will be used, since the caller doesn't
- * have sufficient information to position the expander, this is
- * likely not useful.) The expander is expander_size pixels tall
- * in the collapsed position and expander_size pixels wide in the
- * expanded position.
- **/
-void
-gtk_cairo_paint_expander (GtkStyle           *style,
-                          cairo_t            *cr,
-                          GtkStateType        state_type,
-                          GtkWidget          *widget,
-                          const gchar        *detail,
-                          gint                x,
-                          gint                y,
-                          GtkExpanderStyle    expander_style)
+                    GtkExpanderStyle    expander_style)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
@@ -6074,71 +3863,30 @@ gtk_cairo_paint_expander (GtkStyle           *style,
 /**
  * gtk_paint_layout:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
  * @use_text: whether to use the text or foreground
  *            graphics context of @style
- * @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
  * @x: x origin
  * @y: y origin
  * @layout: the layout to draw
  *
- * Draws a layout on @window using the given parameters.
+ * Draws a layout on @cr using the given parameters.
+ *
+ * Deprecated:3.0: Use gtk_render_layout() instead
  **/
 void
 gtk_paint_layout (GtkStyle           *style,
-                  GdkWindow          *window,
+                  cairo_t            *cr,
                   GtkStateType        state_type,
                   gboolean            use_text,
-                  const GdkRectangle *area,
                   GtkWidget          *widget,
                   const gchar        *detail,
                   gint                x,
                   gint                y,
                   PangoLayout        *layout)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_layout (style, cr, state_type, use_text,
-                          widget, detail,
-                          x, y, layout);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_layout:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @use_text: whether to use the text or foreground
- *            graphics context of @style
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @x: x origin
- * @y: y origin
- * @layout: the layout to draw
- *
- * Draws a layout on @cr using the given parameters.
- **/
-void
-gtk_cairo_paint_layout (GtkStyle           *style,
-                        cairo_t            *cr,
-                        GtkStateType        state_type,
-                        gboolean            use_text,
-                        GtkWidget          *widget,
-                        const gchar        *detail,
-                        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);
@@ -6156,10 +3904,8 @@ gtk_cairo_paint_layout (GtkStyle           *style,
 /**
  * gtk_paint_resize_grip:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
- * @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
  * @edge: the edge in which to draw the resize grip
@@ -6168,14 +3914,15 @@ gtk_cairo_paint_layout (GtkStyle           *style,
  * @width: the width of the rectangle in which to draw the resize grip
  * @height: the height of the rectangle in which to draw the resize grip
  *
- * Draws a resize grip in the given rectangle on @window using the given
- * parameters. 
+ * Draws a resize grip in the given rectangle on @cr using the given
+ * parameters.
+ *
+ * Deprecated:3.0: Use gtk_render_handle() instead
  */
 void
 gtk_paint_resize_grip (GtkStyle           *style,
-                       GdkWindow          *window,
+                       cairo_t            *cr,
                        GtkStateType        state_type,
-                       const GdkRectangle *area,
                        GtkWidget          *widget,
                        const gchar        *detail,
                        GdkWindowEdge       edge,
@@ -6183,48 +3930,6 @@ gtk_paint_resize_grip (GtkStyle           *style,
                        gint                y,
                        gint                width,
                        gint                height)
-
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
-                                                 widget, detail,
-                                                 edge, x, y, width, height);
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_resize_grip:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @widget: (allow-none): the widget
- * @detail: (allow-none): a style detail
- * @edge: the edge in which to draw the resize grip
- * @x: the x origin of the rectangle in which to draw the resize grip
- * @y: the y origin of the rectangle in which to draw the resize grip
- * @width: the width of the rectangle in which to draw the resize grip
- * @height: the height of the rectangle in which to draw the resize grip
- *
- * Draws a resize grip in the given rectangle on @cr using the given
- * parameters. 
- */
-void
-gtk_cairo_paint_resize_grip (GtkStyle           *style,
-                             cairo_t            *cr,
-                             GtkStateType        state_type,
-                             GtkWidget          *widget,
-                             const gchar        *detail,
-                             GdkWindowEdge       edge,
-                             gint                x,
-                             gint                y,
-                             gint                width,
-                             gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
@@ -6241,10 +3946,8 @@ gtk_cairo_paint_resize_grip (GtkStyle           *style,
 /**
  * gtk_paint_spinner:
  * @style: a #GtkStyle
- * @window: a #GdkWindow
+ * @cr: a #cairo_t
  * @state_type: a state
- * @area: (allow-none): clip rectangle, or %NULL if the
- *        output should not be clipped
  * @widget: (allow-none): the widget (may be %NULL)
  * @detail: (allow-none): a style detail (may be %NULL)
  * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
@@ -6255,61 +3958,19 @@ gtk_cairo_paint_resize_grip (GtkStyle           *style,
  *
  * Draws a spinner on @window using the given parameters.
  *
- * Since: 2.20
+ * Deprecated:3.0: Use gtk_render_activity() instead
  */
 void
 gtk_paint_spinner (GtkStyle           *style,
-                  GdkWindow          *window,
-                  GtkStateType        state_type,
-                   const GdkRectangle *area,
+                   cairo_t            *cr,
+                   GtkStateType        state_type,
                    GtkWidget          *widget,
                    const gchar        *detail,
-                  guint               step,
-                  gint                x,
-                  gint                y,
-                  gint                width,
-                  gint                height)
-{
-  cairo_t *cr;
-
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
-
-  cr = gtk_style_cairo_create (window, area);
-
-  gtk_cairo_paint_spinner (style, cr, state_type,
-                           widget, detail,
-                          step, x, y, width, height);
-
-  cairo_destroy (cr);
-}
-
-/**
- * gtk_cairo_paint_spinner:
- * @style: a #GtkStyle
- * @cr: a #cairo_t
- * @state_type: a state
- * @widget: (allow-none): the widget (may be %NULL)
- * @detail: (allow-none): a style detail (may be %NULL)
- * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
- * @x: the x origin of the rectangle in which to draw the spinner
- * @y: the y origin of the rectangle in which to draw the spinner
- * @width: the width of the rectangle in which to draw the spinner
- * @height: the height of the rectangle in which to draw the spinner
- *
- * Draws a spinner on @window using the given parameters.
- */
-void
-gtk_cairo_paint_spinner (GtkStyle           *style,
-                         cairo_t            *cr,
-                         GtkStateType        state_type,
-                         GtkWidget          *widget,
-                         const gchar        *detail,
-                         guint               step,
-                         gint                x,
-                         gint                y,
-                         gint                width,
-                         gint                height)
+                   guint               step,
+                   gint                x,
+                   gint                y,
+                   gint                width,
+                   gint                height)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (cr != NULL);
@@ -6325,157 +3986,7 @@ gtk_cairo_paint_spinner (GtkStyle           *style,
 }
 
 /**
- * gtk_border_new:
- *
- * Allocates a new #GtkBorder structure and initializes its elements to zero.
- * 
- * Returns: a new empty #GtkBorder. The newly allocated #GtkBorder should be 
- *     freed with gtk_border_free()
- *
- * Since: 2.14
- **/
-GtkBorder *
-gtk_border_new (void)
-{
-  return g_slice_new0 (GtkBorder);
-}
-
-/**
- * gtk_border_copy:
- * @border_: a #GtkBorder.
- * @returns: a copy of @border_.
- *
- * Copies a #GtkBorder structure.
- **/
-GtkBorder *
-gtk_border_copy (const GtkBorder *border)
-{
-  g_return_val_if_fail (border != NULL, NULL);
-
-  return g_slice_dup (GtkBorder, border);
-}
-
-/**
- * gtk_border_free:
- * @border_: a #GtkBorder.
- * 
- * Frees a #GtkBorder structure.
- **/
-void
-gtk_border_free (GtkBorder *border)
-{
-  g_slice_free (GtkBorder, border);
-}
-
-G_DEFINE_BOXED_TYPE (GtkBorder, gtk_border,
-                     gtk_border_copy,
-                     gtk_border_free)
-
-typedef struct _CursorInfo CursorInfo;
-
-struct _CursorInfo
-{
-  GType for_type;
-  GdkColor primary;
-  GdkColor secondary;
-};
-
-static void
-style_unrealize_cursors (GtkStyle *style)
-{
-  CursorInfo *
-  
-  cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
-  if (cursor_info)
-    {
-      g_free (cursor_info);
-      g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
-    }
-}
-
-static const GdkColor *
-get_insertion_cursor_color (GtkWidget *widget,
-                           gboolean   is_primary)
-{
-  CursorInfo *cursor_info;
-  GtkStyle *style;
-  GdkColor *cursor_color;
-
-  style = gtk_widget_get_style (widget);
-
-  cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
-  if (!cursor_info)
-    {
-      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;
-    }
-
-  /* We have to keep track of the type because gtk_widget_style_get()
-   * can return different results when called on the same property and
-   * same style but for different widgets. :-(. That is,
-   * GtkEntry::cursor-color = "red" in a style will modify the cursor
-   * color for entries but not for text view.
-   */
-  if (cursor_info->for_type != G_OBJECT_TYPE (widget))
-    {
-      cursor_info->for_type = G_OBJECT_TYPE (widget);
-
-      /* 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];
-        }
-
-      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];
-        }
-    }
-
-  if (is_primary)
-    return &cursor_info->primary;
-  else
-    return &cursor_info->secondary;
-}
-
-void
-_gtk_widget_get_cursor_color (GtkWidget *widget,
-                             GdkColor  *color)
-{
-  GdkColor *style_color;
-
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (color != NULL);
-
-  gtk_widget_style_get (widget, "cursor-color", &style_color, NULL);
-
-  if (style_color)
-    {
-      *color = *style_color;
-      gdk_color_free (style_color);
-    }
-  else
-    *color = gtk_widget_get_style (widget)->text[GTK_STATE_NORMAL];
-}
-
-/**
- * gtk_cairo_draw_insertion_cursor:
+ * gtk_draw_insertion_cursor:
  * @widget:  a #GtkWidget
  * @cr: cairo context to draw to
  * @location: location where to draw the cursor (@location->width is ignored)
@@ -6484,39 +3995,47 @@ _gtk_widget_get_cursor_color (GtkWidget *widget,
  *             right-to-left. Should never be #GTK_TEXT_DIR_NONE
  * @draw_arrow: %TRUE to draw a directional arrow on the
  *        cursor. Should be %FALSE unless the cursor is split.
- * 
+ *
  * Draws a text caret on @cr at @location. This is not a style function
  * but merely a convenience function for drawing the standard cursor shape.
  *
  * Since: 3.0
- **/
+ */
 void
-gtk_cairo_draw_insertion_cursor (GtkWidget          *widget,
-                                 cairo_t            *cr,
-                                 const GdkRectangle *location,
-                                 gboolean            is_primary,
-                                 GtkTextDirection    direction,
-                                 gboolean            draw_arrow)
+gtk_draw_insertion_cursor (GtkWidget          *widget,
+                           cairo_t            *cr,
+                           const GdkRectangle *location,
+                           gboolean            is_primary,
+                           GtkTextDirection    direction,
+                           gboolean            draw_arrow)
 {
   gint stem_width;
   gint arrow_width;
   gint x, y;
   gfloat cursor_aspect_ratio;
   gint offset;
-  
+  GtkStyleContext *context;
+  GdkRGBA primary_color;
+  GdkRGBA secondary_color;
+
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (cr != NULL);
   g_return_if_fail (location != NULL);
   g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
 
-  gdk_cairo_set_source_color (cr, get_insertion_cursor_color (widget, is_primary));
+  context = gtk_widget_get_style_context (widget);
+
+  _gtk_style_context_get_cursor_color (context, &primary_color, &secondary_color);
+  gdk_cairo_set_source_rgba (cr, is_primary ? &primary_color : &secondary_color);
 
   /* When changing the shape or size of the cursor here,
    * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
    */
 
-  gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
-  
+  gtk_style_context_get_style (context,
+                               "cursor-aspect-ratio", &cursor_aspect_ratio,
+                               NULL);
+
   stem_width = location->height * cursor_aspect_ratio + 1;
   arrow_width = stem_width + 1;
 
@@ -6525,8 +4044,8 @@ gtk_cairo_draw_insertion_cursor (GtkWidget          *widget,
     offset = stem_width / 2;
   else
     offset = stem_width - stem_width / 2;
-  
-  cairo_rectangle (cr, 
+
+  cairo_rectangle (cr,
                    location->x - offset, location->y,
                    stem_width, location->height);
   cairo_fill (cr);
@@ -6537,7 +4056,7 @@ gtk_cairo_draw_insertion_cursor (GtkWidget          *widget,
         {
           x = location->x - offset - 1;
           y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
-  
+
           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);
@@ -6547,7 +4066,7 @@ gtk_cairo_draw_insertion_cursor (GtkWidget          *widget,
         {
           x = location->x + stem_width - offset;
           y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
-  
+
           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);
@@ -6555,49 +4074,3 @@ gtk_cairo_draw_insertion_cursor (GtkWidget          *widget,
         }
     }
 }
-
-/**
- * gtk_draw_insertion_cursor:
- * @widget:  a #GtkWidget
- * @drawable: a #GdkDrawable
- * @area: (allow-none): rectangle to which the output is clipped, or %NULL if the
- *        output should not be clipped
- * @location: location where to draw the cursor (@location->width is ignored)
- * @is_primary: if the cursor should be the primary cursor color.
- * @direction: whether the cursor is left-to-right or
- *             right-to-left. Should never be #GTK_TEXT_DIR_NONE
- * @draw_arrow: %TRUE to draw a directional arrow on the
- *        cursor. Should be %FALSE unless the cursor is split.
- * 
- * Draws a text caret on @drawable at @location. This is not a style function
- * but merely a convenience function for drawing the standard cursor shape.
- *
- * Since: 2.4
- **/
-void
-gtk_draw_insertion_cursor (GtkWidget          *widget,
-                          GdkDrawable        *drawable,
-                          const GdkRectangle *area,
-                          const GdkRectangle *location,
-                          gboolean            is_primary,
-                          GtkTextDirection    direction,
-                          gboolean            draw_arrow)
-{
-  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);
-
-  cr = gdk_cairo_create (drawable);
-  if (area)
-    {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
-    }
-  
-  gtk_cairo_draw_insertion_cursor (widget, cr, location, is_primary, direction, draw_arrow);
-  
-  cairo_destroy (cr);
-}