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