]> Pileus Git - ~andy/gtk/blob - gtk/gtkstyle.c
added rc-style argument GtkSpinButton::shadow_type. removed
[~andy/gtk] / gtk / gtkstyle.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <math.h>
28 #include <string.h>
29 #include "gtkgc.h"
30 #include "gtkrc.h"
31 #include "gtkstyle.h"
32 #include "gtkwidget.h"
33 #include "gtkthemes.h"
34 #include "gtkiconfactory.h"
35
36 #define LIGHTNESS_MULT  1.3
37 #define DARKNESS_MULT   0.7
38
39
40 /* --- typedefs & structures --- */
41 typedef struct {
42   GType       widget_type;
43   GParamSpec *pspec;
44   GValue      value;
45 } PropertyValue;
46
47
48 /* --- prototypes --- */
49 static void      gtk_style_init                 (GtkStyle       *style);
50 static void      gtk_style_class_init           (GtkStyleClass  *klass);
51 static void      gtk_style_finalize             (GObject        *object);
52 static void      gtk_style_realize              (GtkStyle       *style,
53                                                  GdkColormap    *colormap);
54 static void      gtk_style_real_realize        (GtkStyle        *style);
55 static void      gtk_style_real_unrealize      (GtkStyle        *style);
56 static void      gtk_style_real_copy           (GtkStyle        *style,
57                                                 GtkStyle        *src);
58 static void      gtk_style_real_set_background (GtkStyle        *style,
59                                                 GdkWindow       *window,
60                                                 GtkStateType     state_type);
61 static GtkStyle *gtk_style_real_clone          (GtkStyle        *style);
62 static void      gtk_style_real_init_from_rc   (GtkStyle        *style,
63                                                 GtkRcStyle      *rc_style);
64 static GdkPixbuf *gtk_default_render_icon      (GtkStyle            *style,
65                                                 const GtkIconSource *source,
66                                                 GtkTextDirection     direction,
67                                                 GtkStateType         state,
68                                                 GtkIconSize          size,
69                                                 GtkWidget           *widget,
70                                                 const gchar         *detail);
71 static void gtk_default_draw_hline      (GtkStyle        *style,
72                                          GdkWindow       *window,
73                                          GtkStateType     state_type,
74                                          GdkRectangle    *area,
75                                          GtkWidget       *widget,
76                                          const gchar     *detail,
77                                          gint             x1,
78                                          gint             x2,
79                                          gint             y);
80 static void gtk_default_draw_vline      (GtkStyle        *style,
81                                          GdkWindow       *window,
82                                          GtkStateType     state_type,
83                                          GdkRectangle    *area,
84                                          GtkWidget       *widget,
85                                          const gchar     *detail,
86                                          gint             y1,
87                                          gint             y2,
88                                          gint             x);
89 static void gtk_default_draw_shadow     (GtkStyle        *style,
90                                          GdkWindow       *window,
91                                          GtkStateType     state_type,
92                                          GtkShadowType    shadow_type,
93                                          GdkRectangle    *area,
94                                          GtkWidget       *widget,
95                                          const gchar     *detail,
96                                          gint             x,
97                                          gint             y,
98                                          gint             width,
99                                          gint             height);
100 static void gtk_default_draw_polygon    (GtkStyle        *style,
101                                          GdkWindow       *window,
102                                          GtkStateType     state_type,
103                                          GtkShadowType    shadow_type,
104                                          GdkRectangle    *area,
105                                          GtkWidget       *widget,
106                                          const gchar     *detail,
107                                          GdkPoint        *points,
108                                          gint             npoints,
109                                          gboolean         fill);
110 static void gtk_default_draw_arrow      (GtkStyle        *style,
111                                          GdkWindow       *window,
112                                          GtkStateType     state_type,
113                                          GtkShadowType    shadow_type,
114                                          GdkRectangle    *area,
115                                          GtkWidget       *widget,
116                                          const gchar     *detail,
117                                          GtkArrowType     arrow_type,
118                                          gboolean         fill,
119                                          gint             x,
120                                          gint             y,
121                                          gint             width,
122                                          gint             height);
123 static void gtk_default_draw_diamond    (GtkStyle        *style,
124                                          GdkWindow       *window,
125                                          GtkStateType     state_type,
126                                          GtkShadowType    shadow_type,
127                                          GdkRectangle    *area,
128                                          GtkWidget       *widget,
129                                          const gchar     *detail,
130                                          gint             x,
131                                          gint             y,
132                                          gint             width,
133                                          gint             height);
134 static void gtk_default_draw_string     (GtkStyle        *style,
135                                          GdkWindow       *window,
136                                          GtkStateType     state_type,
137                                          GdkRectangle    *area,
138                                          GtkWidget       *widget,
139                                          const gchar     *detail,
140                                          gint             x,
141                                          gint             y,
142                                          const gchar     *string);
143 static void gtk_default_draw_box        (GtkStyle        *style,
144                                          GdkWindow       *window,
145                                          GtkStateType     state_type,
146                                          GtkShadowType    shadow_type,
147                                          GdkRectangle    *area,
148                                          GtkWidget       *widget,
149                                          const gchar     *detail,
150                                          gint             x,
151                                          gint             y,
152                                          gint             width,
153                                          gint             height);
154 static void gtk_default_draw_flat_box   (GtkStyle        *style,
155                                          GdkWindow       *window,
156                                          GtkStateType     state_type,
157                                          GtkShadowType    shadow_type,
158                                          GdkRectangle    *area,
159                                          GtkWidget       *widget,
160                                          const gchar     *detail,
161                                          gint             x,
162                                          gint             y,
163                                          gint             width,
164                                          gint             height);
165 static void gtk_default_draw_check      (GtkStyle        *style,
166                                          GdkWindow       *window,
167                                          GtkStateType     state_type,
168                                          GtkShadowType    shadow_type,
169                                          GdkRectangle    *area,
170                                          GtkWidget       *widget,
171                                          const gchar     *detail,
172                                          gint             x,
173                                          gint             y,
174                                          gint             width,
175                                          gint             height);
176 static void gtk_default_draw_option     (GtkStyle        *style,
177                                          GdkWindow       *window,
178                                          GtkStateType     state_type,
179                                          GtkShadowType    shadow_type,
180                                          GdkRectangle    *area,
181                                          GtkWidget       *widget,
182                                          const gchar     *detail,
183                                          gint             x,
184                                          gint             y,
185                                          gint             width,
186                                          gint             height);
187 static void gtk_default_draw_tab        (GtkStyle        *style,
188                                          GdkWindow       *window,
189                                          GtkStateType     state_type,
190                                          GtkShadowType    shadow_type,
191                                          GdkRectangle    *area,
192                                          GtkWidget       *widget,
193                                          const gchar     *detail,
194                                          gint             x,
195                                          gint             y,
196                                          gint             width,
197                                          gint             height);
198 static void gtk_default_draw_shadow_gap (GtkStyle        *style,
199                                          GdkWindow       *window,
200                                          GtkStateType     state_type,
201                                          GtkShadowType    shadow_type,
202                                          GdkRectangle    *area,
203                                          GtkWidget       *widget,
204                                          const gchar     *detail,
205                                          gint             x,
206                                          gint             y,
207                                          gint             width,
208                                          gint             height,
209                                          GtkPositionType  gap_side,
210                                          gint             gap_x,
211                                          gint             gap_width);
212 static void gtk_default_draw_box_gap    (GtkStyle        *style,
213                                          GdkWindow       *window,
214                                          GtkStateType     state_type,
215                                          GtkShadowType    shadow_type,
216                                          GdkRectangle    *area,
217                                          GtkWidget       *widget,
218                                          const gchar     *detail,
219                                          gint             x,
220                                          gint             y,
221                                          gint             width,
222                                          gint             height,
223                                          GtkPositionType  gap_side,
224                                          gint             gap_x,
225                                          gint             gap_width);
226 static void gtk_default_draw_extension  (GtkStyle        *style,
227                                          GdkWindow       *window,
228                                          GtkStateType     state_type,
229                                          GtkShadowType    shadow_type,
230                                          GdkRectangle    *area,
231                                          GtkWidget       *widget,
232                                          const gchar     *detail,
233                                          gint             x,
234                                          gint             y,
235                                          gint             width,
236                                          gint             height,
237                                          GtkPositionType  gap_side);
238 static void gtk_default_draw_focus      (GtkStyle        *style,
239                                          GdkWindow       *window,
240                                          GdkRectangle    *area,
241                                          GtkWidget       *widget,
242                                          const gchar     *detail,
243                                          gint             x,
244                                          gint             y,
245                                          gint             width,
246                                          gint             height);
247 static void gtk_default_draw_slider     (GtkStyle        *style,
248                                          GdkWindow       *window,
249                                          GtkStateType     state_type,
250                                          GtkShadowType    shadow_type,
251                                          GdkRectangle    *area,
252                                          GtkWidget       *widget,
253                                          const gchar     *detail,
254                                          gint             x,
255                                          gint             y,
256                                          gint             width,
257                                          gint             height,
258                                          GtkOrientation   orientation);
259 static void gtk_default_draw_handle     (GtkStyle        *style,
260                                          GdkWindow       *window,
261                                          GtkStateType     state_type,
262                                          GtkShadowType    shadow_type,
263                                          GdkRectangle    *area,
264                                          GtkWidget       *widget,
265                                          const gchar     *detail,
266                                          gint             x,
267                                          gint             y,
268                                          gint             width,
269                                          gint             height,
270                                          GtkOrientation   orientation);
271 static void gtk_default_draw_expander   (GtkStyle        *style,
272                                          GdkWindow       *window,
273                                          GtkStateType     state_type,
274                                          GdkRectangle    *area,
275                                          GtkWidget       *widget,
276                                          const gchar     *detail,
277                                          gint             x,
278                                          gint             y,
279                                          gboolean         is_open);
280 static void gtk_default_draw_layout     (GtkStyle        *style,
281                                          GdkWindow       *window,
282                                          GtkStateType     state_type,
283                                          GdkRectangle    *area,
284                                          GtkWidget       *widget,
285                                          const gchar     *detail,
286                                          gint             x,
287                                          gint             y,
288                                          PangoLayout     *layout);
289 static void gtk_style_shade             (GdkColor        *a,
290                                          GdkColor        *b,
291                                          gdouble          k);
292 static void rgb_to_hls                  (gdouble         *r,
293                                          gdouble         *g,
294                                          gdouble         *b);
295 static void hls_to_rgb                  (gdouble         *h,
296                                          gdouble         *l,
297                                          gdouble         *s);
298
299
300 /* --- variables --- */
301 static GdkColor gtk_default_normal_fg =      { 0,      0,      0,      0 };
302 static GdkColor gtk_default_active_fg =      { 0,      0,      0,      0 };
303 static GdkColor gtk_default_prelight_fg =    { 0,      0,      0,      0 };
304 static GdkColor gtk_default_selected_fg =    { 0, 0xffff, 0xffff, 0xffff };
305 static GdkColor gtk_default_insensitive_fg = { 0, 0x7530, 0x7530, 0x7530 };
306
307 static GdkColor gtk_default_normal_bg =      { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
308 static GdkColor gtk_default_active_bg =      { 0, 0xc350, 0xc350, 0xc350 };
309 static GdkColor gtk_default_prelight_bg =    { 0, 0xea60, 0xea60, 0xea60 };
310 static GdkColor gtk_default_selected_bg =    { 0,      0,      0, 0x9c40 };
311 static GdkColor gtk_default_insensitive_bg = { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
312
313 static gpointer parent_class = NULL;
314 static GdkFont *static_default_font = NULL;
315
316
317 /* --- functions --- */
318 GType
319 gtk_style_get_type (void)
320 {
321   static GType style_type = 0;
322   
323   if (!style_type)
324     {
325       static const GTypeInfo style_info =
326       {
327         sizeof (GtkStyleClass),
328         (GBaseInitFunc) NULL,
329         (GBaseFinalizeFunc) NULL,
330         (GClassInitFunc) gtk_style_class_init,
331         NULL,           /* class_finalize */
332         NULL,           /* class_data */
333         sizeof (GtkStyle),
334         0,              /* n_preallocs */
335         (GInstanceInitFunc) gtk_style_init,
336       };
337       
338       style_type = g_type_register_static (G_TYPE_OBJECT,
339                                            "GtkStyle",
340                                            &style_info, 0);
341     }
342   
343   return style_type;
344 }
345
346 static void
347 gtk_style_init (GtkStyle *style)
348 {
349   gint i;
350   
351   style->font_desc = pango_font_description_from_string ("Sans 10");
352
353   if (!static_default_font)
354     {
355       static_default_font = gdk_font_from_description (style->font_desc);
356
357       if (!static_default_font) 
358         static_default_font = gdk_font_load ("fixed");
359
360       if (!static_default_font) 
361         g_error ("Unable to load \"fixed\" font");
362     }
363   
364   style->font = static_default_font;
365   gdk_font_ref (style->font);
366
367   style->attach_count = 0;
368   style->colormap = NULL;
369   style->depth = -1;
370   
371   style->black.red = 0;
372   style->black.green = 0;
373   style->black.blue = 0;
374   
375   style->white.red = 65535;
376   style->white.green = 65535;
377   style->white.blue = 65535;
378   
379   style->black_gc = NULL;
380   style->white_gc = NULL;
381   
382   style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
383   style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
384   style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
385   style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
386   style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
387   
388   style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
389   style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
390   style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
391   style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
392   style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
393   
394   for (i = 0; i < 4; i++)
395     {
396       style->text[i] = style->fg[i];
397       style->base[i] = style->white;
398     }
399   
400   style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
401   style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
402   
403   for (i = 0; i < 5; i++)
404     style->bg_pixmap[i] = NULL;
405   
406   style->rc_style = NULL;
407   
408   for (i = 0; i < 5; i++)
409     {
410       style->fg_gc[i] = NULL;
411       style->bg_gc[i] = NULL;
412       style->light_gc[i] = NULL;
413       style->dark_gc[i] = NULL;
414       style->mid_gc[i] = NULL;
415       style->text_gc[i] = NULL;
416       style->base_gc[i] = NULL;
417     }
418
419   style->xthickness = 2;
420   style->ythickness = 2;
421
422   style->property_cache = NULL;
423 }
424
425 static void
426 gtk_style_class_init (GtkStyleClass *klass)
427 {
428   GObjectClass *object_class = G_OBJECT_CLASS (klass);
429   
430   parent_class = g_type_class_peek_parent (klass);
431
432   object_class->finalize = gtk_style_finalize;
433
434   klass->clone = gtk_style_real_clone;
435   klass->copy = gtk_style_real_copy;
436   klass->init_from_rc = gtk_style_real_init_from_rc;
437   klass->realize = gtk_style_real_realize;
438   klass->unrealize = gtk_style_real_unrealize;
439   klass->set_background = gtk_style_real_set_background;
440   klass->render_icon = gtk_default_render_icon;
441
442   klass->draw_hline = gtk_default_draw_hline;
443   klass->draw_vline = gtk_default_draw_vline;
444   klass->draw_shadow = gtk_default_draw_shadow;
445   klass->draw_polygon = gtk_default_draw_polygon;
446   klass->draw_arrow = gtk_default_draw_arrow;
447   klass->draw_diamond = gtk_default_draw_diamond;
448   klass->draw_string = gtk_default_draw_string;
449   klass->draw_box = gtk_default_draw_box;
450   klass->draw_flat_box = gtk_default_draw_flat_box;
451   klass->draw_check = gtk_default_draw_check;
452   klass->draw_option = gtk_default_draw_option;
453   klass->draw_tab = gtk_default_draw_tab;
454   klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
455   klass->draw_box_gap = gtk_default_draw_box_gap;
456   klass->draw_extension = gtk_default_draw_extension;
457   klass->draw_focus = gtk_default_draw_focus;
458   klass->draw_slider = gtk_default_draw_slider;
459   klass->draw_handle = gtk_default_draw_handle;
460   klass->draw_expander = gtk_default_draw_expander;
461   klass->draw_layout = gtk_default_draw_layout;
462 }
463
464 static void
465 gtk_style_finalize (GObject *object)
466 {
467   GtkStyle *style = GTK_STYLE (object);
468
469   g_return_if_fail (style->attach_count == 0);
470
471   if (style->property_cache)
472     {
473       guint i;
474
475       for (i = 0; i < style->property_cache->n_nodes; i++)
476         {
477           PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
478
479           g_param_spec_unref (node->pspec);
480           g_value_unset (&node->value);
481         }
482       g_bsearch_array_destroy (style->property_cache);
483       style->property_cache = NULL;
484     }
485   
486   if (style->styles)
487     {
488       if (style->styles->data != style)
489         g_slist_remove (style->styles, style);
490       else
491         {
492           GSList *tmp_list = style->styles->next;
493           
494           while (tmp_list)
495             {
496               GTK_STYLE (tmp_list->data)->styles = style->styles->next;
497               tmp_list = tmp_list->next;
498             }
499           g_slist_free_1 (style->styles);
500         }
501     }
502   
503   gdk_font_unref (style->font);
504   pango_font_description_free (style->font_desc);
505   
506   if (style->rc_style)
507     gtk_rc_style_unref (style->rc_style);
508   
509   G_OBJECT_CLASS (parent_class)->finalize (object);
510 }
511
512
513 GtkStyle*
514 gtk_style_copy (GtkStyle *style)
515 {
516   GtkStyle *new_style;
517   
518   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
519   
520   new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
521   GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
522
523   return new_style;
524 }
525
526 static GtkStyle*
527 gtk_style_duplicate (GtkStyle *style)
528 {
529   GtkStyle *new_style;
530   
531   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
532   
533   new_style = gtk_style_copy (style);
534   
535   style->styles = g_slist_append (style->styles, new_style);
536   new_style->styles = style->styles;  
537   
538   return new_style;
539 }
540
541 GtkStyle*
542 gtk_style_new (void)
543 {
544   GtkStyle *style;
545   
546   style = g_object_new (GTK_TYPE_STYLE, NULL);
547   
548   return style;
549 }
550
551 /*************************************************************
552  * gtk_style_attach:
553  *     Attach a style to a window; this process allocates the
554  *     colors and creates the GC's for the style - it specializes
555  *     it to a particular visual and colormap. The process
556  *     may involve the creation of a new style if the style
557  *     has already been attached to a window with a different
558  *     style and colormap.
559  *   arguments:
560  *     style:
561  *     window: 
562  *   results:
563  *     Either the style parameter, or a newly created style.
564  *     If the style is newly created, the style parameter
565  *     will be dereferenced, and the new style will have
566  *     a reference count belonging to the caller.
567  *
568  * FIXME: The sequence - 
569  *    create a style => s1
570  *    attach s1 to v1, c1 => s1
571  *    attach s1 to v2, c2 => s2
572  *    detach s1 from v1, c1
573  *    attach s1 to v2, c2 => s3
574  * results in two separate, unlinked styles s2 and s3 which
575  * are identical and could be shared. To fix this, we would
576  * want to never remove a style from the list of linked
577  * styles as long as as it has a reference count. However, the 
578  * disadvantage of doing it this way means that we would need two 
579  * passes through the linked list when attaching (one to check for 
580  * matching styles, one to look for empty unattached styles - but 
581  * it will almost never be longer than 2 elements.
582  *************************************************************/
583
584 GtkStyle*
585 gtk_style_attach (GtkStyle  *style,
586                   GdkWindow *window)
587 {
588   GSList *styles;
589   GtkStyle *new_style = NULL;
590   GdkColormap *colormap;
591   
592   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
593   g_return_val_if_fail (window != NULL, NULL);
594   
595   colormap = gdk_window_get_colormap (window);
596   
597   if (!style->styles)
598     style->styles = g_slist_append (NULL, style);
599   
600   styles = style->styles;
601   while (styles)
602     {
603       new_style = styles->data;
604       
605       if (new_style->attach_count == 0)
606         {
607           gtk_style_realize (new_style, colormap);
608           break;
609         }
610       else if (new_style->colormap == colormap)
611         break;
612       
613       new_style = NULL;
614       styles = styles->next;
615     }
616   
617   if (!new_style)
618     {
619       new_style = gtk_style_duplicate (style);
620       gtk_style_realize (new_style, colormap);
621     }
622
623   /* A style gets a refcount from being attached */
624   if (new_style->attach_count == 0)
625     gtk_style_ref (new_style);
626
627   /* Another refcount belongs to the parent */
628   if (style != new_style) 
629     {
630       gtk_style_unref (style);
631       gtk_style_ref (new_style);
632     }
633   
634   new_style->attach_count++;
635   
636   return new_style;
637 }
638
639 void
640 gtk_style_detach (GtkStyle *style)
641 {
642   g_return_if_fail (GTK_IS_STYLE (style));
643   
644   style->attach_count -= 1;
645   if (style->attach_count == 0)
646     {
647       GTK_STYLE_GET_CLASS (style)->unrealize (style);
648       
649       gdk_colormap_unref (style->colormap);
650       style->colormap = NULL;
651       
652       gtk_style_unref (style);
653     }
654 }
655
656 GtkStyle*
657 gtk_style_ref (GtkStyle *style)
658 {
659   return (GtkStyle *) g_object_ref (G_OBJECT (style));
660 }
661
662 void
663 gtk_style_unref (GtkStyle *style)
664 {
665   g_object_unref (G_OBJECT (style));
666 }
667
668 static void
669 gtk_style_realize (GtkStyle    *style,
670                    GdkColormap *colormap)
671 {
672   g_return_if_fail (GTK_IS_STYLE (style));
673   g_return_if_fail (GDK_IS_COLORMAP (colormap));
674   
675   style->colormap = gdk_colormap_ref (colormap);
676   style->depth = gdk_colormap_get_visual (colormap)->depth;
677
678   GTK_STYLE_GET_CLASS (style)->realize (style);
679 }
680
681 GtkIconSet*
682 gtk_style_lookup_icon_set (GtkStyle   *style,
683                            const char *stock_id)
684 {
685   GSList *iter;
686
687   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
688   g_return_val_if_fail (stock_id != NULL, NULL);
689   
690   iter = style->icon_factories;
691   while (iter != NULL)
692     {
693       GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
694                                                       stock_id);
695       if (icon_set)
696         return icon_set;
697       
698       iter = g_slist_next (iter);
699     }
700
701   return gtk_icon_factory_lookup_default (stock_id);
702 }
703
704 void
705 gtk_draw_hline (GtkStyle     *style,
706                 GdkWindow    *window,
707                 GtkStateType  state_type,
708                 gint          x1,
709                 gint          x2,
710                 gint          y)
711 {
712   g_return_if_fail (GTK_IS_STYLE (style));
713   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
714   
715   GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
716 }
717
718
719 void
720 gtk_draw_vline (GtkStyle     *style,
721                 GdkWindow    *window,
722                 GtkStateType  state_type,
723                 gint          y1,
724                 gint          y2,
725                 gint          x)
726 {
727   g_return_if_fail (GTK_IS_STYLE (style));
728   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
729   
730   GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1, y2, x);
731 }
732
733
734 void
735 gtk_draw_shadow (GtkStyle      *style,
736                  GdkWindow     *window,
737                  GtkStateType   state_type,
738                  GtkShadowType  shadow_type,
739                  gint           x,
740                  gint           y,
741                  gint           width,
742                  gint           height)
743 {
744   g_return_if_fail (GTK_IS_STYLE (style));
745   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
746   
747   GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
748 }
749
750 void
751 gtk_draw_polygon (GtkStyle      *style,
752                   GdkWindow     *window,
753                   GtkStateType   state_type,
754                   GtkShadowType  shadow_type,
755                   GdkPoint      *points,
756                   gint           npoints,
757                   gboolean       fill)
758 {
759   g_return_if_fail (GTK_IS_STYLE (style));
760   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
761   
762   GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
763 }
764
765 void
766 gtk_draw_arrow (GtkStyle      *style,
767                 GdkWindow     *window,
768                 GtkStateType   state_type,
769                 GtkShadowType  shadow_type,
770                 GtkArrowType   arrow_type,
771                 gboolean       fill,
772                 gint           x,
773                 gint           y,
774                 gint           width,
775                 gint           height)
776 {
777   g_return_if_fail (GTK_IS_STYLE (style));
778   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
779   
780   GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
781 }
782
783
784 void
785 gtk_draw_diamond (GtkStyle      *style,
786                   GdkWindow     *window,
787                   GtkStateType   state_type,
788                   GtkShadowType  shadow_type,
789                   gint           x,
790                   gint           y,
791                   gint           width,
792                   gint           height)
793 {
794   g_return_if_fail (GTK_IS_STYLE (style));
795   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
796   
797   GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
798 }
799
800
801 void
802 gtk_draw_string (GtkStyle      *style,
803                  GdkWindow     *window,
804                  GtkStateType   state_type,
805                  gint           x,
806                  gint           y,
807                  const gchar   *string)
808 {
809   g_return_if_fail (GTK_IS_STYLE (style));
810   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
811   
812   GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
813 }
814
815 void
816 gtk_draw_box (GtkStyle      *style,
817               GdkWindow     *window,
818               GtkStateType   state_type,
819               GtkShadowType  shadow_type,
820               gint           x,
821               gint           y,
822               gint           width,
823               gint           height)
824 {
825   g_return_if_fail (GTK_IS_STYLE (style));
826   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
827   
828   GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
829 }
830
831 void
832 gtk_draw_flat_box (GtkStyle      *style,
833                    GdkWindow     *window,
834                    GtkStateType   state_type,
835                    GtkShadowType  shadow_type,
836                    gint           x,
837                    gint           y,
838                    gint           width,
839                    gint           height)
840 {
841   g_return_if_fail (GTK_IS_STYLE (style));
842   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
843   
844   GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
845 }
846
847 void
848 gtk_draw_check (GtkStyle      *style,
849                 GdkWindow     *window,
850                 GtkStateType   state_type,
851                 GtkShadowType  shadow_type,
852                 gint           x,
853                 gint           y,
854                 gint           width,
855                 gint           height)
856 {
857   g_return_if_fail (GTK_IS_STYLE (style));
858   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
859   
860   GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
861 }
862
863 void
864 gtk_draw_option (GtkStyle      *style,
865                  GdkWindow     *window,
866                  GtkStateType   state_type,
867                  GtkShadowType  shadow_type,
868                  gint           x,
869                  gint           y,
870                  gint           width,
871                  gint           height)
872 {
873   g_return_if_fail (GTK_IS_STYLE (style));
874   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
875   
876   GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
877 }
878
879 void
880 gtk_draw_tab (GtkStyle      *style,
881               GdkWindow     *window,
882               GtkStateType   state_type,
883               GtkShadowType  shadow_type,
884               gint           x,
885               gint           y,
886               gint           width,
887               gint           height)
888 {
889   g_return_if_fail (GTK_IS_STYLE (style));
890   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
891   
892   GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
893 }
894
895 void
896 gtk_draw_shadow_gap (GtkStyle       *style,
897                      GdkWindow      *window,
898                      GtkStateType    state_type,
899                      GtkShadowType   shadow_type,
900                      gint            x,
901                      gint            y,
902                      gint            width,
903                      gint            height,
904                      GtkPositionType gap_side,
905                      gint            gap_x,
906                      gint            gap_width)
907 {
908   g_return_if_fail (GTK_IS_STYLE (style));
909   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
910   
911   GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
912 }
913
914 void
915 gtk_draw_box_gap (GtkStyle       *style,
916                   GdkWindow      *window,
917                   GtkStateType    state_type,
918                   GtkShadowType   shadow_type,
919                   gint            x,
920                   gint            y,
921                   gint            width,
922                   gint            height,
923                   GtkPositionType gap_side,
924                   gint            gap_x,
925                   gint            gap_width)
926 {
927   g_return_if_fail (GTK_IS_STYLE (style));
928   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
929   
930   GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
931 }
932
933 void
934 gtk_draw_extension (GtkStyle       *style,
935                     GdkWindow      *window,
936                     GtkStateType    state_type,
937                     GtkShadowType   shadow_type,
938                     gint            x,
939                     gint            y,
940                     gint            width,
941                     gint            height,
942                     GtkPositionType gap_side)
943 {
944   g_return_if_fail (GTK_IS_STYLE (style));
945   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
946   
947   GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
948 }
949
950 void
951 gtk_draw_focus (GtkStyle      *style,
952                 GdkWindow     *window,
953                 gint           x,
954                 gint           y,
955                 gint           width,
956                 gint           height)
957 {
958   g_return_if_fail (GTK_IS_STYLE (style));
959   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
960   
961   GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, NULL, NULL, NULL, x, y, width, height);
962 }
963
964 void 
965 gtk_draw_slider (GtkStyle      *style,
966                  GdkWindow     *window,
967                  GtkStateType   state_type,
968                  GtkShadowType  shadow_type,
969                  gint           x,
970                  gint           y,
971                  gint           width,
972                  gint           height,
973                  GtkOrientation orientation)
974 {
975   g_return_if_fail (GTK_IS_STYLE (style));
976   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
977   
978   GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
979 }
980
981 void 
982 gtk_draw_handle (GtkStyle      *style,
983                  GdkWindow     *window,
984                  GtkStateType   state_type,
985                  GtkShadowType  shadow_type,
986                  gint           x,
987                  gint           y,
988                  gint           width,
989                  gint           height,
990                  GtkOrientation orientation)
991 {
992   g_return_if_fail (GTK_IS_STYLE (style));
993   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
994   
995   GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
996 }
997
998 void
999 gtk_draw_expander (GtkStyle        *style,
1000                    GdkWindow       *window,
1001                    GtkStateType     state_type,
1002                    gint             x,
1003                    gint             y,
1004                    gboolean         is_open)
1005 {
1006   g_return_if_fail (GTK_IS_STYLE (style));
1007   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1008   
1009   GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1010                                               NULL, NULL, NULL,
1011                                               x, y, is_open);
1012 }
1013
1014 void
1015 gtk_draw_layout (GtkStyle        *style,
1016                  GdkWindow       *window,
1017                  GtkStateType     state_type,
1018                  gint             x,
1019                  gint             y,
1020                  PangoLayout     *layout)
1021 {
1022   g_return_if_fail (GTK_IS_STYLE (style));
1023   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1024   
1025   GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type,
1026                                             NULL, NULL, NULL,
1027                                             x, y, layout);
1028 }
1029
1030 void
1031 gtk_style_set_background (GtkStyle    *style,
1032                           GdkWindow   *window,
1033                           GtkStateType state_type)
1034 {
1035   g_return_if_fail (GTK_IS_STYLE (style));
1036   g_return_if_fail (window != NULL);
1037   
1038   GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1039 }
1040
1041 /* Default functions */
1042 static GtkStyle *
1043 gtk_style_real_clone (GtkStyle *style)
1044 {
1045   return GTK_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
1046 }
1047
1048 static void
1049 gtk_style_real_copy (GtkStyle *style,
1050                      GtkStyle *src)
1051 {
1052   gint i;
1053   
1054   for (i = 0; i < 5; i++)
1055     {
1056       style->fg[i] = src->fg[i];
1057       style->bg[i] = src->bg[i];
1058       style->text[i] = src->text[i];
1059       style->base[i] = src->base[i];
1060       
1061       style->bg_pixmap[i] = src->bg_pixmap[i];
1062     }
1063
1064   if (style->font)
1065     gdk_font_unref (style->font);
1066   style->font = src->font;
1067   if (style->font)
1068     gdk_font_ref (style->font);
1069
1070   if (style->font_desc)
1071     pango_font_description_free (style->font_desc);
1072   if (src->font_desc)
1073     style->font_desc = pango_font_description_copy (src->font_desc);
1074   else
1075     style->font_desc = NULL;
1076   
1077   style->xthickness = src->xthickness;
1078   style->ythickness = src->ythickness;
1079
1080   if (style->rc_style)
1081     gtk_rc_style_unref (style->rc_style);
1082   style->rc_style = src->rc_style;
1083   if (src->rc_style)
1084     gtk_rc_style_ref (src->rc_style);
1085
1086   /* don't copy, just clear cache */
1087   if (style->property_cache)
1088     {
1089       guint i;
1090
1091       for (i = 0; i < style->property_cache->n_nodes; i++)
1092         {
1093           PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
1094
1095           g_param_spec_unref (node->pspec);
1096           g_value_unset (&node->value);
1097         }
1098       g_bsearch_array_destroy (style->property_cache);
1099       style->property_cache = NULL;
1100     }
1101 }
1102
1103 static void
1104 gtk_style_real_init_from_rc (GtkStyle   *style,
1105                              GtkRcStyle *rc_style)
1106 {
1107   GdkFont *old_font;
1108   gint i;
1109
1110   /* cache _should_ be still empty */
1111   if (style->property_cache)
1112     {
1113       guint i;
1114
1115       for (i = 0; i < style->property_cache->n_nodes; i++)
1116         {
1117           PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
1118
1119           g_param_spec_unref (node->pspec);
1120           g_value_unset (&node->value);
1121         }
1122       g_bsearch_array_destroy (style->property_cache);
1123       style->property_cache = NULL;
1124     }
1125
1126   if (rc_style->font_desc)
1127     {
1128       pango_font_description_free (style->font_desc);
1129       style->font_desc = pango_font_description_copy (rc_style->font_desc);
1130
1131       old_font = style->font;
1132       style->font = gdk_font_from_description (style->font_desc);
1133       if (style->font)
1134         gdk_font_unref (old_font);
1135       else
1136         style->font = old_font;
1137     }
1138     
1139   for (i = 0; i < 5; i++)
1140     {
1141       if (rc_style->color_flags[i] & GTK_RC_FG)
1142         style->fg[i] = rc_style->fg[i];
1143       if (rc_style->color_flags[i] & GTK_RC_BG)
1144         style->bg[i] = rc_style->bg[i];
1145       if (rc_style->color_flags[i] & GTK_RC_TEXT)
1146         style->text[i] = rc_style->text[i];
1147       if (rc_style->color_flags[i] & GTK_RC_BASE)
1148         style->base[i] = rc_style->base[i];
1149     }
1150
1151   if (rc_style->xthickness >= 0)
1152     style->xthickness = rc_style->xthickness;
1153   if (rc_style->ythickness >= 0)
1154     style->ythickness = rc_style->ythickness;
1155
1156   if (rc_style->icon_factories)
1157     {
1158       GSList *iter;
1159
1160       style->icon_factories = g_slist_copy (rc_style->icon_factories);
1161       
1162       iter = style->icon_factories;
1163       while (iter != NULL)
1164         {
1165           g_object_ref (G_OBJECT (iter->data));
1166           
1167           iter = g_slist_next (iter);
1168         }
1169     }
1170 }
1171
1172 static gint
1173 style_property_values_cmp (gconstpointer bsearch_node1,
1174                            gconstpointer bsearch_node2)
1175 {
1176   const PropertyValue *val1 = bsearch_node1;
1177   const PropertyValue *val2 = bsearch_node2;
1178   gint cmp;
1179
1180   cmp = G_BSEARCH_ARRAY_CMP (val1->widget_type, val2->widget_type);
1181   if (cmp == 0)
1182     cmp = G_BSEARCH_ARRAY_CMP (val1->pspec, val2->pspec);
1183
1184   return cmp;
1185 }
1186
1187 const GValue*
1188 _gtk_style_peek_property_value (GtkStyle           *style,
1189                                 GType               widget_type,
1190                                 GParamSpec         *pspec,
1191                                 GtkRcPropertyParser parser)
1192 {
1193   PropertyValue *pcache, key = { 0, NULL, { 0, } };
1194   const GtkRcProperty *rcprop = NULL;
1195
1196   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1197   g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1198   g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1199   g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1200
1201   /* need value cache array */
1202   if (!style->property_cache)
1203     style->property_cache = g_bsearch_array_new (sizeof (PropertyValue),
1204                                                  style_property_values_cmp,
1205                                                  0);
1206   /* lookup, or insert value if not yet present */
1207   key.widget_type = widget_type;
1208   key.pspec = pspec;
1209   pcache = g_bsearch_array_insert (style->property_cache, &key, FALSE);
1210   if (G_VALUE_TYPE (&pcache->value))
1211     return &pcache->value;
1212
1213   /* cache miss, initialize value type, then set contents */
1214   g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1215
1216   /* value provided by rc style? */
1217   if (style->rc_style)
1218     {
1219       GQuark prop_quark = g_quark_from_string (pspec->name);
1220
1221       do
1222         {
1223           rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1224                                                      g_type_qname (widget_type),
1225                                                      prop_quark);
1226           if (rcprop)
1227             break;
1228           widget_type = g_type_parent (widget_type);
1229         }
1230       while (g_type_is_a (widget_type, pspec->owner_type));
1231     }
1232
1233   /* when supplied by rc style, we need to convert */
1234   if (rcprop)
1235     {
1236       if (G_VALUE_TYPE (&rcprop->value) == G_TYPE_GSTRING)
1237         {
1238           GString *gstring;
1239           
1240           /* value still unparsed, need to revert to user supplied parser function */
1241           
1242           gstring = g_value_get_boxed (&rcprop->value);
1243           
1244           if (!parser || !parser (pspec, gstring, &pcache->value) ||
1245               g_param_value_validate (pspec, &pcache->value))
1246             {
1247               gchar *contents = g_strescape (gstring->str, NULL);
1248
1249               g_message ("%s: failed to parse property `%s::%s' of type `%s' from rc file value \"%s\"",
1250                          rcprop->origin,
1251                          g_type_name (pspec->owner_type), pspec->name,
1252                          g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1253                          gstring->str);
1254               g_free (contents);
1255               rcprop = NULL;
1256             }
1257         }
1258       else
1259         {
1260           /* we use the normal conversion functionality of param specs */
1261           if (!g_param_value_convert (pspec, &rcprop->value, &pcache->value, TRUE))
1262             {
1263               gchar *contents = g_strdup_value_contents (&rcprop->value);
1264               
1265               g_message ("%s: failed to retrive property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1266                          rcprop->origin,
1267                          g_type_name (pspec->owner_type), pspec->name,
1268                          g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1269                          contents,
1270                          G_VALUE_TYPE_NAME (&rcprop->value));
1271               g_free (contents);
1272               rcprop = NULL;
1273             }
1274         }
1275     }
1276   
1277   /* not supplied by rc style (or conversion failed), revert to default */
1278   if (!rcprop)
1279     g_param_value_set_default (pspec, &pcache->value);
1280
1281   return &pcache->value;
1282 }
1283
1284 static void
1285 gtk_style_real_realize (GtkStyle *style)
1286 {
1287   GdkGCValues gc_values;
1288   GdkGCValuesMask gc_values_mask;
1289   
1290   gint i;
1291
1292   for (i = 0; i < 5; i++)
1293     {
1294       gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1295       gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1296       
1297       style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1298       style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1299       style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1300     }
1301   
1302   gdk_color_black (style->colormap, &style->black);
1303   gdk_color_white (style->colormap, &style->white);
1304   
1305   gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
1306   if (style->font->type == GDK_FONT_FONT)
1307     {
1308       gc_values.font = style->font;
1309     }
1310   else if (style->font->type == GDK_FONT_FONTSET)
1311     {
1312       gc_values.font = static_default_font;
1313     }
1314   
1315   gc_values.foreground = style->black;
1316   style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1317   
1318   gc_values.foreground = style->white;
1319   style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1320   
1321   for (i = 0; i < 5; i++)
1322     {
1323       if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1324         style->bg_pixmap[i] = gtk_rc_load_image (style->colormap,
1325                                                  &style->bg[i],
1326                                                  style->rc_style->bg_pixmap_name[i]);
1327       
1328       if (!gdk_color_alloc (style->colormap, &style->fg[i]))
1329         g_warning ("unable to allocate color: ( %d %d %d )",
1330                    style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1331       if (!gdk_color_alloc (style->colormap, &style->bg[i]))
1332         g_warning ("unable to allocate color: ( %d %d %d )",
1333                    style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1334       if (!gdk_color_alloc (style->colormap, &style->light[i]))
1335         g_warning ("unable to allocate color: ( %d %d %d )",
1336                    style->light[i].red, style->light[i].green, style->light[i].blue);
1337       if (!gdk_color_alloc (style->colormap, &style->dark[i]))
1338         g_warning ("unable to allocate color: ( %d %d %d )",
1339                    style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1340       if (!gdk_color_alloc (style->colormap, &style->mid[i]))
1341         g_warning ("unable to allocate color: ( %d %d %d )",
1342                    style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1343       if (!gdk_color_alloc (style->colormap, &style->text[i]))
1344         g_warning ("unable to allocate color: ( %d %d %d )",
1345                    style->text[i].red, style->text[i].green, style->text[i].blue);
1346       if (!gdk_color_alloc (style->colormap, &style->base[i]))
1347         g_warning ("unable to allocate color: ( %d %d %d )",
1348                    style->base[i].red, style->base[i].green, style->base[i].blue);
1349       
1350       gc_values.foreground = style->fg[i];
1351       style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1352       
1353       gc_values.foreground = style->bg[i];
1354       style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1355       
1356       gc_values.foreground = style->light[i];
1357       style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1358       
1359       gc_values.foreground = style->dark[i];
1360       style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1361       
1362       gc_values.foreground = style->mid[i];
1363       style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1364       
1365       gc_values.foreground = style->text[i];
1366       style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1367       
1368       gc_values.foreground = style->base[i];
1369       style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1370     }
1371 }
1372
1373 static void
1374 gtk_style_real_unrealize (GtkStyle *style)
1375 {
1376   int i;
1377
1378   gtk_gc_release (style->black_gc);
1379   gtk_gc_release (style->white_gc);
1380       
1381   for (i = 0; i < 5; i++)
1382     {
1383       gtk_gc_release (style->fg_gc[i]);
1384       gtk_gc_release (style->bg_gc[i]);
1385       gtk_gc_release (style->light_gc[i]);
1386       gtk_gc_release (style->dark_gc[i]);
1387       gtk_gc_release (style->mid_gc[i]);
1388       gtk_gc_release (style->text_gc[i]);
1389       gtk_gc_release (style->base_gc[i]);
1390
1391       if (style->bg_pixmap[i] &&  style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1392         gdk_pixmap_unref (style->bg_pixmap[i]);
1393     }
1394   
1395   gdk_colormap_free_colors (style->colormap, style->fg, 5);
1396   gdk_colormap_free_colors (style->colormap, style->bg, 5);
1397   gdk_colormap_free_colors (style->colormap, style->light, 5);
1398   gdk_colormap_free_colors (style->colormap, style->dark, 5);
1399   gdk_colormap_free_colors (style->colormap, style->mid, 5);
1400   gdk_colormap_free_colors (style->colormap, style->text, 5);
1401   gdk_colormap_free_colors (style->colormap, style->base, 5);
1402 }
1403
1404 static void
1405 gtk_style_real_set_background (GtkStyle    *style,
1406                                GdkWindow   *window,
1407                                GtkStateType state_type)
1408 {
1409   GdkPixmap *pixmap;
1410   gint parent_relative;
1411   
1412   if (style->bg_pixmap[state_type])
1413     {
1414       if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1415         {
1416           pixmap = NULL;
1417           parent_relative = TRUE;
1418         }
1419       else
1420         {
1421           pixmap = style->bg_pixmap[state_type];
1422           parent_relative = FALSE;
1423         }
1424       
1425       gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1426     }
1427   else
1428     gdk_window_set_background (window, &style->bg[state_type]);
1429 }
1430
1431 GdkPixbuf *
1432 gtk_style_render_icon (GtkStyle            *style,
1433                        const GtkIconSource *source,
1434                        GtkTextDirection     direction,
1435                        GtkStateType         state,
1436                        GtkIconSize          size,
1437                        GtkWidget           *widget,
1438                        const gchar         *detail)
1439 {
1440   GdkPixbuf *pixbuf;
1441   
1442   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1443   g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1444   
1445   pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1446                                                      size, widget, detail);
1447
1448   g_return_val_if_fail (pixbuf != NULL, NULL);
1449
1450   return pixbuf;
1451 }
1452
1453 /* Default functions */
1454 void
1455 gtk_style_apply_default_background (GtkStyle     *style,
1456                                     GdkWindow    *window,
1457                                     gboolean      set_bg,
1458                                     GtkStateType  state_type, 
1459                                     GdkRectangle *area, 
1460                                     gint          x, 
1461                                     gint          y, 
1462                                     gint          width, 
1463                                     gint          height)
1464 {
1465   GdkRectangle new_rect, old_rect;
1466   
1467   if (area)
1468     {
1469       old_rect.x = x;
1470       old_rect.y = y;
1471       old_rect.width = width;
1472       old_rect.height = height;
1473       
1474       if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
1475         return;
1476     }
1477   else
1478     {
1479       new_rect.x = x;
1480       new_rect.y = y;
1481       new_rect.width = width;
1482       new_rect.height = height;
1483     }
1484   
1485   if (!style->bg_pixmap[state_type] ||
1486       GDK_IS_PIXMAP (window) ||
1487       (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
1488     {
1489       GdkGC *gc = style->bg_gc[state_type];
1490       
1491       if (style->bg_pixmap[state_type])
1492         {
1493           gdk_gc_set_fill (gc, GDK_TILED);
1494           gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
1495         }
1496       
1497       gdk_draw_rectangle (window, gc, TRUE, 
1498                           new_rect.x, new_rect.y, new_rect.width, new_rect.height);
1499       if (style->bg_pixmap[state_type])
1500         gdk_gc_set_fill (gc, GDK_SOLID);
1501     }
1502   else
1503     {
1504       if (set_bg)
1505         {
1506           if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1507             gdk_window_set_back_pixmap (window, NULL, TRUE);
1508           else
1509             gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
1510         }
1511       
1512       gdk_window_clear_area (window, 
1513                              new_rect.x, new_rect.y, 
1514                              new_rect.width, new_rect.height);
1515     }
1516 }
1517
1518 static GdkPixbuf*
1519 scale_or_ref (GdkPixbuf *src,
1520               gint width,
1521               gint height)
1522 {
1523   if (width == gdk_pixbuf_get_width (src) &&
1524       height == gdk_pixbuf_get_height (src))
1525     {
1526       gdk_pixbuf_ref (src);
1527       return src;
1528     }
1529   else
1530     {
1531       return gdk_pixbuf_scale_simple (src,
1532                                       width, height,
1533                                       GDK_INTERP_BILINEAR);
1534     }
1535 }
1536
1537 static GdkPixbuf *
1538 gtk_default_render_icon (GtkStyle            *style,
1539                          const GtkIconSource *source,
1540                          GtkTextDirection     direction,
1541                          GtkStateType         state,
1542                          GtkIconSize          size,
1543                          GtkWidget           *widget,
1544                          const gchar         *detail)
1545 {
1546   gint width = 1;
1547   gint height = 1;
1548   GdkPixbuf *scaled;
1549   GdkPixbuf *stated;
1550
1551   /* Oddly, style can be NULL in this function, because
1552    * GtkIconSet can be used without a style and if so
1553    * it uses this function.
1554    */
1555   
1556   g_return_val_if_fail (source->pixbuf != NULL, NULL);
1557   
1558   if (!gtk_icon_size_lookup (size, &width, &height))
1559     {
1560       g_warning (G_STRLOC ": invalid icon size `%d'", size);
1561       return NULL;
1562     }
1563
1564   /* If the size was wildcarded, then scale; otherwise, leave it
1565    * alone.
1566    */
1567   if (source->any_size)
1568     scaled = scale_or_ref (source->pixbuf, width, height);
1569   else
1570     scaled = GDK_PIXBUF (g_object_ref (G_OBJECT (source->pixbuf)));
1571
1572   /* If the state was wildcarded, then generate a state. */
1573   if (source->any_state)
1574     {
1575       if (state == GTK_STATE_INSENSITIVE)
1576         {
1577           stated = gdk_pixbuf_copy (scaled);      
1578           
1579           gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1580                                             0.8, TRUE);
1581           
1582           gdk_pixbuf_unref (scaled);
1583         }
1584       else if (state == GTK_STATE_PRELIGHT)
1585         {
1586           stated = gdk_pixbuf_copy (scaled);      
1587           
1588           gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1589                                             1.2, FALSE);
1590           
1591           gdk_pixbuf_unref (scaled);
1592         }
1593       else
1594         {
1595           stated = scaled;
1596         }
1597     }
1598   else
1599     stated = scaled;
1600   
1601   return stated;
1602 }
1603
1604 static void
1605 gtk_default_draw_hline (GtkStyle     *style,
1606                         GdkWindow    *window,
1607                         GtkStateType  state_type,
1608                         GdkRectangle  *area,
1609                         GtkWidget     *widget,
1610                         const gchar   *detail,
1611                         gint          x1,
1612                         gint          x2,
1613                         gint          y)
1614 {
1615   gint thickness_light;
1616   gint thickness_dark;
1617   gint i;
1618   
1619   g_return_if_fail (GTK_IS_STYLE (style));
1620   g_return_if_fail (window != NULL);
1621   
1622   thickness_light = style->ythickness / 2;
1623   thickness_dark = style->ythickness - thickness_light;
1624   
1625   if (area)
1626     {
1627       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
1628       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
1629     }
1630   
1631   if (detail && !strcmp (detail, "label"))
1632     {
1633       if (state_type == GTK_STATE_INSENSITIVE)
1634         gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);   
1635       gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);     
1636     }
1637   else
1638     {
1639       for (i = 0; i < thickness_dark; i++)
1640         {
1641           gdk_draw_line (window, style->light_gc[state_type], x2 - i - 1, y + i, x2, y + i);
1642           gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
1643         }
1644       
1645       y += thickness_dark;
1646       for (i = 0; i < thickness_light; i++)
1647         {
1648           gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1649           gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i - 1, y + i, x2, y + i);
1650         }
1651     }
1652   
1653   if (area)
1654     {
1655       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1656       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1657     }
1658 }
1659
1660
1661 static void
1662 gtk_default_draw_vline (GtkStyle     *style,
1663                         GdkWindow    *window,
1664                         GtkStateType  state_type,
1665                         GdkRectangle  *area,
1666                         GtkWidget     *widget,
1667                         const gchar   *detail,
1668                         gint          y1,
1669                         gint          y2,
1670                         gint          x)
1671 {
1672   gint thickness_light;
1673   gint thickness_dark;
1674   gint i;
1675   
1676   g_return_if_fail (GTK_IS_STYLE (style));
1677   g_return_if_fail (window != NULL);
1678   
1679   thickness_light = style->xthickness / 2;
1680   thickness_dark = style->xthickness - thickness_light;
1681   
1682   if (area)
1683     {
1684       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
1685       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
1686     }
1687   for (i = 0; i < thickness_dark; i++)
1688     {
1689       gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i - 1, x + i, y2);
1690       gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
1691     }
1692   
1693   x += thickness_dark;
1694   for (i = 0; i < thickness_light; i++)
1695     {
1696       gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i);
1697       gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
1698     }
1699   if (area)
1700     {
1701       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1702       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1703     }
1704 }
1705
1706
1707 static void
1708 gtk_default_draw_shadow (GtkStyle      *style,
1709                          GdkWindow     *window,
1710                          GtkStateType   state_type,
1711                          GtkShadowType  shadow_type,
1712                          GdkRectangle  *area,
1713                          GtkWidget     *widget,
1714                          const gchar   *detail,
1715                          gint           x,
1716                          gint           y,
1717                          gint           width,
1718                          gint           height)
1719 {
1720   GdkGC *gc1 = NULL;
1721   GdkGC *gc2 = NULL;
1722   gint thickness_light;
1723   gint thickness_dark;
1724   gint i;
1725   
1726   g_return_if_fail (GTK_IS_STYLE (style));
1727   g_return_if_fail (window != NULL);
1728   
1729   if ((width == -1) && (height == -1))
1730     gdk_window_get_size (window, &width, &height);
1731   else if (width == -1)
1732     gdk_window_get_size (window, &width, NULL);
1733   else if (height == -1)
1734     gdk_window_get_size (window, NULL, &height);
1735   
1736   switch (shadow_type)
1737     {
1738     case GTK_SHADOW_NONE:
1739       return;
1740     case GTK_SHADOW_IN:
1741     case GTK_SHADOW_ETCHED_IN:
1742       gc1 = style->light_gc[state_type];
1743       gc2 = style->dark_gc[state_type];
1744       break;
1745     case GTK_SHADOW_OUT:
1746     case GTK_SHADOW_ETCHED_OUT:
1747       gc1 = style->dark_gc[state_type];
1748       gc2 = style->light_gc[state_type];
1749       break;
1750     }
1751   
1752   if (area)
1753     {
1754       gdk_gc_set_clip_rectangle (gc1, area);
1755       gdk_gc_set_clip_rectangle (gc2, area);
1756       if (shadow_type == GTK_SHADOW_IN || 
1757           shadow_type == GTK_SHADOW_OUT)
1758         {
1759           gdk_gc_set_clip_rectangle (style->black_gc, area);
1760           gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
1761         }
1762     }
1763   
1764   switch (shadow_type)
1765     {
1766     case GTK_SHADOW_NONE:
1767       break;
1768       
1769     case GTK_SHADOW_IN:
1770       gdk_draw_line (window, gc1,
1771                      x, y + height - 1, x + width - 1, y + height - 1);
1772       gdk_draw_line (window, gc1,
1773                      x + width - 1, y, x + width - 1, y + height - 1);
1774       
1775       gdk_draw_line (window, style->bg_gc[state_type],
1776                      x + 1, y + height - 2, x + width - 2, y + height - 2);
1777       gdk_draw_line (window, style->bg_gc[state_type],
1778                      x + width - 2, y + 1, x + width - 2, y + height - 2);
1779       
1780       gdk_draw_line (window, style->black_gc,
1781                      x + 1, y + 1, x + width - 2, y + 1);
1782       gdk_draw_line (window, style->black_gc,
1783                      x + 1, y + 1, x + 1, y + height - 2);
1784       
1785       gdk_draw_line (window, gc2,
1786                      x, y, x + width - 1, y);
1787       gdk_draw_line (window, gc2,
1788                      x, y, x, y + height - 1);
1789       break;
1790       
1791     case GTK_SHADOW_OUT:
1792       gdk_draw_line (window, gc1,
1793                      x + 1, y + height - 2, x + width - 2, y + height - 2);
1794       gdk_draw_line (window, gc1,
1795                      x + width - 2, y + 1, x + width - 2, y + height - 2);
1796       
1797       gdk_draw_line (window, gc2,
1798                      x, y, x + width - 1, y);
1799       gdk_draw_line (window, gc2,
1800                      x, y, x, y + height - 1);
1801       
1802       gdk_draw_line (window, style->bg_gc[state_type],
1803                      x + 1, y + 1, x + width - 2, y + 1);
1804       gdk_draw_line (window, style->bg_gc[state_type],
1805                      x + 1, y + 1, x + 1, y + height - 2);
1806       
1807       gdk_draw_line (window, style->black_gc,
1808                      x, y + height - 1, x + width - 1, y + height - 1);
1809       gdk_draw_line (window, style->black_gc,
1810                      x + width - 1, y, x + width - 1, y + height - 1);
1811       break;
1812       
1813     case GTK_SHADOW_ETCHED_IN:
1814     case GTK_SHADOW_ETCHED_OUT:
1815       thickness_light = 1;
1816       thickness_dark = 1;
1817       
1818       for (i = 0; i < thickness_dark; i++)
1819         {
1820           gdk_draw_line (window, gc1,
1821                          x + i,
1822                          y + height - i - 1,
1823                          x + width - i - 1,
1824                          y + height - i - 1);
1825           gdk_draw_line (window, gc1,
1826                          x + width - i - 1,
1827                          y + i,
1828                          x + width - i - 1,
1829                          y + height - i - 1);
1830           
1831           gdk_draw_line (window, gc2,
1832                          x + i,
1833                          y + i,
1834                          x + width - i - 2,
1835                          y + i);
1836           gdk_draw_line (window, gc2,
1837                          x + i,
1838                          y + i,
1839                          x + i,
1840                          y + height - i - 2);
1841         }
1842       
1843       for (i = 0; i < thickness_light; i++)
1844         {
1845           gdk_draw_line (window, gc1,
1846                          x + thickness_dark + i,
1847                          y + thickness_dark + i,
1848                          x + width - thickness_dark - i - 1,
1849                          y + thickness_dark + i);
1850           gdk_draw_line (window, gc1,
1851                          x + thickness_dark + i,
1852                          y + thickness_dark + i,
1853                          x + thickness_dark + i,
1854                          y + height - thickness_dark - i - 1);
1855           
1856           gdk_draw_line (window, gc2,
1857                          x + thickness_dark + i,
1858                          y + height - thickness_light - i - 1,
1859                          x + width - thickness_light - 1,
1860                          y + height - thickness_light - i - 1);
1861           gdk_draw_line (window, gc2,
1862                          x + width - thickness_light - i - 1,
1863                          y + thickness_dark + i,
1864                          x + width - thickness_light - i - 1,
1865                          y + height - thickness_light - 1);
1866         }
1867       break;
1868     }
1869   if (area)
1870     {
1871       gdk_gc_set_clip_rectangle (gc1, NULL);
1872       gdk_gc_set_clip_rectangle (gc2, NULL);
1873       if (shadow_type == GTK_SHADOW_IN || 
1874           shadow_type == GTK_SHADOW_OUT)
1875         {
1876           gdk_gc_set_clip_rectangle (style->black_gc, NULL);
1877           gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
1878         }
1879     }
1880 }
1881
1882 static void
1883 gtk_default_draw_polygon (GtkStyle      *style,
1884                           GdkWindow     *window,
1885                           GtkStateType   state_type,
1886                           GtkShadowType  shadow_type,
1887                           GdkRectangle  *area,
1888                           GtkWidget     *widget,
1889                           const gchar   *detail,
1890                           GdkPoint      *points,
1891                           gint           npoints,
1892                           gboolean       fill)
1893 {
1894   static const gdouble pi_over_4 = G_PI_4;
1895   static const gdouble pi_3_over_4 = G_PI_4 * 3;
1896   GdkGC *gc1;
1897   GdkGC *gc2;
1898   GdkGC *gc3;
1899   GdkGC *gc4;
1900   gdouble angle;
1901   gint xadjust;
1902   gint yadjust;
1903   gint i;
1904   
1905   g_return_if_fail (GTK_IS_STYLE (style));
1906   g_return_if_fail (window != NULL);
1907   g_return_if_fail (points != NULL);
1908   
1909   switch (shadow_type)
1910     {
1911     case GTK_SHADOW_IN:
1912       gc1 = style->bg_gc[state_type];
1913       gc2 = style->dark_gc[state_type];
1914       gc3 = style->light_gc[state_type];
1915       gc4 = style->black_gc;
1916       break;
1917     case GTK_SHADOW_ETCHED_IN:
1918       gc1 = style->light_gc[state_type];
1919       gc2 = style->dark_gc[state_type];
1920       gc3 = style->dark_gc[state_type];
1921       gc4 = style->light_gc[state_type];
1922       break;
1923     case GTK_SHADOW_OUT:
1924       gc1 = style->dark_gc[state_type];
1925       gc2 = style->light_gc[state_type];
1926       gc3 = style->black_gc;
1927       gc4 = style->bg_gc[state_type];
1928       break;
1929     case GTK_SHADOW_ETCHED_OUT:
1930       gc1 = style->dark_gc[state_type];
1931       gc2 = style->light_gc[state_type];
1932       gc3 = style->light_gc[state_type];
1933       gc4 = style->dark_gc[state_type];
1934       break;
1935     default:
1936       return;
1937     }
1938   
1939   if (area)
1940     {
1941       gdk_gc_set_clip_rectangle (gc1, area);
1942       gdk_gc_set_clip_rectangle (gc2, area);
1943       gdk_gc_set_clip_rectangle (gc3, area);
1944       gdk_gc_set_clip_rectangle (gc4, area);
1945     }
1946   
1947   if (fill)
1948     gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
1949   
1950   npoints--;
1951   
1952   for (i = 0; i < npoints; i++)
1953     {
1954       if ((points[i].x == points[i+1].x) &&
1955           (points[i].y == points[i+1].y))
1956         {
1957           angle = 0;
1958         }
1959       else
1960         {
1961           angle = atan2 (points[i+1].y - points[i].y,
1962                          points[i+1].x - points[i].x);
1963         }
1964       
1965       if ((angle > -pi_3_over_4) && (angle < pi_over_4))
1966         {
1967           if (angle > -pi_over_4)
1968             {
1969               xadjust = 0;
1970               yadjust = 1;
1971             }
1972           else
1973             {
1974               xadjust = 1;
1975               yadjust = 0;
1976             }
1977           
1978           gdk_draw_line (window, gc1,
1979                          points[i].x-xadjust, points[i].y-yadjust,
1980                          points[i+1].x-xadjust, points[i+1].y-yadjust);
1981           gdk_draw_line (window, gc3,
1982                          points[i].x, points[i].y,
1983                          points[i+1].x, points[i+1].y);
1984         }
1985       else
1986         {
1987           if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
1988             {
1989               xadjust = 0;
1990               yadjust = 1;
1991             }
1992           else
1993             {
1994               xadjust = 1;
1995               yadjust = 0;
1996             }
1997           
1998           gdk_draw_line (window, gc4,
1999                          points[i].x+xadjust, points[i].y+yadjust,
2000                          points[i+1].x+xadjust, points[i+1].y+yadjust);
2001           gdk_draw_line (window, gc2,
2002                          points[i].x, points[i].y,
2003                          points[i+1].x, points[i+1].y);
2004         }
2005     }
2006
2007   if (area)
2008     {
2009       gdk_gc_set_clip_rectangle (gc1, NULL);
2010       gdk_gc_set_clip_rectangle (gc2, NULL);
2011       gdk_gc_set_clip_rectangle (gc3, NULL);
2012       gdk_gc_set_clip_rectangle (gc4, NULL);
2013     }
2014 }
2015
2016 static void
2017 gtk_default_draw_arrow (GtkStyle      *style,
2018                         GdkWindow     *window,
2019                         GtkStateType   state_type,
2020                         GtkShadowType  shadow_type,
2021                         GdkRectangle  *area,
2022                         GtkWidget     *widget,
2023                         const gchar   *detail,
2024                         GtkArrowType   arrow_type,
2025                         gboolean       fill,
2026                         gint           x,
2027                         gint           y,
2028                         gint           width,
2029                         gint           height)
2030 {
2031   GdkGC *gc1;
2032   GdkGC *gc2;
2033   GdkGC *gc3;
2034   GdkGC *gc4;
2035   gint half_width;
2036   gint half_height;
2037   GdkPoint points[3];
2038   
2039   g_return_if_fail (GTK_IS_STYLE (style));
2040   g_return_if_fail (window != NULL);
2041   
2042   switch (shadow_type)
2043     {
2044     case GTK_SHADOW_IN:
2045       gc1 = style->bg_gc[state_type];
2046       gc2 = style->dark_gc[state_type];
2047       gc3 = style->light_gc[state_type];
2048       gc4 = style->black_gc;
2049       break;
2050     case GTK_SHADOW_OUT:
2051       gc1 = style->dark_gc[state_type];
2052       gc2 = style->light_gc[state_type];
2053       gc3 = style->black_gc;
2054       gc4 = style->bg_gc[state_type];
2055       break;
2056     case GTK_SHADOW_ETCHED_IN:
2057       gc1 = style->light_gc[state_type];
2058       gc2 = style->dark_gc[state_type];
2059       gc3 = NULL;
2060       gc4 = NULL;
2061       break;
2062     case GTK_SHADOW_ETCHED_OUT:
2063       gc1 = style->dark_gc[state_type];
2064       gc2 = style->light_gc[state_type];
2065       gc3 = NULL;
2066       gc4 = NULL;
2067       break;
2068     default:
2069       return;
2070     }
2071   
2072   if ((width == -1) && (height == -1))
2073     gdk_window_get_size (window, &width, &height);
2074   else if (width == -1)
2075     gdk_window_get_size (window, &width, NULL);
2076   else if (height == -1)
2077     gdk_window_get_size (window, NULL, &height);
2078   
2079   half_width = width / 2;
2080   half_height = height / 2;
2081   
2082   if (area)
2083     {
2084       gdk_gc_set_clip_rectangle (gc1, area);
2085       gdk_gc_set_clip_rectangle (gc2, area);
2086       if ((gc3) && (gc4))
2087         {
2088           gdk_gc_set_clip_rectangle (gc3, area);
2089           gdk_gc_set_clip_rectangle (gc4, area);
2090         }
2091     }
2092   
2093   switch (arrow_type)
2094     {
2095     case GTK_ARROW_UP:
2096       if (fill)
2097         {
2098           points[0].x = x + half_width;
2099           points[0].y = y;
2100           points[1].x = x;
2101           points[1].y = y + height - 1;
2102           points[2].x = x + width - 1;
2103           points[2].y = y + height - 1;
2104           
2105           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
2106         }
2107       
2108       switch (shadow_type)
2109         {
2110         case GTK_SHADOW_IN:
2111         case GTK_SHADOW_OUT:
2112           
2113           gdk_draw_line (window, gc1,
2114                          x + 1, y + height - 2,
2115                          x + width - 2, y + height - 2);
2116           gdk_draw_line (window, gc3,
2117                          x + 0, y + height - 1,
2118                          x + width - 1, y + height - 1);
2119           
2120           gdk_draw_line (window, gc1,
2121                          x + width - 2, y + height - 1,
2122                          x + half_width, y + 1);
2123           gdk_draw_line (window, gc3,
2124                          x + width - 1, y + height - 1,
2125                          x + half_width, y);
2126           
2127           gdk_draw_line (window, gc4,
2128                          x + half_width, y + 1,
2129                          x + 1, y + height - 1);
2130           gdk_draw_line (window, gc2,
2131                          x + half_width, y,
2132                          x, y + height - 1);
2133           break;
2134           
2135         case GTK_SHADOW_ETCHED_IN:
2136         case GTK_SHADOW_ETCHED_OUT:
2137           gdk_draw_line (window, gc1,
2138                          x + half_width, y + 1,
2139                          x + 1, y + height - 1);
2140           gdk_draw_line (window, gc1,
2141                          x + 1, y + height - 1,
2142                          x + width - 1, y + height - 1);
2143           gdk_draw_line (window, gc1,
2144                          x + width - 1, y + height - 1,
2145                          x + half_width + 1, y + 1);
2146           
2147           points[0].x = x + half_width;
2148           points[0].y = y;
2149           points[1].x = x;
2150           points[1].y = y + height - 2;
2151           points[2].x = x + width - 2;
2152           points[2].y = y + height - 2;
2153           
2154           gdk_draw_polygon (window, gc2, FALSE, points, 3);
2155           break;
2156           
2157         default:
2158           break;
2159         }
2160       break;
2161       
2162     case GTK_ARROW_DOWN:
2163       if (fill)
2164         {
2165           points[0].x = x + width - 1;
2166           points[0].y = y;
2167           points[1].x = x;
2168           points[1].y = y;
2169           points[2].x = x + half_width;
2170           points[2].y = y + height - 1;
2171           
2172           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
2173         }
2174       switch (shadow_type)
2175         {
2176         case GTK_SHADOW_IN:
2177         case GTK_SHADOW_OUT:
2178           gdk_draw_line (window, gc4,
2179                          x + width - 2,
2180                          y + 1, x + 1, y + 1);
2181           gdk_draw_line (window, gc2,
2182                          x + width - 1, y,
2183                          x, y);
2184           
2185           gdk_draw_line (window, gc4,
2186                          x + 1, y,
2187                          x + half_width, y + height - 2);
2188           gdk_draw_line (window, gc2,
2189                          x, y,
2190                          x + half_width, y + height - 1);
2191           
2192           gdk_draw_line (window, gc1,
2193                          x + half_width, y + height - 2,
2194                          x + width - 2, y);
2195           gdk_draw_line (window, gc3,
2196                          x + half_width, y + height - 1,
2197                          x + width - 1, y);
2198           break;
2199           
2200         case GTK_SHADOW_ETCHED_IN:
2201         case GTK_SHADOW_ETCHED_OUT:
2202           gdk_draw_line (window, gc1,
2203                          x + width - 1, y + 1,
2204                          x + 1, y + 1);
2205           gdk_draw_line (window, gc1,
2206                          x + 1, y + 1,
2207                          x + half_width + 1, y + height - 1);
2208           gdk_draw_line (window, gc1,
2209                          x + half_width + 1, y + height - 2,
2210                          x + width - 1, y);
2211           
2212           points[0].x = x + width - 2;
2213           points[0].y = y;
2214           points[1].x = x;
2215           points[1].y = y;
2216           points[2].x = x + half_width;
2217           points[2].y = y + height - 2;
2218           
2219           gdk_draw_polygon (window, gc2, FALSE, points, 3);
2220           break;
2221           
2222         default:
2223           break;
2224         }
2225       break;
2226     case GTK_ARROW_LEFT:
2227       if (fill)
2228         {
2229           points[0].x = x;
2230           points[0].y = y + half_height;
2231           points[1].x = x + width - 1;
2232           points[1].y = y + height - 1;
2233           points[2].x = x + width - 1;
2234           points[2].y = y;
2235           
2236           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
2237         }
2238       
2239       switch (shadow_type)
2240         {
2241         case GTK_SHADOW_IN:
2242         case GTK_SHADOW_OUT:
2243           gdk_draw_line (window, gc1,
2244                          x + 1, y + half_height,
2245                          x + width - 1, y + height - 1);
2246           gdk_draw_line (window, gc3,
2247                          x, y + half_height,
2248                          x + width - 1, y + height - 1);
2249           
2250           gdk_draw_line (window, gc1,
2251                          x + width - 2, y + height - 1,
2252                          x + width - 2, y + 1);
2253           gdk_draw_line (window, gc3,
2254                          x + width - 1, y + height - 1,
2255                          x + width - 1, y);
2256           
2257           gdk_draw_line (window, gc4,
2258                          x + width - 1, y + 1,
2259                          x + 1, y + half_height);
2260           gdk_draw_line (window, gc2,
2261                          x + width - 1, y,
2262                          x, y + half_height);
2263           break;
2264           
2265         case GTK_SHADOW_ETCHED_IN:
2266         case GTK_SHADOW_ETCHED_OUT:
2267           gdk_draw_line (window, gc1,
2268                          x + width - 1, y + 1,
2269                          x + 1, y + half_height);
2270           gdk_draw_line (window, gc1,
2271                          x + 1, y + half_height + 1,
2272                          x + width - 1, y + height - 1);
2273           gdk_draw_line (window, gc1,
2274                          x + width - 1, y + height - 1,
2275                          x + width - 1, y + 1);
2276           
2277           points[0].x = x + width - 2;
2278           points[0].y = y;
2279           points[1].x = x;
2280           points[1].y = y + half_height;
2281           points[2].x = x + width - 2;
2282           points[2].y = y + height - 2;
2283           
2284           gdk_draw_polygon (window, gc2, FALSE, points, 3);
2285           break;
2286           
2287         default:
2288           break;
2289         }
2290       break;
2291     case GTK_ARROW_RIGHT:
2292       if (fill)
2293         {
2294           points[0].x = x + width - 1;
2295           points[0].y = y + half_height;
2296           points[1].x = x;
2297           points[1].y = y;
2298           points[2].x = x;
2299           points[2].y = y + height - 1;
2300           
2301           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
2302         }
2303       
2304       switch (shadow_type)
2305         {
2306         case GTK_SHADOW_IN:
2307         case GTK_SHADOW_OUT:
2308           gdk_draw_line (window, gc4,
2309                          x + width - 1, y + half_height,
2310                          x + 1, y + 1);
2311           gdk_draw_line (window, gc2,
2312                          x + width - 1, y + half_height,
2313                          x, y);
2314           gdk_draw_line (window, gc4,
2315                          x + 1, y + 1,
2316                          x + 1, y + height - 2);
2317           gdk_draw_line (window, gc2,
2318                          x, y,
2319                          x, y + height - 1);
2320           
2321           gdk_draw_line (window, gc1,
2322                          x + 1, y + height - 2,
2323                          x + width - 1, y + half_height);
2324           gdk_draw_line (window, gc3,
2325                          x, y + height - 1,
2326                          x + width - 1, y + half_height);
2327           break;
2328           
2329         case GTK_SHADOW_ETCHED_IN:
2330         case GTK_SHADOW_ETCHED_OUT:
2331           gdk_draw_line (window, gc1,
2332                          x + width - 1, y + half_height + 1,
2333                          x + 1, y + 1);
2334           gdk_draw_line (window, gc1,
2335                          x + 1, y + 1,
2336                          x + 1, y + height - 1);
2337           gdk_draw_line (window, gc1,
2338                          x + 1, y + height - 1,
2339                          x + width - 1, y + half_height + 1);
2340           
2341           points[0].x = x + width - 2;
2342           points[0].y = y + half_height;
2343           points[1].x = x;
2344           points[1].y = y;
2345           points[2].x = x;
2346           points[2].y = y + height - 1;
2347           
2348           gdk_draw_polygon (window, gc2, FALSE, points, 3);
2349           break;
2350           
2351         default:
2352           break;
2353         }
2354       break;
2355     }
2356
2357   if (area)
2358     {
2359       gdk_gc_set_clip_rectangle (gc1, NULL);
2360       gdk_gc_set_clip_rectangle (gc2, NULL);
2361       if (gc3)
2362         {
2363           gdk_gc_set_clip_rectangle (gc3, NULL);
2364           gdk_gc_set_clip_rectangle (gc4, NULL);
2365         }
2366     }
2367 }
2368
2369 static void
2370 gtk_default_draw_diamond (GtkStyle      *style,
2371                           GdkWindow     *window,
2372                           GtkStateType   state_type,
2373                           GtkShadowType  shadow_type,
2374                           GdkRectangle  *area,
2375                           GtkWidget     *widget,
2376                           const gchar   *detail,
2377                           gint           x,
2378                           gint           y,
2379                           gint           width,
2380                           gint           height)
2381 {
2382   gint half_width;
2383   gint half_height;
2384   GdkGC *outer_nw = NULL;
2385   GdkGC *outer_ne = NULL;
2386   GdkGC *outer_sw = NULL;
2387   GdkGC *outer_se = NULL;
2388   GdkGC *middle_nw = NULL;
2389   GdkGC *middle_ne = NULL;
2390   GdkGC *middle_sw = NULL;
2391   GdkGC *middle_se = NULL;
2392   GdkGC *inner_nw = NULL;
2393   GdkGC *inner_ne = NULL;
2394   GdkGC *inner_sw = NULL;
2395   GdkGC *inner_se = NULL;
2396   
2397   g_return_if_fail (GTK_IS_STYLE (style));
2398   g_return_if_fail (window != NULL);
2399   
2400   if ((width == -1) && (height == -1))
2401     gdk_window_get_size (window, &width, &height);
2402   else if (width == -1)
2403     gdk_window_get_size (window, &width, NULL);
2404   else if (height == -1)
2405     gdk_window_get_size (window, NULL, &height);
2406   
2407   half_width = width / 2;
2408   half_height = height / 2;
2409   
2410   if (area)
2411     {
2412       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2413       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2414       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2415       gdk_gc_set_clip_rectangle (style->black_gc, area);
2416     }
2417   
2418   switch (shadow_type)
2419     {
2420     case GTK_SHADOW_IN:
2421       inner_sw = inner_se = style->bg_gc[state_type];
2422       middle_sw = middle_se = style->light_gc[state_type];
2423       outer_sw = outer_se = style->light_gc[state_type];
2424       inner_nw = inner_ne = style->black_gc;
2425       middle_nw = middle_ne = style->dark_gc[state_type];
2426       outer_nw = outer_ne = style->dark_gc[state_type];
2427       break;
2428           
2429     case GTK_SHADOW_OUT:
2430       inner_sw = inner_se = style->dark_gc[state_type];
2431       middle_sw = middle_se = style->dark_gc[state_type];
2432       outer_sw = outer_se = style->black_gc;
2433       inner_nw = inner_ne = style->bg_gc[state_type];
2434       middle_nw = middle_ne = style->light_gc[state_type];
2435       outer_nw = outer_ne = style->light_gc[state_type];
2436       break;
2437
2438     case GTK_SHADOW_ETCHED_IN:
2439       inner_sw = inner_se = style->bg_gc[state_type];
2440       middle_sw = middle_se = style->dark_gc[state_type];
2441       outer_sw = outer_se = style->light_gc[state_type];
2442       inner_nw = inner_ne = style->bg_gc[state_type];
2443       middle_nw = middle_ne = style->light_gc[state_type];
2444       outer_nw = outer_ne = style->dark_gc[state_type];
2445       break;
2446
2447     case GTK_SHADOW_ETCHED_OUT:
2448       inner_sw = inner_se = style->bg_gc[state_type];
2449       middle_sw = middle_se = style->light_gc[state_type];
2450       outer_sw = outer_se = style->dark_gc[state_type];
2451       inner_nw = inner_ne = style->bg_gc[state_type];
2452       middle_nw = middle_ne = style->dark_gc[state_type];
2453       outer_nw = outer_ne = style->light_gc[state_type];
2454       break;
2455       
2456     default:
2457
2458       break;
2459     }
2460
2461   if (inner_sw)
2462     {
2463       gdk_draw_line (window, inner_sw,
2464                      x + 2, y + half_height,
2465                      x + half_width, y + height - 2);
2466       gdk_draw_line (window, inner_se,
2467                      x + half_width, y + height - 2,
2468                      x + width - 2, y + half_height);
2469       gdk_draw_line (window, middle_sw,
2470                      x + 1, y + half_height,
2471                      x + half_width, y + height - 1);
2472       gdk_draw_line (window, middle_se,
2473                      x + half_width, y + height - 1,
2474                      x + width - 1, y + half_height);
2475       gdk_draw_line (window, outer_sw,
2476                      x, y + half_height,
2477                      x + half_width, y + height);
2478       gdk_draw_line (window, outer_se,
2479                      x + half_width, y + height,
2480                      x + width, y + half_height);
2481   
2482       gdk_draw_line (window, inner_nw,
2483                      x + 2, y + half_height,
2484                      x + half_width, y + 2);
2485       gdk_draw_line (window, inner_ne,
2486                      x + half_width, y + 2,
2487                      x + width - 2, y + half_height);
2488       gdk_draw_line (window, middle_nw,
2489                      x + 1, y + half_height,
2490                      x + half_width, y + 1);
2491       gdk_draw_line (window, middle_ne,
2492                      x + half_width, y + 1,
2493                      x + width - 1, y + half_height);
2494       gdk_draw_line (window, outer_nw,
2495                      x, y + half_height,
2496                      x + half_width, y);
2497       gdk_draw_line (window, outer_ne,
2498                      x + half_width, y,
2499                      x + width, y + half_height);
2500     }
2501   
2502   if (area)
2503     {
2504       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2505       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2506       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2507       gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2508     }
2509 }
2510
2511 static void
2512 gtk_default_draw_string (GtkStyle      *style,
2513                          GdkWindow     *window,
2514                          GtkStateType   state_type,
2515                          GdkRectangle  *area,
2516                          GtkWidget     *widget,
2517                          const gchar   *detail,
2518                          gint           x,
2519                          gint           y,
2520                          const gchar   *string)
2521 {
2522   g_return_if_fail (GTK_IS_STYLE (style));
2523   g_return_if_fail (window != NULL);
2524   
2525   if (area)
2526     {
2527       gdk_gc_set_clip_rectangle (style->white_gc, area);
2528       gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
2529     }
2530
2531   if (state_type == GTK_STATE_INSENSITIVE)
2532     gdk_draw_string (window, style->font, style->white_gc, x + 1, y + 1, string);
2533
2534   gdk_draw_string (window, style->font, style->fg_gc[state_type], x, y, string);
2535
2536   if (area)
2537     {
2538       gdk_gc_set_clip_rectangle (style->white_gc, NULL);
2539       gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
2540     }
2541 }
2542
2543 static void 
2544 gtk_default_draw_box (GtkStyle      *style,
2545                       GdkWindow     *window,
2546                       GtkStateType   state_type,
2547                       GtkShadowType  shadow_type,
2548                       GdkRectangle  *area,
2549                       GtkWidget     *widget,
2550                       const gchar   *detail,
2551                       gint           x,
2552                       gint           y,
2553                       gint           width,
2554                       gint           height)
2555 {
2556   g_return_if_fail (GTK_IS_STYLE (style));
2557   g_return_if_fail (window != NULL);
2558   
2559   if (width == -1 && height == -1)
2560     gdk_window_get_size (window, &width, &height);
2561   else if (width == -1)
2562     gdk_window_get_size (window, &width, NULL);
2563   else if (height == -1)
2564     gdk_window_get_size (window, NULL, &height);
2565   
2566   if (!style->bg_pixmap[state_type] || 
2567       GDK_IS_PIXMAP (window))
2568     {
2569       if (area)
2570         gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2571
2572       gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE,
2573                           x, y, width, height);
2574       if (area)
2575         gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2576     }
2577   else
2578     gtk_style_apply_default_background (style, window,
2579                                         widget && !GTK_WIDGET_NO_WINDOW (widget),
2580                                         state_type, area, x, y, width, height);
2581   
2582   gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
2583                     x, y, width, height);
2584 }
2585
2586 static GdkGC*
2587 get_darkened_gc (GdkWindow *window,
2588                  GdkColor  *color,
2589                  gint       darken_count)
2590 {
2591   GdkColor src = *color;
2592   GdkColor shaded;
2593   GdkGC *gc;
2594   
2595   gc = gdk_gc_new (window);
2596
2597   while (darken_count)
2598     {
2599       gtk_style_shade (&src, &shaded, 0.93);
2600       src = shaded;
2601       --darken_count;
2602     }
2603   
2604   gdk_gc_set_rgb_fg_color (gc, &shaded);
2605
2606   return gc;
2607 }
2608
2609 static void 
2610 gtk_default_draw_flat_box (GtkStyle      *style,
2611                            GdkWindow     *window,
2612                            GtkStateType   state_type,
2613                            GtkShadowType  shadow_type,
2614                            GdkRectangle  *area,
2615                            GtkWidget     *widget,
2616                            const gchar   *detail,
2617                            gint           x,
2618                            gint           y,
2619                            gint           width,
2620                            gint           height)
2621 {
2622   GdkGC *gc1;
2623   GdkGC *freeme = NULL;
2624   
2625   g_return_if_fail (GTK_IS_STYLE (style));
2626   g_return_if_fail (window != NULL);
2627   
2628   if (width == -1 && height == -1)
2629     gdk_window_get_size (window, &width, &height);
2630   else if (width == -1)
2631     gdk_window_get_size (window, &width, NULL);
2632   else if (height == -1)
2633     gdk_window_get_size (window, NULL, &height);
2634   
2635   if (detail)
2636     {
2637       if (state_type == GTK_STATE_SELECTED)
2638         {
2639           if (!strcmp ("text", detail))
2640             gc1 = style->bg_gc[GTK_STATE_SELECTED];
2641           else if (!strcmp ("cell_even_sorted", detail) ||
2642                    !strcmp ("cell_odd_sorted", detail) ||
2643                    !strcmp ("cell_even_ruled_sorted", detail) ||
2644                    !strcmp ("cell_odd_ruled_sorted", detail))
2645             {
2646               freeme = get_darkened_gc (window, &style->bg[state_type], 1);
2647               gc1 = freeme;
2648             }
2649           else
2650             {
2651               gc1 = style->bg_gc[state_type];
2652             }
2653         }
2654       else
2655         {
2656           if (!strcmp ("viewportbin", detail))
2657             gc1 = style->bg_gc[GTK_STATE_NORMAL];
2658           else if (!strcmp ("entry_bg", detail))
2659             gc1 = style->base_gc[state_type];
2660
2661           /* For trees: even rows are base color, odd rows are a shade of
2662            * the base color, the sort column is a shade of the original color
2663            * for that row.
2664            */
2665
2666           /* FIXME when we have style properties, clean this up.
2667            */
2668           
2669           else if (!strcmp ("cell_even", detail) ||
2670                    !strcmp ("cell_odd", detail) ||
2671                    !strcmp ("cell_even_ruled", detail))
2672             {
2673               gc1 = style->base_gc[state_type];
2674             }
2675           else if (!strcmp ("cell_even_sorted", detail) ||
2676                    !strcmp ("cell_odd_sorted", detail) ||
2677                    !strcmp ("cell_odd_ruled", detail) ||
2678                    !strcmp ("cell_even_ruled_sorted", detail))
2679             {
2680               freeme = get_darkened_gc (window, &style->base[state_type], 1);
2681               gc1 = freeme;
2682             }
2683           else if (!strcmp ("cell_odd_ruled_sorted", detail))
2684             {
2685               freeme = get_darkened_gc (window, &style->base[state_type], 2);
2686               gc1 = freeme;
2687             }
2688           else
2689             gc1 = style->bg_gc[state_type];
2690         }
2691     }
2692   else
2693     gc1 = style->bg_gc[state_type];
2694   
2695   if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
2696       GDK_IS_PIXMAP (window))
2697     {
2698       if (area)
2699         gdk_gc_set_clip_rectangle (gc1, area);
2700
2701       gdk_draw_rectangle (window, gc1, TRUE,
2702                           x, y, width, height);
2703
2704       if (detail && !strcmp ("tooltip", detail))
2705         gdk_draw_rectangle (window, style->black_gc, FALSE,
2706                             x, y, width - 1, height - 1);
2707
2708       if (area)
2709         gdk_gc_set_clip_rectangle (gc1, NULL);
2710     }
2711   else
2712     gtk_style_apply_default_background (style, window,
2713                                         widget && !GTK_WIDGET_NO_WINDOW (widget),
2714                                         state_type, area, x, y, width, height);
2715
2716
2717   if (freeme)
2718     g_object_unref (G_OBJECT (freeme));
2719 }
2720
2721 static void 
2722 gtk_default_draw_check (GtkStyle      *style,
2723                         GdkWindow     *window,
2724                         GtkStateType   state_type,
2725                         GtkShadowType  shadow_type,
2726                         GdkRectangle  *area,
2727                         GtkWidget     *widget,
2728                         const gchar   *detail,
2729                         gint           x,
2730                         gint           y,
2731                         gint           width,
2732                         gint           height)
2733 {
2734   if (detail && strcmp (detail, "cellcheck") == 0)
2735     {
2736       gdk_draw_rectangle (window,
2737                           widget->style->fg_gc[state_type],
2738                           FALSE,
2739                           x, y,
2740                           width, height);
2741
2742       if (shadow_type == GTK_SHADOW_IN)
2743         {
2744           gdk_draw_line (window,
2745                          widget->style->fg_gc[state_type],
2746                          x, y,
2747                          x + width,
2748                          y + height);
2749           gdk_draw_line (window,
2750                          widget->style->fg_gc[state_type],
2751                          x + width,
2752                          y,
2753                          x,
2754                          y + height);
2755         }
2756     }
2757   else
2758     {
2759       gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
2760                      x, y, width, height);
2761     }
2762 }
2763
2764 static void 
2765 gtk_default_draw_option (GtkStyle      *style,
2766                          GdkWindow     *window,
2767                          GtkStateType   state_type,
2768                          GtkShadowType  shadow_type,
2769                          GdkRectangle  *area,
2770                          GtkWidget     *widget,
2771                          const gchar   *detail,
2772                          gint           x,
2773                          gint           y,
2774                          gint           width,
2775                          gint           height)
2776 {
2777   if (detail && strcmp (detail, "cellradio") == 0)
2778     {
2779       gdk_draw_arc (window,
2780                     widget->style->fg_gc[state_type],
2781                     FALSE,
2782                     x, y,
2783                     width,
2784                     height,
2785                     0, 360*64);
2786
2787       if (shadow_type == GTK_SHADOW_IN)
2788         {
2789           gdk_draw_arc (window,
2790                         widget->style->fg_gc[state_type],
2791                         TRUE,
2792                         x + 2,
2793                         y + 2,
2794                         width - 4,
2795                         height - 4,
2796                         0, 360*64);
2797         }
2798     }
2799   else
2800     {
2801       gtk_paint_diamond (style, window, state_type, shadow_type, area, widget, 
2802                          detail, x, y, width, height);
2803     }
2804 }
2805
2806 static void
2807 gtk_default_draw_tab (GtkStyle      *style,
2808                       GdkWindow     *window,
2809                       GtkStateType   state_type,
2810                       GtkShadowType  shadow_type,
2811                       GdkRectangle  *area,
2812                       GtkWidget     *widget,
2813                       const gchar   *detail,
2814                       gint           x,
2815                       gint           y,
2816                       gint           width,
2817                       gint           height)
2818 {
2819   g_return_if_fail (GTK_IS_STYLE (style));
2820   g_return_if_fail (window != NULL);
2821   
2822   gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
2823                  x, y, width, height);
2824 }
2825
2826 static void 
2827 gtk_default_draw_shadow_gap (GtkStyle       *style,
2828                              GdkWindow      *window,
2829                              GtkStateType    state_type,
2830                              GtkShadowType   shadow_type,
2831                              GdkRectangle   *area,
2832                              GtkWidget      *widget,
2833                              const gchar    *detail,
2834                              gint            x,
2835                              gint            y,
2836                              gint            width,
2837                              gint            height,
2838                              GtkPositionType gap_side,
2839                              gint            gap_x,
2840                              gint            gap_width)
2841 {
2842   GdkGC *gc1 = NULL;
2843   GdkGC *gc2 = NULL;
2844   GdkGC *gc3 = NULL;
2845   GdkGC *gc4 = NULL;
2846   
2847   g_return_if_fail (GTK_IS_STYLE (style));
2848   g_return_if_fail (window != NULL);
2849   
2850   if (width == -1 && height == -1)
2851     gdk_window_get_size (window, &width, &height);
2852   else if (width == -1)
2853     gdk_window_get_size (window, &width, NULL);
2854   else if (height == -1)
2855     gdk_window_get_size (window, NULL, &height);
2856   
2857   switch (shadow_type)
2858     {
2859     case GTK_SHADOW_NONE:
2860       return;
2861     case GTK_SHADOW_IN:
2862       gc1 = style->dark_gc[state_type];
2863       gc2 = style->black_gc;
2864       gc3 = style->bg_gc[state_type];
2865       gc4 = style->light_gc[state_type];
2866       break;
2867     case GTK_SHADOW_ETCHED_IN:
2868       gc1 = style->dark_gc[state_type];
2869       gc2 = style->light_gc[state_type];
2870       gc3 = style->dark_gc[state_type];
2871       gc4 = style->light_gc[state_type];
2872       break;
2873     case GTK_SHADOW_OUT:
2874       gc1 = style->light_gc[state_type];
2875       gc2 = style->bg_gc[state_type];
2876       gc3 = style->dark_gc[state_type];
2877       gc4 = style->black_gc;
2878       break;
2879     case GTK_SHADOW_ETCHED_OUT:
2880       gc1 = style->light_gc[state_type];
2881       gc2 = style->dark_gc[state_type];
2882       gc3 = style->light_gc[state_type];
2883       gc4 = style->dark_gc[state_type];
2884       break;
2885     }
2886   if (area)
2887     {
2888       gdk_gc_set_clip_rectangle (gc1, area);
2889       gdk_gc_set_clip_rectangle (gc2, area);
2890       gdk_gc_set_clip_rectangle (gc3, area);
2891       gdk_gc_set_clip_rectangle (gc4, area);
2892     }
2893   
2894   switch (shadow_type)
2895     {
2896     case GTK_SHADOW_NONE:
2897     case GTK_SHADOW_IN:
2898     case GTK_SHADOW_OUT:
2899     case GTK_SHADOW_ETCHED_IN:
2900     case GTK_SHADOW_ETCHED_OUT:
2901       switch (gap_side)
2902         {
2903         case GTK_POS_TOP:
2904           gdk_draw_line (window, gc1,
2905                          x, y, x, y + height - 1);
2906           gdk_draw_line (window, gc2,
2907                          x + 1, y, x + 1, y + height - 2);
2908           
2909           gdk_draw_line (window, gc3,
2910                          x + 1, y + height - 2, x + width - 2, y + height - 2);
2911           gdk_draw_line (window, gc3,
2912                          x + width - 2, y, x + width - 2, y + height - 2);
2913           gdk_draw_line (window, gc4,
2914                          x, y + height - 1, x + width - 1, y + height - 1);
2915           gdk_draw_line (window, gc4,
2916                          x + width - 1, y, x + width - 1, y + height - 1);
2917           if (gap_x > 0)
2918             {
2919               gdk_draw_line (window, gc1,
2920                              x, y, x + gap_x - 1, y);
2921               gdk_draw_line (window, gc2,
2922                              x + 1, y + 1, x + gap_x - 1, y + 1);
2923               gdk_draw_line (window, gc2,
2924                              x + gap_x, y, x + gap_x, y);
2925             }
2926           if ((width - (gap_x + gap_width)) > 0)
2927             {
2928               gdk_draw_line (window, gc1,
2929                              x + gap_x + gap_width, y, x + width - 2, y);
2930               gdk_draw_line (window, gc2,
2931                              x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
2932               gdk_draw_line (window, gc2,
2933                              x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
2934             }
2935           break;
2936         case GTK_POS_BOTTOM:
2937           gdk_draw_line (window, gc1,
2938                          x, y, x + width - 1, y);
2939           gdk_draw_line (window, gc1,
2940                          x, y, x, y + height - 1);
2941           gdk_draw_line (window, gc2,
2942                          x + 1, y + 1, x + width - 2, y + 1);
2943           gdk_draw_line (window, gc2,
2944                          x + 1, y + 1, x + 1, y + height - 1);
2945           
2946           gdk_draw_line (window, gc3,
2947                          x + width - 2, y + 1, x + width - 2, y + height - 1);
2948           gdk_draw_line (window, gc4,
2949                          x + width - 1, y, x + width - 1, y + height - 1);
2950           if (gap_x > 0)
2951             {
2952               gdk_draw_line (window, gc4,
2953                              x, y + height - 1, x + gap_x - 1, y + height - 1);
2954               gdk_draw_line (window, gc3,
2955                              x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
2956               gdk_draw_line (window, gc3,
2957                              x + gap_x, y + height - 1, x + gap_x, y + height - 1);
2958             }
2959           if ((width - (gap_x + gap_width)) > 0)
2960             {
2961               gdk_draw_line (window, gc4,
2962                              x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
2963               gdk_draw_line (window, gc3,
2964                              x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
2965               gdk_draw_line (window, gc3,
2966                              x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
2967             }
2968           break;
2969         case GTK_POS_LEFT:
2970           gdk_draw_line (window, gc1,
2971                          x, y, x + width - 1, y);
2972           gdk_draw_line (window, gc2,
2973                          x, y + 1, x + width - 2, y + 1);
2974           
2975           gdk_draw_line (window, gc3,
2976                          x, y + height - 2, x + width - 2, y + height - 2);
2977           gdk_draw_line (window, gc3,
2978                          x + width - 2, y + 1, x + width - 2, y + height - 2);
2979           gdk_draw_line (window, gc4,
2980                          x, y + height - 1, x + width - 1, y + height - 1);
2981           gdk_draw_line (window, gc4,
2982                          x + width - 1, y, x + width - 1, y + height - 1);
2983           if (gap_x > 0)
2984             {
2985               gdk_draw_line (window, gc1,
2986                              x, y, x, y + gap_x - 1);
2987               gdk_draw_line (window, gc2,
2988                              x + 1, y + 1, x + 1, y + gap_x - 1);
2989               gdk_draw_line (window, gc2,
2990                              x, y + gap_x, x, y + gap_x);
2991             }
2992           if ((width - (gap_x + gap_width)) > 0)
2993             {
2994               gdk_draw_line (window, gc1,
2995                              x, y + gap_x + gap_width, x, y + height - 2);
2996               gdk_draw_line (window, gc2,
2997                              x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
2998               gdk_draw_line (window, gc2,
2999                              x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3000             }
3001           break;
3002         case GTK_POS_RIGHT:
3003           gdk_draw_line (window, gc1,
3004                          x, y, x + width - 1, y);
3005           gdk_draw_line (window, gc1,
3006                          x, y, x, y + height - 1);
3007           gdk_draw_line (window, gc2,
3008                          x + 1, y + 1, x + width - 1, y + 1);
3009           gdk_draw_line (window, gc2,
3010                          x + 1, y + 1, x + 1, y + height - 2);
3011           
3012           gdk_draw_line (window, gc3,
3013                          x + 1, y + height - 2, x + width - 1, y + height - 2);
3014           gdk_draw_line (window, gc4,
3015                          x, y + height - 1, x + width - 1, y + height - 1);
3016           if (gap_x > 0)
3017             {
3018               gdk_draw_line (window, gc4,
3019                              x + width - 1, y, x + width - 1, y + gap_x - 1);
3020               gdk_draw_line (window, gc3,
3021                              x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3022               gdk_draw_line (window, gc3,
3023                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3024             }
3025           if ((width - (gap_x + gap_width)) > 0)
3026             {
3027               gdk_draw_line (window, gc4,
3028                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3029               gdk_draw_line (window, gc3,
3030                              x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3031               gdk_draw_line (window, gc3,
3032                              x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3033             }
3034           break;
3035         }
3036     }
3037
3038   if (area)
3039     {
3040       gdk_gc_set_clip_rectangle (gc1, NULL);
3041       gdk_gc_set_clip_rectangle (gc2, NULL);
3042       gdk_gc_set_clip_rectangle (gc3, NULL);
3043       gdk_gc_set_clip_rectangle (gc4, NULL);
3044     }
3045 }
3046
3047 static void 
3048 gtk_default_draw_box_gap (GtkStyle       *style,
3049                           GdkWindow      *window,
3050                           GtkStateType    state_type,
3051                           GtkShadowType   shadow_type,
3052                           GdkRectangle   *area,
3053                           GtkWidget      *widget,
3054                           const gchar    *detail,
3055                           gint            x,
3056                           gint            y,
3057                           gint            width,
3058                           gint            height,
3059                           GtkPositionType gap_side,
3060                           gint            gap_x,
3061                           gint            gap_width)
3062 {
3063   GdkGC *gc1 = NULL;
3064   GdkGC *gc2 = NULL;
3065   GdkGC *gc3 = NULL;
3066   GdkGC *gc4 = NULL;
3067   
3068   g_return_if_fail (GTK_IS_STYLE (style));
3069   g_return_if_fail (window != NULL);
3070   
3071   gtk_style_apply_default_background (style, window,
3072                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
3073                                       state_type, area, x, y, width, height);
3074   
3075   if (width == -1 && height == -1)
3076     gdk_window_get_size (window, &width, &height);
3077   else if (width == -1)
3078     gdk_window_get_size (window, &width, NULL);
3079   else if (height == -1)
3080     gdk_window_get_size (window, NULL, &height);
3081   
3082   switch (shadow_type)
3083     {
3084     case GTK_SHADOW_NONE:
3085       return;
3086     case GTK_SHADOW_IN:
3087       gc1 = style->dark_gc[state_type];
3088       gc2 = style->black_gc;
3089       gc3 = style->bg_gc[state_type];
3090       gc4 = style->light_gc[state_type];
3091       break;
3092     case GTK_SHADOW_ETCHED_IN:
3093       gc1 = style->dark_gc[state_type];
3094       gc2 = style->light_gc[state_type];
3095       gc3 = style->dark_gc[state_type];
3096       gc4 = style->light_gc[state_type];
3097       break;
3098     case GTK_SHADOW_OUT:
3099       gc1 = style->light_gc[state_type];
3100       gc2 = style->bg_gc[state_type];
3101       gc3 = style->dark_gc[state_type];
3102       gc4 = style->black_gc;
3103       break;
3104     case GTK_SHADOW_ETCHED_OUT:
3105       gc1 = style->light_gc[state_type];
3106       gc2 = style->dark_gc[state_type];
3107       gc3 = style->light_gc[state_type];
3108       gc4 = style->dark_gc[state_type];
3109       break;
3110     }
3111
3112   if (area)
3113     {
3114       gdk_gc_set_clip_rectangle (gc1, area);
3115       gdk_gc_set_clip_rectangle (gc2, area);
3116       gdk_gc_set_clip_rectangle (gc3, area);
3117       gdk_gc_set_clip_rectangle (gc4, area);
3118     }
3119   
3120   switch (shadow_type)
3121     {
3122     case GTK_SHADOW_NONE:
3123     case GTK_SHADOW_IN:
3124     case GTK_SHADOW_OUT:
3125     case GTK_SHADOW_ETCHED_IN:
3126     case GTK_SHADOW_ETCHED_OUT:
3127       switch (gap_side)
3128         {
3129         case GTK_POS_TOP:
3130           gdk_draw_line (window, gc1,
3131                          x, y, x, y + height - 1);
3132           gdk_draw_line (window, gc2,
3133                          x + 1, y, x + 1, y + height - 2);
3134           
3135           gdk_draw_line (window, gc3,
3136                          x + 1, y + height - 2, x + width - 2, y + height - 2);
3137           gdk_draw_line (window, gc3,
3138                          x + width - 2, y, x + width - 2, y + height - 2);
3139           gdk_draw_line (window, gc4,
3140                          x, y + height - 1, x + width - 1, y + height - 1);
3141           gdk_draw_line (window, gc4,
3142                          x + width - 1, y, x + width - 1, y + height - 1);
3143           if (gap_x > 0)
3144             {
3145               gdk_draw_line (window, gc1,
3146                              x, y, x + gap_x - 1, y);
3147               gdk_draw_line (window, gc2,
3148                              x + 1, y + 1, x + gap_x - 1, y + 1);
3149               gdk_draw_line (window, gc2,
3150                              x + gap_x, y, x + gap_x, y);
3151             }
3152           if ((width - (gap_x + gap_width)) > 0)
3153             {
3154               gdk_draw_line (window, gc1,
3155                              x + gap_x + gap_width, y, x + width - 2, y);
3156               gdk_draw_line (window, gc2,
3157                              x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3158               gdk_draw_line (window, gc2,
3159                              x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3160             }
3161           break;
3162         case  GTK_POS_BOTTOM:
3163           gdk_draw_line (window, gc1,
3164                          x, y, x + width - 1, y);
3165           gdk_draw_line (window, gc1,
3166                          x, y, x, y + height - 1);
3167           gdk_draw_line (window, gc2,
3168                          x + 1, y + 1, x + width - 2, y + 1);
3169           gdk_draw_line (window, gc2,
3170                          x + 1, y + 1, x + 1, y + height - 1);
3171           
3172           gdk_draw_line (window, gc3,
3173                          x + width - 2, y + 1, x + width - 2, y + height - 1);
3174           gdk_draw_line (window, gc4,
3175                          x + width - 1, y, x + width - 1, y + height - 1);
3176           if (gap_x > 0)
3177             {
3178               gdk_draw_line (window, gc4,
3179                              x, y + height - 1, x + gap_x - 1, y + height - 1);
3180               gdk_draw_line (window, gc3,
3181                              x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3182               gdk_draw_line (window, gc3,
3183                              x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3184             }
3185           if ((width - (gap_x + gap_width)) > 0)
3186             {
3187               gdk_draw_line (window, gc4,
3188                              x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3189               gdk_draw_line (window, gc3,
3190                              x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3191               gdk_draw_line (window, gc3,
3192                              x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3193             }
3194           break;
3195         case GTK_POS_LEFT:
3196           gdk_draw_line (window, gc1,
3197                          x, y, x + width - 1, y);
3198           gdk_draw_line (window, gc2,
3199                          x, y + 1, x + width - 2, y + 1);
3200           
3201           gdk_draw_line (window, gc3,
3202                          x, y + height - 2, x + width - 2, y + height - 2);
3203           gdk_draw_line (window, gc3,
3204                          x + width - 2, y + 1, x + width - 2, y + height - 2);
3205           gdk_draw_line (window, gc4,
3206                          x, y + height - 1, x + width - 1, y + height - 1);
3207           gdk_draw_line (window, gc4,
3208                          x + width - 1, y, x + width - 1, y + height - 1);
3209           if (gap_x > 0)
3210             {
3211               gdk_draw_line (window, gc1,
3212                              x, y, x, y + gap_x - 1);
3213               gdk_draw_line (window, gc2,
3214                              x + 1, y + 1, x + 1, y + gap_x - 1);
3215               gdk_draw_line (window, gc2,
3216                              x, y + gap_x, x, y + gap_x);
3217             }
3218           if ((width - (gap_x + gap_width)) > 0)
3219             {
3220               gdk_draw_line (window, gc1,
3221                              x, y + gap_x + gap_width, x, y + height - 2);
3222               gdk_draw_line (window, gc2,
3223                              x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3224               gdk_draw_line (window, gc2,
3225                              x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3226             }
3227           break;
3228         case GTK_POS_RIGHT:
3229           gdk_draw_line (window, gc1,
3230                          x, y, x + width - 1, y);
3231           gdk_draw_line (window, gc1,
3232                          x, y, x, y + height - 1);
3233           gdk_draw_line (window, gc2,
3234                          x + 1, y + 1, x + width - 1, y + 1);
3235           gdk_draw_line (window, gc2,
3236                          x + 1, y + 1, x + 1, y + height - 2);
3237           
3238           gdk_draw_line (window, gc3,
3239                          x + 1, y + height - 2, x + width - 1, y + height - 2);
3240           gdk_draw_line (window, gc4,
3241                          x, y + height - 1, x + width - 1, y + height - 1);
3242           if (gap_x > 0)
3243             {
3244               gdk_draw_line (window, gc4,
3245                              x + width - 1, y, x + width - 1, y + gap_x - 1);
3246               gdk_draw_line (window, gc3,
3247                              x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3248               gdk_draw_line (window, gc3,
3249                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3250             }
3251           if ((width - (gap_x + gap_width)) > 0)
3252             {
3253               gdk_draw_line (window, gc4,
3254                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3255               gdk_draw_line (window, gc3,
3256                              x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3257               gdk_draw_line (window, gc3,
3258                              x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3259             }
3260           break;
3261         }
3262     }
3263
3264   if (area)
3265     {
3266       gdk_gc_set_clip_rectangle (gc1, NULL);
3267       gdk_gc_set_clip_rectangle (gc2, NULL);
3268       gdk_gc_set_clip_rectangle (gc3, NULL);
3269       gdk_gc_set_clip_rectangle (gc4, NULL);
3270     }
3271 }
3272
3273 static void 
3274 gtk_default_draw_extension (GtkStyle       *style,
3275                             GdkWindow      *window,
3276                             GtkStateType    state_type,
3277                             GtkShadowType   shadow_type,
3278                             GdkRectangle   *area,
3279                             GtkWidget      *widget,
3280                             const gchar    *detail,
3281                             gint            x,
3282                             gint            y,
3283                             gint            width,
3284                             gint            height,
3285                             GtkPositionType gap_side)
3286 {
3287   GdkGC *gc1 = NULL;
3288   GdkGC *gc2 = NULL;
3289   GdkGC *gc3 = NULL;
3290   GdkGC *gc4 = NULL;
3291   
3292   g_return_if_fail (GTK_IS_STYLE (style));
3293   g_return_if_fail (window != NULL);
3294   
3295   gtk_style_apply_default_background (style, window,
3296                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
3297                                       GTK_STATE_NORMAL, area, x, y, width, height);
3298   
3299   if (width == -1 && height == -1)
3300     gdk_window_get_size (window, &width, &height);
3301   else if (width == -1)
3302     gdk_window_get_size (window, &width, NULL);
3303   else if (height == -1)
3304     gdk_window_get_size (window, NULL, &height);
3305   
3306   switch (shadow_type)
3307     {
3308     case GTK_SHADOW_NONE:
3309       return;
3310     case GTK_SHADOW_IN:
3311       gc1 = style->dark_gc[state_type];
3312       gc2 = style->black_gc;
3313       gc3 = style->bg_gc[state_type];
3314       gc4 = style->light_gc[state_type];
3315       break;
3316     case GTK_SHADOW_ETCHED_IN:
3317       gc1 = style->dark_gc[state_type];
3318       gc2 = style->light_gc[state_type];
3319       gc3 = style->dark_gc[state_type];
3320       gc4 = style->light_gc[state_type];
3321       break;
3322     case GTK_SHADOW_OUT:
3323       gc1 = style->light_gc[state_type];
3324       gc2 = style->bg_gc[state_type];
3325       gc3 = style->dark_gc[state_type];
3326       gc4 = style->black_gc;
3327       break;
3328     case GTK_SHADOW_ETCHED_OUT:
3329       gc1 = style->light_gc[state_type];
3330       gc2 = style->dark_gc[state_type];
3331       gc3 = style->light_gc[state_type];
3332       gc4 = style->dark_gc[state_type];
3333       break;
3334     }
3335
3336   if (area)
3337     {
3338       gdk_gc_set_clip_rectangle (gc1, area);
3339       gdk_gc_set_clip_rectangle (gc2, area);
3340       gdk_gc_set_clip_rectangle (gc3, area);
3341       gdk_gc_set_clip_rectangle (gc4, area);
3342     }
3343
3344   switch (shadow_type)
3345     {
3346     case GTK_SHADOW_NONE:
3347     case GTK_SHADOW_IN:
3348     case GTK_SHADOW_OUT:
3349     case GTK_SHADOW_ETCHED_IN:
3350     case GTK_SHADOW_ETCHED_OUT:
3351       switch (gap_side)
3352         {
3353         case GTK_POS_TOP:
3354           gtk_style_apply_default_background (style, window,
3355                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3356                                               state_type, area,
3357                                               x + style->xthickness, 
3358                                               y, 
3359                                               width - (2 * style->xthickness), 
3360                                               height - (style->ythickness));
3361           gdk_draw_line (window, gc1,
3362                          x, y, x, y + height - 2);
3363           gdk_draw_line (window, gc2,
3364                          x + 1, y, x + 1, y + height - 2);
3365           
3366           gdk_draw_line (window, gc3,
3367                          x + 2, y + height - 2, x + width - 2, y + height - 2);
3368           gdk_draw_line (window, gc3,
3369                          x + width - 2, y, x + width - 2, y + height - 2);
3370           gdk_draw_line (window, gc4,
3371                          x + 1, y + height - 1, x + width - 2, y + height - 1);
3372           gdk_draw_line (window, gc4,
3373                          x + width - 1, y, x + width - 1, y + height - 2);
3374           break;
3375         case GTK_POS_BOTTOM:
3376           gtk_style_apply_default_background (style, window,
3377                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3378                                               state_type, area,
3379                                               x + style->xthickness, 
3380                                               y + style->ythickness, 
3381                                               width - (2 * style->xthickness), 
3382                                               height - (style->ythickness));
3383           gdk_draw_line (window, gc1,
3384                          x + 1, y, x + width - 2, y);
3385           gdk_draw_line (window, gc1,
3386                          x, y + 1, x, y + height - 1);
3387           gdk_draw_line (window, gc2,
3388                          x + 1, y + 1, x + width - 2, y + 1);
3389           gdk_draw_line (window, gc2,
3390                          x + 1, y + 1, x + 1, y + height - 1);
3391           
3392           gdk_draw_line (window, gc3,
3393                          x + width - 2, y + 2, x + width - 2, y + height - 1);
3394           gdk_draw_line (window, gc4,
3395                          x + width - 1, y + 1, x + width - 1, y + height - 1);
3396           break;
3397         case GTK_POS_LEFT:
3398           gtk_style_apply_default_background (style, window,
3399                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3400                                               state_type, area,
3401                                               x, 
3402                                               y + style->ythickness, 
3403                                               width - (style->xthickness), 
3404                                               height - (2 * style->ythickness));
3405           gdk_draw_line (window, gc1,
3406                          x, y, x + width - 2, y);
3407           gdk_draw_line (window, gc2,
3408                          x + 1, y + 1, x + width - 2, y + 1);
3409           
3410           gdk_draw_line (window, gc3,
3411                          x, y + height - 2, x + width - 2, y + height - 2);
3412           gdk_draw_line (window, gc3,
3413                          x + width - 2, y + 2, x + width - 2, y + height - 2);
3414           gdk_draw_line (window, gc4,
3415                          x, y + height - 1, x + width - 2, y + height - 1);
3416           gdk_draw_line (window, gc4,
3417                          x + width - 1, y + 1, x + width - 1, y + height - 2);
3418           break;
3419         case GTK_POS_RIGHT:
3420           gtk_style_apply_default_background (style, window,
3421                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3422                                               state_type, area,
3423                                               x + style->xthickness, 
3424                                               y + style->ythickness, 
3425                                               width - (style->xthickness), 
3426                                               height - (2 * style->ythickness));
3427           gdk_draw_line (window, gc1,
3428                          x + 1, y, x + width - 1, y);
3429           gdk_draw_line (window, gc1,
3430                          x, y + 1, x, y + height - 2);
3431           gdk_draw_line (window, gc2,
3432                          x + 1, y + 1, x + width - 1, y + 1);
3433           gdk_draw_line (window, gc2,
3434                          x + 1, y + 1, x + 1, y + height - 2);
3435           
3436           gdk_draw_line (window, gc3,
3437                          x + 2, y + height - 2, x + width - 1, y + height - 2);
3438           gdk_draw_line (window, gc4,
3439                          x + 1, y + height - 1, x + width - 1, y + height - 1);
3440           break;
3441         }
3442     }
3443
3444   if (area)
3445     {
3446       gdk_gc_set_clip_rectangle (gc1, NULL);
3447       gdk_gc_set_clip_rectangle (gc2, NULL);
3448       gdk_gc_set_clip_rectangle (gc3, NULL);
3449       gdk_gc_set_clip_rectangle (gc4, NULL);
3450     }
3451 }
3452
3453 static void 
3454 gtk_default_draw_focus (GtkStyle      *style,
3455                         GdkWindow     *window,
3456                         GdkRectangle  *area,
3457                         GtkWidget     *widget,
3458                         const gchar   *detail,
3459                         gint           x,
3460                         gint           y,
3461                         gint           width,
3462                         gint           height)
3463 {
3464   g_return_if_fail (GTK_IS_STYLE (style));
3465   g_return_if_fail (window != NULL);
3466   
3467   if (width == -1 && height == -1)
3468     {
3469       gdk_window_get_size (window, &width, &height);
3470       width -= 1;
3471       height -= 1;
3472     }
3473   else if (width == -1)
3474     {
3475       gdk_window_get_size (window, &width, NULL);
3476       width -= 1;
3477     }
3478   else if (height == -1)
3479     {
3480       gdk_window_get_size (window, NULL, &height);
3481       height -= 1;
3482     }
3483
3484   if (area)
3485     gdk_gc_set_clip_rectangle (style->black_gc, area);
3486
3487   if (detail && !strcmp (detail, "add-mode"))
3488     {
3489       gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
3490       gdk_gc_set_dashes (style->black_gc, 0, "\4\4", 2);
3491       
3492       gdk_draw_rectangle (window,
3493                           style->black_gc, FALSE,
3494                           x, y, width, height);
3495       
3496       gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_SOLID, 0, 0);
3497     }
3498   else if (detail && strcmp (detail, "treeview") == 0)
3499     {
3500       
3501       gdk_gc_set_background (style->black_gc, &style->white);
3502       gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_DOUBLE_DASH, 0, 0);
3503       gdk_gc_set_dashes (style->black_gc, 0, "\4\4", 2);
3504       
3505       gdk_draw_rectangle (window,
3506                           style->black_gc, FALSE,
3507                           x, y, width, height);
3508       
3509       gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_SOLID, 0, 0);
3510     }
3511   else
3512     {
3513       gdk_draw_rectangle (window,
3514                           style->black_gc, FALSE,
3515                           x, y, width, height);
3516     }
3517
3518   if (area)
3519     gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3520 }
3521
3522 static void 
3523 gtk_default_draw_slider (GtkStyle      *style,
3524                          GdkWindow     *window,
3525                          GtkStateType   state_type,
3526                          GtkShadowType  shadow_type,
3527                          GdkRectangle  *area,
3528                          GtkWidget     *widget,
3529                          const gchar   *detail,
3530                          gint           x,
3531                          gint           y,
3532                          gint           width,
3533                          gint           height,
3534                          GtkOrientation orientation)
3535 {
3536   g_return_if_fail (GTK_IS_STYLE (style));
3537   g_return_if_fail (window != NULL);
3538   
3539   if (width == -1 && height == -1)
3540     gdk_window_get_size (window, &width, &height);
3541   else if (width == -1)
3542     gdk_window_get_size (window, &width, NULL);
3543   else if (height == -1)
3544     gdk_window_get_size (window, NULL, &height);
3545   
3546   gtk_paint_box (style, window, state_type, shadow_type,
3547                  area, widget, detail, x, y, width, height);
3548
3549   if (orientation == GTK_ORIENTATION_HORIZONTAL)
3550     gtk_paint_vline (style, window, state_type, area, widget, detail, 
3551                      style->ythickness, 
3552                      height - style->ythickness - 1, width / 2);
3553   else
3554     gtk_paint_hline (style, window, state_type, area, widget, detail, 
3555                      style->xthickness, 
3556                      width - style->xthickness - 1, height / 2);
3557 }
3558
3559 static void
3560 draw_dot (GdkWindow    *window,
3561           GdkGC        *light_gc,
3562           GdkGC        *dark_gc,
3563           gint          x,
3564           gint          y,
3565           gushort       size)
3566 {
3567   
3568   size = CLAMP (size, 2, 3);
3569
3570   if (size == 2)
3571     {
3572       gdk_draw_point (window, light_gc, x, y);
3573       gdk_draw_point (window, light_gc, x+1, y+1);
3574     }
3575   else if (size == 3);
3576     {
3577       gdk_draw_point (window, light_gc, x, y);
3578       gdk_draw_point (window, light_gc, x+1, y);
3579       gdk_draw_point (window, light_gc, x, y+1);
3580       gdk_draw_point (window, dark_gc, x+1, y+2);
3581       gdk_draw_point (window, dark_gc, x+2, y+1);
3582       gdk_draw_point (window, dark_gc, x+2, y+2);
3583     }
3584 }
3585
3586 static void 
3587 gtk_default_draw_handle (GtkStyle      *style,
3588                          GdkWindow     *window,
3589                          GtkStateType   state_type,
3590                          GtkShadowType  shadow_type,
3591                          GdkRectangle  *area,
3592                          GtkWidget     *widget,
3593                          const gchar   *detail,
3594                          gint           x,
3595                          gint           y,
3596                          gint           width,
3597                          gint           height,
3598                          GtkOrientation orientation)
3599 {
3600   gint xx, yy;
3601   gint xthick, ythick;
3602   GdkGC *light_gc, *dark_gc;
3603   GdkRectangle rect;
3604   GdkRectangle dest;
3605   gint intersect;
3606   
3607   g_return_if_fail (GTK_IS_STYLE (style));
3608   g_return_if_fail (window != NULL);
3609   
3610   if (width == -1 && height == -1)
3611     gdk_window_get_size (window, &width, &height);
3612   else if (width == -1)
3613     gdk_window_get_size (window, &width, NULL);
3614   else if (height == -1)
3615     gdk_window_get_size (window, NULL, &height);
3616   
3617   gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
3618                  detail, x, y, width, height);
3619   
3620   
3621   if (!strcmp (detail, "paned"))
3622     {
3623       /* we want to ignore the shadow border in paned widgets */
3624       xthick = 0;
3625       ythick = 0;
3626
3627       light_gc = style->light_gc[state_type];
3628       dark_gc = style->black_gc;
3629     }
3630   else
3631     {
3632       xthick = style->xthickness;
3633       ythick = style->ythickness;
3634
3635       light_gc = style->light_gc[state_type];
3636       dark_gc = style->dark_gc[state_type];
3637     }
3638   
3639   rect.x = x + xthick;
3640   rect.y = y + ythick;
3641   rect.width = width - (xthick * 2);
3642   rect.height = height - (ythick * 2);
3643
3644   if (area)
3645       intersect = gdk_rectangle_intersect (area, &rect, &dest);
3646   else
3647     {
3648       intersect = TRUE;
3649       dest = rect;
3650     }
3651
3652   if (!intersect)
3653     return;
3654
3655   gdk_gc_set_clip_rectangle (light_gc, &dest);
3656   gdk_gc_set_clip_rectangle (dark_gc, &dest);
3657
3658   if (!strcmp (detail, "paned"))
3659     {
3660       gint window_width;
3661       gint window_height;
3662
3663       gdk_window_get_size (window, &window_width, &window_height);
3664
3665       if (orientation == GTK_ORIENTATION_HORIZONTAL)
3666         for (xx = window_width/2 - 15; xx <= window_width/2 + 15; xx += 5)
3667           draw_dot (window, light_gc, dark_gc, xx, window_height/2 - 1, 3);
3668       else
3669         for (yy = window_height/2 - 15; yy <= window_height/2 + 15; yy += 5)
3670           draw_dot (window, light_gc, dark_gc, window_width/2 - 1, yy, 3);
3671     }
3672   else
3673     {
3674       for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3675         for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3676           {
3677             draw_dot (window, light_gc, dark_gc, xx, yy, 2);
3678             draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
3679           }
3680     }
3681
3682   gdk_gc_set_clip_rectangle (light_gc, NULL);
3683   gdk_gc_set_clip_rectangle (dark_gc, NULL);
3684 }
3685
3686 static void
3687 gtk_default_draw_expander (GtkStyle        *style,
3688                            GdkWindow       *window,
3689                            GtkStateType     state_type,
3690                            GdkRectangle    *area,
3691                            GtkWidget       *widget,
3692                            const gchar     *detail,
3693                            gint             x,
3694                            gint             y,
3695                            gboolean         is_open)
3696 {
3697   /* FIXME replace macro with a style property */
3698 #define PM_SIZE 8
3699   
3700   GdkPoint points[3];
3701
3702   if (area)
3703     {
3704       gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
3705       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
3706     }
3707
3708   if (is_open)
3709     {
3710       points[0].x = x;
3711       points[0].y = y + (PM_SIZE + 2) / 6;
3712       points[1].x = points[0].x + 1 * (PM_SIZE + 2);
3713       points[1].y = points[0].y;
3714       points[2].x = (points[0].x + 1 * (PM_SIZE + 2) / 2);
3715       points[2].y = y + 2 * (PM_SIZE + 2) / 3;
3716     }
3717   else
3718     {
3719       points[0].x = x + 1 * ((PM_SIZE + 2) / 6 + 2);
3720       points[0].y = y - 1;
3721       points[1].x = points[0].x;
3722       points[1].y = points[0].y + (PM_SIZE + 2);
3723       points[2].x = (points[0].x + 1 * (2 * (PM_SIZE + 2) / 3 - 1));
3724       points[2].y = points[0].y + (PM_SIZE + 2) / 2;
3725     }
3726
3727   gdk_draw_polygon (window, style->base_gc[GTK_STATE_NORMAL],
3728                     TRUE, points, 3);
3729   gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
3730                     FALSE, points, 3);
3731   
3732
3733   if (area)
3734     {
3735       gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
3736       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
3737     }
3738   
3739 #undef PM_SIZE
3740 }
3741
3742 typedef struct _ByteRange ByteRange;
3743
3744 struct _ByteRange
3745 {
3746   guint start;
3747   guint end;
3748 };
3749
3750 static ByteRange*
3751 range_new (guint start,
3752            guint end)
3753 {
3754   ByteRange *br = g_new (ByteRange, 1);
3755
3756   br->start = start;
3757   br->end = end;
3758   
3759   return br;
3760 }
3761
3762 static PangoLayout*
3763 get_insensitive_layout (PangoLayout *layout)
3764 {
3765   GSList *embossed_ranges = NULL;
3766   GSList *stippled_ranges = NULL;
3767   PangoLayoutIter *iter;
3768   GSList *tmp_list = NULL;
3769   PangoLayout *new_layout;
3770   PangoAttrList *attrs;
3771   GdkBitmap *stipple = NULL;
3772   
3773   iter = pango_layout_get_iter (layout);
3774   
3775   do
3776     {
3777       PangoLayoutRun *run;
3778       PangoAttribute *attr;
3779       gboolean need_stipple = FALSE;
3780       ByteRange *br;
3781       
3782       run = pango_layout_iter_get_run (iter);
3783
3784       if (run)
3785         {
3786           tmp_list = run->item->extra_attrs;
3787
3788           while (tmp_list != NULL)
3789             {
3790               attr = tmp_list->data;
3791               switch (attr->klass->type)
3792                 {
3793                 case PANGO_ATTR_FOREGROUND:
3794                 case PANGO_ATTR_BACKGROUND:
3795                   need_stipple = TRUE;
3796                   break;
3797               
3798                 default:
3799                   break;
3800                 }
3801
3802               if (need_stipple)
3803                 break;
3804           
3805               tmp_list = g_slist_next (tmp_list);
3806             }
3807
3808           br = range_new (run->item->offset, run->item->offset + run->item->length);
3809       
3810           if (need_stipple)
3811             stippled_ranges = g_slist_prepend (stippled_ranges, br);
3812           else
3813             embossed_ranges = g_slist_prepend (embossed_ranges, br);
3814         }
3815     }
3816   while (pango_layout_iter_next_run (iter));
3817
3818   pango_layout_iter_free (iter);
3819
3820   new_layout = pango_layout_copy (layout);
3821
3822   attrs = pango_layout_get_attributes (new_layout);
3823
3824   if (attrs == NULL)
3825     {
3826       /* Create attr list if there wasn't one */
3827       attrs = pango_attr_list_new ();
3828       pango_layout_set_attributes (new_layout, attrs);
3829       pango_attr_list_unref (attrs);
3830     }
3831   
3832   tmp_list = embossed_ranges;
3833   while (tmp_list != NULL)
3834     {
3835       PangoAttribute *attr;
3836       ByteRange *br = tmp_list->data;
3837
3838       attr = gdk_pango_attr_embossed_new (TRUE);
3839
3840       attr->start_index = br->start;
3841       attr->end_index = br->end;
3842       
3843       pango_attr_list_change (attrs, attr);
3844
3845       g_free (br);
3846       
3847       tmp_list = g_slist_next (tmp_list);
3848     }
3849
3850   g_slist_free (embossed_ranges);
3851   
3852   tmp_list = stippled_ranges;
3853   while (tmp_list != NULL)
3854     {
3855       PangoAttribute *attr;
3856       ByteRange *br = tmp_list->data;
3857
3858       if (stipple == NULL)
3859         {
3860 #define gray50_width 2
3861 #define gray50_height 2
3862           static char gray50_bits[] = {
3863             0x02, 0x01
3864           };
3865
3866           stipple = gdk_bitmap_create_from_data (NULL,
3867                                                  gray50_bits, gray50_width,
3868                                                  gray50_height);
3869         }
3870       
3871       attr = gdk_pango_attr_stipple_new (stipple);
3872
3873       attr->start_index = br->start;
3874       attr->end_index = br->end;
3875       
3876       pango_attr_list_change (attrs, attr);
3877
3878       g_free (br);
3879       
3880       tmp_list = g_slist_next (tmp_list);
3881     }
3882
3883   g_slist_free (stippled_ranges);
3884   
3885   if (stipple)
3886     g_object_unref (G_OBJECT (stipple));
3887
3888   return new_layout;
3889 }
3890
3891 static void
3892 gtk_default_draw_layout (GtkStyle        *style,
3893                          GdkWindow       *window,
3894                          GtkStateType     state_type,
3895                          GdkRectangle    *area,
3896                          GtkWidget       *widget,
3897                          const gchar     *detail,
3898                          gint             x,
3899                          gint             y,
3900                          PangoLayout     *layout)
3901 {
3902   g_return_if_fail (GTK_IS_STYLE (style));
3903   g_return_if_fail (window != NULL);
3904   
3905   if (area)
3906     gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3907
3908   if (state_type == GTK_STATE_INSENSITIVE)
3909     {
3910       PangoLayout *ins;
3911
3912       ins = get_insensitive_layout (layout);
3913       
3914       gdk_draw_layout (window, style->fg_gc[state_type], x, y, ins);
3915
3916       g_object_unref (G_OBJECT (ins));
3917     }
3918   else
3919     {
3920       gdk_draw_layout (window, style->fg_gc[state_type], x, y, layout);
3921     }
3922
3923   if (area)
3924     gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3925 }
3926
3927 static void
3928 gtk_style_shade (GdkColor *a,
3929                  GdkColor *b,
3930                  gdouble   k)
3931 {
3932   gdouble red;
3933   gdouble green;
3934   gdouble blue;
3935   
3936   red = (gdouble) a->red / 65535.0;
3937   green = (gdouble) a->green / 65535.0;
3938   blue = (gdouble) a->blue / 65535.0;
3939   
3940   rgb_to_hls (&red, &green, &blue);
3941   
3942   green *= k;
3943   if (green > 1.0)
3944     green = 1.0;
3945   else if (green < 0.0)
3946     green = 0.0;
3947   
3948   blue *= k;
3949   if (blue > 1.0)
3950     blue = 1.0;
3951   else if (blue < 0.0)
3952     blue = 0.0;
3953   
3954   hls_to_rgb (&red, &green, &blue);
3955   
3956   b->red = red * 65535.0;
3957   b->green = green * 65535.0;
3958   b->blue = blue * 65535.0;
3959 }
3960
3961 static void
3962 rgb_to_hls (gdouble *r,
3963             gdouble *g,
3964             gdouble *b)
3965 {
3966   gdouble min;
3967   gdouble max;
3968   gdouble red;
3969   gdouble green;
3970   gdouble blue;
3971   gdouble h, l, s;
3972   gdouble delta;
3973   
3974   red = *r;
3975   green = *g;
3976   blue = *b;
3977   
3978   if (red > green)
3979     {
3980       if (red > blue)
3981         max = red;
3982       else
3983         max = blue;
3984       
3985       if (green < blue)
3986         min = green;
3987       else
3988         min = blue;
3989     }
3990   else
3991     {
3992       if (green > blue)
3993         max = green;
3994       else
3995         max = blue;
3996       
3997       if (red < blue)
3998         min = red;
3999       else
4000         min = blue;
4001     }
4002   
4003   l = (max + min) / 2;
4004   s = 0;
4005   h = 0;
4006   
4007   if (max != min)
4008     {
4009       if (l <= 0.5)
4010         s = (max - min) / (max + min);
4011       else
4012         s = (max - min) / (2 - max - min);
4013       
4014       delta = max -min;
4015       if (red == max)
4016         h = (green - blue) / delta;
4017       else if (green == max)
4018         h = 2 + (blue - red) / delta;
4019       else if (blue == max)
4020         h = 4 + (red - green) / delta;
4021       
4022       h *= 60;
4023       if (h < 0.0)
4024         h += 360;
4025     }
4026   
4027   *r = h;
4028   *g = l;
4029   *b = s;
4030 }
4031
4032 static void
4033 hls_to_rgb (gdouble *h,
4034             gdouble *l,
4035             gdouble *s)
4036 {
4037   gdouble hue;
4038   gdouble lightness;
4039   gdouble saturation;
4040   gdouble m1, m2;
4041   gdouble r, g, b;
4042   
4043   lightness = *l;
4044   saturation = *s;
4045   
4046   if (lightness <= 0.5)
4047     m2 = lightness * (1 + saturation);
4048   else
4049     m2 = lightness + saturation - lightness * saturation;
4050   m1 = 2 * lightness - m2;
4051   
4052   if (saturation == 0)
4053     {
4054       *h = lightness;
4055       *l = lightness;
4056       *s = lightness;
4057     }
4058   else
4059     {
4060       hue = *h + 120;
4061       while (hue > 360)
4062         hue -= 360;
4063       while (hue < 0)
4064         hue += 360;
4065       
4066       if (hue < 60)
4067         r = m1 + (m2 - m1) * hue / 60;
4068       else if (hue < 180)
4069         r = m2;
4070       else if (hue < 240)
4071         r = m1 + (m2 - m1) * (240 - hue) / 60;
4072       else
4073         r = m1;
4074       
4075       hue = *h;
4076       while (hue > 360)
4077         hue -= 360;
4078       while (hue < 0)
4079         hue += 360;
4080       
4081       if (hue < 60)
4082         g = m1 + (m2 - m1) * hue / 60;
4083       else if (hue < 180)
4084         g = m2;
4085       else if (hue < 240)
4086         g = m1 + (m2 - m1) * (240 - hue) / 60;
4087       else
4088         g = m1;
4089       
4090       hue = *h - 120;
4091       while (hue > 360)
4092         hue -= 360;
4093       while (hue < 0)
4094         hue += 360;
4095       
4096       if (hue < 60)
4097         b = m1 + (m2 - m1) * hue / 60;
4098       else if (hue < 180)
4099         b = m2;
4100       else if (hue < 240)
4101         b = m1 + (m2 - m1) * (240 - hue) / 60;
4102       else
4103         b = m1;
4104       
4105       *h = r;
4106       *l = g;
4107       *s = b;
4108     }
4109 }
4110
4111 void 
4112 gtk_paint_hline (GtkStyle      *style,
4113                  GdkWindow     *window,
4114                  GtkStateType   state_type,
4115                  GdkRectangle  *area,
4116                  GtkWidget     *widget,
4117                  const gchar   *detail,
4118                  gint          x1,
4119                  gint          x2,
4120                  gint          y)
4121 {
4122   g_return_if_fail (GTK_IS_STYLE (style));
4123   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4124   
4125   GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
4126 }
4127
4128 void
4129 gtk_paint_vline (GtkStyle      *style,
4130                  GdkWindow     *window,
4131                  GtkStateType   state_type,
4132                  GdkRectangle  *area,
4133                  GtkWidget     *widget,
4134                  const gchar   *detail,
4135                  gint          y1,
4136                  gint          y2,
4137                  gint          x)
4138 {
4139   g_return_if_fail (GTK_IS_STYLE (style));
4140   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4141   
4142   GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1, y2, x);
4143 }
4144
4145 void
4146 gtk_paint_shadow (GtkStyle     *style,
4147                   GdkWindow    *window,
4148                   GtkStateType  state_type,
4149                   GtkShadowType shadow_type,
4150                   GdkRectangle *area,
4151                   GtkWidget    *widget,
4152                   const gchar  *detail,
4153                   gint          x,
4154                   gint          y,
4155                   gint          width,
4156                   gint          height)
4157 {
4158   g_return_if_fail (GTK_IS_STYLE (style));
4159   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4160   
4161   GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4162 }
4163
4164 void
4165 gtk_paint_polygon (GtkStyle      *style,
4166                    GdkWindow     *window,
4167                    GtkStateType   state_type,
4168                    GtkShadowType  shadow_type,
4169                    GdkRectangle  *area,
4170                    GtkWidget     *widget,
4171                    const gchar   *detail,
4172                    GdkPoint      *points,
4173                    gint           npoints,
4174                    gboolean       fill)
4175 {
4176   g_return_if_fail (GTK_IS_STYLE (style));
4177   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4178   
4179   GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
4180 }
4181
4182 void
4183 gtk_paint_arrow (GtkStyle      *style,
4184                  GdkWindow     *window,
4185                  GtkStateType   state_type,
4186                  GtkShadowType  shadow_type,
4187                  GdkRectangle  *area,
4188                  GtkWidget     *widget,
4189                  const gchar   *detail,
4190                  GtkArrowType   arrow_type,
4191                  gboolean       fill,
4192                  gint           x,
4193                  gint           y,
4194                  gint           width,
4195                  gint           height)
4196 {
4197   g_return_if_fail (GTK_IS_STYLE (style));
4198   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4199   
4200   GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
4201 }
4202
4203 void
4204 gtk_paint_diamond (GtkStyle      *style,
4205                    GdkWindow     *window,
4206                    GtkStateType   state_type,
4207                    GtkShadowType  shadow_type,
4208                    GdkRectangle  *area,
4209                    GtkWidget     *widget,
4210                    const gchar   *detail,
4211                    gint        x,
4212                    gint        y,
4213                    gint        width,
4214                    gint        height)
4215 {
4216   g_return_if_fail (GTK_IS_STYLE (style));
4217   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4218   
4219   GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4220 }
4221
4222 void
4223 gtk_paint_string (GtkStyle      *style,
4224                   GdkWindow     *window,
4225                   GtkStateType   state_type,
4226                   GdkRectangle  *area,
4227                   GtkWidget     *widget,
4228                   const gchar   *detail,
4229                   gint           x,
4230                   gint           y,
4231                   const gchar   *string)
4232 {
4233   g_return_if_fail (GTK_IS_STYLE (style));
4234   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
4235   
4236   GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
4237 }
4238
4239 void
4240 gtk_paint_box (GtkStyle      *style,
4241                GdkWindow     *window,
4242                GtkStateType   state_type,
4243                GtkShadowType  shadow_type,
4244                GdkRectangle  *area,
4245                GtkWidget     *widget,
4246                const gchar   *detail,
4247                gint           x,
4248                gint           y,
4249                gint           width,
4250                gint           height)
4251 {
4252   g_return_if_fail (GTK_IS_STYLE (style));
4253   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
4254   
4255   GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4256 }
4257
4258 void
4259 gtk_paint_flat_box (GtkStyle      *style,
4260                     GdkWindow     *window,
4261                     GtkStateType   state_type,
4262                     GtkShadowType  shadow_type,
4263                     GdkRectangle  *area,
4264                     GtkWidget     *widget,
4265                     const gchar   *detail,
4266                     gint           x,
4267                     gint           y,
4268                     gint           width,
4269                     gint           height)
4270 {
4271   g_return_if_fail (GTK_IS_STYLE (style));
4272   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
4273   
4274   GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4275 }
4276
4277 void
4278 gtk_paint_check (GtkStyle      *style,
4279                  GdkWindow     *window,
4280                  GtkStateType   state_type,
4281                  GtkShadowType  shadow_type,
4282                  GdkRectangle  *area,
4283                  GtkWidget     *widget,
4284                  const gchar   *detail,
4285                  gint           x,
4286                  gint           y,
4287                  gint           width,
4288                  gint           height)
4289 {
4290   g_return_if_fail (GTK_IS_STYLE (style));
4291   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
4292   
4293   GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4294 }
4295
4296 void
4297 gtk_paint_option (GtkStyle      *style,
4298                   GdkWindow     *window,
4299                   GtkStateType   state_type,
4300                   GtkShadowType  shadow_type,
4301                   GdkRectangle  *area,
4302                   GtkWidget     *widget,
4303                   const gchar   *detail,
4304                   gint           x,
4305                   gint           y,
4306                   gint           width,
4307                   gint           height)
4308 {
4309   g_return_if_fail (GTK_IS_STYLE (style));
4310   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4311   
4312   GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4313 }
4314
4315 void
4316 gtk_paint_tab (GtkStyle      *style,
4317                GdkWindow     *window,
4318                GtkStateType   state_type,
4319                GtkShadowType  shadow_type,
4320                GdkRectangle  *area,
4321                GtkWidget     *widget,
4322                const gchar   *detail,
4323                gint           x,
4324                gint           y,
4325                gint           width,
4326                gint           height)
4327 {
4328   g_return_if_fail (GTK_IS_STYLE (style));
4329   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4330   
4331   GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4332 }
4333
4334 void
4335 gtk_paint_shadow_gap (GtkStyle       *style,
4336                       GdkWindow      *window,
4337                       GtkStateType    state_type,
4338                       GtkShadowType   shadow_type,
4339                       GdkRectangle   *area,
4340                       GtkWidget      *widget,
4341                       gchar          *detail,
4342                       gint            x,
4343                       gint            y,
4344                       gint            width,
4345                       gint            height,
4346                       GtkPositionType gap_side,
4347                       gint            gap_x,
4348                       gint            gap_width)
4349 {
4350   g_return_if_fail (GTK_IS_STYLE (style));
4351   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4352   
4353   GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
4354 }
4355
4356
4357 void
4358 gtk_paint_box_gap (GtkStyle       *style,
4359                    GdkWindow      *window,
4360                    GtkStateType    state_type,
4361                    GtkShadowType   shadow_type,
4362                    GdkRectangle   *area,
4363                    GtkWidget      *widget,
4364                    gchar          *detail,
4365                    gint            x,
4366                    gint            y,
4367                    gint            width,
4368                    gint            height,
4369                    GtkPositionType gap_side,
4370                    gint            gap_x,
4371                    gint            gap_width)
4372 {
4373   g_return_if_fail (GTK_IS_STYLE (style));
4374   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
4375   
4376   GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
4377 }
4378
4379 void
4380 gtk_paint_extension (GtkStyle       *style,
4381                      GdkWindow      *window,
4382                      GtkStateType    state_type,
4383                      GtkShadowType   shadow_type,
4384                      GdkRectangle   *area,
4385                      GtkWidget      *widget,
4386                      gchar          *detail,
4387                      gint            x,
4388                      gint            y,
4389                      gint            width,
4390                      gint            height,
4391                      GtkPositionType gap_side)
4392 {
4393   g_return_if_fail (GTK_IS_STYLE (style));
4394   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
4395   
4396   GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
4397 }
4398
4399 void
4400 gtk_paint_focus (GtkStyle      *style,
4401                  GdkWindow     *window,
4402                  GdkRectangle  *area,
4403                  GtkWidget     *widget,
4404                  const gchar   *detail,
4405                  gint           x,
4406                  gint           y,
4407                  gint           width,
4408                  gint           height)
4409 {
4410   g_return_if_fail (GTK_IS_STYLE (style));
4411   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
4412   
4413   GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, detail, x, y, width, height);
4414 }
4415
4416 void
4417 gtk_paint_slider (GtkStyle      *style,
4418                   GdkWindow     *window,
4419                   GtkStateType   state_type,
4420                   GtkShadowType  shadow_type,
4421                   GdkRectangle  *area,
4422                   GtkWidget     *widget,
4423                   const gchar   *detail,
4424                   gint           x,
4425                   gint           y,
4426                   gint           width,
4427                   gint           height,
4428                   GtkOrientation orientation)
4429 {
4430   g_return_if_fail (GTK_IS_STYLE (style));
4431   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
4432   
4433   GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
4434 }
4435
4436 void
4437 gtk_paint_handle (GtkStyle      *style,
4438                   GdkWindow     *window,
4439                   GtkStateType   state_type,
4440                   GtkShadowType  shadow_type,
4441                   GdkRectangle  *area,
4442                   GtkWidget     *widget,
4443                   const gchar   *detail,
4444                   gint           x,
4445                   gint           y,
4446                   gint           width,
4447                   gint           height,
4448                   GtkOrientation orientation)
4449 {
4450   g_return_if_fail (GTK_IS_STYLE (style));
4451   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
4452   
4453   GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
4454 }
4455
4456 void
4457 gtk_paint_expander (GtkStyle        *style,
4458                     GdkWindow       *window,
4459                     GtkStateType     state_type,
4460                     GdkRectangle    *area,
4461                     GtkWidget       *widget,
4462                     const gchar     *detail,
4463                     gint             x,
4464                     gint             y,
4465                     gboolean         is_open)
4466 {
4467   g_return_if_fail (GTK_IS_STYLE (style));
4468   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
4469   
4470   GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
4471                                               widget, detail, x, y, is_open);
4472 }
4473
4474 void
4475 gtk_paint_layout (GtkStyle        *style,
4476                   GdkWindow       *window,
4477                   GtkStateType     state_type,
4478                   GdkRectangle    *area,
4479                   GtkWidget       *widget,
4480                   const gchar     *detail,
4481                   gint             x,
4482                   gint             y,
4483                   PangoLayout     *layout)
4484 {
4485   g_return_if_fail (GTK_IS_STYLE (style));
4486   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
4487   
4488   GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, area,
4489                                             widget, detail, x, y, layout);
4490 }
4491
4492