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