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