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