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