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