]> Pileus Git - ~andy/gtk/blob - gtk/gtkstyle.c
18040214d01c5582727ad707c16d74493ede25b2
[~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   key.widget_type = widget_type;
1304   key.pspec = pspec;
1305
1306   /* need value cache array */
1307   if (!style->property_cache)
1308     style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1309   else
1310     {
1311       pcache = bsearch (&key,
1312                         style->property_cache->data, style->property_cache->len,
1313                         sizeof (PropertyValue), style_property_values_cmp);
1314       if (pcache)
1315         return &pcache->value;
1316     }
1317
1318   i = 0;
1319   while (i < style->property_cache->len &&
1320          style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1321     i++;
1322
1323   g_array_insert_val (style->property_cache, i, key);
1324   pcache = &g_array_index (style->property_cache, PropertyValue, i);
1325
1326   /* cache miss, initialize value type, then set contents */
1327   g_param_spec_ref (pcache->pspec);
1328   g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1329
1330   /* value provided by rc style? */
1331   if (style->rc_style)
1332     {
1333       GQuark prop_quark = g_quark_from_string (pspec->name);
1334
1335       do
1336         {
1337           rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1338                                                      g_type_qname (widget_type),
1339                                                      prop_quark);
1340           if (rcprop)
1341             break;
1342           widget_type = g_type_parent (widget_type);
1343         }
1344       while (g_type_is_a (widget_type, pspec->owner_type));
1345     }
1346
1347   /* when supplied by rc style, we need to convert */
1348   if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1349                                               pspec, &pcache->value))
1350     {
1351       gchar *contents = g_strdup_value_contents (&rcprop->value);
1352       
1353       g_message ("%s: failed to retrive property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1354                  rcprop->origin,
1355                  g_type_name (pspec->owner_type), pspec->name,
1356                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1357                  contents,
1358                  G_VALUE_TYPE_NAME (&rcprop->value));
1359       g_free (contents);
1360       rcprop = NULL; /* needs default */
1361     }
1362   
1363   /* not supplied by rc style (or conversion failed), revert to default */
1364   if (!rcprop)
1365     g_param_value_set_default (pspec, &pcache->value);
1366
1367   return &pcache->value;
1368 }
1369
1370 GdkPixmap *
1371 load_bg_image (GdkColormap *colormap,
1372                GdkColor    *bg_color,
1373                const gchar *filename)
1374 {
1375   if (strcmp (filename, "<parent>") == 0)
1376     return (GdkPixmap*) GDK_PARENT_RELATIVE;
1377   else
1378     {
1379       return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1380                                                   bg_color,
1381                                                   filename);
1382     }
1383 }
1384
1385 static void
1386 gtk_style_real_realize (GtkStyle *style)
1387 {
1388   GdkGCValues gc_values;
1389   GdkGCValuesMask gc_values_mask;
1390   
1391   gint i;
1392
1393   for (i = 0; i < 5; i++)
1394     {
1395       gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1396       gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1397       
1398       style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1399       style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1400       style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1401
1402       style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1403       style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1404       style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1405     }
1406   
1407   gdk_color_black (style->colormap, &style->black);
1408   gdk_color_white (style->colormap, &style->white);
1409   
1410   gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
1411   if (style->font->type == GDK_FONT_FONT)
1412     {
1413       gc_values.font = style->font;
1414     }
1415   else if (style->font->type == GDK_FONT_FONTSET)
1416     {
1417       gc_values.font = static_default_font;
1418     }
1419   
1420   gc_values.foreground = style->black;
1421   style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1422   
1423   gc_values.foreground = style->white;
1424   style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1425   
1426   for (i = 0; i < 5; i++)
1427     {
1428       if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1429         style->bg_pixmap[i] = load_bg_image (style->colormap,
1430                                              &style->bg[i],
1431                                              style->rc_style->bg_pixmap_name[i]);
1432       
1433       if (!gdk_color_alloc (style->colormap, &style->fg[i]))
1434         g_warning ("unable to allocate color: ( %d %d %d )",
1435                    style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1436       if (!gdk_color_alloc (style->colormap, &style->bg[i]))
1437         g_warning ("unable to allocate color: ( %d %d %d )",
1438                    style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1439       if (!gdk_color_alloc (style->colormap, &style->light[i]))
1440         g_warning ("unable to allocate color: ( %d %d %d )",
1441                    style->light[i].red, style->light[i].green, style->light[i].blue);
1442       if (!gdk_color_alloc (style->colormap, &style->dark[i]))
1443         g_warning ("unable to allocate color: ( %d %d %d )",
1444                    style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1445       if (!gdk_color_alloc (style->colormap, &style->mid[i]))
1446         g_warning ("unable to allocate color: ( %d %d %d )",
1447                    style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1448       if (!gdk_color_alloc (style->colormap, &style->text[i]))
1449         g_warning ("unable to allocate color: ( %d %d %d )",
1450                    style->text[i].red, style->text[i].green, style->text[i].blue);
1451       if (!gdk_color_alloc (style->colormap, &style->base[i]))
1452         g_warning ("unable to allocate color: ( %d %d %d )",
1453                    style->base[i].red, style->base[i].green, style->base[i].blue);
1454       if (!gdk_color_alloc (style->colormap, &style->text_aa[i]))
1455         g_warning ("unable to allocate color: ( %d %d %d )",
1456                    style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1457       
1458       gc_values.foreground = style->fg[i];
1459       style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1460       
1461       gc_values.foreground = style->bg[i];
1462       style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1463       
1464       gc_values.foreground = style->light[i];
1465       style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1466       
1467       gc_values.foreground = style->dark[i];
1468       style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1469       
1470       gc_values.foreground = style->mid[i];
1471       style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1472       
1473       gc_values.foreground = style->text[i];
1474       style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1475       
1476       gc_values.foreground = style->base[i];
1477       style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1478
1479       gc_values.foreground = style->text_aa[i];
1480       style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1481     }
1482 }
1483
1484 static void
1485 gtk_style_real_unrealize (GtkStyle *style)
1486 {
1487   int i;
1488
1489   gtk_gc_release (style->black_gc);
1490   gtk_gc_release (style->white_gc);
1491       
1492   for (i = 0; i < 5; i++)
1493     {
1494       gtk_gc_release (style->fg_gc[i]);
1495       gtk_gc_release (style->bg_gc[i]);
1496       gtk_gc_release (style->light_gc[i]);
1497       gtk_gc_release (style->dark_gc[i]);
1498       gtk_gc_release (style->mid_gc[i]);
1499       gtk_gc_release (style->text_gc[i]);
1500       gtk_gc_release (style->base_gc[i]);
1501       gtk_gc_release (style->text_aa_gc[i]);
1502
1503       if (style->bg_pixmap[i] &&  style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1504         gdk_pixmap_unref (style->bg_pixmap[i]);
1505     }
1506   
1507   gdk_colormap_free_colors (style->colormap, style->fg, 5);
1508   gdk_colormap_free_colors (style->colormap, style->bg, 5);
1509   gdk_colormap_free_colors (style->colormap, style->light, 5);
1510   gdk_colormap_free_colors (style->colormap, style->dark, 5);
1511   gdk_colormap_free_colors (style->colormap, style->mid, 5);
1512   gdk_colormap_free_colors (style->colormap, style->text, 5);
1513   gdk_colormap_free_colors (style->colormap, style->base, 5);
1514   gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1515 }
1516
1517 static void
1518 gtk_style_real_set_background (GtkStyle    *style,
1519                                GdkWindow   *window,
1520                                GtkStateType state_type)
1521 {
1522   GdkPixmap *pixmap;
1523   gint parent_relative;
1524   
1525   if (style->bg_pixmap[state_type])
1526     {
1527       if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1528         {
1529           pixmap = NULL;
1530           parent_relative = TRUE;
1531         }
1532       else
1533         {
1534           pixmap = style->bg_pixmap[state_type];
1535           parent_relative = FALSE;
1536         }
1537       
1538       gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1539     }
1540   else
1541     gdk_window_set_background (window, &style->bg[state_type]);
1542 }
1543
1544 GdkPixbuf *
1545 gtk_style_render_icon (GtkStyle            *style,
1546                        const GtkIconSource *source,
1547                        GtkTextDirection     direction,
1548                        GtkStateType         state,
1549                        GtkIconSize          size,
1550                        GtkWidget           *widget,
1551                        const gchar         *detail)
1552 {
1553   GdkPixbuf *pixbuf;
1554   
1555   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1556   g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1557   
1558   pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1559                                                      size, widget, detail);
1560
1561   g_return_val_if_fail (pixbuf != NULL, NULL);
1562
1563   return pixbuf;
1564 }
1565
1566 /* Default functions */
1567 void
1568 gtk_style_apply_default_background (GtkStyle     *style,
1569                                     GdkWindow    *window,
1570                                     gboolean      set_bg,
1571                                     GtkStateType  state_type, 
1572                                     GdkRectangle *area, 
1573                                     gint          x, 
1574                                     gint          y, 
1575                                     gint          width, 
1576                                     gint          height)
1577 {
1578   GdkRectangle new_rect, old_rect;
1579   
1580   if (area)
1581     {
1582       old_rect.x = x;
1583       old_rect.y = y;
1584       old_rect.width = width;
1585       old_rect.height = height;
1586       
1587       if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
1588         return;
1589     }
1590   else
1591     {
1592       new_rect.x = x;
1593       new_rect.y = y;
1594       new_rect.width = width;
1595       new_rect.height = height;
1596     }
1597   
1598   if (!style->bg_pixmap[state_type] ||
1599       GDK_IS_PIXMAP (window) ||
1600       (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
1601     {
1602       GdkGC *gc = style->bg_gc[state_type];
1603       
1604       if (style->bg_pixmap[state_type])
1605         {
1606           gdk_gc_set_fill (gc, GDK_TILED);
1607           gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
1608         }
1609       
1610       gdk_draw_rectangle (window, gc, TRUE, 
1611                           new_rect.x, new_rect.y, new_rect.width, new_rect.height);
1612       if (style->bg_pixmap[state_type])
1613         gdk_gc_set_fill (gc, GDK_SOLID);
1614     }
1615   else
1616     {
1617       if (set_bg)
1618         {
1619           if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1620             gdk_window_set_back_pixmap (window, NULL, TRUE);
1621           else
1622             gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
1623         }
1624       
1625       gdk_window_clear_area (window, 
1626                              new_rect.x, new_rect.y, 
1627                              new_rect.width, new_rect.height);
1628     }
1629 }
1630
1631 static GdkPixbuf*
1632 scale_or_ref (GdkPixbuf *src,
1633               gint width,
1634               gint height)
1635 {
1636   if (width == gdk_pixbuf_get_width (src) &&
1637       height == gdk_pixbuf_get_height (src))
1638     {
1639       gdk_pixbuf_ref (src);
1640       return src;
1641     }
1642   else
1643     {
1644       return gdk_pixbuf_scale_simple (src,
1645                                       width, height,
1646                                       GDK_INTERP_BILINEAR);
1647     }
1648 }
1649
1650 static GdkPixbuf *
1651 gtk_default_render_icon (GtkStyle            *style,
1652                          const GtkIconSource *source,
1653                          GtkTextDirection     direction,
1654                          GtkStateType         state,
1655                          GtkIconSize          size,
1656                          GtkWidget           *widget,
1657                          const gchar         *detail)
1658 {
1659   gint width = 1;
1660   gint height = 1;
1661   GdkPixbuf *scaled;
1662   GdkPixbuf *stated;
1663   GdkPixbuf *base_pixbuf;
1664
1665   /* Oddly, style can be NULL in this function, because
1666    * GtkIconSet can be used without a style and if so
1667    * it uses this function.
1668    */
1669
1670   base_pixbuf = gtk_icon_source_get_pixbuf (source);
1671
1672   g_return_val_if_fail (base_pixbuf != NULL, NULL);
1673   
1674   if (!gtk_icon_size_lookup (size, &width, &height))
1675     {
1676       g_warning (G_STRLOC ": invalid icon size `%d'", size);
1677       return NULL;
1678     }
1679
1680   /* If the size was wildcarded, then scale; otherwise, leave it
1681    * alone.
1682    */
1683   if (gtk_icon_source_get_size_wildcarded (source))
1684     scaled = scale_or_ref (base_pixbuf, width, height);
1685   else
1686     scaled = GDK_PIXBUF (g_object_ref (G_OBJECT (base_pixbuf)));
1687
1688   /* If the state was wildcarded, then generate a state. */
1689   if (gtk_icon_source_get_state_wildcarded (source))
1690     {
1691       if (state == GTK_STATE_INSENSITIVE)
1692         {
1693           stated = gdk_pixbuf_copy (scaled);      
1694           
1695           gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1696                                             0.8, TRUE);
1697           
1698           gdk_pixbuf_unref (scaled);
1699         }
1700       else if (state == GTK_STATE_PRELIGHT)
1701         {
1702           stated = gdk_pixbuf_copy (scaled);      
1703           
1704           gdk_pixbuf_saturate_and_pixelate (scaled, stated,
1705                                             1.2, FALSE);
1706           
1707           gdk_pixbuf_unref (scaled);
1708         }
1709       else
1710         {
1711           stated = scaled;
1712         }
1713     }
1714   else
1715     stated = scaled;
1716   
1717   return stated;
1718 }
1719
1720 static gboolean
1721 sanitize_size (GdkWindow *window,
1722                gint      *width,
1723                gint      *height)
1724 {
1725   gboolean set_bg = FALSE;
1726
1727   if ((*width == -1) && (*height == -1))
1728     {
1729       set_bg = GDK_IS_WINDOW (window);
1730       gdk_window_get_size (window, width, height);
1731     }
1732   else if (*width == -1)
1733     gdk_window_get_size (window, width, NULL);
1734   else if (*height == -1)
1735     gdk_window_get_size (window, NULL, height);
1736
1737   return set_bg;
1738 }
1739
1740 static void
1741 draw_part (GdkDrawable  *drawable,
1742            GdkGC        *gc,
1743            GdkRectangle *area,
1744            gint          x,
1745            gint          y,
1746            IndicatorPart part)
1747 {
1748   if (area)
1749     gdk_gc_set_clip_rectangle (gc, area);
1750   
1751   if (!indicator_parts[part].bmap)
1752     indicator_parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1753                                                               indicator_parts[part].bits,
1754                                                               INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
1755
1756   gdk_gc_set_ts_origin (gc, x, y);
1757   gdk_gc_set_stipple (gc, indicator_parts[part].bmap);
1758   gdk_gc_set_fill (gc, GDK_STIPPLED);
1759
1760   gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
1761
1762   gdk_gc_set_fill (gc, GDK_SOLID);
1763
1764   if (area)
1765     gdk_gc_set_clip_rectangle (gc, NULL);
1766 }
1767
1768 static void
1769 gtk_default_draw_hline (GtkStyle     *style,
1770                         GdkWindow    *window,
1771                         GtkStateType  state_type,
1772                         GdkRectangle  *area,
1773                         GtkWidget     *widget,
1774                         const gchar   *detail,
1775                         gint          x1,
1776                         gint          x2,
1777                         gint          y)
1778 {
1779   gint thickness_light;
1780   gint thickness_dark;
1781   gint i;
1782   
1783   g_return_if_fail (GTK_IS_STYLE (style));
1784   g_return_if_fail (window != NULL);
1785   
1786   thickness_light = style->ythickness / 2;
1787   thickness_dark = style->ythickness - thickness_light;
1788   
1789   if (area)
1790     {
1791       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
1792       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
1793     }
1794   
1795   if (detail && !strcmp (detail, "label"))
1796     {
1797       if (state_type == GTK_STATE_INSENSITIVE)
1798         gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);   
1799       gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);     
1800     }
1801   else
1802     {
1803       for (i = 0; i < thickness_dark; i++)
1804         {
1805           gdk_draw_line (window, style->light_gc[state_type], x2 - i - 1, y + i, x2, y + i);
1806           gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
1807         }
1808       
1809       y += thickness_dark;
1810       for (i = 0; i < thickness_light; i++)
1811         {
1812           gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
1813           gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i - 1, y + i, x2, y + i);
1814         }
1815     }
1816   
1817   if (area)
1818     {
1819       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1820       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1821     }
1822 }
1823
1824
1825 static void
1826 gtk_default_draw_vline (GtkStyle     *style,
1827                         GdkWindow    *window,
1828                         GtkStateType  state_type,
1829                         GdkRectangle  *area,
1830                         GtkWidget     *widget,
1831                         const gchar   *detail,
1832                         gint          y1,
1833                         gint          y2,
1834                         gint          x)
1835 {
1836   gint thickness_light;
1837   gint thickness_dark;
1838   gint i;
1839   
1840   g_return_if_fail (GTK_IS_STYLE (style));
1841   g_return_if_fail (window != NULL);
1842   
1843   thickness_light = style->xthickness / 2;
1844   thickness_dark = style->xthickness - thickness_light;
1845   
1846   if (area)
1847     {
1848       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
1849       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
1850     }
1851   for (i = 0; i < thickness_dark; i++)
1852     {
1853       gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i - 1, x + i, y2);
1854       gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
1855     }
1856   
1857   x += thickness_dark;
1858   for (i = 0; i < thickness_light; i++)
1859     {
1860       gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i);
1861       gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
1862     }
1863   if (area)
1864     {
1865       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1866       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1867     }
1868 }
1869
1870
1871 void
1872 draw_thin_shadow (GtkStyle      *style,
1873                   GdkWindow     *window,
1874                   GtkStateType   state,
1875                   GdkRectangle  *area,
1876                   gint           x,
1877                   gint           y,
1878                   gint           width,
1879                   gint           height)
1880 {
1881   GdkGC *gc1, *gc2;
1882
1883   sanitize_size (window, &width, &height);
1884   
1885   gc1 = style->light_gc[state];
1886   gc2 = style->dark_gc[state];
1887   
1888   if (area)
1889     {
1890       gdk_gc_set_clip_rectangle (gc1, area);
1891       gdk_gc_set_clip_rectangle (gc2, area);
1892     }
1893   
1894   gdk_draw_line (window, gc1,
1895                  x, y + height - 1, x + width - 1, y + height - 1);
1896   gdk_draw_line (window, gc1,
1897                  x + width - 1, y,  x + width - 1, y + height - 1);
1898       
1899   gdk_draw_line (window, gc2,
1900                  x, y, x + width - 1, y);
1901   gdk_draw_line (window, gc2,
1902                  x, y, x, y + height - 1);
1903
1904   if (area)
1905     {
1906       gdk_gc_set_clip_rectangle (gc1, NULL);
1907       gdk_gc_set_clip_rectangle (gc2, NULL);
1908     }
1909 }
1910
1911 void
1912 draw_spin_entry_shadow (GtkStyle      *style,
1913                         GdkWindow     *window,
1914                         GtkStateType   state,
1915                         GdkRectangle  *area,
1916                         gint           x,
1917                         gint           y,
1918                         gint           width,
1919                         gint           height)
1920 {
1921   gint window_width, window_height;
1922   gboolean focus_inset;
1923
1924   gdk_window_get_size (window, &window_width, &window_height);
1925
1926   if (width == -1)
1927     width = window_width;
1928   if (height == 1)
1929     height = window_height;
1930
1931   focus_inset = (width < window_width && height < window_height);
1932   
1933   if (area)
1934     {
1935       gdk_gc_set_clip_rectangle (style->light_gc[state], area);
1936       gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
1937       gdk_gc_set_clip_rectangle (style->black_gc, area);
1938       gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
1939       gdk_gc_set_clip_rectangle (style->base_gc[state], area);
1940     }
1941
1942   gdk_draw_line (window, style->light_gc[state],
1943                  x, y + height - 1, x + width - 1, y + height - 1);
1944
1945   gdk_draw_line (window, 
1946                  style->base_gc[state],
1947                  x + width - 1,  y + 1, x + width - 1,  y + height - 3);
1948       
1949   if (!focus_inset)
1950     {
1951       gdk_draw_line (window, style->bg_gc[state],
1952                      x + 1, y + height - 2, x + width - 1, y + height - 2);
1953       gdk_draw_line (window, 
1954                      style->base_gc[state],
1955                      x + width - 2, y + 1, x + width - 2, y + height - 3);
1956   
1957       gdk_draw_line (window, style->black_gc,
1958                      x + 1, y + 1, x + width - 1, y + 1);
1959       gdk_draw_line (window, style->black_gc,
1960                      x + 1, y + 1, x + 1, y + height - 2);
1961     }
1962       
1963   gdk_draw_line (window, style->dark_gc[state],
1964                  x, y, x + width - 1, y);
1965   gdk_draw_line (window, style->dark_gc[state],
1966                  x, y, x, y + height - 1);
1967
1968   if (area)
1969     {
1970       gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
1971       gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
1972       gdk_gc_set_clip_rectangle (style->black_gc, NULL);
1973       gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
1974       gdk_gc_set_clip_rectangle (style->base_gc[state], NULL);
1975     }
1976 }
1977
1978 static void
1979 draw_spinbutton_shadow (GtkStyle      *style,
1980                         GdkWindow     *window,
1981                         GtkStateType   state,
1982                         GdkRectangle  *area,
1983                         gint           x,
1984                         gint           y,
1985                         gint           width,
1986                         gint           height)
1987 {
1988   gint y_middle = y + height / 2;
1989
1990   sanitize_size (window, &width, &height);
1991   
1992   if (area)
1993     {
1994       gdk_gc_set_clip_rectangle (style->black_gc, area);
1995       gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
1996       gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
1997       gdk_gc_set_clip_rectangle (style->light_gc[state], area);
1998     }
1999   
2000   gdk_draw_line (window, style->black_gc,
2001                  x, y + 2, x, y + height - 3);
2002   gdk_draw_line (window, style->black_gc,
2003                  x, y + 1, x + width - 2, y + 1);
2004   gdk_draw_line (window, style->black_gc,
2005                  x + width - 2, y + 2, x + width - 2, y + height - 3);
2006   
2007   gdk_draw_line (window, style->bg_gc[state],
2008                  x, y + height - 2, x + width - 2, y + height - 2);
2009
2010   gdk_draw_line (window, style->dark_gc[state],
2011                  x, y, x + width - 1, y);
2012   gdk_draw_line (window, style->dark_gc[state],
2013                  x + 1, y_middle - 1, x + width - 3, y_middle - 1);
2014   gdk_draw_line (window, style->dark_gc[state],
2015                  x + 1, y + height - 3, x + width - 3, y + height - 3);
2016
2017   gdk_draw_line (window, style->light_gc[state],
2018                  x + 1, y + 2, x + width - 3, y + 2);
2019   gdk_draw_line (window, style->light_gc[state],
2020                  x + 1, y_middle, x + width - 3, y_middle);
2021   gdk_draw_line (window, style->light_gc[state],
2022                  x + width - 1, y + 1, x + width - 1, y + height - 1);
2023   gdk_draw_line (window, style->light_gc[state],
2024                  x, y + height - 1, x + width - 2, y + height - 1);
2025       
2026   if (area)
2027     {
2028       gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2029       gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2030       gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2031       gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2032     }
2033 }
2034
2035 static void
2036 gtk_default_draw_shadow (GtkStyle      *style,
2037                          GdkWindow     *window,
2038                          GtkStateType   state_type,
2039                          GtkShadowType  shadow_type,
2040                          GdkRectangle  *area,
2041                          GtkWidget     *widget,
2042                          const gchar   *detail,
2043                          gint           x,
2044                          gint           y,
2045                          gint           width,
2046                          gint           height)
2047 {
2048   GdkGC *gc1 = NULL;
2049   GdkGC *gc2 = NULL;
2050   gint thickness_light;
2051   gint thickness_dark;
2052   gint i;
2053   
2054   g_return_if_fail (GTK_IS_STYLE (style));
2055   g_return_if_fail (window != NULL);
2056
2057   if (shadow_type == GTK_SHADOW_IN)
2058     {
2059       if (detail && (strcmp (detail, "buttondefault") == 0))
2060         {
2061           sanitize_size (window, &width, &height);
2062
2063           gdk_draw_rectangle (window, style->black_gc, FALSE,
2064                               x, y, width - 1, height - 1);
2065           
2066           return;
2067         }
2068       if (detail && strcmp (detail, "trough") == 0)
2069         {
2070           draw_thin_shadow (style, window, state_type, area,
2071                             x, y, width, height);
2072           return;
2073         }
2074       else if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2075                detail && strcmp (detail, "entry") == 0)
2076         {
2077           draw_spin_entry_shadow (style, window, state_type, area,
2078                                   x, y, width, height);
2079           return;
2080         }
2081       else if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2082                detail && strcmp (detail, "spinbutton") == 0)
2083         {
2084           draw_spinbutton_shadow (style, window, state_type,
2085                                   area, x, y, width, height);
2086           return;
2087         }
2088     }
2089   
2090   sanitize_size (window, &width, &height);
2091   
2092   switch (shadow_type)
2093     {
2094     case GTK_SHADOW_NONE:
2095       return;
2096     case GTK_SHADOW_IN:
2097     case GTK_SHADOW_ETCHED_IN:
2098       gc1 = style->light_gc[state_type];
2099       gc2 = style->dark_gc[state_type];
2100       break;
2101     case GTK_SHADOW_OUT:
2102     case GTK_SHADOW_ETCHED_OUT:
2103       gc1 = style->dark_gc[state_type];
2104       gc2 = style->light_gc[state_type];
2105       break;
2106     }
2107   
2108   if (area)
2109     {
2110       gdk_gc_set_clip_rectangle (gc1, area);
2111       gdk_gc_set_clip_rectangle (gc2, area);
2112       if (shadow_type == GTK_SHADOW_IN || 
2113           shadow_type == GTK_SHADOW_OUT)
2114         {
2115           gdk_gc_set_clip_rectangle (style->black_gc, area);
2116           gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2117         }
2118     }
2119   
2120   switch (shadow_type)
2121     {
2122     case GTK_SHADOW_NONE:
2123       break;
2124       
2125     case GTK_SHADOW_IN:
2126       /* Light around right and bottom edge */
2127
2128       if (style->ythickness > 0)
2129         gdk_draw_line (window, gc1,
2130                        x, y + height - 1, x + width - 1, y + height - 1);
2131       if (style->xthickness > 0)
2132         gdk_draw_line (window, gc1,
2133                        x + width - 1, y, x + width - 1, y + height - 1);
2134
2135       if (style->ythickness > 1)
2136         gdk_draw_line (window, style->bg_gc[state_type],
2137                        x + 1, y + height - 2, x + width - 2, y + height - 2);
2138       if (style->xthickness > 1)
2139         gdk_draw_line (window, style->bg_gc[state_type],
2140                        x + width - 2, y + 1, x + width - 2, y + height - 2);
2141
2142       /* Dark around left and top */
2143
2144       if (style->ythickness > 1)
2145         gdk_draw_line (window, style->black_gc,
2146                        x + 1, y + 1, x + width - 2, y + 1);
2147       if (style->xthickness > 1)
2148         gdk_draw_line (window, style->black_gc,
2149                        x + 1, y + 1, x + 1, y + height - 2);
2150
2151       if (style->ythickness > 0)
2152         gdk_draw_line (window, gc2,
2153                        x, y, x + width - 1, y);
2154       if (style->xthickness > 0)
2155         gdk_draw_line (window, gc2,
2156                        x, y, x, y + height - 1);
2157       break;
2158       
2159     case GTK_SHADOW_OUT:
2160       /* Dark around right and bottom edge */
2161
2162       if (style->ythickness > 0)
2163         {
2164           if (style->ythickness > 1)
2165             {
2166               gdk_draw_line (window, gc1,
2167                              x + 1, y + height - 2, x + width - 2, y + height - 2);
2168               gdk_draw_line (window, style->black_gc,
2169                              x, y + height - 1, x + width - 1, y + height - 1);
2170             }
2171           else
2172             {
2173               gdk_draw_line (window, gc1,
2174                              x + 1, y + height - 1, x + width - 1, y + height - 1);
2175             }
2176         }
2177
2178       if (style->xthickness > 0)
2179         {
2180           if (style->xthickness > 1)
2181             {
2182               gdk_draw_line (window, gc1,
2183                              x + width - 2, y + 1, x + width - 2, y + height - 2);
2184               
2185               gdk_draw_line (window, style->black_gc,
2186                              x + width - 1, y, x + width - 1, y + height - 1);
2187             }
2188           else
2189             {
2190               gdk_draw_line (window, gc1,
2191                              x + width - 1, y + 1, x + width - 1, y + height - 1);
2192             }
2193         }
2194       
2195       /* Light around top and left */
2196
2197       if (style->ythickness > 0)
2198         gdk_draw_line (window, gc2,
2199                        x, y, x + width - 1, y);
2200       if (style->xthickness > 0)
2201         gdk_draw_line (window, gc2,
2202                        x, y, x, y + height - 1);
2203
2204       if (style->ythickness > 1)
2205         gdk_draw_line (window, style->bg_gc[state_type],
2206                        x + 1, y + 1, x + width - 2, y + 1);
2207       if (style->xthickness > 1)
2208         gdk_draw_line (window, style->bg_gc[state_type],
2209                        x + 1, y + 1, x + 1, y + height - 2);
2210       break;
2211       
2212     case GTK_SHADOW_ETCHED_IN:
2213     case GTK_SHADOW_ETCHED_OUT:
2214       if (style->xthickness > 0)
2215         {
2216           if (style->xthickness > 1)
2217             {
2218               thickness_light = 1;
2219               thickness_dark = 1;
2220       
2221               for (i = 0; i < thickness_dark; i++)
2222                 {
2223                   gdk_draw_line (window, gc1,
2224                                  x + width - i - 1,
2225                                  y + i,
2226                                  x + width - i - 1,
2227                                  y + height - i - 1);
2228                   gdk_draw_line (window, gc2,
2229                                  x + i,
2230                                  y + i,
2231                                  x + i,
2232                                  y + height - i - 2);
2233                 }
2234       
2235               for (i = 0; i < thickness_light; i++)
2236                 {
2237                   gdk_draw_line (window, gc1,
2238                                  x + thickness_dark + i,
2239                                  y + thickness_dark + i,
2240                                  x + thickness_dark + i,
2241                                  y + height - thickness_dark - i - 1);
2242                   gdk_draw_line (window, gc2,
2243                                  x + width - thickness_light - i - 1,
2244                                  y + thickness_dark + i,
2245                                  x + width - thickness_light - i - 1,
2246                                  y + height - thickness_light - 1);
2247                 }
2248             }
2249           else
2250             {
2251               gdk_draw_line (window, 
2252                              style->dark_gc[state_type],
2253                              x, y, x, y + height);                         
2254               gdk_draw_line (window, 
2255                              style->dark_gc[state_type],
2256                              x + width, y, x + width, y + height);
2257             }
2258         }
2259
2260       if (style->ythickness > 0)
2261         {
2262           if (style->ythickness > 1)
2263             {
2264               thickness_light = 1;
2265               thickness_dark = 1;
2266       
2267               for (i = 0; i < thickness_dark; i++)
2268                 {
2269                   gdk_draw_line (window, gc1,
2270                                  x + i,
2271                                  y + height - i - 1,
2272                                  x + width - i - 1,
2273                                  y + height - i - 1);
2274           
2275                   gdk_draw_line (window, gc2,
2276                                  x + i,
2277                                  y + i,
2278                                  x + width - i - 2,
2279                                  y + i);
2280                 }
2281       
2282               for (i = 0; i < thickness_light; i++)
2283                 {
2284                   gdk_draw_line (window, gc1,
2285                                  x + thickness_dark + i,
2286                                  y + thickness_dark + i,
2287                                  x + width - thickness_dark - i - 1,
2288                                  y + thickness_dark + i);
2289           
2290                   gdk_draw_line (window, gc2,
2291                                  x + thickness_dark + i,
2292                                  y + height - thickness_light - i - 1,
2293                                  x + width - thickness_light - 1,
2294                                  y + height - thickness_light - i - 1);
2295                 }
2296             }
2297           else
2298             {
2299               gdk_draw_line (window, 
2300                              style->dark_gc[state_type],
2301                              x, y, x + width, y);
2302               gdk_draw_line (window, 
2303                              style->dark_gc[state_type],
2304                              x, y + height, x + width, y + height);
2305             }
2306         }
2307       
2308       break;
2309     }
2310   if (area)
2311     {
2312       gdk_gc_set_clip_rectangle (gc1, NULL);
2313       gdk_gc_set_clip_rectangle (gc2, NULL);
2314       if (shadow_type == GTK_SHADOW_IN || 
2315           shadow_type == GTK_SHADOW_OUT)
2316         {
2317           gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2318           gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2319         }
2320     }
2321 }
2322
2323 static void
2324 gtk_default_draw_polygon (GtkStyle      *style,
2325                           GdkWindow     *window,
2326                           GtkStateType   state_type,
2327                           GtkShadowType  shadow_type,
2328                           GdkRectangle  *area,
2329                           GtkWidget     *widget,
2330                           const gchar   *detail,
2331                           GdkPoint      *points,
2332                           gint           npoints,
2333                           gboolean       fill)
2334 {
2335   static const gdouble pi_over_4 = G_PI_4;
2336   static const gdouble pi_3_over_4 = G_PI_4 * 3;
2337   GdkGC *gc1;
2338   GdkGC *gc2;
2339   GdkGC *gc3;
2340   GdkGC *gc4;
2341   gdouble angle;
2342   gint xadjust;
2343   gint yadjust;
2344   gint i;
2345   
2346   g_return_if_fail (GTK_IS_STYLE (style));
2347   g_return_if_fail (window != NULL);
2348   g_return_if_fail (points != NULL);
2349   
2350   switch (shadow_type)
2351     {
2352     case GTK_SHADOW_IN:
2353       gc1 = style->bg_gc[state_type];
2354       gc2 = style->dark_gc[state_type];
2355       gc3 = style->light_gc[state_type];
2356       gc4 = style->black_gc;
2357       break;
2358     case GTK_SHADOW_ETCHED_IN:
2359       gc1 = style->light_gc[state_type];
2360       gc2 = style->dark_gc[state_type];
2361       gc3 = style->dark_gc[state_type];
2362       gc4 = style->light_gc[state_type];
2363       break;
2364     case GTK_SHADOW_OUT:
2365       gc1 = style->dark_gc[state_type];
2366       gc2 = style->light_gc[state_type];
2367       gc3 = style->black_gc;
2368       gc4 = style->bg_gc[state_type];
2369       break;
2370     case GTK_SHADOW_ETCHED_OUT:
2371       gc1 = style->dark_gc[state_type];
2372       gc2 = style->light_gc[state_type];
2373       gc3 = style->light_gc[state_type];
2374       gc4 = style->dark_gc[state_type];
2375       break;
2376     default:
2377       return;
2378     }
2379   
2380   if (area)
2381     {
2382       gdk_gc_set_clip_rectangle (gc1, area);
2383       gdk_gc_set_clip_rectangle (gc2, area);
2384       gdk_gc_set_clip_rectangle (gc3, area);
2385       gdk_gc_set_clip_rectangle (gc4, area);
2386     }
2387   
2388   if (fill)
2389     gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2390   
2391   npoints--;
2392   
2393   for (i = 0; i < npoints; i++)
2394     {
2395       if ((points[i].x == points[i+1].x) &&
2396           (points[i].y == points[i+1].y))
2397         {
2398           angle = 0;
2399         }
2400       else
2401         {
2402           angle = atan2 (points[i+1].y - points[i].y,
2403                          points[i+1].x - points[i].x);
2404         }
2405       
2406       if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2407         {
2408           if (angle > -pi_over_4)
2409             {
2410               xadjust = 0;
2411               yadjust = 1;
2412             }
2413           else
2414             {
2415               xadjust = 1;
2416               yadjust = 0;
2417             }
2418           
2419           gdk_draw_line (window, gc1,
2420                          points[i].x-xadjust, points[i].y-yadjust,
2421                          points[i+1].x-xadjust, points[i+1].y-yadjust);
2422           gdk_draw_line (window, gc3,
2423                          points[i].x, points[i].y,
2424                          points[i+1].x, points[i+1].y);
2425         }
2426       else
2427         {
2428           if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
2429             {
2430               xadjust = 0;
2431               yadjust = 1;
2432             }
2433           else
2434             {
2435               xadjust = 1;
2436               yadjust = 0;
2437             }
2438           
2439           gdk_draw_line (window, gc4,
2440                          points[i].x+xadjust, points[i].y+yadjust,
2441                          points[i+1].x+xadjust, points[i+1].y+yadjust);
2442           gdk_draw_line (window, gc2,
2443                          points[i].x, points[i].y,
2444                          points[i+1].x, points[i+1].y);
2445         }
2446     }
2447
2448   if (area)
2449     {
2450       gdk_gc_set_clip_rectangle (gc1, NULL);
2451       gdk_gc_set_clip_rectangle (gc2, NULL);
2452       gdk_gc_set_clip_rectangle (gc3, NULL);
2453       gdk_gc_set_clip_rectangle (gc4, NULL);
2454     }
2455 }
2456
2457 static void
2458 draw_varrow (GdkWindow     *window,
2459              GdkGC         *gc,
2460              GtkShadowType  shadow_type,
2461              GdkRectangle  *area,
2462              GtkArrowType   arrow_type,
2463              gint           x,
2464              gint           y,
2465              gint           width,
2466              gint           height)
2467 {
2468   gint steps, extra;
2469   gint y_start, y_increment;
2470   gint i;
2471
2472   if (area)
2473     gdk_gc_set_clip_rectangle (gc, area);
2474   
2475   width = width + width % 2 - 1;        /* Force odd */
2476   
2477   steps = 1 + width / 2;
2478
2479   extra = height - steps;
2480
2481   if (arrow_type == GTK_ARROW_DOWN)
2482     {
2483       y_start = y;
2484       y_increment = 1;
2485     }
2486   else
2487     {
2488       y_start = y + height - 1;
2489       y_increment = -1;
2490     }
2491
2492   for (i = 0; i < extra; i++)
2493     {
2494       gdk_draw_line (window, gc,
2495                      x,              y_start + i * y_increment,
2496                      x + width - 1,  y_start + i * y_increment);
2497     }
2498   for (; i < height; i++)
2499     {
2500       gdk_draw_line (window, gc,
2501                      x + (i - extra),              y_start + i * y_increment,
2502                      x + width - (i - extra) - 1,  y_start + i * y_increment);
2503     }
2504   
2505
2506   if (area)
2507     gdk_gc_set_clip_rectangle (gc, NULL);
2508 }
2509
2510 static void
2511 draw_harrow (GdkWindow     *window,
2512              GdkGC         *gc,
2513              GtkShadowType  shadow_type,
2514              GdkRectangle  *area,
2515              GtkArrowType   arrow_type,
2516              gint           x,
2517              gint           y,
2518              gint           width,
2519              gint           height)
2520 {
2521   gint steps, extra;
2522   gint x_start, x_increment;
2523   gint i;
2524
2525   if (area)
2526     gdk_gc_set_clip_rectangle (gc, area);
2527   
2528   height = height + height % 2 - 1;     /* Force odd */
2529   
2530   steps = 1 + height / 2;
2531
2532   extra = width - steps;
2533
2534   if (arrow_type == GTK_ARROW_RIGHT)
2535     {
2536       x_start = x;
2537       x_increment = 1;
2538     }
2539   else
2540     {
2541       x_start = x + width - 1;
2542       x_increment = -1;
2543     }
2544
2545   for (i = 0; i < extra; i++)
2546     {
2547       gdk_draw_line (window, gc,
2548                      x_start + i * x_increment, y,
2549                      x_start + i * x_increment, y + height - 1);
2550     }
2551   for (; i < width; i++)
2552     {
2553       gdk_draw_line (window, gc,
2554                      x_start + i * x_increment, y + (i - extra),
2555                      x_start + i * x_increment, y + height - (i - extra) - 1);
2556     }
2557   
2558
2559   if (area)
2560     gdk_gc_set_clip_rectangle (gc, NULL);
2561 }
2562
2563 static void
2564 gtk_default_draw_arrow (GtkStyle      *style,
2565                         GdkWindow     *window,
2566                         GtkStateType   state,
2567                         GtkShadowType  shadow,
2568                         GdkRectangle  *area,
2569                         GtkWidget     *widget,
2570                         const gchar   *detail,
2571                         GtkArrowType   arrow_type,
2572                         gboolean       fill,
2573                         gint           x,
2574                         gint           y,
2575                         gint           width,
2576                         gint           height)
2577 {
2578   sanitize_size (window, &width, &height);
2579   
2580   if (detail && strcmp (detail, "spinbutton") == 0)
2581     {
2582       x += (width - 7) / 2;
2583
2584       if (arrow_type == GTK_ARROW_UP)
2585         y += (height - 4) / 2;
2586       else
2587         y += (1 + height - 4) / 2;
2588
2589       draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
2590                    x, y, 7, 4);
2591     }
2592   else if (detail && strcmp (detail, "vscrollbar") == 0)
2593     {
2594       gtk_paint_box (style, window, state, shadow, area,
2595                      widget, detail, x, y, width, height);
2596       
2597       x += (width - 7) / 2;
2598       y += (height - 5) / 2;
2599
2600       draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
2601                    x, y, 7, 5);
2602       
2603     }
2604   else if (detail && strcmp (detail, "hscrollbar") == 0)
2605     {
2606       gtk_paint_box (style, window, state, shadow, area,
2607                      widget, detail, x, y, width, height);
2608       
2609       y += (height - 7) / 2;
2610       x += (width - 5) / 2;
2611
2612       draw_harrow (window, style->fg_gc[state], shadow, area, arrow_type,
2613                    x, y, 5, 7);
2614     }
2615   else
2616     {
2617       if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
2618         {
2619           x += (width - 7) / 2;
2620           y += (height - 5) / 2;
2621           
2622           draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
2623                        x, y, 7, 5);
2624         }
2625       else
2626         {
2627           x += (width - 5) / 2;
2628           y += (height - 7) / 2;
2629           
2630           draw_harrow (window, style->fg_gc[state], shadow, area, arrow_type,
2631                        x, y, 5, 7);
2632         }
2633     }
2634 }
2635
2636 static void
2637 gtk_default_draw_diamond (GtkStyle      *style,
2638                           GdkWindow     *window,
2639                           GtkStateType   state_type,
2640                           GtkShadowType  shadow_type,
2641                           GdkRectangle  *area,
2642                           GtkWidget     *widget,
2643                           const gchar   *detail,
2644                           gint           x,
2645                           gint           y,
2646                           gint           width,
2647                           gint           height)
2648 {
2649   gint half_width;
2650   gint half_height;
2651   GdkGC *outer_nw = NULL;
2652   GdkGC *outer_ne = NULL;
2653   GdkGC *outer_sw = NULL;
2654   GdkGC *outer_se = NULL;
2655   GdkGC *middle_nw = NULL;
2656   GdkGC *middle_ne = NULL;
2657   GdkGC *middle_sw = NULL;
2658   GdkGC *middle_se = NULL;
2659   GdkGC *inner_nw = NULL;
2660   GdkGC *inner_ne = NULL;
2661   GdkGC *inner_sw = NULL;
2662   GdkGC *inner_se = NULL;
2663   
2664   g_return_if_fail (GTK_IS_STYLE (style));
2665   g_return_if_fail (window != NULL);
2666   
2667   sanitize_size (window, &width, &height);
2668   
2669   half_width = width / 2;
2670   half_height = height / 2;
2671   
2672   if (area)
2673     {
2674       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2675       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2676       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2677       gdk_gc_set_clip_rectangle (style->black_gc, area);
2678     }
2679   
2680   switch (shadow_type)
2681     {
2682     case GTK_SHADOW_IN:
2683       inner_sw = inner_se = style->bg_gc[state_type];
2684       middle_sw = middle_se = style->light_gc[state_type];
2685       outer_sw = outer_se = style->light_gc[state_type];
2686       inner_nw = inner_ne = style->black_gc;
2687       middle_nw = middle_ne = style->dark_gc[state_type];
2688       outer_nw = outer_ne = style->dark_gc[state_type];
2689       break;
2690           
2691     case GTK_SHADOW_OUT:
2692       inner_sw = inner_se = style->dark_gc[state_type];
2693       middle_sw = middle_se = style->dark_gc[state_type];
2694       outer_sw = outer_se = style->black_gc;
2695       inner_nw = inner_ne = style->bg_gc[state_type];
2696       middle_nw = middle_ne = style->light_gc[state_type];
2697       outer_nw = outer_ne = style->light_gc[state_type];
2698       break;
2699
2700     case GTK_SHADOW_ETCHED_IN:
2701       inner_sw = inner_se = style->bg_gc[state_type];
2702       middle_sw = middle_se = style->dark_gc[state_type];
2703       outer_sw = outer_se = style->light_gc[state_type];
2704       inner_nw = inner_ne = style->bg_gc[state_type];
2705       middle_nw = middle_ne = style->light_gc[state_type];
2706       outer_nw = outer_ne = style->dark_gc[state_type];
2707       break;
2708
2709     case GTK_SHADOW_ETCHED_OUT:
2710       inner_sw = inner_se = style->bg_gc[state_type];
2711       middle_sw = middle_se = style->light_gc[state_type];
2712       outer_sw = outer_se = style->dark_gc[state_type];
2713       inner_nw = inner_ne = style->bg_gc[state_type];
2714       middle_nw = middle_ne = style->dark_gc[state_type];
2715       outer_nw = outer_ne = style->light_gc[state_type];
2716       break;
2717       
2718     default:
2719
2720       break;
2721     }
2722
2723   if (inner_sw)
2724     {
2725       gdk_draw_line (window, inner_sw,
2726                      x + 2, y + half_height,
2727                      x + half_width, y + height - 2);
2728       gdk_draw_line (window, inner_se,
2729                      x + half_width, y + height - 2,
2730                      x + width - 2, y + half_height);
2731       gdk_draw_line (window, middle_sw,
2732                      x + 1, y + half_height,
2733                      x + half_width, y + height - 1);
2734       gdk_draw_line (window, middle_se,
2735                      x + half_width, y + height - 1,
2736                      x + width - 1, y + half_height);
2737       gdk_draw_line (window, outer_sw,
2738                      x, y + half_height,
2739                      x + half_width, y + height);
2740       gdk_draw_line (window, outer_se,
2741                      x + half_width, y + height,
2742                      x + width, y + half_height);
2743   
2744       gdk_draw_line (window, inner_nw,
2745                      x + 2, y + half_height,
2746                      x + half_width, y + 2);
2747       gdk_draw_line (window, inner_ne,
2748                      x + half_width, y + 2,
2749                      x + width - 2, y + half_height);
2750       gdk_draw_line (window, middle_nw,
2751                      x + 1, y + half_height,
2752                      x + half_width, y + 1);
2753       gdk_draw_line (window, middle_ne,
2754                      x + half_width, y + 1,
2755                      x + width - 1, y + half_height);
2756       gdk_draw_line (window, outer_nw,
2757                      x, y + half_height,
2758                      x + half_width, y);
2759       gdk_draw_line (window, outer_ne,
2760                      x + half_width, y,
2761                      x + width, y + half_height);
2762     }
2763   
2764   if (area)
2765     {
2766       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2767       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2768       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2769       gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2770     }
2771 }
2772
2773 static void
2774 gtk_default_draw_string (GtkStyle      *style,
2775                          GdkWindow     *window,
2776                          GtkStateType   state_type,
2777                          GdkRectangle  *area,
2778                          GtkWidget     *widget,
2779                          const gchar   *detail,
2780                          gint           x,
2781                          gint           y,
2782                          const gchar   *string)
2783 {
2784   g_return_if_fail (GTK_IS_STYLE (style));
2785   g_return_if_fail (window != NULL);
2786   
2787   if (area)
2788     {
2789       gdk_gc_set_clip_rectangle (style->white_gc, area);
2790       gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
2791     }
2792
2793   if (state_type == GTK_STATE_INSENSITIVE)
2794     gdk_draw_string (window, style->font, style->white_gc, x + 1, y + 1, string);
2795
2796   gdk_draw_string (window, style->font, style->fg_gc[state_type], x, y, string);
2797
2798   if (area)
2799     {
2800       gdk_gc_set_clip_rectangle (style->white_gc, NULL);
2801       gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
2802     }
2803 }
2804
2805 static void
2806 option_menu_get_props (GtkWidget      *widget,
2807                        GtkRequisition *indicator_size,
2808                        GtkBorder      *indicator_spacing)
2809 {
2810   GtkRequisition *tmp_size = NULL;
2811   GtkBorder *tmp_spacing = NULL;
2812   
2813   if (widget)
2814     gtk_widget_style_get (widget, 
2815                           "indicator_size", &tmp_size,
2816                           "indicator_spacing", &tmp_spacing,
2817                           NULL);
2818
2819   if (tmp_size)
2820     {
2821       *indicator_size = *tmp_size;
2822       g_free (tmp_size);
2823     }
2824   else
2825     *indicator_size = default_option_indicator_size;
2826
2827   if (tmp_spacing)
2828     {
2829       *indicator_spacing = *tmp_spacing;
2830       g_free (tmp_spacing);
2831     }
2832   else
2833     *indicator_spacing = default_option_indicator_spacing;
2834 }
2835
2836 static void 
2837 gtk_default_draw_box (GtkStyle      *style,
2838                       GdkWindow     *window,
2839                       GtkStateType   state_type,
2840                       GtkShadowType  shadow_type,
2841                       GdkRectangle  *area,
2842                       GtkWidget     *widget,
2843                       const gchar   *detail,
2844                       gint           x,
2845                       gint           y,
2846                       gint           width,
2847                       gint           height)
2848 {
2849   g_return_if_fail (GTK_IS_STYLE (style));
2850   g_return_if_fail (window != NULL);
2851   
2852   sanitize_size (window, &width, &height);
2853   
2854   if (!style->bg_pixmap[state_type] || 
2855       GDK_IS_PIXMAP (window))
2856     {
2857       if (area)
2858         gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2859
2860       gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE,
2861                           x, y, width, height);
2862       if (area)
2863         gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2864     }
2865   else
2866     gtk_style_apply_default_background (style, window,
2867                                         widget && !GTK_WIDGET_NO_WINDOW (widget),
2868                                         state_type, area, x, y, width, height);
2869   
2870   gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
2871                     x, y, width, height);
2872
2873   if (detail && strcmp (detail, "optionmenu") == 0)
2874     {
2875       GtkRequisition indicator_size;
2876       GtkBorder indicator_spacing;
2877
2878       option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2879
2880       sanitize_size (window, &width, &height);
2881   
2882       gtk_paint_vline (style, window, state_type, area, widget,
2883                        detail,
2884                        y + style->ythickness + 1,
2885                        y + height - style->ythickness - 3,
2886                        x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness);
2887     }
2888 }
2889
2890 static GdkGC*
2891 get_darkened_gc (GdkWindow *window,
2892                  GdkColor  *color,
2893                  gint       darken_count)
2894 {
2895   GdkColor src = *color;
2896   GdkColor shaded;
2897   GdkGC *gc;
2898   
2899   gc = gdk_gc_new (window);
2900
2901   while (darken_count)
2902     {
2903       gtk_style_shade (&src, &shaded, 0.93);
2904       src = shaded;
2905       --darken_count;
2906     }
2907   
2908   gdk_gc_set_rgb_fg_color (gc, &shaded);
2909
2910   return gc;
2911 }
2912
2913 static void 
2914 gtk_default_draw_flat_box (GtkStyle      *style,
2915                            GdkWindow     *window,
2916                            GtkStateType   state_type,
2917                            GtkShadowType  shadow_type,
2918                            GdkRectangle  *area,
2919                            GtkWidget     *widget,
2920                            const gchar   *detail,
2921                            gint           x,
2922                            gint           y,
2923                            gint           width,
2924                            gint           height)
2925 {
2926   GdkGC *gc1;
2927   GdkGC *freeme = NULL;
2928   
2929   g_return_if_fail (GTK_IS_STYLE (style));
2930   g_return_if_fail (window != NULL);
2931   
2932   sanitize_size (window, &width, &height);
2933   
2934   if (detail)
2935     {
2936       if (state_type == GTK_STATE_SELECTED)
2937         {
2938           if (!strcmp ("text", detail))
2939             gc1 = style->bg_gc[GTK_STATE_SELECTED];
2940           else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
2941                    !strncmp ("cell_odd", detail, strlen ("cell_odd")))
2942             {
2943               /* This has to be really broken; alex made me do it. -jrb */
2944               /* Red rum!!! REd RUM!!! */
2945               if (GTK_WIDGET_HAS_FOCUS (widget))
2946                 gc1 = style->bg_gc[state_type];
2947               else 
2948                 gc1 = style->bg_gc[GTK_STATE_ACTIVE];
2949               
2950             }
2951           else
2952             {
2953               gc1 = style->bg_gc[state_type];
2954             }
2955         }
2956       else
2957         {
2958           if (!strcmp ("viewportbin", detail))
2959             gc1 = style->bg_gc[GTK_STATE_NORMAL];
2960           else if (!strcmp ("entry_bg", detail))
2961             gc1 = style->base_gc[state_type];
2962
2963           /* For trees: even rows are base color, odd rows are a shade of
2964            * the base color, the sort column is a shade of the original color
2965            * for that row.
2966            */
2967
2968           /* FIXME when we have style properties, clean this up.
2969            */
2970           
2971           else if (!strcmp ("cell_even", detail) ||
2972                    !strcmp ("cell_odd", detail) ||
2973                    !strcmp ("cell_even_ruled", detail))
2974             {
2975               gc1 = style->base_gc[state_type];
2976             }
2977           else if (!strcmp ("cell_even_sorted", detail) ||
2978                    !strcmp ("cell_odd_sorted", detail) ||
2979                    !strcmp ("cell_odd_ruled", detail) ||
2980                    !strcmp ("cell_even_ruled_sorted", detail))
2981             {
2982               freeme = get_darkened_gc (window, &style->base[state_type], 1);
2983               gc1 = freeme;
2984             }
2985           else if (!strcmp ("cell_odd_ruled_sorted", detail))
2986             {
2987               freeme = get_darkened_gc (window, &style->base[state_type], 2);
2988               gc1 = freeme;
2989             }
2990           else
2991             gc1 = style->bg_gc[state_type];
2992         }
2993     }
2994   else
2995     gc1 = style->bg_gc[state_type];
2996   
2997   if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
2998       GDK_IS_PIXMAP (window))
2999     {
3000       if (area)
3001         gdk_gc_set_clip_rectangle (gc1, area);
3002
3003       gdk_draw_rectangle (window, gc1, TRUE,
3004                           x, y, width, height);
3005
3006       if (detail && !strcmp ("tooltip", detail))
3007         gdk_draw_rectangle (window, style->black_gc, FALSE,
3008                             x, y, width - 1, height - 1);
3009
3010       if (area)
3011         gdk_gc_set_clip_rectangle (gc1, NULL);
3012     }
3013   else
3014     gtk_style_apply_default_background (style, window,
3015                                         widget && !GTK_WIDGET_NO_WINDOW (widget),
3016                                         state_type, area, x, y, width, height);
3017
3018
3019   if (freeme)
3020     g_object_unref (G_OBJECT (freeme));
3021 }
3022
3023 static void 
3024 gtk_default_draw_check (GtkStyle      *style,
3025                         GdkWindow     *window,
3026                         GtkStateType   state_type,
3027                         GtkShadowType  shadow_type,
3028                         GdkRectangle  *area,
3029                         GtkWidget     *widget,
3030                         const gchar   *detail,
3031                         gint           x,
3032                         gint           y,
3033                         gint           width,
3034                         gint           height)
3035 {
3036   if (detail && strcmp (detail, "cellcheck") == 0)
3037     {
3038       gdk_draw_rectangle (window,
3039                           widget->style->fg_gc[state_type],
3040                           FALSE,
3041                           x, y,
3042                           width, height);
3043
3044       if (shadow_type == GTK_SHADOW_IN)
3045         {
3046           gdk_draw_line (window,
3047                          widget->style->fg_gc[state_type],
3048                          x, y,
3049                          x + width,
3050                          y + height);
3051           gdk_draw_line (window,
3052                          widget->style->fg_gc[state_type],
3053                          x + width,
3054                          y,
3055                          x,
3056                          y + height);
3057         }
3058     }
3059   else
3060     {
3061       x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3062       y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3063       
3064       if (strcmp (detail, "check") == 0)        /* Menu item */
3065         {
3066           if (shadow_type == GTK_SHADOW_IN)
3067             {
3068               draw_part (window, style->black_gc, area, x, y, CHECK_TEXT);
3069               draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_AA);
3070             }
3071         }
3072       else
3073         {
3074           draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
3075           draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
3076           draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
3077           draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
3078           draw_part (window, style->base_gc[state_type], area, x, y, CHECK_BASE);
3079           
3080           if (shadow_type == GTK_SHADOW_IN)
3081             {
3082               draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3083               draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3084             }
3085         }
3086     }
3087
3088 }
3089
3090 static void 
3091 gtk_default_draw_option (GtkStyle      *style,
3092                          GdkWindow     *window,
3093                          GtkStateType   state_type,
3094                          GtkShadowType  shadow_type,
3095                          GdkRectangle  *area,
3096                          GtkWidget     *widget,
3097                          const gchar   *detail,
3098                          gint           x,
3099                          gint           y,
3100                          gint           width,
3101                          gint           height)
3102 {
3103   if (detail && strcmp (detail, "cellradio") == 0)
3104     {
3105       gdk_draw_arc (window,
3106                     widget->style->fg_gc[state_type],
3107                     FALSE,
3108                     x, y,
3109                     width,
3110                     height,
3111                     0, 360*64);
3112
3113       if (shadow_type == GTK_SHADOW_IN)
3114         {
3115           gdk_draw_arc (window,
3116                         widget->style->fg_gc[state_type],
3117                         TRUE,
3118                         x + 2,
3119                         y + 2,
3120                         width - 4,
3121                         height - 4,
3122                         0, 360*64);
3123         }
3124     }
3125   else
3126     {
3127       x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3128       y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3129       
3130       if (strcmp (detail, "option") == 0)       /* Menu item */
3131         {
3132           if (shadow_type == GTK_SHADOW_IN)
3133             draw_part (window, style->fg_gc[state_type], area, x, y, RADIO_TEXT);
3134         }
3135       else
3136         {
3137           draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
3138           draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
3139           draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
3140           draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
3141           draw_part (window, style->base_gc[state_type], area, x, y, RADIO_BASE);
3142           
3143           if (shadow_type == GTK_SHADOW_IN)
3144             draw_part (window, style->text_gc[state_type], area, x, y, RADIO_TEXT);
3145         }
3146     }
3147 }
3148
3149 static void
3150 gtk_default_draw_tab (GtkStyle      *style,
3151                       GdkWindow     *window,
3152                       GtkStateType   state_type,
3153                       GtkShadowType  shadow_type,
3154                       GdkRectangle  *area,
3155                       GtkWidget     *widget,
3156                       const gchar   *detail,
3157                       gint           x,
3158                       gint           y,
3159                       gint           width,
3160                       gint           height)
3161 {
3162   GtkRequisition indicator_size;
3163   GtkBorder indicator_spacing;
3164   
3165   option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3166
3167   x += (width - indicator_size.width) / 2;
3168   y += (height - indicator_size.height) / 2 - 1;
3169
3170   draw_varrow (window, style->black_gc, shadow_type, area, GTK_ARROW_UP,
3171                x, y, indicator_size.width, 5);
3172   draw_varrow (window, style->black_gc, shadow_type, area, GTK_ARROW_DOWN,
3173                x, y + 8, indicator_size.width, 5);
3174 }
3175
3176 static void 
3177 gtk_default_draw_shadow_gap (GtkStyle       *style,
3178                              GdkWindow      *window,
3179                              GtkStateType    state_type,
3180                              GtkShadowType   shadow_type,
3181                              GdkRectangle   *area,
3182                              GtkWidget      *widget,
3183                              const gchar    *detail,
3184                              gint            x,
3185                              gint            y,
3186                              gint            width,
3187                              gint            height,
3188                              GtkPositionType gap_side,
3189                              gint            gap_x,
3190                              gint            gap_width)
3191 {
3192   GdkGC *gc1 = NULL;
3193   GdkGC *gc2 = NULL;
3194   GdkGC *gc3 = NULL;
3195   GdkGC *gc4 = NULL;
3196   
3197   g_return_if_fail (GTK_IS_STYLE (style));
3198   g_return_if_fail (window != NULL);
3199   
3200   sanitize_size (window, &width, &height);
3201   
3202   switch (shadow_type)
3203     {
3204     case GTK_SHADOW_NONE:
3205       return;
3206     case GTK_SHADOW_IN:
3207       gc1 = style->dark_gc[state_type];
3208       gc2 = style->black_gc;
3209       gc3 = style->bg_gc[state_type];
3210       gc4 = style->light_gc[state_type];
3211       break;
3212     case GTK_SHADOW_ETCHED_IN:
3213       gc1 = style->dark_gc[state_type];
3214       gc2 = style->light_gc[state_type];
3215       gc3 = style->dark_gc[state_type];
3216       gc4 = style->light_gc[state_type];
3217       break;
3218     case GTK_SHADOW_OUT:
3219       gc1 = style->light_gc[state_type];
3220       gc2 = style->bg_gc[state_type];
3221       gc3 = style->dark_gc[state_type];
3222       gc4 = style->black_gc;
3223       break;
3224     case GTK_SHADOW_ETCHED_OUT:
3225       gc1 = style->light_gc[state_type];
3226       gc2 = style->dark_gc[state_type];
3227       gc3 = style->light_gc[state_type];
3228       gc4 = style->dark_gc[state_type];
3229       break;
3230     }
3231   if (area)
3232     {
3233       gdk_gc_set_clip_rectangle (gc1, area);
3234       gdk_gc_set_clip_rectangle (gc2, area);
3235       gdk_gc_set_clip_rectangle (gc3, area);
3236       gdk_gc_set_clip_rectangle (gc4, area);
3237     }
3238   
3239   switch (shadow_type)
3240     {
3241     case GTK_SHADOW_NONE:
3242     case GTK_SHADOW_IN:
3243     case GTK_SHADOW_OUT:
3244     case GTK_SHADOW_ETCHED_IN:
3245     case GTK_SHADOW_ETCHED_OUT:
3246       switch (gap_side)
3247         {
3248         case GTK_POS_TOP:
3249           gdk_draw_line (window, gc1,
3250                          x, y, x, y + height - 1);
3251           gdk_draw_line (window, gc2,
3252                          x + 1, y, x + 1, y + height - 2);
3253           
3254           gdk_draw_line (window, gc3,
3255                          x + 1, y + height - 2, x + width - 2, y + height - 2);
3256           gdk_draw_line (window, gc3,
3257                          x + width - 2, y, x + width - 2, y + height - 2);
3258           gdk_draw_line (window, gc4,
3259                          x, y + height - 1, x + width - 1, y + height - 1);
3260           gdk_draw_line (window, gc4,
3261                          x + width - 1, y, x + width - 1, y + height - 1);
3262           if (gap_x > 0)
3263             {
3264               gdk_draw_line (window, gc1,
3265                              x, y, x + gap_x - 1, y);
3266               gdk_draw_line (window, gc2,
3267                              x + 1, y + 1, x + gap_x - 1, y + 1);
3268               gdk_draw_line (window, gc2,
3269                              x + gap_x, y, x + gap_x, y);
3270             }
3271           if ((width - (gap_x + gap_width)) > 0)
3272             {
3273               gdk_draw_line (window, gc1,
3274                              x + gap_x + gap_width, y, x + width - 2, y);
3275               gdk_draw_line (window, gc2,
3276                              x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3277               gdk_draw_line (window, gc2,
3278                              x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3279             }
3280           break;
3281         case GTK_POS_BOTTOM:
3282           gdk_draw_line (window, gc1,
3283                          x, y, x + width - 1, y);
3284           gdk_draw_line (window, gc1,
3285                          x, y, x, y + height - 1);
3286           gdk_draw_line (window, gc2,
3287                          x + 1, y + 1, x + width - 2, y + 1);
3288           gdk_draw_line (window, gc2,
3289                          x + 1, y + 1, x + 1, y + height - 1);
3290           
3291           gdk_draw_line (window, gc3,
3292                          x + width - 2, y + 1, x + width - 2, y + height - 1);
3293           gdk_draw_line (window, gc4,
3294                          x + width - 1, y, x + width - 1, y + height - 1);
3295           if (gap_x > 0)
3296             {
3297               gdk_draw_line (window, gc4,
3298                              x, y + height - 1, x + gap_x - 1, y + height - 1);
3299               gdk_draw_line (window, gc3,
3300                              x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3301               gdk_draw_line (window, gc3,
3302                              x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3303             }
3304           if ((width - (gap_x + gap_width)) > 0)
3305             {
3306               gdk_draw_line (window, gc4,
3307                              x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3308               gdk_draw_line (window, gc3,
3309                              x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3310               gdk_draw_line (window, gc3,
3311                              x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3312             }
3313           break;
3314         case GTK_POS_LEFT:
3315           gdk_draw_line (window, gc1,
3316                          x, y, x + width - 1, y);
3317           gdk_draw_line (window, gc2,
3318                          x, y + 1, x + width - 2, y + 1);
3319           
3320           gdk_draw_line (window, gc3,
3321                          x, y + height - 2, x + width - 2, y + height - 2);
3322           gdk_draw_line (window, gc3,
3323                          x + width - 2, y + 1, x + width - 2, y + height - 2);
3324           gdk_draw_line (window, gc4,
3325                          x, y + height - 1, x + width - 1, y + height - 1);
3326           gdk_draw_line (window, gc4,
3327                          x + width - 1, y, x + width - 1, y + height - 1);
3328           if (gap_x > 0)
3329             {
3330               gdk_draw_line (window, gc1,
3331                              x, y, x, y + gap_x - 1);
3332               gdk_draw_line (window, gc2,
3333                              x + 1, y + 1, x + 1, y + gap_x - 1);
3334               gdk_draw_line (window, gc2,
3335                              x, y + gap_x, x, y + gap_x);
3336             }
3337           if ((width - (gap_x + gap_width)) > 0)
3338             {
3339               gdk_draw_line (window, gc1,
3340                              x, y + gap_x + gap_width, x, y + height - 2);
3341               gdk_draw_line (window, gc2,
3342                              x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3343               gdk_draw_line (window, gc2,
3344                              x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3345             }
3346           break;
3347         case GTK_POS_RIGHT:
3348           gdk_draw_line (window, gc1,
3349                          x, y, x + width - 1, y);
3350           gdk_draw_line (window, gc1,
3351                          x, y, x, y + height - 1);
3352           gdk_draw_line (window, gc2,
3353                          x + 1, y + 1, x + width - 1, y + 1);
3354           gdk_draw_line (window, gc2,
3355                          x + 1, y + 1, x + 1, y + height - 2);
3356           
3357           gdk_draw_line (window, gc3,
3358                          x + 1, y + height - 2, x + width - 1, y + height - 2);
3359           gdk_draw_line (window, gc4,
3360                          x, y + height - 1, x + width - 1, y + height - 1);
3361           if (gap_x > 0)
3362             {
3363               gdk_draw_line (window, gc4,
3364                              x + width - 1, y, x + width - 1, y + gap_x - 1);
3365               gdk_draw_line (window, gc3,
3366                              x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3367               gdk_draw_line (window, gc3,
3368                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3369             }
3370           if ((width - (gap_x + gap_width)) > 0)
3371             {
3372               gdk_draw_line (window, gc4,
3373                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3374               gdk_draw_line (window, gc3,
3375                              x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3376               gdk_draw_line (window, gc3,
3377                              x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3378             }
3379           break;
3380         }
3381     }
3382
3383   if (area)
3384     {
3385       gdk_gc_set_clip_rectangle (gc1, NULL);
3386       gdk_gc_set_clip_rectangle (gc2, NULL);
3387       gdk_gc_set_clip_rectangle (gc3, NULL);
3388       gdk_gc_set_clip_rectangle (gc4, NULL);
3389     }
3390 }
3391
3392 static void 
3393 gtk_default_draw_box_gap (GtkStyle       *style,
3394                           GdkWindow      *window,
3395                           GtkStateType    state_type,
3396                           GtkShadowType   shadow_type,
3397                           GdkRectangle   *area,
3398                           GtkWidget      *widget,
3399                           const gchar    *detail,
3400                           gint            x,
3401                           gint            y,
3402                           gint            width,
3403                           gint            height,
3404                           GtkPositionType gap_side,
3405                           gint            gap_x,
3406                           gint            gap_width)
3407 {
3408   GdkGC *gc1 = NULL;
3409   GdkGC *gc2 = NULL;
3410   GdkGC *gc3 = NULL;
3411   GdkGC *gc4 = NULL;
3412   
3413   g_return_if_fail (GTK_IS_STYLE (style));
3414   g_return_if_fail (window != NULL);
3415   
3416   gtk_style_apply_default_background (style, window,
3417                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
3418                                       state_type, area, x, y, width, height);
3419   
3420   sanitize_size (window, &width, &height);
3421   
3422   switch (shadow_type)
3423     {
3424     case GTK_SHADOW_NONE:
3425       return;
3426     case GTK_SHADOW_IN:
3427       gc1 = style->dark_gc[state_type];
3428       gc2 = style->black_gc;
3429       gc3 = style->bg_gc[state_type];
3430       gc4 = style->light_gc[state_type];
3431       break;
3432     case GTK_SHADOW_ETCHED_IN:
3433       gc1 = style->dark_gc[state_type];
3434       gc2 = style->light_gc[state_type];
3435       gc3 = style->dark_gc[state_type];
3436       gc4 = style->light_gc[state_type];
3437       break;
3438     case GTK_SHADOW_OUT:
3439       gc1 = style->light_gc[state_type];
3440       gc2 = style->bg_gc[state_type];
3441       gc3 = style->dark_gc[state_type];
3442       gc4 = style->black_gc;
3443       break;
3444     case GTK_SHADOW_ETCHED_OUT:
3445       gc1 = style->light_gc[state_type];
3446       gc2 = style->dark_gc[state_type];
3447       gc3 = style->light_gc[state_type];
3448       gc4 = style->dark_gc[state_type];
3449       break;
3450     }
3451
3452   if (area)
3453     {
3454       gdk_gc_set_clip_rectangle (gc1, area);
3455       gdk_gc_set_clip_rectangle (gc2, area);
3456       gdk_gc_set_clip_rectangle (gc3, area);
3457       gdk_gc_set_clip_rectangle (gc4, area);
3458     }
3459   
3460   switch (shadow_type)
3461     {
3462     case GTK_SHADOW_NONE:
3463     case GTK_SHADOW_IN:
3464     case GTK_SHADOW_OUT:
3465     case GTK_SHADOW_ETCHED_IN:
3466     case GTK_SHADOW_ETCHED_OUT:
3467       switch (gap_side)
3468         {
3469         case GTK_POS_TOP:
3470           gdk_draw_line (window, gc1,
3471                          x, y, x, y + height - 1);
3472           gdk_draw_line (window, gc2,
3473                          x + 1, y, x + 1, y + height - 2);
3474           
3475           gdk_draw_line (window, gc3,
3476                          x + 1, y + height - 2, x + width - 2, y + height - 2);
3477           gdk_draw_line (window, gc3,
3478                          x + width - 2, y, x + width - 2, y + height - 2);
3479           gdk_draw_line (window, gc4,
3480                          x, y + height - 1, x + width - 1, y + height - 1);
3481           gdk_draw_line (window, gc4,
3482                          x + width - 1, y, x + width - 1, y + height - 1);
3483           if (gap_x > 0)
3484             {
3485               gdk_draw_line (window, gc1,
3486                              x, y, x + gap_x - 1, y);
3487               gdk_draw_line (window, gc2,
3488                              x + 1, y + 1, x + gap_x - 1, y + 1);
3489               gdk_draw_line (window, gc2,
3490                              x + gap_x, y, x + gap_x, y);
3491             }
3492           if ((width - (gap_x + gap_width)) > 0)
3493             {
3494               gdk_draw_line (window, gc1,
3495                              x + gap_x + gap_width, y, x + width - 2, y);
3496               gdk_draw_line (window, gc2,
3497                              x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3498               gdk_draw_line (window, gc2,
3499                              x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3500             }
3501           break;
3502         case  GTK_POS_BOTTOM:
3503           gdk_draw_line (window, gc1,
3504                          x, y, x + width - 1, y);
3505           gdk_draw_line (window, gc1,
3506                          x, y, x, y + height - 1);
3507           gdk_draw_line (window, gc2,
3508                          x + 1, y + 1, x + width - 2, y + 1);
3509           gdk_draw_line (window, gc2,
3510                          x + 1, y + 1, x + 1, y + height - 1);
3511           
3512           gdk_draw_line (window, gc3,
3513                          x + width - 2, y + 1, x + width - 2, y + height - 1);
3514           gdk_draw_line (window, gc4,
3515                          x + width - 1, y, x + width - 1, y + height - 1);
3516           if (gap_x > 0)
3517             {
3518               gdk_draw_line (window, gc4,
3519                              x, y + height - 1, x + gap_x - 1, y + height - 1);
3520               gdk_draw_line (window, gc3,
3521                              x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3522               gdk_draw_line (window, gc3,
3523                              x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3524             }
3525           if ((width - (gap_x + gap_width)) > 0)
3526             {
3527               gdk_draw_line (window, gc4,
3528                              x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3529               gdk_draw_line (window, gc3,
3530                              x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3531               gdk_draw_line (window, gc3,
3532                              x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3533             }
3534           break;
3535         case GTK_POS_LEFT:
3536           gdk_draw_line (window, gc1,
3537                          x, y, x + width - 1, y);
3538           gdk_draw_line (window, gc2,
3539                          x, y + 1, x + width - 2, y + 1);
3540           
3541           gdk_draw_line (window, gc3,
3542                          x, y + height - 2, x + width - 2, y + height - 2);
3543           gdk_draw_line (window, gc3,
3544                          x + width - 2, y + 1, x + width - 2, y + height - 2);
3545           gdk_draw_line (window, gc4,
3546                          x, y + height - 1, x + width - 1, y + height - 1);
3547           gdk_draw_line (window, gc4,
3548                          x + width - 1, y, x + width - 1, y + height - 1);
3549           if (gap_x > 0)
3550             {
3551               gdk_draw_line (window, gc1,
3552                              x, y, x, y + gap_x - 1);
3553               gdk_draw_line (window, gc2,
3554                              x + 1, y + 1, x + 1, y + gap_x - 1);
3555               gdk_draw_line (window, gc2,
3556                              x, y + gap_x, x, y + gap_x);
3557             }
3558           if ((width - (gap_x + gap_width)) > 0)
3559             {
3560               gdk_draw_line (window, gc1,
3561                              x, y + gap_x + gap_width, x, y + height - 2);
3562               gdk_draw_line (window, gc2,
3563                              x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3564               gdk_draw_line (window, gc2,
3565                              x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3566             }
3567           break;
3568         case GTK_POS_RIGHT:
3569           gdk_draw_line (window, gc1,
3570                          x, y, x + width - 1, y);
3571           gdk_draw_line (window, gc1,
3572                          x, y, x, y + height - 1);
3573           gdk_draw_line (window, gc2,
3574                          x + 1, y + 1, x + width - 1, y + 1);
3575           gdk_draw_line (window, gc2,
3576                          x + 1, y + 1, x + 1, y + height - 2);
3577           
3578           gdk_draw_line (window, gc3,
3579                          x + 1, y + height - 2, x + width - 1, y + height - 2);
3580           gdk_draw_line (window, gc4,
3581                          x, y + height - 1, x + width - 1, y + height - 1);
3582           if (gap_x > 0)
3583             {
3584               gdk_draw_line (window, gc4,
3585                              x + width - 1, y, x + width - 1, y + gap_x - 1);
3586               gdk_draw_line (window, gc3,
3587                              x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3588               gdk_draw_line (window, gc3,
3589                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3590             }
3591           if ((width - (gap_x + gap_width)) > 0)
3592             {
3593               gdk_draw_line (window, gc4,
3594                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3595               gdk_draw_line (window, gc3,
3596                              x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3597               gdk_draw_line (window, gc3,
3598                              x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3599             }
3600           break;
3601         }
3602     }
3603
3604   if (area)
3605     {
3606       gdk_gc_set_clip_rectangle (gc1, NULL);
3607       gdk_gc_set_clip_rectangle (gc2, NULL);
3608       gdk_gc_set_clip_rectangle (gc3, NULL);
3609       gdk_gc_set_clip_rectangle (gc4, NULL);
3610     }
3611 }
3612
3613 static void 
3614 gtk_default_draw_extension (GtkStyle       *style,
3615                             GdkWindow      *window,
3616                             GtkStateType    state_type,
3617                             GtkShadowType   shadow_type,
3618                             GdkRectangle   *area,
3619                             GtkWidget      *widget,
3620                             const gchar    *detail,
3621                             gint            x,
3622                             gint            y,
3623                             gint            width,
3624                             gint            height,
3625                             GtkPositionType gap_side)
3626 {
3627   GdkGC *gc1 = NULL;
3628   GdkGC *gc2 = NULL;
3629   GdkGC *gc3 = NULL;
3630   GdkGC *gc4 = NULL;
3631   
3632   g_return_if_fail (GTK_IS_STYLE (style));
3633   g_return_if_fail (window != NULL);
3634   
3635   gtk_style_apply_default_background (style, window,
3636                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
3637                                       GTK_STATE_NORMAL, area, x, y, width, height);
3638   
3639   sanitize_size (window, &width, &height);
3640   
3641   switch (shadow_type)
3642     {
3643     case GTK_SHADOW_NONE:
3644       return;
3645     case GTK_SHADOW_IN:
3646       gc1 = style->dark_gc[state_type];
3647       gc2 = style->black_gc;
3648       gc3 = style->bg_gc[state_type];
3649       gc4 = style->light_gc[state_type];
3650       break;
3651     case GTK_SHADOW_ETCHED_IN:
3652       gc1 = style->dark_gc[state_type];
3653       gc2 = style->light_gc[state_type];
3654       gc3 = style->dark_gc[state_type];
3655       gc4 = style->light_gc[state_type];
3656       break;
3657     case GTK_SHADOW_OUT:
3658       gc1 = style->light_gc[state_type];
3659       gc2 = style->bg_gc[state_type];
3660       gc3 = style->dark_gc[state_type];
3661       gc4 = style->black_gc;
3662       break;
3663     case GTK_SHADOW_ETCHED_OUT:
3664       gc1 = style->light_gc[state_type];
3665       gc2 = style->dark_gc[state_type];
3666       gc3 = style->light_gc[state_type];
3667       gc4 = style->dark_gc[state_type];
3668       break;
3669     }
3670
3671   if (area)
3672     {
3673       gdk_gc_set_clip_rectangle (gc1, area);
3674       gdk_gc_set_clip_rectangle (gc2, area);
3675       gdk_gc_set_clip_rectangle (gc3, area);
3676       gdk_gc_set_clip_rectangle (gc4, area);
3677     }
3678
3679   switch (shadow_type)
3680     {
3681     case GTK_SHADOW_NONE:
3682     case GTK_SHADOW_IN:
3683     case GTK_SHADOW_OUT:
3684     case GTK_SHADOW_ETCHED_IN:
3685     case GTK_SHADOW_ETCHED_OUT:
3686       switch (gap_side)
3687         {
3688         case GTK_POS_TOP:
3689           gtk_style_apply_default_background (style, window,
3690                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3691                                               state_type, area,
3692                                               x + style->xthickness, 
3693                                               y, 
3694                                               width - (2 * style->xthickness), 
3695                                               height - (style->ythickness));
3696           gdk_draw_line (window, gc1,
3697                          x, y, x, y + height - 2);
3698           gdk_draw_line (window, gc2,
3699                          x + 1, y, x + 1, y + height - 2);
3700           
3701           gdk_draw_line (window, gc3,
3702                          x + 2, y + height - 2, x + width - 2, y + height - 2);
3703           gdk_draw_line (window, gc3,
3704                          x + width - 2, y, x + width - 2, y + height - 2);
3705           gdk_draw_line (window, gc4,
3706                          x + 1, y + height - 1, x + width - 2, y + height - 1);
3707           gdk_draw_line (window, gc4,
3708                          x + width - 1, y, x + width - 1, y + height - 2);
3709           break;
3710         case GTK_POS_BOTTOM:
3711           gtk_style_apply_default_background (style, window,
3712                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3713                                               state_type, area,
3714                                               x + style->xthickness, 
3715                                               y + style->ythickness, 
3716                                               width - (2 * style->xthickness), 
3717                                               height - (style->ythickness));
3718           gdk_draw_line (window, gc1,
3719                          x + 1, y, x + width - 2, y);
3720           gdk_draw_line (window, gc1,
3721                          x, y + 1, x, y + height - 1);
3722           gdk_draw_line (window, gc2,
3723                          x + 1, y + 1, x + width - 2, y + 1);
3724           gdk_draw_line (window, gc2,
3725                          x + 1, y + 1, x + 1, y + height - 1);
3726           
3727           gdk_draw_line (window, gc3,
3728                          x + width - 2, y + 2, x + width - 2, y + height - 1);
3729           gdk_draw_line (window, gc4,
3730                          x + width - 1, y + 1, x + width - 1, y + height - 1);
3731           break;
3732         case GTK_POS_LEFT:
3733           gtk_style_apply_default_background (style, window,
3734                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3735                                               state_type, area,
3736                                               x, 
3737                                               y + style->ythickness, 
3738                                               width - (style->xthickness), 
3739                                               height - (2 * style->ythickness));
3740           gdk_draw_line (window, gc1,
3741                          x, y, x + width - 2, y);
3742           gdk_draw_line (window, gc2,
3743                          x + 1, y + 1, x + width - 2, y + 1);
3744           
3745           gdk_draw_line (window, gc3,
3746                          x, y + height - 2, x + width - 2, y + height - 2);
3747           gdk_draw_line (window, gc3,
3748                          x + width - 2, y + 2, x + width - 2, y + height - 2);
3749           gdk_draw_line (window, gc4,
3750                          x, y + height - 1, x + width - 2, y + height - 1);
3751           gdk_draw_line (window, gc4,
3752                          x + width - 1, y + 1, x + width - 1, y + height - 2);
3753           break;
3754         case GTK_POS_RIGHT:
3755           gtk_style_apply_default_background (style, window,
3756                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3757                                               state_type, area,
3758                                               x + style->xthickness, 
3759                                               y + style->ythickness, 
3760                                               width - (style->xthickness), 
3761                                               height - (2 * style->ythickness));
3762           gdk_draw_line (window, gc1,
3763                          x + 1, y, x + width - 1, y);
3764           gdk_draw_line (window, gc1,
3765                          x, y + 1, x, y + height - 2);
3766           gdk_draw_line (window, gc2,
3767                          x + 1, y + 1, x + width - 1, y + 1);
3768           gdk_draw_line (window, gc2,
3769                          x + 1, y + 1, x + 1, y + height - 2);
3770           
3771           gdk_draw_line (window, gc3,
3772                          x + 2, y + height - 2, x + width - 1, y + height - 2);
3773           gdk_draw_line (window, gc4,
3774                          x + 1, y + height - 1, x + width - 1, y + height - 1);
3775           break;
3776         }
3777     }
3778
3779   if (area)
3780     {
3781       gdk_gc_set_clip_rectangle (gc1, NULL);
3782       gdk_gc_set_clip_rectangle (gc2, NULL);
3783       gdk_gc_set_clip_rectangle (gc3, NULL);
3784       gdk_gc_set_clip_rectangle (gc4, NULL);
3785     }
3786 }
3787
3788 static void 
3789 gtk_default_draw_focus (GtkStyle      *style,
3790                         GdkWindow     *window,
3791                         GdkRectangle  *area,
3792                         GtkWidget     *widget,
3793                         const gchar   *detail,
3794                         gint           x,
3795                         gint           y,
3796                         gint           width,
3797                         gint           height)
3798 {
3799   GdkPoint points[5];
3800   
3801   sanitize_size (window, &width, &height);
3802   
3803   if (area)
3804     gdk_gc_set_clip_rectangle (style->black_gc, area);
3805
3806   gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
3807
3808   if (detail && !strcmp (detail, "add-mode"))
3809     gdk_gc_set_dashes (style->black_gc, 0, "\4\4", 2);
3810   else
3811     gdk_gc_set_dashes (style->black_gc, 0, "\1\1", 2);
3812
3813   points[0].x = x;
3814   points[0].y = y;
3815   points[1].x = x + width;
3816   points[1].y = y;
3817   points[2].x = x + width;
3818   points[2].y = y + height;
3819   points[3].x = x;
3820   points[3].y = y + height;
3821   points[4] = points[0];
3822   
3823   gdk_draw_polygon (window, style->black_gc, FALSE, points, 4);
3824   gdk_gc_set_line_attributes (style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
3825
3826   if (area)
3827     gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3828 }
3829
3830 static void 
3831 gtk_default_draw_slider (GtkStyle      *style,
3832                          GdkWindow     *window,
3833                          GtkStateType   state_type,
3834                          GtkShadowType  shadow_type,
3835                          GdkRectangle  *area,
3836                          GtkWidget     *widget,
3837                          const gchar   *detail,
3838                          gint           x,
3839                          gint           y,
3840                          gint           width,
3841                          gint           height,
3842                          GtkOrientation orientation)
3843 {
3844   g_return_if_fail (GTK_IS_STYLE (style));
3845   g_return_if_fail (window != NULL);
3846   
3847   sanitize_size (window, &width, &height);
3848   
3849   gtk_paint_box (style, window, state_type, shadow_type,
3850                  area, widget, detail, x, y, width, height);
3851
3852   if (detail &&
3853       (strcmp ("hscale", detail) == 0 ||
3854        strcmp ("vscale", detail) == 0))
3855     {
3856       if (orientation == GTK_ORIENTATION_HORIZONTAL)
3857         gtk_paint_vline (style, window, state_type, area, widget, detail, 
3858                          y + style->ythickness, 
3859                          y + height - style->ythickness - 1, x + width / 2);
3860       else
3861         gtk_paint_hline (style, window, state_type, area, widget, detail, 
3862                          x + style->xthickness, 
3863                          x + width - style->xthickness - 1, y + height / 2);
3864     }
3865 }
3866
3867 static void
3868 draw_dot (GdkWindow    *window,
3869           GdkGC        *light_gc,
3870           GdkGC        *dark_gc,
3871           gint          x,
3872           gint          y,
3873           gushort       size)
3874 {
3875   
3876   size = CLAMP (size, 2, 3);
3877
3878   if (size == 2)
3879     {
3880       gdk_draw_point (window, light_gc, x, y);
3881       gdk_draw_point (window, light_gc, x+1, y+1);
3882     }
3883   else if (size == 3);
3884     {
3885       gdk_draw_point (window, light_gc, x, y);
3886       gdk_draw_point (window, light_gc, x+1, y);
3887       gdk_draw_point (window, light_gc, x, y+1);
3888       gdk_draw_point (window, dark_gc, x+1, y+2);
3889       gdk_draw_point (window, dark_gc, x+2, y+1);
3890       gdk_draw_point (window, dark_gc, x+2, y+2);
3891     }
3892 }
3893
3894 static void 
3895 gtk_default_draw_handle (GtkStyle      *style,
3896                          GdkWindow     *window,
3897                          GtkStateType   state_type,
3898                          GtkShadowType  shadow_type,
3899                          GdkRectangle  *area,
3900                          GtkWidget     *widget,
3901                          const gchar   *detail,
3902                          gint           x,
3903                          gint           y,
3904                          gint           width,
3905                          gint           height,
3906                          GtkOrientation orientation)
3907 {
3908   gint xx, yy;
3909   gint xthick, ythick;
3910   GdkGC *light_gc, *dark_gc;
3911   GdkRectangle rect;
3912   GdkRectangle dest;
3913   gint intersect;
3914   
3915   g_return_if_fail (GTK_IS_STYLE (style));
3916   g_return_if_fail (window != NULL);
3917   
3918   sanitize_size (window, &width, &height);
3919   
3920   gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
3921                  detail, x, y, width, height);
3922   
3923   
3924   if (!strcmp (detail, "paned"))
3925     {
3926       /* we want to ignore the shadow border in paned widgets */
3927       xthick = 0;
3928       ythick = 0;
3929
3930       light_gc = style->light_gc[state_type];
3931       dark_gc = style->black_gc;
3932     }
3933   else
3934     {
3935       xthick = style->xthickness;
3936       ythick = style->ythickness;
3937
3938       light_gc = style->light_gc[state_type];
3939       dark_gc = style->dark_gc[state_type];
3940     }
3941   
3942   rect.x = x + xthick;
3943   rect.y = y + ythick;
3944   rect.width = width - (xthick * 2);
3945   rect.height = height - (ythick * 2);
3946
3947   if (area)
3948       intersect = gdk_rectangle_intersect (area, &rect, &dest);
3949   else
3950     {
3951       intersect = TRUE;
3952       dest = rect;
3953     }
3954
3955   if (!intersect)
3956     return;
3957
3958   gdk_gc_set_clip_rectangle (light_gc, &dest);
3959   gdk_gc_set_clip_rectangle (dark_gc, &dest);
3960
3961   if (!strcmp (detail, "paned"))
3962     {
3963       gint window_width;
3964       gint window_height;
3965
3966       gdk_window_get_size (window, &window_width, &window_height);
3967
3968       if (orientation == GTK_ORIENTATION_HORIZONTAL)
3969         for (xx = window_width/2 - 15; xx <= window_width/2 + 15; xx += 5)
3970           draw_dot (window, light_gc, dark_gc, xx, window_height/2 - 1, 3);
3971       else
3972         for (yy = window_height/2 - 15; yy <= window_height/2 + 15; yy += 5)
3973           draw_dot (window, light_gc, dark_gc, window_width/2 - 1, yy, 3);
3974     }
3975   else
3976     {
3977       for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3978         for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3979           {
3980             draw_dot (window, light_gc, dark_gc, xx, yy, 2);
3981             draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
3982           }
3983     }
3984
3985   gdk_gc_set_clip_rectangle (light_gc, NULL);
3986   gdk_gc_set_clip_rectangle (dark_gc, NULL);
3987 }
3988
3989 static void
3990 create_expander_affine (gdouble affine[6],
3991                         gint    degrees,
3992                         gint    expander_size,
3993                         gint    x,
3994                         gint    y)
3995 {
3996   gdouble s, c;
3997   gdouble width;
3998   gdouble height;
3999
4000   width = expander_size / 4.0;
4001   height = expander_size / 2.0;
4002   
4003   s = sin (degrees * G_PI / 180.0);
4004   c = cos (degrees * G_PI / 180.0);
4005   
4006   affine[0] = c;
4007   affine[1] = s;
4008   affine[2] = -s;
4009   affine[3] = c;
4010   affine[4] = -width * c - height * -s + x;
4011   affine[5] = -width * s - height * c + y;
4012 }
4013
4014 static void
4015 apply_affine_on_point (double affine[6], GdkPoint *point)
4016 {
4017   gdouble x, y;
4018
4019   x = point->x * affine[0] + point->y * affine[2] + affine[4];
4020   y = point->x * affine[1] + point->y * affine[3] + affine[5];
4021
4022   point->x = x;
4023   point->y = y;
4024 }
4025
4026 static void
4027 gtk_default_draw_expander (GtkStyle        *style,
4028                            GdkWindow       *window,
4029                            GtkStateType     state_type,
4030                            GdkRectangle    *area,
4031                            GtkWidget       *widget,
4032                            const gchar     *detail,
4033                            gint             x,
4034                            gint             y,
4035                            GtkExpanderStyle expander_style)
4036 {
4037   gint expander_size;
4038   GdkPoint points[3];
4039   gint i;
4040   gdouble affine[6];
4041   gint degrees = 0;
4042   
4043   gtk_widget_style_get (widget,
4044                         "expander_size", &expander_size,
4045                         NULL);
4046
4047   if (area)
4048     {
4049       gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
4050       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
4051     }
4052
4053   points[0].x = 0;
4054   points[0].y = 0;
4055   points[1].x = expander_size / 2;
4056   points[1].y =  expander_size / 2;
4057   points[2].x = 0;
4058   points[2].y = expander_size;
4059
4060   switch (expander_style)
4061     {
4062     case GTK_EXPANDER_COLLAPSED:
4063       degrees = 0;
4064       break;
4065     case GTK_EXPANDER_SEMI_COLLAPSED:
4066       degrees = 30;
4067       break;
4068     case GTK_EXPANDER_SEMI_EXPANDED:
4069       degrees = 60;
4070       break;
4071     case GTK_EXPANDER_EXPANDED:
4072       degrees = 90;
4073       break;
4074     default:
4075       g_assert_not_reached ();
4076     }
4077   
4078   create_expander_affine (affine, degrees, expander_size, x, y);
4079
4080   for (i = 0; i < 3; i++)
4081     apply_affine_on_point (affine, &points[i]);
4082
4083   if (state_type == GTK_STATE_PRELIGHT)
4084     {
4085       gdk_draw_polygon (window, style->base_gc[GTK_STATE_NORMAL],
4086                         TRUE, points, 3);
4087       gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
4088                         FALSE, points, 3);
4089     }
4090   else if (state_type == GTK_STATE_ACTIVE)
4091     {
4092       gdk_draw_polygon (window, style->light_gc[GTK_STATE_ACTIVE],
4093                         TRUE, points, 3);
4094       gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
4095                         FALSE, points, 3);
4096     }
4097   else
4098     {
4099       gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
4100                         TRUE, points, 3);
4101     }
4102   if (area)
4103     {
4104       gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
4105       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
4106     }
4107 }
4108
4109 typedef struct _ByteRange ByteRange;
4110
4111 struct _ByteRange
4112 {
4113   guint start;
4114   guint end;
4115 };
4116
4117 static ByteRange*
4118 range_new (guint start,
4119            guint end)
4120 {
4121   ByteRange *br = g_new (ByteRange, 1);
4122
4123   br->start = start;
4124   br->end = end;
4125   
4126   return br;
4127 }
4128
4129 static PangoLayout*
4130 get_insensitive_layout (PangoLayout *layout)
4131 {
4132   GSList *embossed_ranges = NULL;
4133   GSList *stippled_ranges = NULL;
4134   PangoLayoutIter *iter;
4135   GSList *tmp_list = NULL;
4136   PangoLayout *new_layout;
4137   PangoAttrList *attrs;
4138   GdkBitmap *stipple = NULL;
4139   
4140   iter = pango_layout_get_iter (layout);
4141   
4142   do
4143     {
4144       PangoLayoutRun *run;
4145       PangoAttribute *attr;
4146       gboolean need_stipple = FALSE;
4147       ByteRange *br;
4148       
4149       run = pango_layout_iter_get_run (iter);
4150
4151       if (run)
4152         {
4153           tmp_list = run->item->analysis.extra_attrs;
4154
4155           while (tmp_list != NULL)
4156             {
4157               attr = tmp_list->data;
4158               switch (attr->klass->type)
4159                 {
4160                 case PANGO_ATTR_FOREGROUND:
4161                 case PANGO_ATTR_BACKGROUND:
4162                   need_stipple = TRUE;
4163                   break;
4164               
4165                 default:
4166                   break;
4167                 }
4168
4169               if (need_stipple)
4170                 break;
4171           
4172               tmp_list = g_slist_next (tmp_list);
4173             }
4174
4175           br = range_new (run->item->offset, run->item->offset + run->item->length);
4176       
4177           if (need_stipple)
4178             stippled_ranges = g_slist_prepend (stippled_ranges, br);
4179           else
4180             embossed_ranges = g_slist_prepend (embossed_ranges, br);
4181         }
4182     }
4183   while (pango_layout_iter_next_run (iter));
4184
4185   pango_layout_iter_free (iter);
4186
4187   new_layout = pango_layout_copy (layout);
4188
4189   attrs = pango_layout_get_attributes (new_layout);
4190
4191   if (attrs == NULL)
4192     {
4193       /* Create attr list if there wasn't one */
4194       attrs = pango_attr_list_new ();
4195       pango_layout_set_attributes (new_layout, attrs);
4196       pango_attr_list_unref (attrs);
4197     }
4198   
4199   tmp_list = embossed_ranges;
4200   while (tmp_list != NULL)
4201     {
4202       PangoAttribute *attr;
4203       ByteRange *br = tmp_list->data;
4204
4205       attr = gdk_pango_attr_embossed_new (TRUE);
4206
4207       attr->start_index = br->start;
4208       attr->end_index = br->end;
4209       
4210       pango_attr_list_change (attrs, attr);
4211
4212       g_free (br);
4213       
4214       tmp_list = g_slist_next (tmp_list);
4215     }
4216
4217   g_slist_free (embossed_ranges);
4218   
4219   tmp_list = stippled_ranges;
4220   while (tmp_list != NULL)
4221     {
4222       PangoAttribute *attr;
4223       ByteRange *br = tmp_list->data;
4224
4225       if (stipple == NULL)
4226         {
4227 #define gray50_width 2
4228 #define gray50_height 2
4229           static char gray50_bits[] = {
4230             0x02, 0x01
4231           };
4232
4233           stipple = gdk_bitmap_create_from_data (NULL,
4234                                                  gray50_bits, gray50_width,
4235                                                  gray50_height);
4236         }
4237       
4238       attr = gdk_pango_attr_stipple_new (stipple);
4239
4240       attr->start_index = br->start;
4241       attr->end_index = br->end;
4242       
4243       pango_attr_list_change (attrs, attr);
4244
4245       g_free (br);
4246       
4247       tmp_list = g_slist_next (tmp_list);
4248     }
4249
4250   g_slist_free (stippled_ranges);
4251   
4252   if (stipple)
4253     g_object_unref (G_OBJECT (stipple));
4254
4255   return new_layout;
4256 }
4257
4258 static void
4259 gtk_default_draw_layout (GtkStyle        *style,
4260                          GdkWindow       *window,
4261                          GtkStateType     state_type,
4262                          gboolean         use_text,
4263                          GdkRectangle    *area,
4264                          GtkWidget       *widget,
4265                          const gchar     *detail,
4266                          gint             x,
4267                          gint             y,
4268                          PangoLayout     *layout)
4269 {
4270   GdkGC *gc;
4271   
4272   g_return_if_fail (GTK_IS_STYLE (style));
4273   g_return_if_fail (window != NULL);
4274
4275   gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
4276   
4277   if (area)
4278     gdk_gc_set_clip_rectangle (gc, area);
4279
4280   if (state_type == GTK_STATE_INSENSITIVE)
4281     {
4282       PangoLayout *ins;
4283
4284       ins = get_insensitive_layout (layout);
4285       
4286       gdk_draw_layout (window, gc, x, y, ins);
4287
4288       g_object_unref (G_OBJECT (ins));
4289     }
4290   else
4291     {
4292       gdk_draw_layout (window, gc, x, y, layout);
4293     }
4294
4295   if (area)
4296     gdk_gc_set_clip_rectangle (gc, NULL);
4297 }
4298
4299 static void
4300 gtk_default_draw_resize_grip (GtkStyle       *style,
4301                               GdkWindow      *window,
4302                               GtkStateType    state_type,
4303                               GdkRectangle   *area,
4304                               GtkWidget      *widget,
4305                               const gchar    *detail,
4306                               GdkWindowEdge   edge,
4307                               gint            x,
4308                               gint            y,
4309                               gint            width,
4310                               gint            height)
4311 {
4312   g_return_if_fail (GTK_IS_STYLE (style));
4313   g_return_if_fail (window != NULL);
4314   
4315   if (area)
4316     {
4317       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
4318       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
4319       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
4320     }
4321
4322   /* make it square, aligning to bottom right */
4323   if (width < height)
4324     {
4325       y += (height - width);
4326       height = width;
4327     }
4328   else if (height < width)
4329     {
4330       x += (width - height);
4331       width = height;
4332     }
4333
4334   /* Clear background */
4335   gdk_draw_rectangle (window,
4336                       style->bg_gc[state_type],
4337                       TRUE,
4338                       x, y, width, height);
4339   
4340   switch (edge)
4341     {
4342     case GDK_WINDOW_EDGE_SOUTH_EAST:
4343       {
4344         gint xi, yi;
4345
4346         xi = x;
4347         yi = y;
4348
4349         while (xi < (x + width - 3))
4350           {
4351             gdk_draw_line (window,
4352                            style->light_gc[state_type],
4353                            xi, y + height,
4354                            x + width, yi);                           
4355
4356             ++xi;
4357             ++yi;
4358             
4359             gdk_draw_line (window,
4360                            style->dark_gc[state_type],
4361                            xi, y + height,
4362                            x + width, yi);                           
4363
4364             ++xi;
4365             ++yi;
4366             
4367             gdk_draw_line (window,
4368                            style->dark_gc[state_type],
4369                            xi, y + height,
4370                            x + width, yi);
4371
4372             xi += 3;
4373             yi += 3;
4374           }
4375       }
4376       break;
4377     default:
4378       g_assert_not_reached ();
4379       break;
4380     }
4381   
4382   if (area)
4383     {
4384       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
4385       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
4386       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
4387     }
4388 }
4389
4390 static void
4391 gtk_style_shade (GdkColor *a,
4392                  GdkColor *b,
4393                  gdouble   k)
4394 {
4395   gdouble red;
4396   gdouble green;
4397   gdouble blue;
4398   
4399   red = (gdouble) a->red / 65535.0;
4400   green = (gdouble) a->green / 65535.0;
4401   blue = (gdouble) a->blue / 65535.0;
4402   
4403   rgb_to_hls (&red, &green, &blue);
4404   
4405   green *= k;
4406   if (green > 1.0)
4407     green = 1.0;
4408   else if (green < 0.0)
4409     green = 0.0;
4410   
4411   blue *= k;
4412   if (blue > 1.0)
4413     blue = 1.0;
4414   else if (blue < 0.0)
4415     blue = 0.0;
4416   
4417   hls_to_rgb (&red, &green, &blue);
4418   
4419   b->red = red * 65535.0;
4420   b->green = green * 65535.0;
4421   b->blue = blue * 65535.0;
4422 }
4423
4424 static void
4425 rgb_to_hls (gdouble *r,
4426             gdouble *g,
4427             gdouble *b)
4428 {
4429   gdouble min;
4430   gdouble max;
4431   gdouble red;
4432   gdouble green;
4433   gdouble blue;
4434   gdouble h, l, s;
4435   gdouble delta;
4436   
4437   red = *r;
4438   green = *g;
4439   blue = *b;
4440   
4441   if (red > green)
4442     {
4443       if (red > blue)
4444         max = red;
4445       else
4446         max = blue;
4447       
4448       if (green < blue)
4449         min = green;
4450       else
4451         min = blue;
4452     }
4453   else
4454     {
4455       if (green > blue)
4456         max = green;
4457       else
4458         max = blue;
4459       
4460       if (red < blue)
4461         min = red;
4462       else
4463         min = blue;
4464     }
4465   
4466   l = (max + min) / 2;
4467   s = 0;
4468   h = 0;
4469   
4470   if (max != min)
4471     {
4472       if (l <= 0.5)
4473         s = (max - min) / (max + min);
4474       else
4475         s = (max - min) / (2 - max - min);
4476       
4477       delta = max -min;
4478       if (red == max)
4479         h = (green - blue) / delta;
4480       else if (green == max)
4481         h = 2 + (blue - red) / delta;
4482       else if (blue == max)
4483         h = 4 + (red - green) / delta;
4484       
4485       h *= 60;
4486       if (h < 0.0)
4487         h += 360;
4488     }
4489   
4490   *r = h;
4491   *g = l;
4492   *b = s;
4493 }
4494
4495 static void
4496 hls_to_rgb (gdouble *h,
4497             gdouble *l,
4498             gdouble *s)
4499 {
4500   gdouble hue;
4501   gdouble lightness;
4502   gdouble saturation;
4503   gdouble m1, m2;
4504   gdouble r, g, b;
4505   
4506   lightness = *l;
4507   saturation = *s;
4508   
4509   if (lightness <= 0.5)
4510     m2 = lightness * (1 + saturation);
4511   else
4512     m2 = lightness + saturation - lightness * saturation;
4513   m1 = 2 * lightness - m2;
4514   
4515   if (saturation == 0)
4516     {
4517       *h = lightness;
4518       *l = lightness;
4519       *s = lightness;
4520     }
4521   else
4522     {
4523       hue = *h + 120;
4524       while (hue > 360)
4525         hue -= 360;
4526       while (hue < 0)
4527         hue += 360;
4528       
4529       if (hue < 60)
4530         r = m1 + (m2 - m1) * hue / 60;
4531       else if (hue < 180)
4532         r = m2;
4533       else if (hue < 240)
4534         r = m1 + (m2 - m1) * (240 - hue) / 60;
4535       else
4536         r = m1;
4537       
4538       hue = *h;
4539       while (hue > 360)
4540         hue -= 360;
4541       while (hue < 0)
4542         hue += 360;
4543       
4544       if (hue < 60)
4545         g = m1 + (m2 - m1) * hue / 60;
4546       else if (hue < 180)
4547         g = m2;
4548       else if (hue < 240)
4549         g = m1 + (m2 - m1) * (240 - hue) / 60;
4550       else
4551         g = m1;
4552       
4553       hue = *h - 120;
4554       while (hue > 360)
4555         hue -= 360;
4556       while (hue < 0)
4557         hue += 360;
4558       
4559       if (hue < 60)
4560         b = m1 + (m2 - m1) * hue / 60;
4561       else if (hue < 180)
4562         b = m2;
4563       else if (hue < 240)
4564         b = m1 + (m2 - m1) * (240 - hue) / 60;
4565       else
4566         b = m1;
4567       
4568       *h = r;
4569       *l = g;
4570       *s = b;
4571     }
4572 }
4573
4574 void 
4575 gtk_paint_hline (GtkStyle      *style,
4576                  GdkWindow     *window,
4577                  GtkStateType   state_type,
4578                  GdkRectangle  *area,
4579                  GtkWidget     *widget,
4580                  const gchar   *detail,
4581                  gint          x1,
4582                  gint          x2,
4583                  gint          y)
4584 {
4585   g_return_if_fail (GTK_IS_STYLE (style));
4586   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4587   
4588   GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
4589 }
4590
4591 void
4592 gtk_paint_vline (GtkStyle      *style,
4593                  GdkWindow     *window,
4594                  GtkStateType   state_type,
4595                  GdkRectangle  *area,
4596                  GtkWidget     *widget,
4597                  const gchar   *detail,
4598                  gint          y1,
4599                  gint          y2,
4600                  gint          x)
4601 {
4602   g_return_if_fail (GTK_IS_STYLE (style));
4603   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4604   
4605   GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1, y2, x);
4606 }
4607
4608 void
4609 gtk_paint_shadow (GtkStyle     *style,
4610                   GdkWindow    *window,
4611                   GtkStateType  state_type,
4612                   GtkShadowType shadow_type,
4613                   GdkRectangle *area,
4614                   GtkWidget    *widget,
4615                   const gchar  *detail,
4616                   gint          x,
4617                   gint          y,
4618                   gint          width,
4619                   gint          height)
4620 {
4621   g_return_if_fail (GTK_IS_STYLE (style));
4622   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4623   
4624   GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4625 }
4626
4627 void
4628 gtk_paint_polygon (GtkStyle      *style,
4629                    GdkWindow     *window,
4630                    GtkStateType   state_type,
4631                    GtkShadowType  shadow_type,
4632                    GdkRectangle  *area,
4633                    GtkWidget     *widget,
4634                    const gchar   *detail,
4635                    GdkPoint      *points,
4636                    gint           npoints,
4637                    gboolean       fill)
4638 {
4639   g_return_if_fail (GTK_IS_STYLE (style));
4640   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4641   
4642   GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
4643 }
4644
4645 void
4646 gtk_paint_arrow (GtkStyle      *style,
4647                  GdkWindow     *window,
4648                  GtkStateType   state_type,
4649                  GtkShadowType  shadow_type,
4650                  GdkRectangle  *area,
4651                  GtkWidget     *widget,
4652                  const gchar   *detail,
4653                  GtkArrowType   arrow_type,
4654                  gboolean       fill,
4655                  gint           x,
4656                  gint           y,
4657                  gint           width,
4658                  gint           height)
4659 {
4660   g_return_if_fail (GTK_IS_STYLE (style));
4661   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4662   
4663   GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
4664 }
4665
4666 void
4667 gtk_paint_diamond (GtkStyle      *style,
4668                    GdkWindow     *window,
4669                    GtkStateType   state_type,
4670                    GtkShadowType  shadow_type,
4671                    GdkRectangle  *area,
4672                    GtkWidget     *widget,
4673                    const gchar   *detail,
4674                    gint        x,
4675                    gint        y,
4676                    gint        width,
4677                    gint        height)
4678 {
4679   g_return_if_fail (GTK_IS_STYLE (style));
4680   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4681   
4682   GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4683 }
4684
4685 void
4686 gtk_paint_string (GtkStyle      *style,
4687                   GdkWindow     *window,
4688                   GtkStateType   state_type,
4689                   GdkRectangle  *area,
4690                   GtkWidget     *widget,
4691                   const gchar   *detail,
4692                   gint           x,
4693                   gint           y,
4694                   const gchar   *string)
4695 {
4696   g_return_if_fail (GTK_IS_STYLE (style));
4697   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
4698   
4699   GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
4700 }
4701
4702 void
4703 gtk_paint_box (GtkStyle      *style,
4704                GdkWindow     *window,
4705                GtkStateType   state_type,
4706                GtkShadowType  shadow_type,
4707                GdkRectangle  *area,
4708                GtkWidget     *widget,
4709                const gchar   *detail,
4710                gint           x,
4711                gint           y,
4712                gint           width,
4713                gint           height)
4714 {
4715   g_return_if_fail (GTK_IS_STYLE (style));
4716   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
4717   
4718   GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4719 }
4720
4721 void
4722 gtk_paint_flat_box (GtkStyle      *style,
4723                     GdkWindow     *window,
4724                     GtkStateType   state_type,
4725                     GtkShadowType  shadow_type,
4726                     GdkRectangle  *area,
4727                     GtkWidget     *widget,
4728                     const gchar   *detail,
4729                     gint           x,
4730                     gint           y,
4731                     gint           width,
4732                     gint           height)
4733 {
4734   g_return_if_fail (GTK_IS_STYLE (style));
4735   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
4736   
4737   GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4738 }
4739
4740 void
4741 gtk_paint_check (GtkStyle      *style,
4742                  GdkWindow     *window,
4743                  GtkStateType   state_type,
4744                  GtkShadowType  shadow_type,
4745                  GdkRectangle  *area,
4746                  GtkWidget     *widget,
4747                  const gchar   *detail,
4748                  gint           x,
4749                  gint           y,
4750                  gint           width,
4751                  gint           height)
4752 {
4753   g_return_if_fail (GTK_IS_STYLE (style));
4754   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
4755   
4756   GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4757 }
4758
4759 void
4760 gtk_paint_option (GtkStyle      *style,
4761                   GdkWindow     *window,
4762                   GtkStateType   state_type,
4763                   GtkShadowType  shadow_type,
4764                   GdkRectangle  *area,
4765                   GtkWidget     *widget,
4766                   const gchar   *detail,
4767                   gint           x,
4768                   gint           y,
4769                   gint           width,
4770                   gint           height)
4771 {
4772   g_return_if_fail (GTK_IS_STYLE (style));
4773   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4774   
4775   GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4776 }
4777
4778 void
4779 gtk_paint_tab (GtkStyle      *style,
4780                GdkWindow     *window,
4781                GtkStateType   state_type,
4782                GtkShadowType  shadow_type,
4783                GdkRectangle  *area,
4784                GtkWidget     *widget,
4785                const gchar   *detail,
4786                gint           x,
4787                gint           y,
4788                gint           width,
4789                gint           height)
4790 {
4791   g_return_if_fail (GTK_IS_STYLE (style));
4792   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4793   
4794   GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4795 }
4796
4797 void
4798 gtk_paint_shadow_gap (GtkStyle       *style,
4799                       GdkWindow      *window,
4800                       GtkStateType    state_type,
4801                       GtkShadowType   shadow_type,
4802                       GdkRectangle   *area,
4803                       GtkWidget      *widget,
4804                       gchar          *detail,
4805                       gint            x,
4806                       gint            y,
4807                       gint            width,
4808                       gint            height,
4809                       GtkPositionType gap_side,
4810                       gint            gap_x,
4811                       gint            gap_width)
4812 {
4813   g_return_if_fail (GTK_IS_STYLE (style));
4814   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4815   
4816   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);
4817 }
4818
4819
4820 void
4821 gtk_paint_box_gap (GtkStyle       *style,
4822                    GdkWindow      *window,
4823                    GtkStateType    state_type,
4824                    GtkShadowType   shadow_type,
4825                    GdkRectangle   *area,
4826                    GtkWidget      *widget,
4827                    gchar          *detail,
4828                    gint            x,
4829                    gint            y,
4830                    gint            width,
4831                    gint            height,
4832                    GtkPositionType gap_side,
4833                    gint            gap_x,
4834                    gint            gap_width)
4835 {
4836   g_return_if_fail (GTK_IS_STYLE (style));
4837   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
4838   
4839   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);
4840 }
4841
4842 void
4843 gtk_paint_extension (GtkStyle       *style,
4844                      GdkWindow      *window,
4845                      GtkStateType    state_type,
4846                      GtkShadowType   shadow_type,
4847                      GdkRectangle   *area,
4848                      GtkWidget      *widget,
4849                      gchar          *detail,
4850                      gint            x,
4851                      gint            y,
4852                      gint            width,
4853                      gint            height,
4854                      GtkPositionType gap_side)
4855 {
4856   g_return_if_fail (GTK_IS_STYLE (style));
4857   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
4858   
4859   GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
4860 }
4861
4862 void
4863 gtk_paint_focus (GtkStyle      *style,
4864                  GdkWindow     *window,
4865                  GdkRectangle  *area,
4866                  GtkWidget     *widget,
4867                  const gchar   *detail,
4868                  gint           x,
4869                  gint           y,
4870                  gint           width,
4871                  gint           height)
4872 {
4873   g_return_if_fail (GTK_IS_STYLE (style));
4874   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
4875   
4876   GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, detail, x, y, width, height);
4877 }
4878
4879 void
4880 gtk_paint_slider (GtkStyle      *style,
4881                   GdkWindow     *window,
4882                   GtkStateType   state_type,
4883                   GtkShadowType  shadow_type,
4884                   GdkRectangle  *area,
4885                   GtkWidget     *widget,
4886                   const gchar   *detail,
4887                   gint           x,
4888                   gint           y,
4889                   gint           width,
4890                   gint           height,
4891                   GtkOrientation orientation)
4892 {
4893   g_return_if_fail (GTK_IS_STYLE (style));
4894   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
4895   
4896   GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
4897 }
4898
4899 void
4900 gtk_paint_handle (GtkStyle      *style,
4901                   GdkWindow     *window,
4902                   GtkStateType   state_type,
4903                   GtkShadowType  shadow_type,
4904                   GdkRectangle  *area,
4905                   GtkWidget     *widget,
4906                   const gchar   *detail,
4907                   gint           x,
4908                   gint           y,
4909                   gint           width,
4910                   gint           height,
4911                   GtkOrientation orientation)
4912 {
4913   g_return_if_fail (GTK_IS_STYLE (style));
4914   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
4915   
4916   GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
4917 }
4918
4919 void
4920 gtk_paint_expander (GtkStyle        *style,
4921                     GdkWindow       *window,
4922                     GtkStateType     state_type,
4923                     GdkRectangle    *area,
4924                     GtkWidget       *widget,
4925                     const gchar     *detail,
4926                     gint             x,
4927                     gint             y,
4928                     GtkExpanderStyle expander_style)
4929 {
4930   g_return_if_fail (GTK_IS_STYLE (style));
4931   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
4932   
4933   GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
4934                                               widget, detail, x, y, expander_style);
4935 }
4936
4937 void
4938 gtk_paint_layout (GtkStyle        *style,
4939                   GdkWindow       *window,
4940                   GtkStateType     state_type,
4941                   gboolean         use_text,
4942                   GdkRectangle    *area,
4943                   GtkWidget       *widget,
4944                   const gchar     *detail,
4945                   gint             x,
4946                   gint             y,
4947                   PangoLayout     *layout)
4948 {
4949   g_return_if_fail (GTK_IS_STYLE (style));
4950   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
4951   
4952   GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
4953                                             widget, detail, x, y, layout);
4954 }
4955
4956 void
4957 gtk_paint_resize_grip (GtkStyle      *style,
4958                        GdkWindow     *window,
4959                        GtkStateType   state_type,
4960                        GdkRectangle  *area,
4961                        GtkWidget     *widget,
4962                        const gchar   *detail,
4963                        GdkWindowEdge  edge,
4964                        gint           x,
4965                        gint           y,
4966                        gint           width,
4967                        gint           height)
4968
4969 {
4970   g_return_if_fail (GTK_IS_STYLE (style));
4971   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
4972
4973   GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
4974                                                  area, widget, detail,
4975                                                  edge, x, y, width, height);
4976 }
4977
4978 GtkBorder *
4979 gtk_border_copy (const GtkBorder *border)
4980 {
4981   return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
4982 }
4983
4984 void
4985 gtk_border_free (GtkBorder *border)
4986 {
4987   g_free (border);
4988 }
4989