]> Pileus Git - ~andy/gtk/blob - gtk/deprecated/gtkstyle.c
filechooserbutton: Test that the expected filename is shown
[~andy/gtk] / gtk / deprecated / gtkstyle.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GTK+ Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
23  */
24
25 #include "config.h"
26
27 #define GDK_DISABLE_DEPRECATION_WARNINGS
28
29 #include <math.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <gobject/gvaluecollector.h>
33 #include "gtkmarshalers.h"
34 #include "gtkpango.h"
35 #include "gtkrc.h"
36 #include "gtkspinbutton.h"
37 #include "gtkstyle.h"
38 #include "gtkstylecontextprivate.h"
39 #include "gtkwidget.h"
40 #include "gtkwidgetprivate.h"
41 #include "gtkiconfactory.h"
42 #include "gtkintl.h"
43 #include "gtkdebug.h"
44 #include "gtkspinner.h"
45 #include "gtkborder.h"
46 #include "gtkwidgetpath.h"
47
48 /**
49  * SECTION:gtkstyle
50  * @Short_description: Deprecated object that holds style information
51  *     for widgets
52  * @Title: GtkStyle
53  *
54  * A #GtkStyle object encapsulates the information that provides the look and
55  * feel for a widget.
56  *
57  * <warning>
58  * In GTK+ 3.0, GtkStyle has been deprecated and replaced by #GtkStyleContext.
59  * </warning>
60  *
61  * Each #GtkWidget has an associated #GtkStyle object that is used when
62  * rendering that widget. Also, a #GtkStyle holds information for the five
63  * possible widget states though not every widget supports all five
64  * states; see #GtkStateType.
65  *
66  * Usually the #GtkStyle for a widget is the same as the default style that
67  * is set by GTK+ and modified the theme engine.
68  *
69  * Usually applications should not need to use or modify the #GtkStyle of
70  * their widgets.
71  */
72
73
74 #define LIGHTNESS_MULT  1.3
75 #define DARKNESS_MULT   0.7
76
77 /* --- typedefs & structures --- */
78 typedef struct {
79   GType       widget_type;
80   GParamSpec *pspec;
81   GValue      value;
82 } PropertyValue;
83
84 #define GTK_STYLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_STYLE, GtkStylePrivate))
85
86 typedef struct _GtkStylePrivate GtkStylePrivate;
87
88 struct _GtkStylePrivate {
89   GtkStyleContext *context;
90   gulong context_changed_id;
91 };
92
93 enum {
94   PROP_0,
95   PROP_CONTEXT
96 };
97
98 /* --- prototypes --- */
99 static void      gtk_style_finalize             (GObject        *object);
100 static void      gtk_style_constructed          (GObject        *object);
101 static void      gtk_style_set_property         (GObject        *object,
102                                                  guint           prop_id,
103                                                  const GValue   *value,
104                                                  GParamSpec     *pspec);
105 static void      gtk_style_get_property         (GObject        *object,
106                                                  guint           prop_id,
107                                                  GValue         *value,
108                                                  GParamSpec     *pspec);
109
110 static void      gtk_style_real_realize        (GtkStyle        *style);
111 static void      gtk_style_real_unrealize      (GtkStyle        *style);
112 static void      gtk_style_real_copy           (GtkStyle        *style,
113                                                 GtkStyle        *src);
114 static void      gtk_style_real_set_background (GtkStyle        *style,
115                                                 GdkWindow       *window,
116                                                 GtkStateType     state_type);
117 static GtkStyle *gtk_style_real_clone          (GtkStyle        *style);
118 static void      gtk_style_real_init_from_rc   (GtkStyle        *style,
119                                                 GtkRcStyle      *rc_style);
120 static GdkPixbuf *gtk_default_render_icon      (GtkStyle            *style,
121                                                 const GtkIconSource *source,
122                                                 GtkTextDirection     direction,
123                                                 GtkStateType         state,
124                                                 GtkIconSize          size,
125                                                 GtkWidget           *widget,
126                                                 const gchar         *detail);
127 static void gtk_default_draw_hline      (GtkStyle        *style,
128                                          cairo_t         *cr,
129                                          GtkStateType     state_type,
130                                          GtkWidget       *widget,
131                                          const gchar     *detail,
132                                          gint             x1,
133                                          gint             x2,
134                                          gint             y);
135 static void gtk_default_draw_vline      (GtkStyle        *style,
136                                          cairo_t         *cr,
137                                          GtkStateType     state_type,
138                                          GtkWidget       *widget,
139                                          const gchar     *detail,
140                                          gint             y1,
141                                          gint             y2,
142                                          gint             x);
143 static void gtk_default_draw_shadow     (GtkStyle        *style,
144                                          cairo_t         *cr,
145                                          GtkStateType     state_type,
146                                          GtkShadowType    shadow_type,
147                                          GtkWidget       *widget,
148                                          const gchar     *detail,
149                                          gint             x,
150                                          gint             y,
151                                          gint             width,
152                                          gint             height);
153 static void gtk_default_draw_arrow      (GtkStyle        *style,
154                                          cairo_t         *cr,
155                                          GtkStateType     state_type,
156                                          GtkShadowType    shadow_type,
157                                          GtkWidget       *widget,
158                                          const gchar     *detail,
159                                          GtkArrowType     arrow_type,
160                                          gboolean         fill,
161                                          gint             x,
162                                          gint             y,
163                                          gint             width,
164                                          gint             height);
165 static void gtk_default_draw_diamond    (GtkStyle        *style,
166                                          cairo_t         *cr,
167                                          GtkStateType     state_type,
168                                          GtkShadowType    shadow_type,
169                                          GtkWidget       *widget,
170                                          const gchar     *detail,
171                                          gint             x,
172                                          gint             y,
173                                          gint             width,
174                                          gint             height);
175 static void gtk_default_draw_box        (GtkStyle        *style,
176                                          cairo_t         *cr,
177                                          GtkStateType     state_type,
178                                          GtkShadowType    shadow_type,
179                                          GtkWidget       *widget,
180                                          const gchar     *detail,
181                                          gint             x,
182                                          gint             y,
183                                          gint             width,
184                                          gint             height);
185 static void gtk_default_draw_flat_box   (GtkStyle        *style,
186                                          cairo_t         *cr,
187                                          GtkStateType     state_type,
188                                          GtkShadowType    shadow_type,
189                                          GtkWidget       *widget,
190                                          const gchar     *detail,
191                                          gint             x,
192                                          gint             y,
193                                          gint             width,
194                                          gint             height);
195 static void gtk_default_draw_check      (GtkStyle        *style,
196                                          cairo_t         *cr,
197                                          GtkStateType     state_type,
198                                          GtkShadowType    shadow_type,
199                                          GtkWidget       *widget,
200                                          const gchar     *detail,
201                                          gint             x,
202                                          gint             y,
203                                          gint             width,
204                                          gint             height);
205 static void gtk_default_draw_option     (GtkStyle        *style,
206                                          cairo_t         *cr,
207                                          GtkStateType     state_type,
208                                          GtkShadowType    shadow_type,
209                                          GtkWidget       *widget,
210                                          const gchar     *detail,
211                                          gint             x,
212                                          gint             y,
213                                          gint             width,
214                                          gint             height);
215 static void gtk_default_draw_tab        (GtkStyle        *style,
216                                          cairo_t         *cr,
217                                          GtkStateType     state_type,
218                                          GtkShadowType    shadow_type,
219                                          GtkWidget       *widget,
220                                          const gchar     *detail,
221                                          gint             x,
222                                          gint             y,
223                                          gint             width,
224                                          gint             height);
225 static void gtk_default_draw_shadow_gap (GtkStyle        *style,
226                                          cairo_t         *cr,
227                                          GtkStateType     state_type,
228                                          GtkShadowType    shadow_type,
229                                          GtkWidget       *widget,
230                                          const gchar     *detail,
231                                          gint             x,
232                                          gint             y,
233                                          gint             width,
234                                          gint             height,
235                                          GtkPositionType  gap_side,
236                                          gint             gap_x,
237                                          gint             gap_width);
238 static void gtk_default_draw_box_gap    (GtkStyle        *style,
239                                          cairo_t         *cr,
240                                          GtkStateType     state_type,
241                                          GtkShadowType    shadow_type,
242                                          GtkWidget       *widget,
243                                          const gchar     *detail,
244                                          gint             x,
245                                          gint             y,
246                                          gint             width,
247                                          gint             height,
248                                          GtkPositionType  gap_side,
249                                          gint             gap_x,
250                                          gint             gap_width);
251 static void gtk_default_draw_extension  (GtkStyle        *style,
252                                          cairo_t         *cr,
253                                          GtkStateType     state_type,
254                                          GtkShadowType    shadow_type,
255                                          GtkWidget       *widget,
256                                          const gchar     *detail,
257                                          gint             x,
258                                          gint             y,
259                                          gint             width,
260                                          gint             height,
261                                          GtkPositionType  gap_side);
262 static void gtk_default_draw_focus      (GtkStyle        *style,
263                                          cairo_t         *cr,
264                                          GtkStateType     state_type,
265                                          GtkWidget       *widget,
266                                          const gchar     *detail,
267                                          gint             x,
268                                          gint             y,
269                                          gint             width,
270                                          gint             height);
271 static void gtk_default_draw_slider     (GtkStyle        *style,
272                                          cairo_t         *cr,
273                                          GtkStateType     state_type,
274                                          GtkShadowType    shadow_type,
275                                          GtkWidget       *widget,
276                                          const gchar     *detail,
277                                          gint             x,
278                                          gint             y,
279                                          gint             width,
280                                          gint             height,
281                                          GtkOrientation   orientation);
282 static void gtk_default_draw_handle     (GtkStyle        *style,
283                                          cairo_t         *cr,
284                                          GtkStateType     state_type,
285                                          GtkShadowType    shadow_type,
286                                          GtkWidget       *widget,
287                                          const gchar     *detail,
288                                          gint             x,
289                                          gint             y,
290                                          gint             width,
291                                          gint             height,
292                                          GtkOrientation   orientation);
293 static void gtk_default_draw_expander   (GtkStyle        *style,
294                                          cairo_t         *cr,
295                                          GtkStateType     state_type,
296                                          GtkWidget       *widget,
297                                          const gchar     *detail,
298                                          gint             x,
299                                          gint             y,
300                                          GtkExpanderStyle expander_style);
301 static void gtk_default_draw_layout     (GtkStyle        *style,
302                                          cairo_t         *cr,
303                                          GtkStateType     state_type,
304                                          gboolean         use_text,
305                                          GtkWidget       *widget,
306                                          const gchar     *detail,
307                                          gint             x,
308                                          gint             y,
309                                          PangoLayout     *layout);
310 static void gtk_default_draw_resize_grip (GtkStyle       *style,
311                                           cairo_t        *cr,
312                                           GtkStateType    state_type,
313                                           GtkWidget      *widget,
314                                           const gchar    *detail,
315                                           GdkWindowEdge   edge,
316                                           gint            x,
317                                           gint            y,
318                                           gint            width,
319                                           gint            height);
320 static void gtk_default_draw_spinner     (GtkStyle       *style,
321                                           cairo_t        *cr,
322                                           GtkStateType    state_type,
323                                           GtkWidget      *widget,
324                                           const gchar    *detail,
325                                           guint           step,
326                                           gint            x,
327                                           gint            y,
328                                           gint            width,
329                                           gint            height);
330
331 static void rgb_to_hls                  (gdouble         *r,
332                                          gdouble         *g,
333                                          gdouble         *b);
334 static void hls_to_rgb                  (gdouble         *h,
335                                          gdouble         *l,
336                                          gdouble         *s);
337
338 static void transform_detail_string (const gchar     *detail,
339                                      GtkStyleContext *context);
340
341 /*
342  * Data for default check and radio buttons
343  */
344
345 static const GtkRequisition default_option_indicator_size = { 7, 13 };
346 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
347
348 #define GTK_GRAY                0xdcdc, 0xdada, 0xd5d5
349 #define GTK_DARK_GRAY           0xc4c4, 0xc2c2, 0xbdbd
350 #define GTK_LIGHT_GRAY          0xeeee, 0xebeb, 0xe7e7
351 #define GTK_WHITE               0xffff, 0xffff, 0xffff
352 #define GTK_BLUE                0x4b4b, 0x6969, 0x8383
353 #define GTK_VERY_DARK_GRAY      0x9c9c, 0x9a9a, 0x9494
354 #define GTK_BLACK               0x0000, 0x0000, 0x0000
355 #define GTK_WEAK_GRAY           0x7530, 0x7530, 0x7530
356
357 /* --- variables --- */
358 static const GdkColor gtk_default_normal_fg =      { 0, GTK_BLACK };
359 static const GdkColor gtk_default_active_fg =      { 0, GTK_BLACK };
360 static const GdkColor gtk_default_prelight_fg =    { 0, GTK_BLACK };
361 static const GdkColor gtk_default_selected_fg =    { 0, GTK_WHITE };
362 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
363
364 static const GdkColor gtk_default_normal_bg =      { 0, GTK_GRAY };
365 static const GdkColor gtk_default_active_bg =      { 0, GTK_DARK_GRAY };
366 static const GdkColor gtk_default_prelight_bg =    { 0, GTK_LIGHT_GRAY };
367 static const GdkColor gtk_default_selected_bg =    { 0, GTK_BLUE };
368 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
369 static const GdkColor gtk_default_selected_base =  { 0, GTK_BLUE };
370 static const GdkColor gtk_default_active_base =    { 0, GTK_VERY_DARK_GRAY };
371
372 /* --- signals --- */
373 static guint realize_signal = 0;
374 static guint unrealize_signal = 0;
375
376 G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
377
378 /* --- functions --- */
379
380 static void
381 gtk_style_init (GtkStyle *style)
382 {
383   gint i;
384
385   style->font_desc = pango_font_description_from_string ("Sans 10");
386
387   style->attach_count = 0;
388   
389   style->black.red = 0;
390   style->black.green = 0;
391   style->black.blue = 0;
392   
393   style->white.red = 65535;
394   style->white.green = 65535;
395   style->white.blue = 65535;
396   
397   style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
398   style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
399   style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
400   style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
401   style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
402   
403   style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
404   style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
405   style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
406   style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
407   style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
408   
409   for (i = 0; i < 4; i++)
410     {
411       style->text[i] = style->fg[i];
412       style->base[i] = style->white;
413     }
414
415   style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
416   style->text[GTK_STATE_SELECTED] = style->white;
417   style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
418   style->text[GTK_STATE_ACTIVE] = style->white;
419   style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
420   style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
421   
422   style->rc_style = NULL;
423   
424   style->xthickness = 2;
425   style->ythickness = 2;
426
427   style->property_cache = NULL;
428 }
429
430 static void
431 gtk_style_class_init (GtkStyleClass *klass)
432 {
433   GObjectClass *object_class = G_OBJECT_CLASS (klass);
434   
435   object_class->finalize = gtk_style_finalize;
436   object_class->set_property = gtk_style_set_property;
437   object_class->get_property = gtk_style_get_property;
438   object_class->constructed = gtk_style_constructed;
439
440   klass->clone = gtk_style_real_clone;
441   klass->copy = gtk_style_real_copy;
442   klass->init_from_rc = gtk_style_real_init_from_rc;
443   klass->realize = gtk_style_real_realize;
444   klass->unrealize = gtk_style_real_unrealize;
445   klass->set_background = gtk_style_real_set_background;
446   klass->render_icon = gtk_default_render_icon;
447
448   klass->draw_hline = gtk_default_draw_hline;
449   klass->draw_vline = gtk_default_draw_vline;
450   klass->draw_shadow = gtk_default_draw_shadow;
451   klass->draw_arrow = gtk_default_draw_arrow;
452   klass->draw_diamond = gtk_default_draw_diamond;
453   klass->draw_box = gtk_default_draw_box;
454   klass->draw_flat_box = gtk_default_draw_flat_box;
455   klass->draw_check = gtk_default_draw_check;
456   klass->draw_option = gtk_default_draw_option;
457   klass->draw_tab = gtk_default_draw_tab;
458   klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
459   klass->draw_box_gap = gtk_default_draw_box_gap;
460   klass->draw_extension = gtk_default_draw_extension;
461   klass->draw_focus = gtk_default_draw_focus;
462   klass->draw_slider = gtk_default_draw_slider;
463   klass->draw_handle = gtk_default_draw_handle;
464   klass->draw_expander = gtk_default_draw_expander;
465   klass->draw_layout = gtk_default_draw_layout;
466   klass->draw_resize_grip = gtk_default_draw_resize_grip;
467   klass->draw_spinner = gtk_default_draw_spinner;
468
469   g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
470
471   g_object_class_install_property (object_class,
472                                    PROP_CONTEXT,
473                                    g_param_spec_object ("context",
474                                                         P_("Style context"),
475                                                         P_("GtkStyleContext to get style from"),
476                                                         GTK_TYPE_STYLE_CONTEXT,
477                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
478
479   /**
480    * GtkStyle::realize:
481    * @style: the object which received the signal
482    *
483    * Emitted when the style has been initialized for a particular
484    * visual. Connecting to this signal is probably seldom
485    * useful since most of the time applications and widgets only
486    * deal with styles that have been already realized.
487    *
488    * Since: 2.4
489    */
490   realize_signal = g_signal_new (I_("realize"),
491                                  G_TYPE_FROM_CLASS (object_class),
492                                  G_SIGNAL_RUN_FIRST,
493                                  G_STRUCT_OFFSET (GtkStyleClass, realize),
494                                  NULL, NULL,
495                                  _gtk_marshal_VOID__VOID,
496                                  G_TYPE_NONE, 0);
497   /**
498    * GtkStyle::unrealize:
499    * @style: the object which received the signal
500    *
501    * Emitted when the aspects of the style specific to a particular visual
502    * is being cleaned up. A connection to this signal can be useful
503    * if a widget wants to cache objects as object data on #GtkStyle.
504    * This signal provides a convenient place to free such cached objects.
505    *
506    * Since: 2.4
507    */
508   unrealize_signal = g_signal_new (I_("unrealize"),
509                                    G_TYPE_FROM_CLASS (object_class),
510                                    G_SIGNAL_RUN_FIRST,
511                                    G_STRUCT_OFFSET (GtkStyleClass, unrealize),
512                                    NULL, NULL,
513                                    _gtk_marshal_VOID__VOID,
514                                    G_TYPE_NONE, 0);
515 }
516
517 static void
518 gtk_style_finalize (GObject *object)
519 {
520   GtkStyle *style = GTK_STYLE (object);
521   GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
522   gint i;
523
524   g_return_if_fail (style->attach_count == 0);
525
526   /* All the styles in the list have the same 
527    * style->styles pointer. If we delete the 
528    * *first* style from the list, we need to update
529    * the style->styles pointers from all the styles.
530    * Otherwise we simply remove the node from
531    * the list.
532    */
533   if (style->styles)
534     {
535       if (style->styles->data != style)
536         style->styles = g_slist_remove (style->styles, style);
537       else
538         {
539           GSList *tmp_list = style->styles->next;
540           
541           while (tmp_list)
542             {
543               GTK_STYLE (tmp_list->data)->styles = style->styles->next;
544               tmp_list = tmp_list->next;
545             }
546           g_slist_free_1 (style->styles);
547         }
548     }
549
550   g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
551   g_slist_free (style->icon_factories);
552
553   pango_font_description_free (style->font_desc);
554
555   if (style->private_font_desc)
556     pango_font_description_free (style->private_font_desc);
557
558   if (style->rc_style)
559     g_object_unref (style->rc_style);
560
561   if (priv->context)
562     {
563       if (priv->context_changed_id)
564         g_signal_handler_disconnect (priv->context, priv->context_changed_id);
565
566       g_object_unref (priv->context);
567     }
568
569   for (i = 0; i < 5; i++)
570     {
571       if (style->background[i])
572         cairo_pattern_destroy (style->background[i]);
573     }
574
575   G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
576 }
577
578 static void
579 gtk_style_set_property (GObject      *object,
580                         guint         prop_id,
581                         const GValue *value,
582                         GParamSpec   *pspec)
583 {
584   GtkStylePrivate *priv;
585
586   priv = GTK_STYLE_GET_PRIVATE (object);
587
588   switch (prop_id)
589     {
590     case PROP_CONTEXT:
591       priv->context = g_value_dup_object (value);
592       break;
593     default:
594       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
595       break;
596     }
597 }
598
599 static void
600 gtk_style_get_property (GObject      *object,
601                         guint         prop_id,
602                         GValue       *value,
603                         GParamSpec   *pspec)
604 {
605   GtkStylePrivate *priv;
606
607   priv = GTK_STYLE_GET_PRIVATE (object);
608
609   switch (prop_id)
610     {
611     case PROP_CONTEXT:
612       g_value_set_object (value, priv->context);
613       break;
614     default:
615       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
616       break;
617     }
618 }
619
620 static gboolean
621 set_color_from_context (GtkStyle *style,
622                         GtkStateType state,
623                         GtkStyleContext *context,
624                         GtkStateFlags flags,
625                         GtkRcFlags prop)
626 {
627   GdkRGBA *color = NULL;
628   GdkColor *dest = { 0 }; /* Shut up gcc */
629
630   switch (prop)
631     {
632     case GTK_RC_BG:
633       gtk_style_context_get (context, flags,
634                              "background-color", &color,
635                              NULL);
636       dest = &style->bg[state];
637       break;
638     case GTK_RC_FG:
639       gtk_style_context_get (context, flags,
640                              "color", &color,
641                              NULL);
642       dest = &style->fg[state];
643       break;
644     case GTK_RC_TEXT:
645       gtk_style_context_get (context, flags,
646                              "color", &color,
647                              NULL);
648       dest = &style->text[state];
649       break;
650     case GTK_RC_BASE:
651       gtk_style_context_get (context, flags,
652                              "background-color", &color,
653                              NULL);
654       dest = &style->base[state];
655       break;
656     }
657
658   if (!color)
659     return FALSE;
660
661   if (!(color->alpha > 0.01))
662     {
663       gdk_rgba_free (color);
664       return FALSE;
665     }
666
667   dest->pixel = 0;
668   dest->red = CLAMP ((guint) (color->red * 65535), 0, 65535);
669   dest->green = CLAMP ((guint) (color->green * 65535), 0, 65535);
670   dest->blue = CLAMP ((guint) (color->blue * 65535), 0, 65535);
671   gdk_rgba_free (color);
672
673   return TRUE;
674 }
675
676 static void
677 set_color (GtkStyle        *style,
678            GtkStyleContext *context,
679            GtkStateType     state,
680            GtkRcFlags       prop)
681 {
682   GtkStateFlags flags;
683
684   switch (state)
685     {
686     case GTK_STATE_ACTIVE:
687       flags = GTK_STATE_FLAG_ACTIVE;
688       break;
689     case GTK_STATE_PRELIGHT:
690       flags = GTK_STATE_FLAG_PRELIGHT;
691       break;
692     case GTK_STATE_SELECTED:
693       flags = GTK_STATE_FLAG_SELECTED;
694       break;
695     case GTK_STATE_INSENSITIVE:
696       flags = GTK_STATE_FLAG_INSENSITIVE;
697       break;
698     default:
699       flags = 0;
700     }
701
702   /* Try to fill in the values from the associated GtkStyleContext.
703    * Since fully-transparent black is a very common default (e.g. for 
704    * background-color properties), and we must store the result in a GdkColor
705    * to retain API compatibility, in case the fetched color is fully transparent
706    * we give themes a fallback style class they can style, before using the
707    * hardcoded default values.
708    */
709   if (!set_color_from_context (style, state, context, flags, prop))
710     {
711       gtk_style_context_save (context);
712       gtk_style_context_add_class (context, "gtkstyle-fallback");
713       set_color_from_context (style, state, context, flags, prop);
714       gtk_style_context_restore (context);
715     }
716 }
717
718 static void
719 gtk_style_update_from_context (GtkStyle *style)
720 {
721   GtkStylePrivate *priv;
722   GtkStateType state;
723   GtkBorder padding;
724   gint i;
725
726   priv = GTK_STYLE_GET_PRIVATE (style);
727
728   for (state = GTK_STATE_NORMAL; state <= GTK_STATE_INSENSITIVE; state++)
729     {
730       if (gtk_style_context_has_class (priv->context, "entry"))
731         {
732           gtk_style_context_save (priv->context);
733           gtk_style_context_remove_class (priv->context, "entry");
734           set_color (style, priv->context, state, GTK_RC_BG);
735           set_color (style, priv->context, state, GTK_RC_FG);
736           gtk_style_context_restore (priv->context);
737
738           set_color (style, priv->context, state, GTK_RC_BASE);
739           set_color (style, priv->context, state, GTK_RC_TEXT);
740         }
741       else
742         {
743           gtk_style_context_save (priv->context);
744           gtk_style_context_add_class (priv->context, "entry");
745           set_color (style, priv->context, state, GTK_RC_BASE);
746           set_color (style, priv->context, state, GTK_RC_TEXT);
747           gtk_style_context_restore (priv->context);
748
749           set_color (style, priv->context, state, GTK_RC_BG);
750           set_color (style, priv->context, state, GTK_RC_FG);
751         }
752     }
753
754   if (style->font_desc)
755     pango_font_description_free (style->font_desc);
756
757   gtk_style_context_get (priv->context, 0,
758                          "font", &style->font_desc,
759                          NULL);
760   gtk_style_context_get_padding (priv->context, 0, &padding);
761
762   style->xthickness = padding.left;
763   style->ythickness = padding.top;
764
765   for (i = 0; i < 5; i++)
766     {
767       _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
768       _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
769
770       style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
771       style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
772       style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
773
774       style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
775       style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
776       style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
777     }
778
779   style->black.red = 0x0000;
780   style->black.green = 0x0000;
781   style->black.blue = 0x0000;
782
783   style->white.red = 0xffff;
784   style->white.green = 0xffff;
785   style->white.blue = 0xffff;
786
787   for (i = 0; i < 5; i++)
788     {
789       if (style->background[i])
790         cairo_pattern_destroy (style->background[i]);
791
792       style->background[i] = cairo_pattern_create_rgb (style->bg[i].red / 65535.0,
793                                                        style->bg[i].green / 65535.0,
794                                                        style->bg[i].blue / 65535.0);
795     }
796 }
797
798 static void
799 style_context_changed (GtkStyleContext *context,
800                        gpointer         user_data)
801 {
802   gtk_style_update_from_context (GTK_STYLE (user_data));
803 }
804
805 static void
806 gtk_style_constructed (GObject *object)
807 {
808   GtkStylePrivate *priv;
809
810   priv = GTK_STYLE_GET_PRIVATE (object);
811
812   if (priv->context)
813     {
814       gtk_style_update_from_context (GTK_STYLE (object));
815
816       priv->context_changed_id = g_signal_connect (priv->context, "changed",
817                                                    G_CALLBACK (style_context_changed), object);
818     }
819 }
820
821 /**
822  * gtk_style_copy:
823  * @style: a #GtkStyle
824  *
825  * Creates a copy of the passed in #GtkStyle object.
826  *
827  * Returns: (transfer full): a copy of @style
828  *
829  * Deprecated:3.0: Use #GtkStyleContext instead
830  */
831 GtkStyle*
832 gtk_style_copy (GtkStyle *style)
833 {
834   GtkStyle *new_style;
835   
836   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
837   
838   new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
839   GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
840
841   return new_style;
842 }
843
844 GtkStyle*
845 _gtk_style_new_for_path (GdkScreen     *screen,
846                          GtkWidgetPath *path)
847 {
848   GtkStyleContext *context;
849   GtkStyle *style;
850
851   context = gtk_style_context_new ();
852
853   if (screen)
854     gtk_style_context_set_screen (context, screen);
855
856   gtk_style_context_set_path (context, path);
857
858   style = g_object_new (GTK_TYPE_STYLE,
859                         "context", context,
860                         NULL);
861
862   g_object_unref (context);
863
864   return style;
865 }
866
867 /**
868  * gtk_style_new:
869  *
870  * Creates a new #GtkStyle.
871  *
872  * Returns: a new #GtkStyle.
873  *
874  * Deprecated: 3.0: Use #GtkStyleContext
875  */
876 GtkStyle*
877 gtk_style_new (void)
878 {
879   GtkWidgetPath *path;
880   GtkStyle *style;
881
882   path = gtk_widget_path_new ();
883   gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
884
885   style = _gtk_style_new_for_path (gdk_screen_get_default (), path);
886
887   gtk_widget_path_free (path);
888
889   return style;
890 }
891
892 /**
893  * gtk_style_has_context:
894  * @style: a #GtkStyle
895  *
896  * Returns whether @style has an associated #GtkStyleContext.
897  *
898  * Returns: %TRUE if @style has a #GtkStyleContext
899  *
900  * Since: 3.0
901  */
902 gboolean
903 gtk_style_has_context (GtkStyle *style)
904 {
905   GtkStylePrivate *priv;
906
907   priv = GTK_STYLE_GET_PRIVATE (style);
908
909   return priv->context != NULL;
910 }
911
912 /**
913  * gtk_style_attach: (skip)
914  * @style: a #GtkStyle.
915  * @window: a #GdkWindow.
916  *
917  * Attaches a style to a window; this process allocates the
918  * colors and creates the GC's for the style - it specializes
919  * it to a particular visual. The process may involve the creation
920  * of a new style if the style has already been attached to a
921  * window with a different style and visual.
922  *
923  * Since this function may return a new object, you have to use it
924  * in the following way:
925  * <literal>style = gtk_style_attach (style, window)</literal>
926  *
927  * Returns: Either @style, or a newly-created #GtkStyle.
928  *   If the style is newly created, the style parameter
929  *   will be unref'ed, and the new style will have
930  *   a reference count belonging to the caller.
931  *
932  * Deprecated:3.0: Use gtk_widget_style_attach() instead
933  */
934 GtkStyle*
935 gtk_style_attach (GtkStyle  *style,
936                   GdkWindow *window)
937 {
938   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
939   g_return_val_if_fail (window != NULL, NULL);
940
941   return style;
942 }
943
944 /**
945  * gtk_style_detach:
946  * @style: a #GtkStyle
947  *
948  * Detaches a style from a window. If the style is not attached
949  * to any windows anymore, it is unrealized. See gtk_style_attach().
950  *
951  * Deprecated:3.0: Use #GtkStyleContext instead
952  */
953 void
954 gtk_style_detach (GtkStyle *style)
955 {
956   g_return_if_fail (GTK_IS_STYLE (style));
957 }
958
959 /**
960  * gtk_style_lookup_icon_set:
961  * @style: a #GtkStyle
962  * @stock_id: an icon name
963  *
964  * Looks up @stock_id in the icon factories associated with @style
965  * and the default icon factory, returning an icon set if found,
966  * otherwise %NULL.
967  *
968  * Return value: (transfer none): icon set of @stock_id
969  *
970  * Deprecated:3.0: Use gtk_style_context_lookup_icon_set() instead
971  */
972 GtkIconSet*
973 gtk_style_lookup_icon_set (GtkStyle   *style,
974                            const char *stock_id)
975 {
976   GtkStylePrivate *priv;
977
978   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
979   g_return_val_if_fail (stock_id != NULL, NULL);
980
981   priv = GTK_STYLE_GET_PRIVATE (style);
982
983   if (priv->context)
984     return gtk_style_context_lookup_icon_set (priv->context, stock_id);
985
986   return gtk_icon_factory_lookup_default (stock_id);
987 }
988
989 /**
990  * gtk_style_lookup_color:
991  * @style: a #GtkStyle
992  * @color_name: the name of the logical color to look up
993  * @color: (out): the #GdkColor to fill in
994  *
995  * Looks up @color_name in the style's logical color mappings,
996  * filling in @color and returning %TRUE if found, otherwise
997  * returning %FALSE. Do not cache the found mapping, because
998  * it depends on the #GtkStyle and might change when a theme
999  * switch occurs.
1000  *
1001  * Return value: %TRUE if the mapping was found.
1002  *
1003  * Since: 2.10
1004  *
1005  * Deprecated:3.0: Use gtk_style_context_lookup_color() instead
1006  **/
1007 gboolean
1008 gtk_style_lookup_color (GtkStyle   *style,
1009                         const char *color_name,
1010                         GdkColor   *color)
1011 {
1012   GtkStylePrivate *priv;
1013   gboolean result;
1014   GdkRGBA rgba;
1015
1016   g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
1017   g_return_val_if_fail (color_name != NULL, FALSE);
1018   g_return_val_if_fail (color != NULL, FALSE);
1019
1020   priv = GTK_STYLE_GET_PRIVATE (style);
1021
1022   if (!priv->context)
1023     return FALSE;
1024
1025   result = gtk_style_context_lookup_color (priv->context, color_name, &rgba);
1026
1027   if (color)
1028     {
1029       color->red = (guint16) (rgba.red * 65535);
1030       color->green = (guint16) (rgba.green * 65535);
1031       color->blue = (guint16) (rgba.blue * 65535);
1032       color->pixel = 0;
1033     }
1034
1035   return result;
1036 }
1037
1038 /**
1039  * gtk_style_set_background:
1040  * @style: a #GtkStyle
1041  * @window: a #GdkWindow
1042  * @state_type: a state
1043  * 
1044  * Sets the background of @window to the background color or pixmap
1045  * specified by @style for the given state.
1046  *
1047  * Deprecated:3.0: Use gtk_style_context_set_background() instead
1048  */
1049 void
1050 gtk_style_set_background (GtkStyle    *style,
1051                           GdkWindow   *window,
1052                           GtkStateType state_type)
1053 {
1054   g_return_if_fail (GTK_IS_STYLE (style));
1055   g_return_if_fail (window != NULL);
1056   
1057   GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1058 }
1059
1060 /* Default functions */
1061 static GtkStyle *
1062 gtk_style_real_clone (GtkStyle *style)
1063 {
1064   GtkStylePrivate *priv;
1065
1066   priv = GTK_STYLE_GET_PRIVATE (style);
1067
1068   return g_object_new (G_OBJECT_TYPE (style),
1069                        "context", priv->context,
1070                        NULL);
1071 }
1072
1073 static void
1074 gtk_style_real_copy (GtkStyle *style,
1075                      GtkStyle *src)
1076 {
1077   gint i;
1078   
1079   for (i = 0; i < 5; i++)
1080     {
1081       style->fg[i] = src->fg[i];
1082       style->bg[i] = src->bg[i];
1083       style->text[i] = src->text[i];
1084       style->base[i] = src->base[i];
1085
1086       if (style->background[i])
1087         cairo_pattern_destroy (style->background[i]),
1088       style->background[i] = src->background[i];
1089       if (style->background[i])
1090         cairo_pattern_reference (style->background[i]);
1091     }
1092
1093   if (style->font_desc)
1094     pango_font_description_free (style->font_desc);
1095   if (src->font_desc)
1096     style->font_desc = pango_font_description_copy (src->font_desc);
1097   else
1098     style->font_desc = NULL;
1099   
1100   style->xthickness = src->xthickness;
1101   style->ythickness = src->ythickness;
1102
1103   if (style->rc_style)
1104     g_object_unref (style->rc_style);
1105   style->rc_style = src->rc_style;
1106   if (src->rc_style)
1107     g_object_ref (src->rc_style);
1108
1109   g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
1110   g_slist_free (style->icon_factories);
1111   style->icon_factories = g_slist_copy (src->icon_factories);
1112   g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1113 }
1114
1115 static void
1116 gtk_style_real_init_from_rc (GtkStyle   *style,
1117                              GtkRcStyle *rc_style)
1118 {
1119 }
1120
1121 /**
1122  * gtk_style_get_style_property:
1123  * @style: a #GtkStyle
1124  * @widget_type: the #GType of a descendant of #GtkWidget
1125  * @property_name: the name of the style property to get
1126  * @value: a #GValue where the value of the property being
1127  *     queried will be stored
1128  *
1129  * Queries the value of a style property corresponding to a
1130  * widget class is in the given style.
1131  *
1132  * Since: 2.16
1133  */
1134 void 
1135 gtk_style_get_style_property (GtkStyle     *style,
1136                               GType        widget_type,
1137                               const gchar *property_name,
1138                               GValue      *value)
1139 {
1140   GtkStylePrivate *priv;
1141   GtkWidgetClass *klass;
1142   GParamSpec *pspec;
1143   const GValue *peek_value;
1144
1145   klass = g_type_class_ref (widget_type);
1146   pspec = gtk_widget_class_find_style_property (klass, property_name);
1147   g_type_class_unref (klass);
1148
1149   if (!pspec)
1150     {
1151       g_warning ("%s: widget class `%s' has no property named `%s'",
1152                  G_STRLOC,
1153                  g_type_name (widget_type),
1154                  property_name);
1155       return;
1156     }
1157
1158   priv = GTK_STYLE_GET_PRIVATE (style);
1159   peek_value = _gtk_style_context_peek_style_property (priv->context,
1160                                                        widget_type,
1161                                                        0, pspec);
1162
1163   if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1164     g_value_copy (peek_value, value);
1165   else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1166     g_value_transform (peek_value, value);
1167   else
1168     g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
1169                pspec->name,
1170                g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1171                G_VALUE_TYPE_NAME (value));
1172 }
1173
1174 /**
1175  * gtk_style_get_valist:
1176  * @style: a #GtkStyle
1177  * @widget_type: the #GType of a descendant of #GtkWidget
1178  * @first_property_name: the name of the first style property to get
1179  * @var_args: a <type>va_list</type> of pairs of property names and
1180  *     locations to return the property values, starting with the
1181  *     location for @first_property_name.
1182  *
1183  * Non-vararg variant of gtk_style_get().
1184  * Used primarily by language bindings.
1185  *
1186  * Since: 2.16
1187  */
1188 void 
1189 gtk_style_get_valist (GtkStyle    *style,
1190                       GType        widget_type,
1191                       const gchar *first_property_name,
1192                       va_list      var_args)
1193 {
1194   GtkStylePrivate *priv;
1195   const char *property_name;
1196   GtkWidgetClass *klass;
1197
1198   g_return_if_fail (GTK_IS_STYLE (style));
1199
1200   klass = g_type_class_ref (widget_type);
1201
1202   priv = GTK_STYLE_GET_PRIVATE (style);
1203   property_name = first_property_name;
1204   while (property_name)
1205     {
1206       GParamSpec *pspec;
1207       const GValue *peek_value;
1208       gchar *error;
1209
1210       pspec = gtk_widget_class_find_style_property (klass, property_name);
1211
1212       if (!pspec)
1213         {
1214           g_warning ("%s: widget class `%s' has no property named `%s'",
1215                      G_STRLOC,
1216                      g_type_name (widget_type),
1217                      property_name);
1218           break;
1219         }
1220
1221       peek_value = _gtk_style_context_peek_style_property (priv->context, widget_type,
1222                                                            0, pspec);
1223       G_VALUE_LCOPY (peek_value, var_args, 0, &error);
1224       if (error)
1225         {
1226           g_warning ("%s: %s", G_STRLOC, error);
1227           g_free (error);
1228           break;
1229         }
1230
1231       property_name = va_arg (var_args, gchar*);
1232     }
1233
1234   g_type_class_unref (klass);
1235 }
1236
1237 /**
1238  * gtk_style_get:
1239  * @style: a #GtkStyle
1240  * @widget_type: the #GType of a descendant of #GtkWidget
1241  * @first_property_name: the name of the first style property to get
1242  * @...: pairs of property names and locations to
1243  *   return the property values, starting with the location for
1244  *   @first_property_name, terminated by %NULL.
1245  *
1246  * Gets the values of a multiple style properties for @widget_type
1247  * from @style.
1248  *
1249  * Since: 2.16
1250  */
1251 void
1252 gtk_style_get (GtkStyle    *style,
1253                GType        widget_type,
1254                const gchar *first_property_name,
1255                ...)
1256 {
1257   va_list var_args;
1258
1259   va_start (var_args, first_property_name);
1260   gtk_style_get_valist (style, widget_type, first_property_name, var_args);
1261   va_end (var_args);
1262 }
1263
1264 static void
1265 gtk_style_real_realize (GtkStyle *style)
1266 {
1267 }
1268
1269 static void
1270 gtk_style_real_unrealize (GtkStyle *style)
1271 {
1272 }
1273
1274 static void
1275 gtk_style_real_set_background (GtkStyle    *style,
1276                                GdkWindow   *window,
1277                                GtkStateType state_type)
1278 {
1279   gdk_window_set_background_pattern (window, style->background[state_type]);
1280 }
1281
1282 /**
1283  * gtk_style_render_icon:
1284  * @style: a #GtkStyle
1285  * @source: the #GtkIconSource specifying the icon to render
1286  * @direction: a text direction
1287  * @state: a state
1288  * @size: (type int): the size to render the icon at. A size of
1289  *     (GtkIconSize)-1 means render at the size of the source and
1290  *     don't scale.
1291  * @widget: (allow-none): the widget
1292  * @detail: (allow-none): a style detail
1293  *
1294  * Renders the icon specified by @source at the given @size
1295  * according to the given parameters and returns the result in a
1296  * pixbuf.
1297  *
1298  * Return value: (transfer full): a newly-created #GdkPixbuf
1299  *     containing the rendered icon
1300  *
1301  * Deprecated:3.0: Use gtk_render_icon_pixbuf() instead
1302  */
1303 GdkPixbuf *
1304 gtk_style_render_icon (GtkStyle            *style,
1305                        const GtkIconSource *source,
1306                        GtkTextDirection     direction,
1307                        GtkStateType         state,
1308                        GtkIconSize          size,
1309                        GtkWidget           *widget,
1310                        const gchar         *detail)
1311 {
1312   GdkPixbuf *pixbuf;
1313   
1314   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1315   g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1316   
1317   pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1318                                                      size, widget, detail);
1319
1320   g_return_val_if_fail (pixbuf != NULL, NULL);
1321
1322   return pixbuf;
1323 }
1324
1325 /* Default functions */
1326
1327 /**
1328  * gtk_style_apply_default_background:
1329  * @style:
1330  * @cr:
1331  * @window:
1332  * @state_type:
1333  * @x:
1334  * @y:
1335  * @width:
1336  * @height:
1337  *
1338  * Deprecated:3.0: Use #GtkStyleContext instead
1339  */
1340 void
1341 gtk_style_apply_default_background (GtkStyle          *style,
1342                                     cairo_t           *cr,
1343                                     GdkWindow         *window,
1344                                     GtkStateType       state_type,
1345                                     gint               x,
1346                                     gint               y,
1347                                     gint               width,
1348                                     gint               height)
1349 {
1350   cairo_save (cr);
1351
1352   if (style->background[state_type] == NULL)
1353     {
1354       GdkWindow *parent = gdk_window_get_parent (window);
1355       int x_offset, y_offset;
1356
1357       if (parent)
1358         {
1359           gdk_window_get_position (window, &x_offset, &y_offset);
1360           cairo_translate (cr, -x_offset, -y_offset);
1361           gtk_style_apply_default_background (style, cr,
1362                                               parent, state_type,
1363                                               x + x_offset, y + y_offset,
1364                                               width, height);
1365           goto out;
1366         }
1367       else
1368         gdk_cairo_set_source_color (cr, &style->bg[state_type]);
1369     }
1370   else
1371     cairo_set_source (cr, style->background[state_type]);
1372
1373   cairo_rectangle (cr, x, y, width, height);
1374   cairo_fill (cr);
1375
1376 out:
1377   cairo_restore (cr);
1378 }
1379
1380 static GdkPixbuf *
1381 gtk_default_render_icon (GtkStyle            *style,
1382                          const GtkIconSource *source,
1383                          GtkTextDirection     direction,
1384                          GtkStateType         state,
1385                          GtkIconSize          size,
1386                          GtkWidget           *widget,
1387                          const gchar         *detail)
1388 {
1389   GtkStyleContext *context;
1390   GtkStylePrivate *priv;
1391   GtkStateFlags flags = 0;
1392   GdkPixbuf *pixbuf;
1393
1394   if (widget)
1395     context = gtk_widget_get_style_context (widget);
1396   else
1397     {
1398       priv = GTK_STYLE_GET_PRIVATE (style);
1399       context = priv->context;
1400     }
1401
1402   if (!context)
1403     return NULL;
1404
1405   gtk_style_context_save (context);
1406
1407   if (detail)
1408     transform_detail_string (detail, context);
1409
1410   switch (state)
1411     {
1412     case GTK_STATE_PRELIGHT:
1413       flags |= GTK_STATE_FLAG_PRELIGHT;
1414       break;
1415     case GTK_STATE_INSENSITIVE:
1416       flags |= GTK_STATE_FLAG_INSENSITIVE;
1417       break;
1418     default:
1419       break;
1420     }
1421
1422   gtk_style_context_set_state (context, flags);
1423
1424   pixbuf = gtk_render_icon_pixbuf (context, source, size);
1425
1426   gtk_style_context_restore (context);
1427
1428   return pixbuf;
1429 }
1430
1431 static void
1432 _cairo_draw_line (cairo_t  *cr,
1433                   GdkColor *color,
1434                   gint      x1,
1435                   gint      y1,
1436                   gint      x2,
1437                   gint      y2)
1438 {
1439   cairo_save (cr);
1440
1441   gdk_cairo_set_source_color (cr, color);
1442   cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
1443
1444   cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
1445   cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
1446   cairo_stroke (cr);
1447
1448   cairo_restore (cr);
1449 }
1450
1451 static void
1452 transform_detail_string (const gchar     *detail,
1453                          GtkStyleContext *context)
1454 {
1455   if (!detail)
1456     return;
1457
1458   if (strcmp (detail, "arrow") == 0)
1459     gtk_style_context_add_class (context, "arrow");
1460   else if (strcmp (detail, "button") == 0)
1461     gtk_style_context_add_class (context, "button");
1462   else if (strcmp (detail, "buttondefault") == 0)
1463     {
1464       gtk_style_context_add_class (context, "button");
1465       gtk_style_context_add_class (context, "default");
1466     }
1467   else if (strcmp (detail, "calendar") == 0)
1468     gtk_style_context_add_class (context, "calendar");
1469   else if (strcmp (detail, "cellcheck") == 0)
1470     {
1471       gtk_style_context_add_class (context, "cell");
1472       gtk_style_context_add_class (context, "check");
1473     }
1474   else if (strcmp (detail, "cellradio") == 0)
1475     {
1476       gtk_style_context_add_class (context, "cell");
1477       gtk_style_context_add_class (context, "radio");
1478     }
1479   else if (strcmp (detail, "checkbutton") == 0)
1480     gtk_style_context_add_class (context, "check");
1481   else if (strcmp (detail, "check") == 0)
1482     {
1483       gtk_style_context_add_class (context, "check");
1484       gtk_style_context_add_class (context, "menu");
1485     }
1486   else if (strcmp (detail, "radiobutton") == 0)
1487     {
1488       gtk_style_context_add_class (context, "radio");
1489     }
1490   else if (strcmp (detail, "option") == 0)
1491     {
1492       gtk_style_context_add_class (context, "radio");
1493       gtk_style_context_add_class (context, "menu");
1494     }
1495   else if (strcmp (detail, "entry") == 0 ||
1496            strcmp (detail, "entry_bg") == 0)
1497     gtk_style_context_add_class (context, "entry");
1498   else if (strcmp (detail, "expander") == 0)
1499     gtk_style_context_add_class (context, "expander");
1500   else if (strcmp (detail, "tooltip") == 0)
1501     gtk_style_context_add_class (context, "tooltip");
1502   else if (strcmp (detail, "frame") == 0)
1503     gtk_style_context_add_class (context, "frame");
1504   else if (strcmp (detail, "scrolled_window") == 0)
1505     gtk_style_context_add_class (context, "scrolled-window");
1506   else if (strcmp (detail, "viewport") == 0 ||
1507            strcmp (detail, "viewportbin") == 0)
1508     gtk_style_context_add_class (context, "viewport");
1509   else if (strncmp (detail, "trough", 6) == 0)
1510     gtk_style_context_add_class (context, "trough");
1511   else if (strcmp (detail, "spinbutton") == 0)
1512     gtk_style_context_add_class (context, "spinbutton");
1513   else if (strcmp (detail, "spinbutton_up") == 0)
1514     {
1515       gtk_style_context_add_class (context, "spinbutton");
1516       gtk_style_context_add_class (context, "button");
1517       gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
1518     }
1519   else if (strcmp (detail, "spinbutton_down") == 0)
1520     {
1521       gtk_style_context_add_class (context, "spinbutton");
1522       gtk_style_context_add_class (context, "button");
1523       gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
1524     }
1525   else if ((detail[0] == 'h' || detail[0] == 'v') &&
1526            strncmp (&detail[1], "scrollbar_", 10) == 0)
1527     {
1528       gtk_style_context_add_class (context, "button");
1529       gtk_style_context_add_class (context, "scrollbar");
1530     }
1531   else if (strcmp (detail, "slider") == 0)
1532     {
1533       gtk_style_context_add_class (context, "slider");
1534       gtk_style_context_add_class (context, "scrollbar");
1535     }
1536   else if (strcmp (detail, "vscale") == 0 ||
1537            strcmp (detail, "hscale") == 0)
1538     {
1539       gtk_style_context_add_class (context, "slider");
1540       gtk_style_context_add_class (context, "scale");
1541     }
1542   else if (strcmp (detail, "menuitem") == 0)
1543     {
1544       gtk_style_context_add_class (context, "menuitem");
1545       gtk_style_context_add_class (context, "menu");
1546     }
1547   else if (strcmp (detail, "menu") == 0)
1548     {
1549       gtk_style_context_add_class (context, "popup");
1550       gtk_style_context_add_class (context, "menu");
1551     }
1552   else if (strcmp (detail, "accellabel") == 0)
1553     gtk_style_context_add_class (context, "accelerator");
1554   else if (strcmp (detail, "menubar") == 0)
1555     gtk_style_context_add_class (context, "menubar");
1556   else if (strcmp (detail, "base") == 0)
1557     gtk_style_context_add_class (context, "background");
1558   else if (strcmp (detail, "bar") == 0 ||
1559            strcmp (detail, "progressbar") == 0)
1560     gtk_style_context_add_class (context, "progressbar");
1561   else if (strcmp (detail, "toolbar") == 0)
1562     gtk_style_context_add_class (context, "toolbar");
1563   else if (strcmp (detail, "handlebox_bin") == 0)
1564     gtk_style_context_add_class (context, "dock");
1565   else if (strcmp (detail, "notebook") == 0)
1566     gtk_style_context_add_class (context, "notebook");
1567   else if (strcmp (detail, "tab") == 0)
1568     {
1569       gtk_style_context_add_class (context, "notebook");
1570       gtk_style_context_add_region (context, GTK_STYLE_REGION_TAB, 0);
1571     }
1572   else if (g_str_has_prefix (detail, "cell"))
1573     {
1574       GtkRegionFlags row, col;
1575       gboolean ruled = FALSE;
1576       GStrv tokens;
1577       guint i;
1578
1579       tokens = g_strsplit (detail, "_", -1);
1580       row = col = 0;
1581       i = 0;
1582
1583       while (tokens[i])
1584         {
1585           if (strcmp (tokens[i], "even") == 0)
1586             row |= GTK_REGION_EVEN;
1587           else if (strcmp (tokens[i], "odd") == 0)
1588             row |= GTK_REGION_ODD;
1589           else if (strcmp (tokens[i], "start") == 0)
1590             col |= GTK_REGION_FIRST;
1591           else if (strcmp (tokens[i], "end") == 0)
1592             col |= GTK_REGION_LAST;
1593           else if (strcmp (tokens[i], "ruled") == 0)
1594             ruled = TRUE;
1595           else if (strcmp (tokens[i], "sorted") == 0)
1596             col |= GTK_REGION_SORTED;
1597
1598           i++;
1599         }
1600
1601       if (!ruled)
1602         row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
1603
1604       gtk_style_context_add_class (context, "cell");
1605       gtk_style_context_add_region (context, "row", row);
1606       gtk_style_context_add_region (context, "column", col);
1607
1608       g_strfreev (tokens);
1609     }
1610 }
1611
1612 static void
1613 gtk_default_draw_hline (GtkStyle     *style,
1614                         cairo_t       *cr,
1615                         GtkStateType  state_type,
1616                         GtkWidget     *widget,
1617                         const gchar   *detail,
1618                         gint          x1,
1619                         gint          x2,
1620                         gint          y)
1621 {
1622   GtkStyleContext *context;
1623   GtkStylePrivate *priv;
1624
1625   if (widget)
1626     context = gtk_widget_get_style_context (widget);
1627   else
1628     {
1629       priv = GTK_STYLE_GET_PRIVATE (style);
1630       context = priv->context;
1631     }
1632
1633   gtk_style_context_save (context);
1634
1635   if (detail)
1636     transform_detail_string (detail, context);
1637
1638   cairo_save (cr);
1639
1640   gtk_render_line (context, cr,
1641                    x1, y, x2, y);
1642
1643   cairo_restore (cr);
1644
1645   gtk_style_context_restore (context);
1646 }
1647
1648
1649 static void
1650 gtk_default_draw_vline (GtkStyle      *style,
1651                         cairo_t       *cr,
1652                         GtkStateType  state_type,
1653                         GtkWidget     *widget,
1654                         const gchar   *detail,
1655                         gint          y1,
1656                         gint          y2,
1657                         gint          x)
1658 {
1659   GtkStyleContext *context;
1660   GtkStylePrivate *priv;
1661
1662   if (widget)
1663     context = gtk_widget_get_style_context (widget);
1664   else
1665     {
1666       priv = GTK_STYLE_GET_PRIVATE (style);
1667       context = priv->context;
1668     }
1669
1670   gtk_style_context_save (context);
1671
1672   if (detail)
1673     transform_detail_string (detail, context);
1674
1675   cairo_save (cr);
1676
1677   gtk_render_line (context, cr,
1678                    x, y1, x, y2);
1679
1680   cairo_restore (cr);
1681   gtk_style_context_restore (context);
1682 }
1683
1684 static void
1685 gtk_default_draw_shadow (GtkStyle      *style,
1686                          cairo_t       *cr,
1687                          GtkStateType   state_type,
1688                          GtkShadowType  shadow_type,
1689                          GtkWidget     *widget,
1690                          const gchar   *detail,
1691                          gint           x,
1692                          gint           y,
1693                          gint           width,
1694                          gint           height)
1695 {
1696   GtkStyleContext *context;
1697   GtkStylePrivate *priv;
1698
1699   if (shadow_type == GTK_SHADOW_NONE)
1700     return;
1701
1702   if (widget)
1703     context = gtk_widget_get_style_context (widget);
1704   else
1705     {
1706       priv = GTK_STYLE_GET_PRIVATE (style);
1707       context = priv->context;
1708     }
1709
1710   gtk_style_context_save (context);
1711
1712   if (detail)
1713     transform_detail_string (detail, context);
1714
1715   cairo_save (cr);
1716
1717   gtk_render_frame (context, cr,
1718                     (gdouble) x,
1719                     (gdouble) y,
1720                     (gdouble) width,
1721                     (gdouble) height);
1722
1723   cairo_restore (cr);
1724   gtk_style_context_restore (context);
1725 }
1726
1727 static void
1728 draw_arrow (cairo_t       *cr,
1729             GdkColor      *color,
1730             GtkArrowType   arrow_type,
1731             gint           x,
1732             gint           y,
1733             gint           width,
1734             gint           height)
1735 {
1736   gdk_cairo_set_source_color (cr, color);
1737   cairo_save (cr);
1738     
1739   if (arrow_type == GTK_ARROW_DOWN)
1740     {
1741       cairo_move_to (cr, x,              y);
1742       cairo_line_to (cr, x + width,      y);
1743       cairo_line_to (cr, x + width / 2., y + height);
1744     }
1745   else if (arrow_type == GTK_ARROW_UP)
1746     {
1747       cairo_move_to (cr, x,              y + height);
1748       cairo_line_to (cr, x + width / 2., y);
1749       cairo_line_to (cr, x + width,      y + height);
1750     }
1751   else if (arrow_type == GTK_ARROW_LEFT)
1752     {
1753       cairo_move_to (cr, x + width,      y);
1754       cairo_line_to (cr, x + width,      y + height);
1755       cairo_line_to (cr, x,              y + height / 2.);
1756     }
1757   else if (arrow_type == GTK_ARROW_RIGHT)
1758     {
1759       cairo_move_to (cr, x,              y);
1760       cairo_line_to (cr, x + width,      y + height / 2.);
1761       cairo_line_to (cr, x,              y + height);
1762     }
1763
1764   cairo_close_path (cr);
1765   cairo_fill (cr);
1766
1767   cairo_restore (cr);
1768 }
1769
1770 static void
1771 gtk_default_draw_arrow (GtkStyle      *style,
1772                         cairo_t       *cr,
1773                         GtkStateType   state,
1774                         GtkShadowType  shadow,
1775                         GtkWidget     *widget,
1776                         const gchar   *detail,
1777                         GtkArrowType   arrow_type,
1778                         gboolean       fill,
1779                         gint           x,
1780                         gint           y,
1781                         gint           width,
1782                         gint           height)
1783 {
1784   GtkStyleContext *context;
1785   GtkStylePrivate *priv;
1786   GtkStateFlags flags = 0;
1787   gdouble angle, size;
1788
1789   if (arrow_type == GTK_ARROW_NONE)
1790     return;
1791
1792   if (widget)
1793     context = gtk_widget_get_style_context (widget);
1794   else
1795     {
1796       priv = GTK_STYLE_GET_PRIVATE (style);
1797       context = priv->context;
1798     }
1799
1800   gtk_style_context_save (context);
1801
1802   if (detail)
1803     transform_detail_string (detail, context);
1804
1805   switch (arrow_type)
1806     {
1807     case GTK_ARROW_UP:
1808       angle = 0;
1809       size = width;
1810       break;
1811     case GTK_ARROW_RIGHT:
1812       angle = G_PI / 2;
1813       size = height;
1814       break;
1815     case GTK_ARROW_DOWN:
1816       angle = G_PI;
1817       size = width;
1818       break;
1819     case GTK_ARROW_LEFT:
1820       angle = 3 * (G_PI / 2);
1821       size = height;
1822       break;
1823     default:
1824       g_assert_not_reached ();
1825     }
1826
1827   switch (state)
1828     {
1829     case GTK_STATE_PRELIGHT:
1830       flags |= GTK_STATE_FLAG_PRELIGHT;
1831       break;
1832     case GTK_STATE_SELECTED:
1833       flags |= GTK_STATE_FLAG_SELECTED;
1834       break;
1835     case GTK_STATE_INSENSITIVE:
1836       flags |= GTK_STATE_FLAG_INSENSITIVE;
1837       break;
1838     case GTK_STATE_ACTIVE:
1839       flags |= GTK_STATE_FLAG_ACTIVE;
1840       break;
1841     default:
1842       break;
1843     }
1844
1845   gtk_style_context_set_state (context, flags);
1846
1847   cairo_save (cr);
1848
1849   gtk_render_arrow (context,
1850                     cr, angle,
1851                     (gdouble) x,
1852                     (gdouble) y,
1853                     size);
1854
1855   cairo_restore (cr);
1856   gtk_style_context_restore (context);
1857 }
1858
1859 static void
1860 gtk_default_draw_diamond (GtkStyle      *style,
1861                           cairo_t       *cr,
1862                           GtkStateType   state_type,
1863                           GtkShadowType  shadow_type,
1864                           GtkWidget     *widget,
1865                           const gchar   *detail,
1866                           gint           x,
1867                           gint           y,
1868                           gint           width,
1869                           gint           height)
1870 {
1871   gint half_width;
1872   gint half_height;
1873   GdkColor *outer_nw = NULL;
1874   GdkColor *outer_ne = NULL;
1875   GdkColor *outer_sw = NULL;
1876   GdkColor *outer_se = NULL;
1877   GdkColor *middle_nw = NULL;
1878   GdkColor *middle_ne = NULL;
1879   GdkColor *middle_sw = NULL;
1880   GdkColor *middle_se = NULL;
1881   GdkColor *inner_nw = NULL;
1882   GdkColor *inner_ne = NULL;
1883   GdkColor *inner_sw = NULL;
1884   GdkColor *inner_se = NULL;
1885   
1886   half_width = width / 2;
1887   half_height = height / 2;
1888   
1889   switch (shadow_type)
1890     {
1891     case GTK_SHADOW_IN:
1892       inner_sw = inner_se = &style->bg[state_type];
1893       middle_sw = middle_se = &style->light[state_type];
1894       outer_sw = outer_se = &style->light[state_type];
1895       inner_nw = inner_ne = &style->black;
1896       middle_nw = middle_ne = &style->dark[state_type];
1897       outer_nw = outer_ne = &style->dark[state_type];
1898       break;
1899           
1900     case GTK_SHADOW_OUT:
1901       inner_sw = inner_se = &style->dark[state_type];
1902       middle_sw = middle_se = &style->dark[state_type];
1903       outer_sw = outer_se = &style->black;
1904       inner_nw = inner_ne = &style->bg[state_type];
1905       middle_nw = middle_ne = &style->light[state_type];
1906       outer_nw = outer_ne = &style->light[state_type];
1907       break;
1908
1909     case GTK_SHADOW_ETCHED_IN:
1910       inner_sw = inner_se = &style->bg[state_type];
1911       middle_sw = middle_se = &style->dark[state_type];
1912       outer_sw = outer_se = &style->light[state_type];
1913       inner_nw = inner_ne = &style->bg[state_type];
1914       middle_nw = middle_ne = &style->light[state_type];
1915       outer_nw = outer_ne = &style->dark[state_type];
1916       break;
1917
1918     case GTK_SHADOW_ETCHED_OUT:
1919       inner_sw = inner_se = &style->bg[state_type];
1920       middle_sw = middle_se = &style->light[state_type];
1921       outer_sw = outer_se = &style->dark[state_type];
1922       inner_nw = inner_ne = &style->bg[state_type];
1923       middle_nw = middle_ne = &style->dark[state_type];
1924       outer_nw = outer_ne = &style->light[state_type];
1925       break;
1926       
1927     default:
1928
1929       break;
1930     }
1931
1932   if (inner_sw)
1933     {
1934       _cairo_draw_line (cr, inner_sw,
1935                         x + 2, y + half_height,
1936                         x + half_width, y + height - 2);
1937       _cairo_draw_line (cr, inner_se,
1938                         x + half_width, y + height - 2,
1939                         x + width - 2, y + half_height);
1940       _cairo_draw_line (cr, middle_sw,
1941                         x + 1, y + half_height,
1942                         x + half_width, y + height - 1);
1943       _cairo_draw_line (cr, middle_se,
1944                         x + half_width, y + height - 1,
1945                         x + width - 1, y + half_height);
1946       _cairo_draw_line (cr, outer_sw,
1947                         x, y + half_height,
1948                         x + half_width, y + height);
1949       _cairo_draw_line (cr, outer_se,
1950                         x + half_width, y + height,
1951                         x + width, y + half_height);
1952   
1953       _cairo_draw_line (cr, inner_nw,
1954                         x + 2, y + half_height,
1955                         x + half_width, y + 2);
1956       _cairo_draw_line (cr, inner_ne,
1957                         x + half_width, y + 2,
1958                         x + width - 2, y + half_height);
1959       _cairo_draw_line (cr, middle_nw,
1960                         x + 1, y + half_height,
1961                         x + half_width, y + 1);
1962       _cairo_draw_line (cr, middle_ne,
1963                         x + half_width, y + 1,
1964                         x + width - 1, y + half_height);
1965       _cairo_draw_line (cr, outer_nw,
1966                         x, y + half_height,
1967                         x + half_width, y);
1968       _cairo_draw_line (cr, outer_ne,
1969                         x + half_width, y,
1970                         x + width, y + half_height);
1971     }
1972 }
1973
1974 static void
1975 option_menu_get_props (GtkWidget      *widget,
1976                        GtkRequisition *indicator_size,
1977                        GtkBorder      *indicator_spacing)
1978 {
1979   GtkRequisition *tmp_size = NULL;
1980   GtkBorder *tmp_spacing = NULL;
1981
1982   if (tmp_size)
1983     {
1984       *indicator_size = *tmp_size;
1985       gtk_requisition_free (tmp_size);
1986     }
1987   else
1988     *indicator_size = default_option_indicator_size;
1989
1990   if (tmp_spacing)
1991     {
1992       *indicator_spacing = *tmp_spacing;
1993       gtk_border_free (tmp_spacing);
1994     }
1995   else
1996     *indicator_spacing = default_option_indicator_spacing;
1997 }
1998
1999 static void 
2000 gtk_default_draw_box (GtkStyle      *style,
2001                       cairo_t       *cr,
2002                       GtkStateType   state_type,
2003                       GtkShadowType  shadow_type,
2004                       GtkWidget     *widget,
2005                       const gchar   *detail,
2006                       gint           x,
2007                       gint           y,
2008                       gint           width,
2009                       gint           height)
2010 {
2011   GtkStyleContext *context;
2012   GtkStylePrivate *priv;
2013   GtkStateFlags flags = 0;
2014
2015   if (widget)
2016     context = gtk_widget_get_style_context (widget);
2017   else
2018     {
2019       priv = GTK_STYLE_GET_PRIVATE (style);
2020       context = priv->context;
2021     }
2022
2023   gtk_style_context_save (context);
2024
2025   if (detail)
2026     transform_detail_string (detail, context);
2027
2028   switch (state_type)
2029     {
2030     case GTK_STATE_ACTIVE:
2031       flags |= GTK_STATE_FLAG_ACTIVE;
2032       break;
2033     case GTK_STATE_PRELIGHT:
2034       flags |= GTK_STATE_FLAG_PRELIGHT;
2035       break;
2036     case GTK_STATE_SELECTED:
2037       flags |= GTK_STATE_FLAG_SELECTED;
2038       break;
2039     case GTK_STATE_INSENSITIVE:
2040       flags |= GTK_STATE_FLAG_INSENSITIVE;
2041       break;
2042     default:
2043       break;
2044     }
2045
2046   if (shadow_type == GTK_SHADOW_IN)
2047     flags |= GTK_STATE_FLAG_ACTIVE;
2048
2049   gtk_style_context_set_state (context, flags);
2050
2051   cairo_save (cr);
2052
2053   if (gtk_style_context_has_class (context, GTK_STYLE_CLASS_PROGRESSBAR))
2054     gtk_render_activity (context, cr, x, y, width, height);
2055   else
2056     {
2057       gtk_render_background (context, cr, x, y, width, height);
2058
2059       if (shadow_type != GTK_SHADOW_NONE)
2060         gtk_render_frame (context, cr, x, y, width, height);
2061     }
2062
2063   cairo_restore (cr);
2064   gtk_style_context_restore (context);
2065 }
2066
2067 static void 
2068 gtk_default_draw_flat_box (GtkStyle      *style,
2069                            cairo_t       *cr,
2070                            GtkStateType   state_type,
2071                            GtkShadowType  shadow_type,
2072                            GtkWidget     *widget,
2073                            const gchar   *detail,
2074                            gint           x,
2075                            gint           y,
2076                            gint           width,
2077                            gint           height)
2078 {
2079   GtkStyleContext *context;
2080   GtkStylePrivate *priv;
2081   GtkStateFlags flags = 0;
2082
2083   if (widget)
2084     context = gtk_widget_get_style_context (widget);
2085   else
2086     {
2087       priv = GTK_STYLE_GET_PRIVATE (style);
2088       context = priv->context;
2089     }
2090
2091   gtk_style_context_save (context);
2092
2093   if (detail)
2094     transform_detail_string (detail, context);
2095
2096   switch (state_type)
2097     {
2098     case GTK_STATE_PRELIGHT:
2099       flags |= GTK_STATE_FLAG_PRELIGHT;
2100       break;
2101     case GTK_STATE_SELECTED:
2102       flags |= GTK_STATE_FLAG_SELECTED;
2103       break;
2104     case GTK_STATE_INSENSITIVE:
2105       flags |= GTK_STATE_FLAG_INSENSITIVE;
2106       break;
2107     case GTK_STATE_ACTIVE:
2108       flags |= GTK_STATE_FLAG_ACTIVE;
2109       break;
2110     case GTK_STATE_FOCUSED:
2111       flags |= GTK_STATE_FLAG_FOCUSED;
2112       break;
2113     default:
2114       break;
2115     }
2116
2117   gtk_style_context_set_state (context, flags);
2118
2119   cairo_save (cr);
2120
2121   gtk_render_background (context, cr,
2122                          (gdouble) x,
2123                          (gdouble) y,
2124                          (gdouble) width,
2125                          (gdouble) height);
2126
2127   cairo_restore (cr);
2128   gtk_style_context_restore (context);
2129 }
2130
2131 static void 
2132 gtk_default_draw_check (GtkStyle      *style,
2133                         cairo_t       *cr,
2134                         GtkStateType   state_type,
2135                         GtkShadowType  shadow_type,
2136                         GtkWidget     *widget,
2137                         const gchar   *detail,
2138                         gint           x,
2139                         gint           y,
2140                         gint           width,
2141                         gint           height)
2142 {
2143   GtkStyleContext *context;
2144   GtkStylePrivate *priv;
2145   GtkStateFlags flags = 0;
2146
2147   if (widget)
2148     context = gtk_widget_get_style_context (widget);
2149   else
2150     {
2151       priv = GTK_STYLE_GET_PRIVATE (style);
2152       context = priv->context;
2153     }
2154
2155   gtk_style_context_save (context);
2156
2157   if (detail)
2158     transform_detail_string (detail, context);
2159
2160   switch (state_type)
2161     {
2162     case GTK_STATE_PRELIGHT:
2163       flags |= GTK_STATE_FLAG_PRELIGHT;
2164       break;
2165     case GTK_STATE_SELECTED:
2166       flags |= GTK_STATE_FLAG_SELECTED;
2167       break;
2168     case GTK_STATE_INSENSITIVE:
2169       flags |= GTK_STATE_FLAG_INSENSITIVE;
2170       break;
2171     default:
2172       break;
2173     }
2174
2175   if (shadow_type == GTK_SHADOW_IN)
2176     flags |= GTK_STATE_FLAG_ACTIVE;
2177   else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2178     flags |= GTK_STATE_FLAG_INCONSISTENT;
2179
2180   gtk_style_context_set_state (context, flags);
2181
2182   cairo_save (cr);
2183
2184   gtk_render_check (context,
2185                     cr, x, y,
2186                     width, height);
2187
2188   cairo_restore (cr);
2189   gtk_style_context_restore (context);
2190 }
2191
2192 static void 
2193 gtk_default_draw_option (GtkStyle      *style,
2194                          cairo_t       *cr,
2195                          GtkStateType   state_type,
2196                          GtkShadowType  shadow_type,
2197                          GtkWidget     *widget,
2198                          const gchar   *detail,
2199                          gint           x,
2200                          gint           y,
2201                          gint           width,
2202                          gint           height)
2203 {
2204   GtkStyleContext *context;
2205   GtkStylePrivate *priv;
2206   GtkStateFlags flags = 0;
2207
2208   if (widget)
2209     context = gtk_widget_get_style_context (widget);
2210   else
2211     {
2212       priv = GTK_STYLE_GET_PRIVATE (style);
2213       context = priv->context;
2214     }
2215
2216   gtk_style_context_save (context);
2217
2218   if (detail)
2219     transform_detail_string (detail, context);
2220
2221   switch (state_type)
2222     {
2223     case GTK_STATE_PRELIGHT:
2224       flags |= GTK_STATE_FLAG_PRELIGHT;
2225       break;
2226     case GTK_STATE_SELECTED:
2227       flags |= GTK_STATE_FLAG_SELECTED;
2228       break;
2229     case GTK_STATE_INSENSITIVE:
2230       flags |= GTK_STATE_FLAG_INSENSITIVE;
2231       break;
2232     default:
2233       break;
2234     }
2235
2236   if (shadow_type == GTK_SHADOW_IN)
2237     flags |= GTK_STATE_FLAG_ACTIVE;
2238   else if (shadow_type == GTK_SHADOW_ETCHED_IN)
2239     flags |= GTK_STATE_FLAG_INCONSISTENT;
2240
2241   gtk_style_context_set_state (context, flags);
2242
2243   cairo_save (cr);
2244   gtk_render_option (context, cr,
2245                      (gdouble) x,
2246                      (gdouble) y,
2247                      (gdouble) width,
2248                      (gdouble) height);
2249
2250   cairo_restore (cr);
2251   gtk_style_context_restore (context);
2252 }
2253
2254 static void
2255 gtk_default_draw_tab (GtkStyle      *style,
2256                       cairo_t       *cr,
2257                       GtkStateType   state_type,
2258                       GtkShadowType  shadow_type,
2259                       GtkWidget     *widget,
2260                       const gchar   *detail,
2261                       gint           x,
2262                       gint           y,
2263                       gint           width,
2264                       gint           height)
2265 {
2266 #define ARROW_SPACE 4
2267
2268   GtkRequisition indicator_size;
2269   GtkBorder indicator_spacing;
2270   gint arrow_height;
2271
2272   option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2273
2274   indicator_size.width += (indicator_size.width % 2) - 1;
2275   arrow_height = indicator_size.width / 2 + 1;
2276
2277   x += (width - indicator_size.width) / 2;
2278   y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
2279
2280   if (state_type == GTK_STATE_INSENSITIVE)
2281     {
2282       draw_arrow (cr, &style->white,
2283                   GTK_ARROW_UP, x + 1, y + 1,
2284                   indicator_size.width, arrow_height);
2285       
2286       draw_arrow (cr, &style->white,
2287                   GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
2288                   indicator_size.width, arrow_height);
2289     }
2290   
2291   draw_arrow (cr, &style->fg[state_type],
2292               GTK_ARROW_UP, x, y,
2293               indicator_size.width, arrow_height);
2294   
2295   
2296   draw_arrow (cr, &style->fg[state_type],
2297               GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
2298               indicator_size.width, arrow_height);
2299 }
2300
2301 static void 
2302 gtk_default_draw_shadow_gap (GtkStyle       *style,
2303                              cairo_t        *cr,
2304                              GtkStateType    state_type,
2305                              GtkShadowType   shadow_type,
2306                              GtkWidget      *widget,
2307                              const gchar    *detail,
2308                              gint            x,
2309                              gint            y,
2310                              gint            width,
2311                              gint            height,
2312                              GtkPositionType gap_side,
2313                              gint            gap_x,
2314                              gint            gap_width)
2315 {
2316   GtkStyleContext *context;
2317   GtkStylePrivate *priv;
2318   GtkStateFlags flags = 0;
2319
2320   if (shadow_type == GTK_SHADOW_NONE)
2321     return;
2322
2323   if (widget)
2324     context = gtk_widget_get_style_context (widget);
2325   else
2326     {
2327       priv = GTK_STYLE_GET_PRIVATE (style);
2328       context = priv->context;
2329     }
2330
2331   gtk_style_context_save (context);
2332
2333   if (detail)
2334     transform_detail_string (detail, context);
2335
2336   switch (state_type)
2337     {
2338     case GTK_STATE_ACTIVE:
2339       flags |= GTK_STATE_FLAG_ACTIVE;
2340       break;
2341     case GTK_STATE_PRELIGHT:
2342       flags |= GTK_STATE_FLAG_PRELIGHT;
2343       break;
2344     case GTK_STATE_SELECTED:
2345       flags |= GTK_STATE_FLAG_SELECTED;
2346       break;
2347     case GTK_STATE_INSENSITIVE:
2348       flags |= GTK_STATE_FLAG_INSENSITIVE;
2349       break;
2350     default:
2351       break;
2352     }
2353
2354   gtk_style_context_set_state (context, flags);
2355
2356   cairo_save (cr);
2357   gtk_render_frame_gap (context, cr,
2358                         (gdouble) x,
2359                         (gdouble) y,
2360                         (gdouble) width,
2361                         (gdouble) height,
2362                         gap_side,
2363                         (gdouble) gap_x,
2364                         (gdouble) gap_x + gap_width);
2365
2366   cairo_restore (cr);
2367   gtk_style_context_restore (context);
2368 }
2369
2370 static void 
2371 gtk_default_draw_box_gap (GtkStyle       *style,
2372                           cairo_t        *cr,
2373                           GtkStateType    state_type,
2374                           GtkShadowType   shadow_type,
2375                           GtkWidget      *widget,
2376                           const gchar    *detail,
2377                           gint            x,
2378                           gint            y,
2379                           gint            width,
2380                           gint            height,
2381                           GtkPositionType gap_side,
2382                           gint            gap_x,
2383                           gint            gap_width)
2384 {
2385   GtkStyleContext *context;
2386   GtkStylePrivate *priv;
2387   GtkStateFlags flags = 0;
2388
2389   if (widget)
2390     context = gtk_widget_get_style_context (widget);
2391   else
2392     {
2393       priv = GTK_STYLE_GET_PRIVATE (style);
2394       context = priv->context;
2395     }
2396
2397   gtk_style_context_save (context);
2398
2399   if (detail)
2400     transform_detail_string (detail, context);
2401
2402   switch (state_type)
2403     {
2404     case GTK_STATE_ACTIVE:
2405       flags |= GTK_STATE_FLAG_ACTIVE;
2406       break;
2407     case GTK_STATE_PRELIGHT:
2408       flags |= GTK_STATE_FLAG_PRELIGHT;
2409       break;
2410     case GTK_STATE_SELECTED:
2411       flags |= GTK_STATE_FLAG_SELECTED;
2412       break;
2413     case GTK_STATE_INSENSITIVE:
2414       flags |= GTK_STATE_FLAG_INSENSITIVE;
2415       break;
2416     default:
2417       break;
2418     }
2419
2420   gtk_style_context_set_state (context, flags);
2421
2422   cairo_save (cr);
2423   gtk_render_background (context, cr,
2424                          (gdouble) x,
2425                          (gdouble) y,
2426                          (gdouble) width,
2427                          (gdouble) height);
2428
2429
2430   if (shadow_type != GTK_SHADOW_NONE)
2431     gtk_render_frame_gap (context, cr,
2432                           (gdouble) x,
2433                           (gdouble) y,
2434                           (gdouble) width,
2435                           (gdouble) height,
2436                           gap_side,
2437                           (gdouble) gap_x,
2438                           (gdouble) gap_x + gap_width);
2439   
2440   cairo_restore (cr);
2441   gtk_style_context_restore (context);
2442 }
2443
2444 static void 
2445 gtk_default_draw_extension (GtkStyle       *style,
2446                             cairo_t        *cr,
2447                             GtkStateType    state_type,
2448                             GtkShadowType   shadow_type,
2449                             GtkWidget      *widget,
2450                             const gchar    *detail,
2451                             gint            x,
2452                             gint            y,
2453                             gint            width,
2454                             gint            height,
2455                             GtkPositionType gap_side)
2456 {
2457   GtkStyleContext *context;
2458   GtkStylePrivate *priv;
2459   GtkStateFlags flags = 0;
2460
2461   if (widget)
2462     context = gtk_widget_get_style_context (widget);
2463   else
2464     {
2465       priv = GTK_STYLE_GET_PRIVATE (style);
2466       context = priv->context;
2467     }
2468
2469   gtk_style_context_save (context);
2470
2471   if (detail)
2472     transform_detail_string (detail, context);
2473
2474   switch (state_type)
2475     {
2476     case GTK_STATE_ACTIVE:
2477       flags |= GTK_STATE_FLAG_ACTIVE;
2478       break;
2479     case GTK_STATE_PRELIGHT:
2480       flags |= GTK_STATE_FLAG_PRELIGHT;
2481       break;
2482     case GTK_STATE_SELECTED:
2483       flags |= GTK_STATE_FLAG_SELECTED;
2484       break;
2485     case GTK_STATE_INSENSITIVE:
2486       flags |= GTK_STATE_FLAG_INSENSITIVE;
2487       break;
2488     default:
2489       break;
2490     }
2491
2492   gtk_style_context_set_state (context, flags);
2493
2494   cairo_save (cr);
2495
2496   gtk_render_extension (context, cr,
2497                         (gdouble) x,
2498                         (gdouble) y,
2499                         (gdouble) width,
2500                         (gdouble) height,
2501                         gap_side);
2502
2503   cairo_restore (cr);
2504   gtk_style_context_restore (context);
2505 }
2506
2507 static void 
2508 gtk_default_draw_focus (GtkStyle      *style,
2509                         cairo_t       *cr,
2510                         GtkStateType   state_type,
2511                         GtkWidget     *widget,
2512                         const gchar   *detail,
2513                         gint           x,
2514                         gint           y,
2515                         gint           width,
2516                         gint           height)
2517 {
2518   GtkStyleContext *context;
2519   GtkStylePrivate *priv;
2520
2521   if (widget)
2522     context = gtk_widget_get_style_context (widget);
2523   else
2524     {
2525       priv = GTK_STYLE_GET_PRIVATE (style);
2526       context = priv->context;
2527     }
2528
2529   gtk_style_context_save (context);
2530
2531   if (detail)
2532     transform_detail_string (detail, context);
2533
2534   cairo_save (cr);
2535
2536   gtk_render_focus (context, cr,
2537                     (gdouble) x,
2538                     (gdouble) y,
2539                     (gdouble) width,
2540                     (gdouble) height);
2541
2542   cairo_restore (cr);
2543   gtk_style_context_restore (context);
2544 }
2545
2546 static void 
2547 gtk_default_draw_slider (GtkStyle      *style,
2548                          cairo_t       *cr,
2549                          GtkStateType   state_type,
2550                          GtkShadowType  shadow_type,
2551                          GtkWidget     *widget,
2552                          const gchar   *detail,
2553                          gint           x,
2554                          gint           y,
2555                          gint           width,
2556                          gint           height,
2557                          GtkOrientation orientation)
2558 {
2559   GtkStyleContext *context;
2560   GtkStylePrivate *priv;
2561   GtkStateFlags flags = 0;
2562
2563   if (widget)
2564     context = gtk_widget_get_style_context (widget);
2565   else
2566     {
2567       priv = GTK_STYLE_GET_PRIVATE (style);
2568       context = priv->context;
2569     }
2570
2571   gtk_style_context_save (context);
2572
2573   if (detail)
2574     transform_detail_string (detail, context);
2575
2576   switch (state_type)
2577     {
2578     case GTK_STATE_PRELIGHT:
2579       flags |= GTK_STATE_FLAG_PRELIGHT;
2580       break;
2581     case GTK_STATE_SELECTED:
2582       flags |= GTK_STATE_FLAG_SELECTED;
2583       break;
2584     case GTK_STATE_INSENSITIVE:
2585       flags |= GTK_STATE_FLAG_INSENSITIVE;
2586       break;
2587     default:
2588       break;
2589     }
2590
2591   gtk_style_context_set_state (context, flags);
2592
2593   cairo_save (cr);
2594
2595   gtk_render_slider (context, cr,  x, y, width, height, orientation);
2596
2597   cairo_restore (cr);
2598   gtk_style_context_restore (context);
2599 }
2600
2601 static void 
2602 gtk_default_draw_handle (GtkStyle      *style,
2603                          cairo_t       *cr,
2604                          GtkStateType   state_type,
2605                          GtkShadowType  shadow_type,
2606                          GtkWidget     *widget,
2607                          const gchar   *detail,
2608                          gint           x,
2609                          gint           y,
2610                          gint           width,
2611                          gint           height,
2612                          GtkOrientation orientation)
2613 {
2614   GtkStyleContext *context;
2615   GtkStylePrivate *priv;
2616   GtkStateFlags flags = 0;
2617
2618   if (widget)
2619     context = gtk_widget_get_style_context (widget);
2620   else
2621     {
2622       priv = GTK_STYLE_GET_PRIVATE (style);
2623       context = priv->context;
2624     }
2625
2626   gtk_style_context_save (context);
2627
2628   if (detail)
2629     transform_detail_string (detail, context);
2630
2631   switch (state_type)
2632     {
2633     case GTK_STATE_PRELIGHT:
2634       flags |= GTK_STATE_FLAG_PRELIGHT;
2635       break;
2636     case GTK_STATE_SELECTED:
2637       flags |= GTK_STATE_FLAG_SELECTED;
2638       break;
2639     case GTK_STATE_INSENSITIVE:
2640       flags |= GTK_STATE_FLAG_INSENSITIVE;
2641       break;
2642     default:
2643       break;
2644     }
2645
2646   gtk_style_context_set_state (context, flags);
2647
2648   cairo_save (cr);
2649
2650   gtk_render_handle (context, cr,
2651                      (gdouble) x,
2652                      (gdouble) y,
2653                      (gdouble) width,
2654                      (gdouble) height);
2655
2656   cairo_restore (cr);
2657   gtk_style_context_restore (context);
2658 }
2659
2660 static void
2661 gtk_default_draw_expander (GtkStyle        *style,
2662                            cairo_t         *cr,
2663                            GtkStateType     state_type,
2664                            GtkWidget       *widget,
2665                            const gchar     *detail,
2666                            gint             x,
2667                            gint             y,
2668                            GtkExpanderStyle expander_style)
2669 {
2670   GtkStyleContext *context;
2671   GtkStylePrivate *priv;
2672   GtkStateFlags flags = 0;
2673   gint size;
2674
2675   if (widget)
2676     context = gtk_widget_get_style_context (widget);
2677   else
2678     {
2679       priv = GTK_STYLE_GET_PRIVATE (style);
2680       context = priv->context;
2681     }
2682
2683   gtk_style_context_save (context);
2684
2685   if (detail)
2686     transform_detail_string (detail, context);
2687
2688   gtk_style_context_add_class (context, "expander");
2689
2690   switch (state_type)
2691     {
2692     case GTK_STATE_PRELIGHT:
2693       flags |= GTK_STATE_FLAG_PRELIGHT;
2694       break;
2695     case GTK_STATE_SELECTED:
2696       flags |= GTK_STATE_FLAG_SELECTED;
2697       break;
2698     case GTK_STATE_INSENSITIVE:
2699       flags |= GTK_STATE_FLAG_INSENSITIVE;
2700       break;
2701     default:
2702       break;
2703     }
2704
2705   if (widget &&
2706       gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
2707                                             "expander-size"))
2708     gtk_widget_style_get (widget, "expander-size", &size, NULL);
2709   else
2710     size = 12;
2711
2712   if (expander_style == GTK_EXPANDER_EXPANDED)
2713     flags |= GTK_STATE_FLAG_ACTIVE;
2714
2715   gtk_style_context_set_state (context, flags);
2716
2717   cairo_save (cr);
2718
2719   gtk_render_expander (context, cr,
2720                        (gdouble) x - (size / 2),
2721                        (gdouble) y - (size / 2),
2722                        (gdouble) size,
2723                        (gdouble) size);
2724
2725   cairo_restore (cr);
2726   gtk_style_context_restore (context);
2727 }
2728
2729 static void
2730 gtk_default_draw_layout (GtkStyle        *style,
2731                          cairo_t         *cr,
2732                          GtkStateType     state_type,
2733                          gboolean         use_text,
2734                          GtkWidget       *widget,
2735                          const gchar     *detail,
2736                          gint             x,
2737                          gint             y,
2738                          PangoLayout     *layout)
2739 {
2740   GtkStyleContext *context;
2741   GtkStylePrivate *priv;
2742   GtkStateFlags flags = 0;
2743
2744   if (widget)
2745     context = gtk_widget_get_style_context (widget);
2746   else
2747     {
2748       priv = GTK_STYLE_GET_PRIVATE (style);
2749       context = priv->context;
2750     }
2751
2752   gtk_style_context_save (context);
2753
2754   if (detail)
2755     transform_detail_string (detail, context);
2756
2757   switch (state_type)
2758     {
2759     case GTK_STATE_PRELIGHT:
2760       flags |= GTK_STATE_FLAG_PRELIGHT;
2761       break;
2762     case GTK_STATE_SELECTED:
2763       flags |= GTK_STATE_FLAG_SELECTED;
2764       break;
2765     case GTK_STATE_INSENSITIVE:
2766       flags |= GTK_STATE_FLAG_INSENSITIVE;
2767       break;
2768     default:
2769       break;
2770     }
2771
2772   gtk_style_context_set_state (context, flags);
2773
2774   cairo_save (cr);
2775
2776   gtk_render_layout (context, cr,
2777                      (gdouble) x,
2778                      (gdouble) y,
2779                      layout);
2780
2781   cairo_restore (cr);
2782   gtk_style_context_restore (context);
2783 }
2784
2785 static void
2786 gtk_default_draw_resize_grip (GtkStyle       *style,
2787                               cairo_t        *cr,
2788                               GtkStateType    state_type,
2789                               GtkWidget      *widget,
2790                               const gchar    *detail,
2791                               GdkWindowEdge   edge,
2792                               gint            x,
2793                               gint            y,
2794                               gint            width,
2795                               gint            height)
2796 {
2797   GtkStyleContext *context;
2798   GtkStylePrivate *priv;
2799   GtkStateFlags flags = 0;
2800   GtkJunctionSides sides = 0;
2801
2802   if (widget)
2803     context = gtk_widget_get_style_context (widget);
2804   else
2805     {
2806       priv = GTK_STYLE_GET_PRIVATE (style);
2807       context = priv->context;
2808     }
2809
2810   gtk_style_context_save (context);
2811
2812   if (detail)
2813     transform_detail_string (detail, context);
2814
2815   gtk_style_context_add_class (context, "grip");
2816
2817   switch (state_type)
2818     {
2819     case GTK_STATE_PRELIGHT:
2820       flags |= GTK_STATE_FLAG_PRELIGHT;
2821       break;
2822     case GTK_STATE_SELECTED:
2823       flags |= GTK_STATE_FLAG_SELECTED;
2824       break;
2825     case GTK_STATE_INSENSITIVE:
2826       flags |= GTK_STATE_FLAG_INSENSITIVE;
2827       break;
2828     default:
2829       break;
2830     }
2831
2832   gtk_style_context_set_state (context, flags);
2833
2834   switch (edge)
2835     {
2836     case GDK_WINDOW_EDGE_NORTH_WEST:
2837       sides = GTK_JUNCTION_CORNER_TOPLEFT;
2838       break;
2839     case GDK_WINDOW_EDGE_NORTH:
2840       sides = GTK_JUNCTION_TOP;
2841       break;
2842     case GDK_WINDOW_EDGE_NORTH_EAST:
2843       sides = GTK_JUNCTION_CORNER_TOPRIGHT;
2844       break;
2845     case GDK_WINDOW_EDGE_WEST:
2846       sides = GTK_JUNCTION_LEFT;
2847       break;
2848     case GDK_WINDOW_EDGE_EAST:
2849       sides = GTK_JUNCTION_RIGHT;
2850       break;
2851     case GDK_WINDOW_EDGE_SOUTH_WEST:
2852       sides = GTK_JUNCTION_CORNER_BOTTOMLEFT;
2853       break;
2854     case GDK_WINDOW_EDGE_SOUTH:
2855       sides = GTK_JUNCTION_BOTTOM;
2856       break;
2857     case GDK_WINDOW_EDGE_SOUTH_EAST:
2858       sides = GTK_JUNCTION_CORNER_BOTTOMRIGHT;
2859       break;
2860     }
2861
2862   gtk_style_context_set_junction_sides (context, sides);
2863
2864   cairo_save (cr);
2865
2866   gtk_render_handle (context, cr,
2867                      (gdouble) x,
2868                      (gdouble) y,
2869                      (gdouble) width,
2870                      (gdouble) height);
2871
2872   cairo_restore (cr);
2873   gtk_style_context_restore (context);
2874 }
2875
2876 static void
2877 gtk_default_draw_spinner (GtkStyle     *style,
2878                           cairo_t      *cr,
2879                           GtkStateType  state_type,
2880                           GtkWidget    *widget,
2881                           const gchar  *detail,
2882                           guint         step,
2883                           gint          x,
2884                           gint          y,
2885                           gint          width,
2886                           gint          height)
2887 {
2888   GdkColor *color;
2889   guint num_steps;
2890   gdouble dx, dy;
2891   gdouble radius;
2892   gdouble half;
2893   gint i;
2894   guint real_step;
2895
2896   num_steps = 12;
2897   real_step = step % num_steps;
2898
2899   /* set a clip region for the expose event */
2900   cairo_rectangle (cr, x, y, width, height);
2901   cairo_clip (cr);
2902
2903   cairo_translate (cr, x, y);
2904
2905   /* draw clip region */
2906   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
2907
2908   color = &style->fg[state_type];
2909   dx = width / 2;
2910   dy = height / 2;
2911   radius = MIN (width / 2, height / 2);
2912   half = num_steps / 2;
2913
2914   for (i = 0; i < num_steps; i++)
2915     {
2916       gint inset = 0.7 * radius;
2917
2918       /* transparency is a function of time and intial value */
2919       gdouble t = (gdouble) ((i + num_steps - real_step)
2920                              % num_steps) / num_steps;
2921
2922       cairo_save (cr);
2923
2924       cairo_set_source_rgba (cr,
2925                              color->red / 65535.,
2926                              color->green / 65535.,
2927                              color->blue / 65535.,
2928                              t);
2929
2930       cairo_set_line_width (cr, 2.0);
2931       cairo_move_to (cr,
2932                      dx + (radius - inset) * cos (i * G_PI / half),
2933                      dy + (radius - inset) * sin (i * G_PI / half));
2934       cairo_line_to (cr,
2935                      dx + radius * cos (i * G_PI / half),
2936                      dy + radius * sin (i * G_PI / half));
2937       cairo_stroke (cr);
2938
2939       cairo_restore (cr);
2940     }
2941 }
2942
2943 void
2944 _gtk_style_shade (const GdkColor *a,
2945                   GdkColor       *b,
2946                   gdouble         k)
2947 {
2948   gdouble red;
2949   gdouble green;
2950   gdouble blue;
2951   
2952   red = (gdouble) a->red / 65535.0;
2953   green = (gdouble) a->green / 65535.0;
2954   blue = (gdouble) a->blue / 65535.0;
2955   
2956   rgb_to_hls (&red, &green, &blue);
2957   
2958   green *= k;
2959   if (green > 1.0)
2960     green = 1.0;
2961   else if (green < 0.0)
2962     green = 0.0;
2963   
2964   blue *= k;
2965   if (blue > 1.0)
2966     blue = 1.0;
2967   else if (blue < 0.0)
2968     blue = 0.0;
2969   
2970   hls_to_rgb (&red, &green, &blue);
2971   
2972   b->red = red * 65535.0;
2973   b->green = green * 65535.0;
2974   b->blue = blue * 65535.0;
2975 }
2976
2977 static void
2978 rgb_to_hls (gdouble *r,
2979             gdouble *g,
2980             gdouble *b)
2981 {
2982   gdouble min;
2983   gdouble max;
2984   gdouble red;
2985   gdouble green;
2986   gdouble blue;
2987   gdouble h, l, s;
2988   gdouble delta;
2989   
2990   red = *r;
2991   green = *g;
2992   blue = *b;
2993   
2994   if (red > green)
2995     {
2996       if (red > blue)
2997         max = red;
2998       else
2999         max = blue;
3000       
3001       if (green < blue)
3002         min = green;
3003       else
3004         min = blue;
3005     }
3006   else
3007     {
3008       if (green > blue)
3009         max = green;
3010       else
3011         max = blue;
3012       
3013       if (red < blue)
3014         min = red;
3015       else
3016         min = blue;
3017     }
3018   
3019   l = (max + min) / 2;
3020   s = 0;
3021   h = 0;
3022   
3023   if (max != min)
3024     {
3025       if (l <= 0.5)
3026         s = (max - min) / (max + min);
3027       else
3028         s = (max - min) / (2 - max - min);
3029       
3030       delta = max -min;
3031       if (red == max)
3032         h = (green - blue) / delta;
3033       else if (green == max)
3034         h = 2 + (blue - red) / delta;
3035       else if (blue == max)
3036         h = 4 + (red - green) / delta;
3037       
3038       h *= 60;
3039       if (h < 0.0)
3040         h += 360;
3041     }
3042   
3043   *r = h;
3044   *g = l;
3045   *b = s;
3046 }
3047
3048 static void
3049 hls_to_rgb (gdouble *h,
3050             gdouble *l,
3051             gdouble *s)
3052 {
3053   gdouble hue;
3054   gdouble lightness;
3055   gdouble saturation;
3056   gdouble m1, m2;
3057   gdouble r, g, b;
3058   
3059   lightness = *l;
3060   saturation = *s;
3061   
3062   if (lightness <= 0.5)
3063     m2 = lightness * (1 + saturation);
3064   else
3065     m2 = lightness + saturation - lightness * saturation;
3066   m1 = 2 * lightness - m2;
3067   
3068   if (saturation == 0)
3069     {
3070       *h = lightness;
3071       *l = lightness;
3072       *s = lightness;
3073     }
3074   else
3075     {
3076       hue = *h + 120;
3077       while (hue > 360)
3078         hue -= 360;
3079       while (hue < 0)
3080         hue += 360;
3081       
3082       if (hue < 60)
3083         r = m1 + (m2 - m1) * hue / 60;
3084       else if (hue < 180)
3085         r = m2;
3086       else if (hue < 240)
3087         r = m1 + (m2 - m1) * (240 - hue) / 60;
3088       else
3089         r = m1;
3090       
3091       hue = *h;
3092       while (hue > 360)
3093         hue -= 360;
3094       while (hue < 0)
3095         hue += 360;
3096       
3097       if (hue < 60)
3098         g = m1 + (m2 - m1) * hue / 60;
3099       else if (hue < 180)
3100         g = m2;
3101       else if (hue < 240)
3102         g = m1 + (m2 - m1) * (240 - hue) / 60;
3103       else
3104         g = m1;
3105       
3106       hue = *h - 120;
3107       while (hue > 360)
3108         hue -= 360;
3109       while (hue < 0)
3110         hue += 360;
3111       
3112       if (hue < 60)
3113         b = m1 + (m2 - m1) * hue / 60;
3114       else if (hue < 180)
3115         b = m2;
3116       else if (hue < 240)
3117         b = m1 + (m2 - m1) * (240 - hue) / 60;
3118       else
3119         b = m1;
3120       
3121       *h = r;
3122       *l = g;
3123       *s = b;
3124     }
3125 }
3126
3127
3128 /**
3129  * gtk_paint_hline:
3130  * @style: a #GtkStyle
3131  * @cr: a #caio_t
3132  * @state_type: a state
3133  * @widget: (allow-none): the widget
3134  * @detail: (allow-none): a style detail
3135  * @x1: the starting x coordinate
3136  * @x2: the ending x coordinate
3137  * @y: the y coordinate
3138  *
3139  * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @cr
3140  * using the given style and state.
3141  *
3142  * Deprecated:3.0: Use gtk_render_line() instead
3143  **/
3144 void
3145 gtk_paint_hline (GtkStyle           *style,
3146                  cairo_t            *cr,
3147                  GtkStateType        state_type,
3148                  GtkWidget          *widget,
3149                  const gchar        *detail,
3150                  gint                x1,
3151                  gint                x2,
3152                  gint                y)
3153 {
3154   g_return_if_fail (GTK_IS_STYLE (style));
3155   g_return_if_fail (cr != NULL);
3156   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
3157
3158   cairo_save (cr);
3159
3160   GTK_STYLE_GET_CLASS (style)->draw_hline (style, cr, state_type,
3161                                            widget, detail,
3162                                            x1, x2, y);
3163
3164   cairo_restore (cr);
3165 }
3166
3167 /**
3168  * gtk_paint_vline:
3169  * @style: a #GtkStyle
3170  * @cr: a #cairo_t
3171  * @state_type: a state
3172  * @widget: (allow-none): the widget
3173  * @detail: (allow-none): a style detail
3174  * @y1_: the starting y coordinate
3175  * @y2_: the ending y coordinate
3176  * @x: the x coordinate
3177  *
3178  * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @cr
3179  * using the given style and state.
3180  *
3181  * Deprecated:3.0: Use gtk_render_line() instead
3182  */
3183 void
3184 gtk_paint_vline (GtkStyle           *style,
3185                  cairo_t            *cr,
3186                  GtkStateType        state_type,
3187                  GtkWidget          *widget,
3188                  const gchar        *detail,
3189                  gint                y1_,
3190                  gint                y2_,
3191                  gint                x)
3192 {
3193   g_return_if_fail (GTK_IS_STYLE (style));
3194   g_return_if_fail (cr != NULL);
3195   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
3196
3197   cairo_save (cr);
3198
3199   GTK_STYLE_GET_CLASS (style)->draw_vline (style, cr, state_type,
3200                                            widget, detail,
3201                                            y1_, y2_, x);
3202
3203   cairo_restore (cr);
3204 }
3205
3206 /**
3207  * gtk_paint_shadow:
3208  * @style: a #GtkStyle
3209  * @cr: a #cairo_t
3210  * @state_type: a state
3211  * @shadow_type: type of shadow to draw
3212  * @widget: (allow-none): the widget
3213  * @detail: (allow-none): a style detail
3214  * @x: x origin of the rectangle
3215  * @y: y origin of the rectangle
3216  * @width: width of the rectangle
3217  * @height: width of the rectangle
3218  *
3219  * Draws a shadow around the given rectangle in @cr
3220  * using the given style and state and shadow type.
3221  *
3222  * Deprecated:3.0: Use gtk_render_frame() instead
3223  */
3224 void
3225 gtk_paint_shadow (GtkStyle           *style,
3226                   cairo_t            *cr,
3227                   GtkStateType        state_type,
3228                   GtkShadowType       shadow_type,
3229                   GtkWidget          *widget,
3230                   const gchar        *detail,
3231                   gint                x,
3232                   gint                y,
3233                   gint                width,
3234                   gint                height)
3235 {
3236   g_return_if_fail (GTK_IS_STYLE (style));
3237   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
3238   g_return_if_fail (cr != NULL);
3239   g_return_if_fail (width >= 0);
3240   g_return_if_fail (height >= 0);
3241
3242   cairo_save (cr);
3243
3244   GTK_STYLE_GET_CLASS (style)->draw_shadow (style, cr, state_type, shadow_type,
3245                                             widget, detail,
3246                                             x, y, width, height);
3247
3248   cairo_restore (cr);
3249 }
3250
3251 /**
3252  * gtk_paint_arrow:
3253  * @style: a #GtkStyle
3254  * @cr: a #cairo_t
3255  * @state_type: a state
3256  * @shadow_type: the type of shadow to draw
3257  * @widget: (allow-none): the widget
3258  * @detail: (allow-none): a style detail
3259  * @arrow_type: the type of arrow to draw
3260  * @fill: %TRUE if the arrow tip should be filled
3261  * @x: x origin of the rectangle to draw the arrow in
3262  * @y: y origin of the rectangle to draw the arrow in
3263  * @width: width of the rectangle to draw the arrow in
3264  * @height: height of the rectangle to draw the arrow in
3265  *
3266  * Draws an arrow in the given rectangle on @cr using the given
3267  * parameters. @arrow_type determines the direction of the arrow.
3268  *
3269  * Deprecated:3.0: Use gtk_render_arrow() instead
3270  */
3271 void
3272 gtk_paint_arrow (GtkStyle           *style,
3273                  cairo_t            *cr,
3274                  GtkStateType        state_type,
3275                  GtkShadowType       shadow_type,
3276                  GtkWidget          *widget,
3277                  const gchar        *detail,
3278                  GtkArrowType        arrow_type,
3279                  gboolean            fill,
3280                  gint                x,
3281                  gint                y,
3282                  gint                width,
3283                  gint                height)
3284 {
3285   g_return_if_fail (GTK_IS_STYLE (style));
3286   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
3287   g_return_if_fail (cr != NULL);
3288   g_return_if_fail (width >= 0);
3289   g_return_if_fail (height >= 0);
3290
3291   cairo_save (cr);
3292
3293   GTK_STYLE_GET_CLASS (style)->draw_arrow (style, cr, state_type, shadow_type,
3294                                            widget, detail,
3295                                            arrow_type, fill, x, y, width, height);
3296
3297   cairo_restore (cr);
3298 }
3299
3300 /**
3301  * gtk_paint_diamond:
3302  * @style: a #GtkStyle
3303  * @cr: a #cairo_t
3304  * @state_type: a state
3305  * @shadow_type: the type of shadow to draw
3306  * @widget: (allow-none): the widget
3307  * @detail: (allow-none): a style detail
3308  * @x: x origin of the rectangle to draw the diamond in
3309  * @y: y origin of the rectangle to draw the diamond in
3310  * @width: width of the rectangle to draw the diamond in
3311  * @height: height of the rectangle to draw the diamond in
3312  *
3313  * Draws a diamond in the given rectangle on @window using the given
3314  * parameters.
3315  *
3316  * Deprecated:3.0: Use cairo instead
3317  */
3318 void
3319 gtk_paint_diamond (GtkStyle           *style,
3320                    cairo_t            *cr,
3321                    GtkStateType        state_type,
3322                    GtkShadowType       shadow_type,
3323                    GtkWidget          *widget,
3324                    const gchar        *detail,
3325                    gint                x,
3326                    gint                y,
3327                    gint                width,
3328                    gint                height)
3329 {
3330   g_return_if_fail (GTK_IS_STYLE (style));
3331   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
3332   g_return_if_fail (cr != NULL);
3333   g_return_if_fail (width >= 0);
3334   g_return_if_fail (height >= 0);
3335
3336   cairo_save (cr);
3337
3338   GTK_STYLE_GET_CLASS (style)->draw_diamond (style, cr, state_type, shadow_type,
3339                                              widget, detail,
3340                                              x, y, width, height);
3341
3342   cairo_restore (cr);
3343 }
3344
3345 /**
3346  * gtk_paint_box:
3347  * @style: a #GtkStyle
3348  * @cr: a #cairo_t
3349  * @state_type: a state
3350  * @shadow_type: the type of shadow to draw
3351  * @widget: (allow-none): the widget
3352  * @detail: (allow-none): a style detail
3353  * @x: x origin of the box
3354  * @y: y origin of the box
3355  * @width: the width of the box
3356  * @height: the height of the box
3357  *
3358  * Draws a box on @cr with the given parameters.
3359  *
3360  * Deprecated:3.0: Use gtk_render_frame() and gtk_render_background() instead
3361  */
3362 void
3363 gtk_paint_box (GtkStyle           *style,
3364                cairo_t            *cr,
3365                GtkStateType        state_type,
3366                GtkShadowType       shadow_type,
3367                GtkWidget          *widget,
3368                const gchar        *detail,
3369                gint                x,
3370                gint                y,
3371                gint                width,
3372                gint                height)
3373 {
3374   g_return_if_fail (GTK_IS_STYLE (style));
3375   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
3376   g_return_if_fail (cr != NULL);
3377
3378   cairo_save (cr);
3379
3380   GTK_STYLE_GET_CLASS (style)->draw_box (style, cr, state_type, shadow_type,
3381                                          widget, detail,
3382                                          x, y, width, height);
3383
3384   cairo_restore (cr);
3385 }
3386
3387 /**
3388  * gtk_paint_flat_box:
3389  * @style: a #GtkStyle
3390  * @cr: a #cairo_t
3391  * @state_type: a state
3392  * @shadow_type: the type of shadow to draw
3393  * @widget: (allow-none): the widget
3394  * @detail: (allow-none): a style detail
3395  * @x: x origin of the box
3396  * @y: y origin of the box
3397  * @width: the width of the box
3398  * @height: the height of the box
3399  *
3400  * Draws a flat box on @cr with the given parameters.
3401  *
3402  * Deprecated:3.0: Use gtk_render_frame() and gtk_render_background() instead
3403  */
3404 void
3405 gtk_paint_flat_box (GtkStyle           *style,
3406                     cairo_t            *cr,
3407                     GtkStateType        state_type,
3408                     GtkShadowType       shadow_type,
3409                     GtkWidget          *widget,
3410                     const gchar        *detail,
3411                     gint                x,
3412                     gint                y,
3413                     gint                width,
3414                     gint                height)
3415 {
3416   g_return_if_fail (GTK_IS_STYLE (style));
3417   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
3418   g_return_if_fail (cr != NULL);
3419   g_return_if_fail (width >= 0);
3420   g_return_if_fail (height >= 0);
3421
3422   cairo_save (cr);
3423
3424   GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, cr, state_type, shadow_type,
3425                                               widget, detail,
3426                                               x, y, width, height);
3427
3428   cairo_restore (cr);
3429 }
3430
3431 /**
3432  * gtk_paint_check:
3433  * @style: a #GtkStyle
3434  * @cr: a #cairo_t
3435  * @state_type: a state
3436  * @shadow_type: the type of shadow to draw
3437  * @widget: (allow-none): the widget
3438  * @detail: (allow-none): a style detail
3439  * @x: x origin of the rectangle to draw the check in
3440  * @y: y origin of the rectangle to draw the check in
3441  * @width: the width of the rectangle to draw the check in
3442  * @height: the height of the rectangle to draw the check in
3443  *
3444  * Draws a check button indicator in the given rectangle on @cr with
3445  * the given parameters.
3446  *
3447  * Deprecated:3.0: Use gtk_render_check() instead
3448  */
3449 void
3450 gtk_paint_check (GtkStyle           *style,
3451                  cairo_t            *cr,
3452                  GtkStateType        state_type,
3453                  GtkShadowType       shadow_type,
3454                  GtkWidget          *widget,
3455                  const gchar        *detail,
3456                  gint                x,
3457                  gint                y,
3458                  gint                width,
3459                  gint                height)
3460 {
3461   g_return_if_fail (GTK_IS_STYLE (style));
3462   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
3463   g_return_if_fail (cr != NULL);
3464
3465   cairo_save (cr);
3466
3467   GTK_STYLE_GET_CLASS (style)->draw_check (style, cr, state_type, shadow_type,
3468                                            widget, detail,
3469                                            x, y, width, height);
3470
3471   cairo_restore (cr);
3472 }
3473
3474 /**
3475  * gtk_paint_option:
3476  * @style: a #GtkStyle
3477  * @cr: a #cairo_t
3478  * @state_type: a state
3479  * @shadow_type: the type of shadow to draw
3480  * @widget: (allow-none): the widget
3481  * @detail: (allow-none): a style detail
3482  * @x: x origin of the rectangle to draw the option in
3483  * @y: y origin of the rectangle to draw the option in
3484  * @width: the width of the rectangle to draw the option in
3485  * @height: the height of the rectangle to draw the option in
3486  *
3487  * Draws a radio button indicator in the given rectangle on @cr with
3488  * the given parameters.
3489  *
3490  * Deprecated:3.0: Use gtk_render_option() instead
3491  */
3492 void
3493 gtk_paint_option (GtkStyle           *style,
3494                   cairo_t            *cr,
3495                   GtkStateType        state_type,
3496                   GtkShadowType       shadow_type,
3497                   GtkWidget          *widget,
3498                   const gchar        *detail,
3499                   gint                x,
3500                   gint                y,
3501                   gint                width,
3502                   gint                height)
3503 {
3504   g_return_if_fail (GTK_IS_STYLE (style));
3505   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
3506   g_return_if_fail (cr != NULL);
3507
3508   cairo_save (cr);
3509
3510   GTK_STYLE_GET_CLASS (style)->draw_option (style, cr, state_type, shadow_type,
3511                                             widget, detail,
3512                                             x, y, width, height);
3513
3514   cairo_restore (cr);
3515 }
3516
3517 /**
3518  * gtk_paint_tab:
3519  * @style: a #GtkStyle
3520  * @cr: a #cairo_t
3521  * @state_type: a state
3522  * @shadow_type: the type of shadow to draw
3523  * @widget: (allow-none): the widget
3524  * @detail: (allow-none): a style detail
3525  * @x: x origin of the rectangle to draw the tab in
3526  * @y: y origin of the rectangle to draw the tab in
3527  * @width: the width of the rectangle to draw the tab in
3528  * @height: the height of the rectangle to draw the tab in
3529  *
3530  * Draws an option menu tab (i.e. the up and down pointing arrows)
3531  * in the given rectangle on @cr using the given parameters.
3532  *
3533  * Deprecated:3.0: Use cairo instead
3534  */
3535 void
3536 gtk_paint_tab (GtkStyle           *style,
3537                cairo_t            *cr,
3538                GtkStateType        state_type,
3539                GtkShadowType       shadow_type,
3540                GtkWidget          *widget,
3541                const gchar        *detail,
3542                gint                x,
3543                gint                y,
3544                gint                width,
3545                gint                height)
3546 {
3547   g_return_if_fail (GTK_IS_STYLE (style));
3548   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
3549   g_return_if_fail (cr != NULL);
3550
3551   cairo_save (cr);
3552
3553   GTK_STYLE_GET_CLASS (style)->draw_tab (style, cr, state_type, shadow_type,
3554                                          widget, detail,
3555                                          x, y, width, height);
3556
3557   cairo_restore (cr);
3558 }
3559
3560 /**
3561  * gtk_paint_shadow_gap:
3562  * @style: a #GtkStyle
3563  * @cr: a #cairo_t
3564  * @state_type: a state
3565  * @shadow_type: type of shadow to draw
3566  * @widget: (allow-none): the widget
3567  * @detail: (allow-none): a style detail
3568  * @x: x origin of the rectangle
3569  * @y: y origin of the rectangle
3570  * @width: width of the rectangle
3571  * @height: width of the rectangle
3572  * @gap_side: side in which to leave the gap
3573  * @gap_x: starting position of the gap
3574  * @gap_width: width of the gap
3575  *
3576  * Draws a shadow around the given rectangle in @cr
3577  * using the given style and state and shadow type, leaving a
3578  * gap in one side.
3579  *
3580  * Deprecated:3.0: Use gtk_render_frame_gap() instead
3581  */
3582 void
3583 gtk_paint_shadow_gap (GtkStyle           *style,
3584                       cairo_t            *cr,
3585                       GtkStateType        state_type,
3586                       GtkShadowType       shadow_type,
3587                       GtkWidget          *widget,
3588                       const gchar        *detail,
3589                       gint                x,
3590                       gint                y,
3591                       gint                width,
3592                       gint                height,
3593                       GtkPositionType     gap_side,
3594                       gint                gap_x,
3595                       gint                gap_width)
3596 {
3597   g_return_if_fail (GTK_IS_STYLE (style));
3598   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
3599   g_return_if_fail (cr != NULL);
3600   g_return_if_fail (width >= 0);
3601   g_return_if_fail (height >= 0);
3602
3603   cairo_save (cr);
3604
3605   GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, cr, state_type, shadow_type,
3606                                                 widget, detail,
3607                                                 x, y, width, height, gap_side, gap_x, gap_width);
3608
3609   cairo_restore (cr);
3610 }
3611
3612 /**
3613  * gtk_paint_box_gap:
3614  * @style: a #GtkStyle
3615  * @cr: a #cairo_t
3616  * @state_type: a state
3617  * @shadow_type: type of shadow to draw
3618  * @widget: (allow-none): the widget
3619  * @detail: (allow-none): a style detail
3620  * @x: x origin of the rectangle
3621  * @y: y origin of the rectangle
3622  * @width: width of the rectangle
3623  * @height: width of the rectangle
3624  * @gap_side: side in which to leave the gap
3625  * @gap_x: starting position of the gap
3626  * @gap_width: width of the gap
3627  *
3628  * Draws a box in @cr using the given style and state and shadow type,
3629  * leaving a gap in one side.
3630  *
3631  * Deprecated:3.0: Use gtk_render_frame_gap() instead
3632  */
3633 void
3634 gtk_paint_box_gap (GtkStyle           *style,
3635                    cairo_t            *cr,
3636                    GtkStateType        state_type,
3637                    GtkShadowType       shadow_type,
3638                    GtkWidget          *widget,
3639                    const gchar        *detail,
3640                    gint                x,
3641                    gint                y,
3642                    gint                width,
3643                    gint                height,
3644                    GtkPositionType     gap_side,
3645                    gint                gap_x,
3646                    gint                gap_width)
3647 {
3648   g_return_if_fail (GTK_IS_STYLE (style));
3649   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
3650   g_return_if_fail (cr != NULL);
3651   g_return_if_fail (width >= 0);
3652   g_return_if_fail (height >= 0);
3653
3654   cairo_save (cr);
3655
3656   GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, cr, state_type, shadow_type,
3657                                              widget, detail,
3658                                              x, y, width, height, gap_side, gap_x, gap_width);
3659
3660   cairo_restore (cr);
3661 }
3662
3663 /**
3664  * gtk_paint_extension:
3665  * @style: a #GtkStyle
3666  * @cr: a #cairo_t
3667  * @state_type: a state
3668  * @shadow_type: type of shadow to draw
3669  * @widget: (allow-none): the widget
3670  * @detail: (allow-none): a style detail
3671  * @x: x origin of the extension
3672  * @y: y origin of the extension
3673  * @width: width of the extension
3674  * @height: width of the extension
3675  * @gap_side: the side on to which the extension is attached
3676  *
3677  * Draws an extension, i.e. a notebook tab.
3678  *
3679  * Deprecated:3.0: Use gtk_render_extension() instead
3680  **/
3681 void
3682 gtk_paint_extension (GtkStyle           *style,
3683                      cairo_t            *cr,
3684                      GtkStateType        state_type,
3685                      GtkShadowType       shadow_type,
3686                      GtkWidget          *widget,
3687                      const gchar        *detail,
3688                      gint                x,
3689                      gint                y,
3690                      gint                width,
3691                      gint                height,
3692                      GtkPositionType     gap_side)
3693 {
3694   g_return_if_fail (GTK_IS_STYLE (style));
3695   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
3696   g_return_if_fail (cr != NULL);
3697   g_return_if_fail (width >= 0);
3698   g_return_if_fail (height >= 0);
3699
3700   cairo_save (cr);
3701
3702   GTK_STYLE_GET_CLASS (style)->draw_extension (style, cr, state_type, shadow_type,
3703                                                widget, detail,
3704                                                x, y, width, height, gap_side);
3705
3706   cairo_restore (cr);
3707 }
3708
3709 /**
3710  * gtk_paint_focus:
3711  * @style: a #GtkStyle
3712  * @cr: a #cairo_t
3713  * @state_type: a state
3714  * @widget: (allow-none): the widget
3715  * @detail: (allow-none): a style detail
3716  * @x: the x origin of the rectangle around which to draw a focus indicator
3717  * @y: the y origin of the rectangle around which to draw a focus indicator
3718  * @width: the width of the rectangle around which to draw a focus indicator
3719  * @height: the height of the rectangle around which to draw a focus indicator
3720  *
3721  * Draws a focus indicator around the given rectangle on @cr using the
3722  * given style.
3723  *
3724  * Deprecated:3.0: Use gtk_render_focus() instead
3725  */
3726 void
3727 gtk_paint_focus (GtkStyle           *style,
3728                  cairo_t            *cr,
3729                  GtkStateType        state_type,
3730                  GtkWidget          *widget,
3731                  const gchar        *detail,
3732                  gint                x,
3733                  gint                y,
3734                  gint                width,
3735                  gint                height)
3736 {
3737   g_return_if_fail (GTK_IS_STYLE (style));
3738   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
3739   g_return_if_fail (cr != NULL);
3740   g_return_if_fail (width >= 0);
3741   g_return_if_fail (height >= 0);
3742
3743   cairo_save (cr);
3744
3745   GTK_STYLE_GET_CLASS (style)->draw_focus (style, cr, state_type,
3746                                            widget, detail,
3747                                            x, y, width, height);
3748
3749   cairo_restore (cr);
3750 }
3751
3752 /**
3753  * gtk_paint_slider:
3754  * @style: a #GtkStyle
3755  * @cr: a #cairo_t
3756  * @state_type: a state
3757  * @shadow_type: a shadow
3758  * @widget: (allow-none): the widget
3759  * @detail: (allow-none): a style detail
3760  * @x: the x origin of the rectangle in which to draw a slider
3761  * @y: the y origin of the rectangle in which to draw a slider
3762  * @width: the width of the rectangle in which to draw a slider
3763  * @height: the height of the rectangle in which to draw a slider
3764  * @orientation: the orientation to be used
3765  *
3766  * Draws a slider in the given rectangle on @cr using the
3767  * given style and orientation.
3768  *
3769  * Deprecated:3.0: Use gtk_render_slider() instead
3770  **/
3771 void
3772 gtk_paint_slider (GtkStyle           *style,
3773                   cairo_t            *cr,
3774                   GtkStateType        state_type,
3775                   GtkShadowType       shadow_type,
3776                   GtkWidget          *widget,
3777                   const gchar        *detail,
3778                   gint                x,
3779                   gint                y,
3780                   gint                width,
3781                   gint                height,
3782                   GtkOrientation      orientation)
3783 {
3784   g_return_if_fail (GTK_IS_STYLE (style));
3785   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
3786   g_return_if_fail (cr != NULL);
3787   g_return_if_fail (width >= 0);
3788   g_return_if_fail (height >= 0);
3789
3790   cairo_save (cr);
3791
3792   GTK_STYLE_GET_CLASS (style)->draw_slider (style, cr, state_type, shadow_type,
3793                                             widget, detail,
3794                                             x, y, width, height, orientation);
3795
3796   cairo_restore (cr);
3797 }
3798
3799 /**
3800  * gtk_paint_handle:
3801  * @style: a #GtkStyle
3802  * @cr: a #cairo_t
3803  * @state_type: a state
3804  * @shadow_type: type of shadow to draw
3805  * @widget: (allow-none): the widget
3806  * @detail: (allow-none): a style detail
3807  * @x: x origin of the handle
3808  * @y: y origin of the handle
3809  * @width: with of the handle
3810  * @height: height of the handle
3811  * @orientation: the orientation of the handle
3812  *
3813  * Draws a handle as used in #GtkHandleBox and #GtkPaned.
3814  *
3815  * Deprecated:3.0: Use gtk_render_handle() instead
3816  **/
3817 void
3818 gtk_paint_handle (GtkStyle           *style,
3819                   cairo_t            *cr,
3820                   GtkStateType        state_type,
3821                   GtkShadowType       shadow_type,
3822                   GtkWidget          *widget,
3823                   const gchar        *detail,
3824                   gint                x,
3825                   gint                y,
3826                   gint                width,
3827                   gint                height,
3828                   GtkOrientation      orientation)
3829 {
3830   g_return_if_fail (GTK_IS_STYLE (style));
3831   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
3832   g_return_if_fail (cr != NULL);
3833   g_return_if_fail (width >= 0);
3834   g_return_if_fail (height >= 0);
3835
3836   cairo_save (cr);
3837
3838   GTK_STYLE_GET_CLASS (style)->draw_handle (style, cr, state_type, shadow_type,
3839                                             widget, detail,
3840                                             x, y, width, height, orientation);
3841
3842   cairo_restore (cr);
3843 }
3844
3845 /**
3846  * gtk_paint_expander:
3847  * @style: a #GtkStyle
3848  * @cr: a #cairo_t
3849  * @state_type: a state
3850  * @widget: (allow-none): the widget
3851  * @detail: (allow-none): a style detail
3852  * @x: the x position to draw the expander at
3853  * @y: the y position to draw the expander at
3854  * @expander_style: the style to draw the expander in; determines
3855  *   whether the expander is collapsed, expanded, or in an
3856  *   intermediate state.
3857  *
3858  * Draws an expander as used in #GtkTreeView. @x and @y specify the
3859  * center the expander. The size of the expander is determined by the
3860  * "expander-size" style property of @widget.  (If widget is not
3861  * specified or doesn't have an "expander-size" property, an
3862  * unspecified default size will be used, since the caller doesn't
3863  * have sufficient information to position the expander, this is
3864  * likely not useful.) The expander is expander_size pixels tall
3865  * in the collapsed position and expander_size pixels wide in the
3866  * expanded position.
3867  *
3868  * Deprecated:3.0: Use gtk_render_expander() instead
3869  **/
3870 void
3871 gtk_paint_expander (GtkStyle           *style,
3872                     cairo_t            *cr,
3873                     GtkStateType        state_type,
3874                     GtkWidget          *widget,
3875                     const gchar        *detail,
3876                     gint                x,
3877                     gint                y,
3878                     GtkExpanderStyle    expander_style)
3879 {
3880   g_return_if_fail (GTK_IS_STYLE (style));
3881   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
3882   g_return_if_fail (cr != NULL);
3883
3884   cairo_save (cr);
3885
3886   GTK_STYLE_GET_CLASS (style)->draw_expander (style, cr, state_type,
3887                                               widget, detail,
3888                                               x, y, expander_style);
3889
3890   cairo_restore (cr);
3891 }
3892
3893 /**
3894  * gtk_paint_layout:
3895  * @style: a #GtkStyle
3896  * @cr: a #cairo_t
3897  * @state_type: a state
3898  * @use_text: whether to use the text or foreground
3899  *            graphics context of @style
3900  * @widget: (allow-none): the widget
3901  * @detail: (allow-none): a style detail
3902  * @x: x origin
3903  * @y: y origin
3904  * @layout: the layout to draw
3905  *
3906  * Draws a layout on @cr using the given parameters.
3907  *
3908  * Deprecated:3.0: Use gtk_render_layout() instead
3909  **/
3910 void
3911 gtk_paint_layout (GtkStyle           *style,
3912                   cairo_t            *cr,
3913                   GtkStateType        state_type,
3914                   gboolean            use_text,
3915                   GtkWidget          *widget,
3916                   const gchar        *detail,
3917                   gint                x,
3918                   gint                y,
3919                   PangoLayout        *layout)
3920 {
3921   g_return_if_fail (GTK_IS_STYLE (style));
3922   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
3923   g_return_if_fail (cr != NULL);
3924
3925   cairo_save (cr);
3926
3927   GTK_STYLE_GET_CLASS (style)->draw_layout (style, cr, state_type, use_text,
3928                                             widget, detail,
3929                                             x, y, layout);
3930
3931   cairo_restore (cr);
3932 }
3933
3934 /**
3935  * gtk_paint_resize_grip:
3936  * @style: a #GtkStyle
3937  * @cr: a #cairo_t
3938  * @state_type: a state
3939  * @widget: (allow-none): the widget
3940  * @detail: (allow-none): a style detail
3941  * @edge: the edge in which to draw the resize grip
3942  * @x: the x origin of the rectangle in which to draw the resize grip
3943  * @y: the y origin of the rectangle in which to draw the resize grip
3944  * @width: the width of the rectangle in which to draw the resize grip
3945  * @height: the height of the rectangle in which to draw the resize grip
3946  *
3947  * Draws a resize grip in the given rectangle on @cr using the given
3948  * parameters.
3949  *
3950  * Deprecated:3.0: Use gtk_render_handle() instead
3951  */
3952 void
3953 gtk_paint_resize_grip (GtkStyle           *style,
3954                        cairo_t            *cr,
3955                        GtkStateType        state_type,
3956                        GtkWidget          *widget,
3957                        const gchar        *detail,
3958                        GdkWindowEdge       edge,
3959                        gint                x,
3960                        gint                y,
3961                        gint                width,
3962                        gint                height)
3963 {
3964   g_return_if_fail (GTK_IS_STYLE (style));
3965   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
3966   g_return_if_fail (cr != NULL);
3967
3968   cairo_save (cr);
3969
3970   GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, cr, state_type,
3971                                                  widget, detail,
3972                                                  edge, x, y, width, height);
3973   cairo_restore (cr);
3974 }
3975
3976 /**
3977  * gtk_paint_spinner:
3978  * @style: a #GtkStyle
3979  * @cr: a #cairo_t
3980  * @state_type: a state
3981  * @widget: (allow-none): the widget (may be %NULL)
3982  * @detail: (allow-none): a style detail (may be %NULL)
3983  * @step: the nth step, a value between 0 and #GtkSpinner:num-steps
3984  * @x: the x origin of the rectangle in which to draw the spinner
3985  * @y: the y origin of the rectangle in which to draw the spinner
3986  * @width: the width of the rectangle in which to draw the spinner
3987  * @height: the height of the rectangle in which to draw the spinner
3988  *
3989  * Draws a spinner on @window using the given parameters.
3990  *
3991  * Deprecated:3.0: Use gtk_render_activity() instead
3992  */
3993 void
3994 gtk_paint_spinner (GtkStyle           *style,
3995                    cairo_t            *cr,
3996                    GtkStateType        state_type,
3997                    GtkWidget          *widget,
3998                    const gchar        *detail,
3999                    guint               step,
4000                    gint                x,
4001                    gint                y,
4002                    gint                width,
4003                    gint                height)
4004 {
4005   g_return_if_fail (GTK_IS_STYLE (style));
4006   g_return_if_fail (cr != NULL);
4007   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_spinner != NULL);
4008
4009   cairo_save (cr);
4010
4011   GTK_STYLE_GET_CLASS (style)->draw_spinner (style, cr, state_type,
4012                                              widget, detail,
4013                                              step, x, y, width, height);
4014
4015   cairo_restore (cr);
4016 }
4017
4018 static GtkStyle *
4019 gtk_widget_get_default_style_for_screen (GdkScreen *screen)
4020 {
4021   GtkStyle *default_style;
4022
4023   default_style = g_object_get_data (G_OBJECT (screen), "gtk-legacy-default-style");
4024   if (default_style == NULL)
4025     {
4026       default_style = gtk_style_new ();
4027       g_object_set_data_full (G_OBJECT (screen),
4028                               I_("gtk-legacy-default-style"),
4029                               default_style,
4030                               g_object_unref);
4031     }
4032
4033   return default_style;
4034 }
4035
4036 /**
4037  * gtk_widget_get_default_style:
4038  *
4039  * Returns the default style used by all widgets initially.
4040  *
4041  * Returns: (transfer none): the default style. This #GtkStyle
4042  *     object is owned by GTK+ and should not be modified or freed.
4043  *
4044  * Deprecated:3.0: Use #GtkStyleContext instead, and
4045  *     gtk_css_provider_get_default() to obtain a #GtkStyleProvider
4046  *     with the default widget style information.
4047  */
4048 GtkStyle *
4049 gtk_widget_get_default_style (void)
4050 {
4051   static GtkStyle *default_style = NULL;
4052   GtkStyle *style = NULL;
4053   GdkScreen *screen = gdk_screen_get_default ();
4054
4055   if (screen)
4056     style = gtk_widget_get_default_style_for_screen (screen);
4057   else
4058     {
4059       if (default_style == NULL)
4060         default_style = gtk_style_new ();
4061       style = default_style;
4062     }
4063
4064   return style;
4065 }
4066
4067 /**
4068  * gtk_widget_style_attach:
4069  * @widget: a #GtkWidget
4070  *
4071  * This function attaches the widget's #GtkStyle to the widget's
4072  * #GdkWindow. It is a replacement for
4073  *
4074  * <programlisting>
4075  * widget->style = gtk_style_attach (widget->style, widget->window);
4076  * </programlisting>
4077  *
4078  * and should only ever be called in a derived widget's "realize"
4079  * implementation which does not chain up to its parent class'
4080  * "realize" implementation, because one of the parent classes
4081  * (finally #GtkWidget) would attach the style itself.
4082  *
4083  * Since: 2.20
4084  *
4085  * Deprecated: 3.0. This step is unnecessary with #GtkStyleContext.
4086  **/
4087 void
4088 gtk_widget_style_attach (GtkWidget *widget)
4089 {
4090   g_return_if_fail (GTK_IS_WIDGET (widget));
4091   g_return_if_fail (gtk_widget_get_realized (widget));
4092 }
4093
4094 /**
4095  * gtk_widget_has_rc_style:
4096  * @widget: a #GtkWidget
4097  *
4098  * Determines if the widget style has been looked up through the rc mechanism.
4099  *
4100  * Returns: %TRUE if the widget has been looked up through the rc
4101  *   mechanism, %FALSE otherwise.
4102  *
4103  * Since: 2.20
4104  *
4105  * Deprecated:3.0: Use #GtkStyleContext instead
4106  **/
4107 gboolean
4108 gtk_widget_has_rc_style (GtkWidget *widget)
4109 {
4110   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4111
4112   return FALSE;
4113 }
4114
4115 /**
4116  * gtk_widget_set_style:
4117  * @widget: a #GtkWidget
4118  * @style: (allow-none): a #GtkStyle, or %NULL to remove the effect
4119  *     of a previous call to gtk_widget_set_style() and go back to
4120  *     the default style
4121  *
4122  * Used to set the #GtkStyle for a widget (@widget->style). Since
4123  * GTK 3, this function does nothing, the passed in style is ignored.
4124  *
4125  * Deprecated:3.0: Use #GtkStyleContext instead
4126  */
4127 void
4128 gtk_widget_set_style (GtkWidget *widget,
4129                       GtkStyle  *style)
4130 {
4131   g_return_if_fail (GTK_IS_WIDGET (widget));
4132 }
4133
4134 /**
4135  * gtk_widget_ensure_style:
4136  * @widget: a #GtkWidget
4137  *
4138  * Ensures that @widget has a style (@widget->style).
4139  *
4140  * Not a very useful function; most of the time, if you
4141  * want the style, the widget is realized, and realized
4142  * widgets are guaranteed to have a style already.
4143  *
4144  * Deprecated:3.0: Use #GtkStyleContext instead
4145  */
4146 void
4147 gtk_widget_ensure_style (GtkWidget *widget)
4148 {
4149   GtkStyle *style;
4150   g_return_if_fail (GTK_IS_WIDGET (widget));
4151
4152   style = _gtk_widget_get_style (widget);
4153   if (style == gtk_widget_get_default_style ())
4154     {
4155       g_object_unref (style);
4156       _gtk_widget_set_style (widget, NULL);
4157
4158       g_signal_emit_by_name (widget, "style-set", 0, NULL);
4159     }
4160 }
4161
4162 /**
4163  * gtk_widget_get_style:
4164  * @widget: a #GtkWidget
4165  *
4166  * Simply an accessor function that returns @widget->style.
4167  *
4168  * Return value: (transfer none): the widget's #GtkStyle
4169  *
4170  * Deprecated:3.0: Use #GtkStyleContext instead
4171  */
4172 GtkStyle*
4173 gtk_widget_get_style (GtkWidget *widget)
4174 {
4175   GtkStyle *style;
4176   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4177
4178   style = _gtk_widget_get_style (widget);
4179
4180   if (style == NULL)
4181     {
4182       style = g_object_new (GTK_TYPE_STYLE,
4183                             "context", gtk_widget_get_style_context (widget),
4184                             NULL);
4185       _gtk_widget_set_style (widget, style);
4186     }
4187
4188   return style;
4189 }
4190
4191 /**
4192  * gtk_widget_modify_style:
4193  * @widget: a #GtkWidget
4194  * @style: the #GtkRcStyle holding the style modifications
4195  *
4196  * Modifies style values on the widget.
4197  *
4198  * Modifications made using this technique take precedence over
4199  * style values set via an RC file, however, they will be overridden
4200  * if a style is explicitely set on the widget using gtk_widget_set_style().
4201  * The #GtkRcStyle structure is designed so each field can either be
4202  * set or unset, so it is possible, using this function, to modify some
4203  * style values and leave the others unchanged.
4204  *
4205  * Note that modifications made with this function are not cumulative
4206  * with previous calls to gtk_widget_modify_style() or with such
4207  * functions as gtk_widget_modify_fg(). If you wish to retain
4208  * previous values, you must first call gtk_widget_get_modifier_style(),
4209  * make your modifications to the returned style, then call
4210  * gtk_widget_modify_style() with that style. On the other hand,
4211  * if you first call gtk_widget_modify_style(), subsequent calls
4212  * to such functions gtk_widget_modify_fg() will have a cumulative
4213  * effect with the initial modifications.
4214  *
4215  * Deprecated:3.0: Use #GtkStyleContext with a custom #GtkStyleProvider instead
4216  */
4217 void
4218 gtk_widget_modify_style (GtkWidget      *widget,
4219                          GtkRcStyle     *style)
4220 {
4221   g_return_if_fail (GTK_IS_WIDGET (widget));
4222   g_return_if_fail (GTK_IS_RC_STYLE (style));
4223
4224   g_object_set_data_full (G_OBJECT (widget),
4225                           "gtk-rc-style",
4226                            gtk_rc_style_copy (style),
4227                            (GDestroyNotify) g_object_unref);
4228 }
4229
4230 /**
4231  * gtk_widget_get_modifier_style:
4232  * @widget: a #GtkWidget
4233  *
4234  * Returns the current modifier style for the widget. (As set by
4235  * gtk_widget_modify_style().) If no style has previously set, a new
4236  * #GtkRcStyle will be created with all values unset, and set as the
4237  * modifier style for the widget. If you make changes to this rc
4238  * style, you must call gtk_widget_modify_style(), passing in the
4239  * returned rc style, to make sure that your changes take effect.
4240  *
4241  * Caution: passing the style back to gtk_widget_modify_style() will
4242  * normally end up destroying it, because gtk_widget_modify_style() copies
4243  * the passed-in style and sets the copy as the new modifier style,
4244  * thus dropping any reference to the old modifier style. Add a reference
4245  * to the modifier style if you want to keep it alive.
4246  *
4247  * Return value: (transfer none): the modifier style for the widget.
4248  *     This rc style is owned by the widget. If you want to keep a
4249  *     pointer to value this around, you must add a refcount using
4250  *     g_object_ref().
4251  *
4252  * Deprecated:3.0: Use #GtkStyleContext with a custom #GtkStyleProvider instead
4253  */
4254 GtkRcStyle *
4255 gtk_widget_get_modifier_style (GtkWidget *widget)
4256 {
4257   GtkRcStyle *rc_style;
4258
4259   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4260
4261   rc_style = g_object_get_data (G_OBJECT (widget), "gtk-rc-style");
4262
4263   if (!rc_style)
4264     {
4265       rc_style = gtk_rc_style_new ();
4266       g_object_set_data_full (G_OBJECT (widget),
4267                               "gtk-rc-style",
4268                               rc_style,
4269                               (GDestroyNotify) g_object_unref);
4270     }
4271
4272   return rc_style;
4273 }
4274
4275 static void
4276 gtk_widget_modify_color_component (GtkWidget      *widget,
4277                                    GtkRcFlags      component,
4278                                    GtkStateType    state,
4279                                    const GdkColor *color)
4280 {
4281   GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);
4282
4283   if (color)
4284     {
4285       switch (component)
4286         {
4287         case GTK_RC_FG:
4288           rc_style->fg[state] = *color;
4289           break;
4290         case GTK_RC_BG:
4291           rc_style->bg[state] = *color;
4292           break;
4293         case GTK_RC_TEXT:
4294           rc_style->text[state] = *color;
4295           break;
4296         case GTK_RC_BASE:
4297           rc_style->base[state] = *color;
4298           break;
4299         default:
4300           g_assert_not_reached();
4301         }
4302
4303       rc_style->color_flags[state] |= component;
4304     }
4305   else
4306     rc_style->color_flags[state] &= ~component;
4307
4308   gtk_widget_modify_style (widget, rc_style);
4309 }
4310
4311 /**
4312  * gtk_widget_modify_fg:
4313  * @widget: a #GtkWidget
4314  * @state: the state for which to set the foreground color
4315  * @color: (allow-none): the color to assign (does not need to be allocated),
4316  *     or %NULL to undo the effect of previous calls to
4317  *     of gtk_widget_modify_fg().
4318  *
4319  * Sets the foreground color for a widget in a particular state.
4320  *
4321  * All other style values are left untouched.
4322  * See also gtk_widget_modify_style().
4323  *
4324  * Deprecated:3.0: Use gtk_widget_override_color() instead
4325  */
4326 void
4327 gtk_widget_modify_fg (GtkWidget      *widget,
4328                       GtkStateType    state,
4329                       const GdkColor *color)
4330 {
4331   GtkStateFlags flags;
4332   GdkRGBA rgba;
4333
4334   g_return_if_fail (GTK_IS_WIDGET (widget));
4335   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4336
4337   switch (state)
4338     {
4339     case GTK_STATE_ACTIVE:
4340       flags = GTK_STATE_FLAG_ACTIVE;
4341       break;
4342     case GTK_STATE_PRELIGHT:
4343       flags = GTK_STATE_FLAG_PRELIGHT;
4344       break;
4345     case GTK_STATE_SELECTED:
4346       flags = GTK_STATE_FLAG_SELECTED;
4347       break;
4348     case GTK_STATE_INSENSITIVE:
4349       flags = GTK_STATE_FLAG_INSENSITIVE;
4350       break;
4351     case GTK_STATE_NORMAL:
4352     default:
4353       flags = 0;
4354     }
4355
4356   if (color)
4357     {
4358       rgba.red = color->red / 65535.;
4359       rgba.green = color->green / 65535.;
4360       rgba.blue = color->blue / 65535.;
4361       rgba.alpha = 1;
4362
4363       gtk_widget_override_color (widget, flags, &rgba);
4364     }
4365   else
4366     gtk_widget_override_color (widget, flags, NULL);
4367 }
4368
4369 /**
4370  * gtk_widget_modify_bg:
4371  * @widget: a #GtkWidget
4372  * @state: the state for which to set the background color
4373  * @color: (allow-none): the color to assign (does not need
4374  *     to be allocated), or %NULL to undo the effect of previous
4375  *     calls to of gtk_widget_modify_bg().
4376  *
4377  * Sets the background color for a widget in a particular state.
4378  *
4379  * All other style values are left untouched.
4380  * See also gtk_widget_modify_style().
4381  *
4382  * <note><para>
4383  * Note that "no window" widgets (which have the %GTK_NO_WINDOW
4384  * flag set) draw on their parent container's window and thus may
4385  * not draw any background themselves. This is the case for e.g.
4386  * #GtkLabel.
4387  * </para><para>
4388  * To modify the background of such widgets, you have to set the
4389  * background color on their parent; if you want to set the background
4390  * of a rectangular area around a label, try placing the label in
4391  * a #GtkEventBox widget and setting the background color on that.
4392  * </para></note>
4393  *
4394  * Deprecated:3.0: Use gtk_widget_override_background_color() instead
4395  */
4396 void
4397 gtk_widget_modify_bg (GtkWidget      *widget,
4398                       GtkStateType    state,
4399                       const GdkColor *color)
4400 {
4401   GtkStateFlags flags;
4402   GdkRGBA rgba;
4403
4404   g_return_if_fail (GTK_IS_WIDGET (widget));
4405   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4406
4407   switch (state)
4408     {
4409     case GTK_STATE_ACTIVE:
4410       flags = GTK_STATE_FLAG_ACTIVE;
4411       break;
4412     case GTK_STATE_PRELIGHT:
4413       flags = GTK_STATE_FLAG_PRELIGHT;
4414       break;
4415     case GTK_STATE_SELECTED:
4416       flags = GTK_STATE_FLAG_SELECTED;
4417       break;
4418     case GTK_STATE_INSENSITIVE:
4419       flags = GTK_STATE_FLAG_INSENSITIVE;
4420       break;
4421     case GTK_STATE_NORMAL:
4422     default:
4423       flags = 0;
4424     }
4425
4426   if (color)
4427     {
4428       rgba.red = color->red / 65535.;
4429       rgba.green = color->green / 65535.;
4430       rgba.blue = color->blue / 65535.;
4431       rgba.alpha = 1;
4432
4433       gtk_widget_override_background_color (widget, flags, &rgba);
4434     }
4435   else
4436     gtk_widget_override_background_color (widget, flags, NULL);
4437 }
4438
4439 /**
4440  * gtk_widget_modify_text:
4441  * @widget: a #GtkWidget
4442  * @state: the state for which to set the text color
4443  * @color: (allow-none): the color to assign (does not need to
4444  *     be allocated), or %NULL to undo the effect of previous
4445  *     calls to of gtk_widget_modify_text().
4446  *
4447  * Sets the text color for a widget in a particular state.
4448  *
4449  * All other style values are left untouched.
4450  * The text color is the foreground color used along with the
4451  * base color (see gtk_widget_modify_base()) for widgets such
4452  * as #GtkEntry and #GtkTextView.
4453  * See also gtk_widget_modify_style().
4454  *
4455  * Deprecated:3.0: Use gtk_widget_override_color() instead
4456  */
4457 void
4458 gtk_widget_modify_text (GtkWidget      *widget,
4459                         GtkStateType    state,
4460                         const GdkColor *color)
4461 {
4462   g_return_if_fail (GTK_IS_WIDGET (widget));
4463   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4464
4465   gtk_widget_modify_color_component (widget, GTK_RC_TEXT, state, color);
4466 }
4467
4468 /**
4469  * gtk_widget_modify_base:
4470  * @widget: a #GtkWidget
4471  * @state: the state for which to set the base color
4472  * @color: (allow-none): the color to assign (does not need to
4473  *     be allocated), or %NULL to undo the effect of previous
4474  *     calls to of gtk_widget_modify_base().
4475  *
4476  * Sets the base color for a widget in a particular state.
4477  * All other style values are left untouched. The base color
4478  * is the background color used along with the text color
4479  * (see gtk_widget_modify_text()) for widgets such as #GtkEntry
4480  * and #GtkTextView. See also gtk_widget_modify_style().
4481  *
4482  * <note><para>
4483  * Note that "no window" widgets (which have the %GTK_NO_WINDOW
4484  * flag set) draw on their parent container's window and thus may
4485  * not draw any background themselves. This is the case for e.g.
4486  * #GtkLabel.
4487  * </para><para>
4488  * To modify the background of such widgets, you have to set the
4489  * base color on their parent; if you want to set the background
4490  * of a rectangular area around a label, try placing the label in
4491  * a #GtkEventBox widget and setting the base color on that.
4492  * </para></note>
4493  *
4494  * Deprecated:3.0: Use gtk_widget_override_background_color() instead
4495  */
4496 void
4497 gtk_widget_modify_base (GtkWidget      *widget,
4498                         GtkStateType    state,
4499                         const GdkColor *color)
4500 {
4501   g_return_if_fail (GTK_IS_WIDGET (widget));
4502   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4503
4504   gtk_widget_modify_color_component (widget, GTK_RC_BASE, state, color);
4505 }
4506
4507 /**
4508  * gtk_widget_modify_cursor:
4509  * @widget: a #GtkWidget
4510  * @primary: the color to use for primary cursor (does not need to be
4511  *     allocated), or %NULL to undo the effect of previous calls to
4512  *     of gtk_widget_modify_cursor().
4513  * @secondary: the color to use for secondary cursor (does not need to be
4514  *     allocated), or %NULL to undo the effect of previous calls to
4515  *     of gtk_widget_modify_cursor().
4516  *
4517  * Sets the cursor color to use in a widget, overriding the
4518  * #GtkWidget:cursor-color and #GtkWidget:secondary-cursor-color
4519  * style properties.
4520  *
4521  * All other style values are left untouched.
4522  * See also gtk_widget_modify_style().
4523  *
4524  * Since: 2.12
4525  *
4526  * Deprecated: 3.0. Use gtk_widget_override_cursor() instead.
4527  */
4528 void
4529 gtk_widget_modify_cursor (GtkWidget      *widget,
4530                           const GdkColor *primary,
4531                           const GdkColor *secondary)
4532 {
4533   GdkRGBA primary_rgba, secondary_rgba;
4534
4535   g_return_if_fail (GTK_IS_WIDGET (widget));
4536
4537   primary_rgba.red = primary->red / 65535.;
4538   primary_rgba.green = primary->green / 65535.;
4539   primary_rgba.blue = primary->blue / 65535.;
4540   primary_rgba.alpha = 1;
4541
4542   secondary_rgba.red = secondary->red / 65535.;
4543   secondary_rgba.green = secondary->green / 65535.;
4544   secondary_rgba.blue = secondary->blue / 65535.;
4545   secondary_rgba.alpha = 1;
4546
4547   gtk_widget_override_cursor (widget, &primary_rgba, &secondary_rgba);
4548 }
4549
4550 /**
4551  * gtk_widget_modify_font:
4552  * @widget: a #GtkWidget
4553  * @font_desc: (allow-none): the font description to use, or %NULL
4554  *     to undo the effect of previous calls to gtk_widget_modify_font()
4555  *
4556  * Sets the font to use for a widget.
4557  *
4558  * All other style values are left untouched.
4559  * See also gtk_widget_modify_style().
4560  *
4561  * Deprecated:3.0: Use gtk_widget_override_font() instead
4562  */
4563 void
4564 gtk_widget_modify_font (GtkWidget            *widget,
4565                         PangoFontDescription *font_desc)
4566 {
4567   g_return_if_fail (GTK_IS_WIDGET (widget));
4568
4569   gtk_widget_override_font (widget, font_desc);
4570 }
4571
4572 /**
4573  * gtk_widget_reset_rc_styles:
4574  * @widget: a #GtkWidget.
4575  *
4576  * Reset the styles of @widget and all descendents, so when
4577  * they are looked up again, they get the correct values
4578  * for the currently loaded RC file settings.
4579  *
4580  * This function is not useful for applications.
4581  *
4582  * Deprecated:3.0: Use #GtkStyleContext instead, and gtk_widget_reset_style()
4583  */
4584 void
4585 gtk_widget_reset_rc_styles (GtkWidget *widget)
4586 {
4587   g_return_if_fail (GTK_IS_WIDGET (widget));
4588
4589   gtk_widget_reset_style (widget);
4590 }
4591
4592 /**
4593  * gtk_widget_path:
4594  * @widget: a #GtkWidget
4595  * @path_length: (out) (allow-none): location to store length of the path,
4596  *     or %NULL
4597  * @path: (out) (allow-none): location to store allocated path string,
4598  *     or %NULL
4599  * @path_reversed: (out) (allow-none): location to store allocated reverse
4600  *     path string, or %NULL
4601  *
4602  * Obtains the full path to @widget. The path is simply the name of a
4603  * widget and all its parents in the container hierarchy, separated by
4604  * periods. The name of a widget comes from
4605  * gtk_widget_get_name(). Paths are used to apply styles to a widget
4606  * in gtkrc configuration files. Widget names are the type of the
4607  * widget by default (e.g. "GtkButton") or can be set to an
4608  * application-specific value with gtk_widget_set_name(). By setting
4609  * the name of a widget, you allow users or theme authors to apply
4610  * styles to that specific widget in their gtkrc
4611  * file. @path_reversed_p fills in the path in reverse order,
4612  * i.e. starting with @widget's name instead of starting with the name
4613  * of @widget's outermost ancestor.
4614  *
4615  * Deprecated:3.0: Use gtk_widget_get_path() instead
4616  **/
4617 void
4618 gtk_widget_path (GtkWidget *widget,
4619                  guint     *path_length,
4620                  gchar    **path,
4621                  gchar    **path_reversed)
4622 {
4623   static gchar *rev_path = NULL;
4624   static guint tmp_path_len = 0;
4625   guint len;
4626
4627 #define INIT_PATH_SIZE (512)
4628
4629   g_return_if_fail (GTK_IS_WIDGET (widget));
4630
4631   len = 0;
4632   do
4633     {
4634       const gchar *string;
4635       const gchar *s;
4636       gchar *d;
4637       guint l;
4638
4639       string = gtk_widget_get_name (widget);
4640       l = strlen (string);
4641       while (tmp_path_len <= len + l + 1)
4642         {
4643           tmp_path_len += INIT_PATH_SIZE;
4644           rev_path = g_realloc (rev_path, tmp_path_len);
4645         }
4646       s = string + l - 1;
4647       d = rev_path + len;
4648       while (s >= string)
4649         *(d++) = *(s--);
4650       len += l;
4651
4652       widget = gtk_widget_get_parent (widget);
4653
4654       if (widget)
4655         rev_path[len++] = '.';
4656       else
4657         rev_path[len++] = 0;
4658     }
4659   while (widget);
4660
4661   if (path_length)
4662     *path_length = len - 1;
4663   if (path_reversed)
4664     *path_reversed = g_strdup (rev_path);
4665   if (path)
4666     {
4667       *path = g_strdup (rev_path);
4668       g_strreverse (*path);
4669     }
4670 }
4671
4672 /**
4673  * gtk_widget_class_path:
4674  * @widget: a #GtkWidget
4675  * @path_length: (out) (allow-none): location to store the length of the
4676  *     class path, or %NULL
4677  * @path: (out) (allow-none): location to store the class path as an
4678  *     allocated string, or %NULL
4679  * @path_reversed: (out) (allow-none): location to store the reverse
4680  *     class path as an allocated string, or %NULL
4681  *
4682  * Same as gtk_widget_path(), but always uses the name of a widget's type,
4683  * never uses a custom name set with gtk_widget_set_name().
4684  *
4685  * Deprecated:3.0: Use gtk_widget_get_path() instead
4686  **/
4687 void
4688 gtk_widget_class_path (GtkWidget *widget,
4689                        guint     *path_length,
4690                        gchar    **path,
4691                        gchar    **path_reversed)
4692 {
4693   static gchar *rev_path = NULL;
4694   static guint tmp_path_len = 0;
4695   guint len;
4696
4697   g_return_if_fail (GTK_IS_WIDGET (widget));
4698
4699   len = 0;
4700   do
4701     {
4702       const gchar *string;
4703       const gchar *s;
4704       gchar *d;
4705       guint l;
4706
4707       string = g_type_name (G_OBJECT_TYPE (widget));
4708       l = strlen (string);
4709       while (tmp_path_len <= len + l + 1)
4710         {
4711           tmp_path_len += INIT_PATH_SIZE;
4712           rev_path = g_realloc (rev_path, tmp_path_len);
4713         }
4714       s = string + l - 1;
4715       d = rev_path + len;
4716       while (s >= string)
4717         *(d++) = *(s--);
4718       len += l;
4719
4720       widget = gtk_widget_get_parent (widget);
4721
4722       if (widget)
4723         rev_path[len++] = '.';
4724       else
4725         rev_path[len++] = 0;
4726     }
4727   while (widget);
4728
4729   if (path_length)
4730     *path_length = len - 1;
4731   if (path_reversed)
4732     *path_reversed = g_strdup (rev_path);
4733   if (path)
4734     {
4735       *path = g_strdup (rev_path);
4736       g_strreverse (*path);
4737     }
4738 }
4739
4740 /**
4741  * gtk_widget_render_icon:
4742  * @widget: a #GtkWidget
4743  * @stock_id: a stock ID
4744  * @size: (type int): a stock size. A size of (GtkIconSize)-1 means
4745  *     render at the size of the source and don't scale (if there are
4746  *     multiple source sizes, GTK+ picks one of the available sizes).
4747  * @detail: (allow-none): render detail to pass to theme engine
4748  *
4749  * A convenience function that uses the theme settings for @widget
4750  * to look up @stock_id and render it to a pixbuf. @stock_id should
4751  * be a stock icon ID such as #GTK_STOCK_OPEN or #GTK_STOCK_OK. @size
4752  * should be a size such as #GTK_ICON_SIZE_MENU. @detail should be a
4753  * string that identifies the widget or code doing the rendering, so
4754  * that theme engines can special-case rendering for that widget or
4755  * code.
4756  *
4757  * The pixels in the returned #GdkPixbuf are shared with the rest of
4758  * the application and should not be modified. The pixbuf should be
4759  * freed after use with g_object_unref().
4760  *
4761  * Return value: (transfer full): a new pixbuf, or %NULL if the
4762  *     stock ID wasn't known
4763  *
4764  * Deprecated: 3.0: Use gtk_widget_render_icon_pixbuf() instead.
4765  **/
4766 GdkPixbuf*
4767 gtk_widget_render_icon (GtkWidget      *widget,
4768                         const gchar    *stock_id,
4769                         GtkIconSize     size,
4770                         const gchar    *detail)
4771 {
4772   gtk_widget_ensure_style (widget);
4773
4774   return gtk_widget_render_icon_pixbuf (widget, stock_id, size);
4775 }