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