]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkstyle.c
removed the "widget &&" part from "widget && GTK_IS_FOO (widget)" checks.
[~andy/gtk] / gtk / gtkstyle.c
index 7452c52e88903556a8f1aa7abab3d0b4868b9e8b..58f4d0ef9aefba05d35ed9c5e1c31ba1fa01930e 100644 (file)
@@ -37,6 +37,7 @@
 #include "gtkthemes.h"
 #include "gtkiconfactory.h"
 #include "gtksettings.h"       /* _gtk_settings_parse_convert() */
+#include "gtkintl.h"
 #include "gtkalias.h"
 
 #define LIGHTNESS_MULT  1.3
@@ -49,9 +50,15 @@ typedef struct {
   GValue      value;
 } PropertyValue;
 
+#define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
+
+typedef struct _GtkStylePrivate GtkStylePrivate;
+
+struct _GtkStylePrivate {
+  GSList *color_hashes;
+};
+
 /* --- prototypes --- */
-static void     gtk_style_init                 (GtkStyle       *style);
-static void     gtk_style_class_init           (GtkStyleClass  *klass);
 static void     gtk_style_finalize             (GObject        *object);
 static void     gtk_style_realize              (GtkStyle       *style,
                                                 GdkColormap    *colormap);
@@ -304,9 +311,6 @@ static void gtk_default_draw_resize_grip (GtkStyle       *style,
                                           gint            width,
                                           gint            height);
 
-static void gtk_style_shade            (GdkColor        *a,
-                                        GdkColor        *b,
-                                        gdouble          k);
 static void rgb_to_hls                 (gdouble         *r,
                                         gdouble         *g,
                                         gdouble         *b);
@@ -349,39 +353,13 @@ static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
 static const GdkColor gtk_default_selected_base =  { 0, GTK_BLUE };
 static const GdkColor gtk_default_active_base =    { 0, GTK_VERY_DARK_GRAY };
 
-static gpointer parent_class = NULL;
-
 /* --- signals --- */
 static guint realize_signal = 0;
 static guint unrealize_signal = 0;
 
+G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
+
 /* --- functions --- */
-GType
-gtk_style_get_type (void)
-{
-  static GType style_type = 0;
-  
-  if (!style_type)
-    {
-      static const GTypeInfo style_info =
-      {
-        sizeof (GtkStyleClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) gtk_style_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (GtkStyle),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) gtk_style_init,
-      };
-      
-      style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
-                                          &style_info, 0);
-    }
-  
-  return style_type;
-}
 
 /**
  * _gtk_style_init_for_settings:
@@ -499,8 +477,6 @@ gtk_style_class_init (GtkStyleClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   
-  parent_class = g_type_class_peek_parent (klass);
-
   object_class->finalize = gtk_style_finalize;
 
   klass->clone = gtk_style_real_clone;
@@ -533,7 +509,8 @@ gtk_style_class_init (GtkStyleClass *klass)
   klass->draw_layout = gtk_default_draw_layout;
   klass->draw_resize_grip = gtk_default_draw_resize_grip;
 
-  
+  g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
+
   /**
    * GtkStyle::realize:
    * @style: the object which received the signal
@@ -545,7 +522,7 @@ gtk_style_class_init (GtkStyleClass *klass)
    *
    * Since: 2.4
    */
-  realize_signal = g_signal_new ("realize",
+  realize_signal = g_signal_new (I_("realize"),
                                 G_TYPE_FROM_CLASS (object_class),
                                 G_SIGNAL_RUN_FIRST,
                                 G_STRUCT_OFFSET (GtkStyleClass, realize),
@@ -563,7 +540,7 @@ gtk_style_class_init (GtkStyleClass *klass)
    *
    * Since: 2.4
    */
-  unrealize_signal = g_signal_new ("unrealize",
+  unrealize_signal = g_signal_new (I_("unrealize"),
                                   G_TYPE_FROM_CLASS (object_class),
                                   G_SIGNAL_RUN_FIRST,
                                   G_STRUCT_OFFSET (GtkStyleClass, unrealize),
@@ -595,6 +572,7 @@ static void
 gtk_style_finalize (GObject *object)
 {
   GtkStyle *style = GTK_STYLE (object);
+  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
 
   g_return_if_fail (style->attach_count == 0);
 
@@ -624,18 +602,11 @@ gtk_style_finalize (GObject *object)
         }
     }
 
-  if (style->icon_factories)
-    {
-      GSList *tmp_list = style->icon_factories;
-
-      while (tmp_list)
-       {
-         g_object_unref (tmp_list->data);
-         tmp_list = tmp_list->next;
-       }
+  g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
+  g_slist_free (style->icon_factories);
 
-      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);
   
@@ -648,7 +619,7 @@ gtk_style_finalize (GObject *object)
   if (style->rc_style)
     gtk_rc_style_unref (style->rc_style);
   
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
 }
 
 
@@ -715,6 +686,10 @@ gtk_style_new (void)
  * 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.
+ *
+ * Since this function may return a new object, you have to use it 
+ * in the following way: 
+ * <literal>style = gtk_style_attach (style, window)</literal>
  **/
 GtkStyle*
 gtk_style_attach (GtkStyle  *style,
@@ -791,10 +766,19 @@ gtk_style_attach (GtkStyle  *style,
   return new_style;
 }
 
+/**
+ * gtk_style_detach:
+ * @style: a #GtkStyle
+ *
+ * Detaches a style from a window. If the style is not attached
+ * to any windows anymore, it is unrealized. See gtk_style_attach().
+ * 
+ */
 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)
@@ -849,9 +833,6 @@ static void
 gtk_style_realize (GtkStyle    *style,
                    GdkColormap *colormap)
 {
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (GDK_IS_COLORMAP (colormap));
-  
   style->colormap = g_object_ref (colormap);
   style->depth = gdk_colormap_get_visual (colormap)->depth;
 
@@ -881,6 +862,53 @@ gtk_style_lookup_icon_set (GtkStyle   *style,
   return gtk_icon_factory_lookup_default (stock_id);
 }
 
+/**
+ * gtk_style_lookup_color:
+ * @style: a #GtkStyle
+ * @color_name: the name of the logical color to look up
+ * @color: 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
+ * returning %FALSE. Do not cache the found mapping, because
+ * it depends on the #GtkStyle and might change when a theme
+ * switch occurs.
+ *
+ * Return value: %TRUE if the mapping was found.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_style_lookup_color (GtkStyle   *style,
+                        const char *color_name,
+                        GdkColor   *color)
+{
+  GtkStylePrivate *priv;
+  GSList *iter;
+
+  g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
+  g_return_val_if_fail (color_name != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  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 (mapping)
+        {
+          color->red = mapping->red;
+          color->green = mapping->green;
+          color->blue = mapping->blue;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 /**
  * gtk_draw_hline:
  * @style: a #GtkStyle
@@ -1586,10 +1614,10 @@ gtk_style_real_copy (GtkStyle *style,
   style->ythickness = src->ythickness;
 
   if (style->rc_style)
-    gtk_rc_style_unref (style->rc_style);
+    g_object_unref (style->rc_style);
   style->rc_style = src->rc_style;
   if (src->rc_style)
-    gtk_rc_style_ref (src->rc_style);
+    g_object_ref (src->rc_style);
 
   /* don't copy, just clear cache */
   clear_property_cache (style);
@@ -1599,6 +1627,7 @@ 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 */
@@ -1624,19 +1653,11 @@ gtk_style_real_init_from_rc (GtkStyle   *style,
   if (rc_style->ythickness >= 0)
     style->ythickness = rc_style->ythickness;
 
-  if (rc_style->icon_factories)
-    {
-      GSList *iter;
+  style->icon_factories = g_slist_copy (rc_style->icon_factories);
+  g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
 
-      style->icon_factories = g_slist_copy (rc_style->icon_factories);
-      
-      iter = style->icon_factories;
-      while (iter != NULL)
-        {
-          g_object_ref (iter->data);
-          iter = g_slist_next (iter);
-        }
-    }
+  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
@@ -1718,7 +1739,7 @@ _gtk_style_peek_property_value (GtkStyle           *style,
       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 ? 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,
@@ -1759,9 +1780,9 @@ gtk_style_real_realize (GtkStyle *style)
 
   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);
-      
+      _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;
@@ -2156,9 +2177,6 @@ gtk_default_draw_hline (GtkStyle     *style,
   gint thickness_dark;
   gint i;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   thickness_light = style->ythickness / 2;
   thickness_dark = style->ythickness - thickness_light;
   
@@ -2213,9 +2231,6 @@ gtk_default_draw_vline (GtkStyle     *style,
   gint thickness_dark;
   gint i;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   thickness_light = style->xthickness / 2;
   thickness_dark = style->xthickness - thickness_light;
   
@@ -2441,12 +2456,9 @@ gtk_default_draw_shadow (GtkStyle      *style,
   gint thickness_dark;
   gint i;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-
   if (shadow_type == GTK_SHADOW_IN)
     {
-      if (detail && (strcmp (detail, "buttondefault") == 0))
+      if (detail && strcmp (detail, "buttondefault") == 0)
        {
          sanitize_size (window, &width, &height);
 
@@ -2461,7 +2473,7 @@ gtk_default_draw_shadow (GtkStyle      *style,
                            x, y, width, height);
          return;
        }
-      if (widget && GTK_IS_SPIN_BUTTON (widget) &&
+      if (GTK_IS_SPIN_BUTTON (widget) &&
          detail && strcmp (detail, "spinbutton") == 0)
        {
          draw_spinbutton_shadow (style, window, state_type, 
@@ -2699,7 +2711,7 @@ gtk_default_draw_shadow (GtkStyle      *style,
     }
 
   if (shadow_type == GTK_SHADOW_IN &&
-      widget && GTK_IS_SPIN_BUTTON (widget) &&
+      GTK_IS_SPIN_BUTTON (widget) &&
       detail && strcmp (detail, "entry") == 0)
     {
       if (get_direction (widget) == GTK_TEXT_DIR_LTR)
@@ -2779,10 +2791,6 @@ gtk_default_draw_polygon (GtkStyle      *style,
   gint yadjust;
   gint i;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  g_return_if_fail (points != NULL);
-  
   switch (shadow_type)
     {
     case GTK_SHADOW_IN:
@@ -2900,14 +2908,13 @@ draw_arrow (GdkWindow     *window,
            gint           width,
            gint           height)
 {
-  cairo_t *cr = gdk_drawable_create_cairo_context (window);
+  cairo_t *cr = gdk_cairo_create (window);
   gdk_cairo_set_source_color (cr, color);
   
   if (area)
     {
-      cairo_rectangle (cr, area->x, area->y, area->width, area->height);
+      gdk_cairo_rectangle (cr, area);
       cairo_clip (cr);
-      cairo_new_path (cr);
     }
     
   if (arrow_type == GTK_ARROW_DOWN)
@@ -3025,13 +3032,8 @@ gtk_default_draw_arrow (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  gint original_width, original_x;
-  
   sanitize_size (window, &width, &height);
 
-  original_width = width;
-  original_x = x;
-
   calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
 
   if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
@@ -3072,9 +3074,6 @@ gtk_default_draw_diamond (GtkStyle      *style,
   GdkGC *inner_sw = NULL;
   GdkGC *inner_se = NULL;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   sanitize_size (window, &width, &height);
   
   half_width = width / 2;
@@ -3192,13 +3191,6 @@ gtk_default_draw_string (GtkStyle      *style,
                          gint           y,
                          const gchar   *string)
 {
-  GdkDisplay *display;
-  
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
-  display = gdk_drawable_get_display (window);
-  
   if (area)
     {
       gdk_gc_set_clip_rectangle (style->white_gc, area);
@@ -3267,12 +3259,9 @@ gtk_default_draw_box (GtkStyle      *style,
 {
   gboolean is_spinbutton_box = FALSE;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   sanitize_size (window, &width, &height);
 
-  if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
+  if (GTK_IS_SPIN_BUTTON (widget) && detail)
     {
       if (strcmp (detail, "spinbutton_up") == 0)
        {
@@ -3392,7 +3381,7 @@ get_darkened_gc (GdkWindow *window,
 
   while (darken_count)
     {
-      gtk_style_shade (&src, &shaded, 0.93);
+      _gtk_style_shade (&src, &shaded, 0.93);
       src = shaded;
       --darken_count;
     }
@@ -3418,9 +3407,6 @@ gtk_default_draw_flat_box (GtkStyle      *style,
   GdkGC *gc1;
   GdkGC *freeme = NULL;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   sanitize_size (window, &width, &height);
   
   if (detail)
@@ -3429,15 +3415,26 @@ gtk_default_draw_flat_box (GtkStyle      *style,
         {
           if (!strcmp ("text", detail))
             gc1 = style->bg_gc[GTK_STATE_SELECTED];
-          else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
-                  !strncmp ("cell_odd", detail, strlen ("cell_odd")))
+          else if (!strcmp ("cell_even", detail) ||
+                   !strcmp ("cell_odd", detail) ||
+                   !strcmp ("cell_even_ruled", detail) ||
+                  !strcmp ("cell_even_ruled_sorted", detail))
             {
              /* This has to be really broken; alex made me do it. -jrb */
              if (GTK_WIDGET_HAS_FOCUS (widget))
                gc1 = style->base_gc[state_type];
-             else 
-               gc1 = style->base_gc[GTK_STATE_ACTIVE];
+             else
+               gc1 = style->base_gc[GTK_STATE_ACTIVE];
             }
+         else if (!strcmp ("cell_odd_ruled", detail) ||
+                  !strcmp ("cell_odd_ruled_sorted", detail))
+           {
+             if (GTK_WIDGET_HAS_FOCUS (widget))
+               freeme = get_darkened_gc (window, &style->base[state_type], 1);
+             else
+               freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
+             gc1 = freeme;
+           }
           else
             {
               gc1 = style->bg_gc[state_type];
@@ -3611,7 +3608,7 @@ gtk_default_draw_check (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  cairo_t *cr = gdk_drawable_create_cairo_context (window);
+  cairo_t *cr = gdk_cairo_create (window);
   enum { BUTTON, MENU, CELL } type = BUTTON;
   int exterior_size;
   int interior_size;
@@ -3627,9 +3624,8 @@ gtk_default_draw_check (GtkStyle      *style,
       
   if (area)
     {
-      cairo_rectangle (cr, area->x, area->y, area->width, area->height);
+      gdk_cairo_rectangle (cr, area);
       cairo_clip (cr);
-      cairo_new_path (cr);
     }
   
   exterior_size = MIN (width, height);
@@ -3737,7 +3733,7 @@ gtk_default_draw_option (GtkStyle      *style,
                         gint           width,
                         gint           height)
 {
-  cairo_t *cr = gdk_drawable_create_cairo_context (window);
+  cairo_t *cr = gdk_cairo_create (window);
   enum { BUTTON, MENU, CELL } type = BUTTON;
   int exterior_size;
   
@@ -3751,9 +3747,8 @@ gtk_default_draw_option (GtkStyle      *style,
       
   if (area)
     {
-      cairo_rectangle (cr, area->x, area->y, area->width, area->height);
+      gdk_cairo_rectangle (cr, area);
       cairo_clip (cr);
-      cairo_new_path (cr);
     }
   
   exterior_size = MIN (width, height);
@@ -3914,9 +3909,6 @@ gtk_default_draw_shadow_gap (GtkStyle       *style,
   GdkGC *gc3 = NULL;
   GdkGC *gc4 = NULL;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   sanitize_size (window, &width, &height);
   
   switch (shadow_type)
@@ -4130,9 +4122,6 @@ gtk_default_draw_box_gap (GtkStyle       *style,
   GdkGC *gc3 = NULL;
   GdkGC *gc4 = NULL;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   gtk_style_apply_default_background (style, window,
                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
                                       state_type, area, x, y, width, height);
@@ -4275,7 +4264,7 @@ gtk_default_draw_box_gap (GtkStyle       *style,
               gdk_draw_line (window, gc2,
                              x, y + gap_x, x, y + gap_x);
             }
-          if ((width - (gap_x + gap_width)) > 0)
+          if ((height - (gap_x + gap_width)) > 0)
             {
               gdk_draw_line (window, gc1,
                              x, y + gap_x + gap_width, x, y + height - 2);
@@ -4308,7 +4297,7 @@ gtk_default_draw_box_gap (GtkStyle       *style,
               gdk_draw_line (window, gc3,
                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
             }
-          if ((width - (gap_x + gap_width)) > 0)
+          if ((height - (gap_x + gap_width)) > 0)
             {
               gdk_draw_line (window, gc4,
                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
@@ -4349,9 +4338,6 @@ gtk_default_draw_extension (GtkStyle       *style,
   GdkGC *gc3 = NULL;
   GdkGC *gc4 = NULL;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   gtk_style_apply_default_background (style, window,
                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
                                       GTK_STATE_NORMAL, area, x, y, width, height);
@@ -4543,7 +4529,7 @@ gtk_default_draw_focus (GtkStyle      *style,
 
   sanitize_size (window, &width, &height);
 
-  cr = gdk_drawable_create_cairo_context (window);
+  cr = gdk_cairo_create (window);
   
   if (detail && !strcmp (detail, "colorwheel_light"))
     cairo_set_source_rgb (cr, 0., 0., 0.);
@@ -4583,10 +4569,8 @@ gtk_default_draw_focus (GtkStyle      *style,
 
   if (area)
     {
-      cairo_rectangle (cr,
-                      area->x, area->y, area->width, area->height);
+      gdk_cairo_rectangle (cr, area);
       cairo_clip (cr);
-      cairo_new_path (cr);
     }
 
   cairo_rectangle (cr,
@@ -4615,9 +4599,6 @@ gtk_default_draw_slider (GtkStyle      *style,
                          gint           height,
                          GtkOrientation orientation)
 {
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   sanitize_size (window, &width, &height);
   
   gtk_paint_box (style, window, state_type, shadow_type,
@@ -4646,7 +4627,6 @@ draw_dot (GdkWindow    *window,
          gint          y,
          gushort       size)
 {
-  
   size = CLAMP (size, 2, 3);
 
   if (size == 2)
@@ -4687,9 +4667,6 @@ gtk_default_draw_handle (GtkStyle      *style,
   GdkRectangle dest;
   gint intersect;
   
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   sanitize_size (window, &width, &height);
   
   gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
@@ -4705,9 +4682,9 @@ gtk_default_draw_handle (GtkStyle      *style,
       if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
        {
          GdkColor unfocused_light;
-      
-         gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
-                          LIGHTNESS_MULT);
+
+         _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
+                            LIGHTNESS_MULT);
 
          light_gc = free_me = gdk_gc_new (window);
          gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
@@ -4790,16 +4767,18 @@ gtk_default_draw_expander (GtkStyle        *style,
   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;
 
-  cairo_t *cr = gdk_drawable_create_cairo_context (window);
+  cairo_t *cr = gdk_cairo_create (window);
   
   if (area)
     {
-      cairo_rectangle (cr, area->x, area->y, area->width, area->height);
+      gdk_cairo_rectangle (cr, area);
       cairo_clip (cr);
-      cairo_new_path (cr);
     }
 
   if (widget &&
@@ -4819,15 +4798,19 @@ gtk_default_draw_expander (GtkStyle        *style,
     {
     case GTK_EXPANDER_COLLAPSED:
       degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
+      interp = 0.0;
       break;
     case GTK_EXPANDER_SEMI_COLLAPSED:
       degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
+      interp = 0.25;
       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;
       break;
     default:
       g_assert_not_reached ();
@@ -4851,20 +4834,29 @@ gtk_default_draw_expander (GtkStyle        *style,
   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
+   * 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.;
 
   /* Adjust the center so that the stroke is properly aligned with
-   * the pixel grid
+   * the pixel grid. The center adjustment is different for the
+   * horizontal and vertical orientations. For intermediate positions
+   * we interpolate between the two.
    */
-  x_double = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
-  y_double = y + 0.5;
+  x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
+  y_double_vert = y - 0.5;
+
+  x_double_horz = x - 0.5;
+  y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
+
+  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 * M_PI / 180);
+  cairo_rotate (cr, degrees * G_PI / 180);
 
   cairo_move_to (cr, - radius / 2., - radius);
   cairo_line_to (cr,   radius / 2.,   0);
@@ -5054,9 +5046,6 @@ gtk_default_draw_layout (GtkStyle        *style,
                          PangoLayout     *layout)
 {
   GdkGC *gc;
-  
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
 
   gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
   
@@ -5098,9 +5087,6 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
   GdkPoint points[4];
   gint i, j, skip;
 
-  g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (window != NULL);
-  
   if (area)
     {
       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
@@ -5402,10 +5388,10 @@ gtk_default_draw_resize_grip (GtkStyle       *style,
     }
 }
 
-static void
-gtk_style_shade (GdkColor *a,
-                 GdkColor *b,
-                 gdouble   k)
+void
+_gtk_style_shade (GdkColor *a,
+                  GdkColor *b,
+                  gdouble   k)
 {
   gdouble red;
   gdouble green;
@@ -6196,6 +6182,25 @@ gtk_paint_focus (GtkStyle      *style,
   GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
 }
 
+/**
+ * gtk_paint_slider:
+ * @style: a #GtkStyle
+ * @window: a #GdkWindow
+ * @state_type: a state
+ * @shadow_type: a shadow
+ * @area: clip rectangle, or %NULL if the
+ *        output should not be clipped
+ * @widget: the widget (may be %NULL)
+ * @detail: a style detail (may be %NULL)
+ * @x: the x origin of the rectangle in which to draw a slider
+ * @y: the y origin of the rectangle in which to draw a slider
+ * @width: the width of the rectangle in which to draw a slider
+ * @height: the height of the rectangle in which to draw a slider
+ * @orientation: the orientation to be used
+ *
+ * Draws a slider in the given rectangle on @window using the
+ * given style and orientation.
+ **/
 void
 gtk_paint_slider (GtkStyle      *style,
                   GdkWindow     *window,
@@ -6300,11 +6305,28 @@ gtk_paint_expander (GtkStyle        *style,
                                               widget, detail, x, y, expander_style);
 }
 
+/**
+ * gtk_paint_layout:
+ * @style: a #GtkStyle
+ * @window: a #GdkWindow
+ * @state_type: a state
+ * @use_text: whether to use the text or foreground
+ *            graphics context of @style
+ * @area: clip rectangle, or %NULL if the
+ *        output should not be clipped
+ * @widget: the widget (may be %NULL)
+ * @detail: a style detail (may be %NULL)
+ * @x: x origin
+ * @y: y origin
+ * @layout: the layout to draw
+ * 
+ * Draws a layout on @window using the given parameters.
+ **/
 void
 gtk_paint_layout (GtkStyle        *style,
                   GdkWindow       *window,
                   GtkStateType     state_type,
-                 gboolean         use_text,
+                  gboolean         use_text,
                   GdkRectangle    *area,
                   GtkWidget       *widget,
                   const gchar     *detail,
@@ -6392,7 +6414,7 @@ gtk_border_get_type (void)
   static GType our_type = 0;
   
   if (our_type == 0)
-    our_type = g_boxed_type_register_static ("GtkBorder",
+    our_type = g_boxed_type_register_static (I_("GtkBorder"),
                                             (GBoxedCopyFunc) gtk_border_copy,
                                             (GBoxedFreeFunc) gtk_border_free);
 
@@ -6531,7 +6553,7 @@ style_unrealize_cursor_gcs (GtkStyle *style)
        gtk_gc_release (cursor_info->secondary_gc);
       
       g_free (cursor_info);
-      g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
+      g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
     }
 }
 
@@ -6569,7 +6591,7 @@ get_insertion_cursor_gc (GtkWidget *widget,
   if (!cursor_info)
     {
       cursor_info = g_new (CursorInfo, 1);
-      g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
+      g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
       cursor_info->primary_gc = NULL;
       cursor_info->secondary_gc = NULL;
       cursor_info->for_type = G_TYPE_INVALID;
@@ -6633,8 +6655,10 @@ draw_insertion_cursor (GtkWidget        *widget,
   gfloat cursor_aspect_ratio;
   gint offset;
   
-  g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
-  
+  /* 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);
   
   stem_width = location->height * cursor_aspect_ratio + 1;