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