]> Pileus Git - ~andy/gtk/blob - gtk/gtkstyle.c
ue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
[~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       x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3022       y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
3023       if (shadow_type == GTK_SHADOW_IN)
3024         {
3025           draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3026           draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3027         }
3028     }
3029   else
3030     {
3031       x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3032       y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3033       
3034       if (strcmp (detail, "check") == 0)        /* Menu item */
3035         {
3036           if (shadow_type == GTK_SHADOW_IN)
3037             {
3038               draw_part (window, style->black_gc, area, x, y, CHECK_TEXT);
3039               draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_AA);
3040             }
3041         }
3042       else
3043         {
3044           draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
3045           draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
3046           draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
3047           draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
3048           draw_part (window, style->base_gc[state_type], area, x, y, CHECK_BASE);
3049           
3050           if (shadow_type == GTK_SHADOW_IN)
3051             {
3052               draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3053               draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3054             }
3055         }
3056     }
3057
3058 }
3059
3060 static void 
3061 gtk_default_draw_option (GtkStyle      *style,
3062                          GdkWindow     *window,
3063                          GtkStateType   state_type,
3064                          GtkShadowType  shadow_type,
3065                          GdkRectangle  *area,
3066                          GtkWidget     *widget,
3067                          const gchar   *detail,
3068                          gint           x,
3069                          gint           y,
3070                          gint           width,
3071                          gint           height)
3072 {
3073   if (detail && strcmp (detail, "cellradio") == 0)
3074     {
3075       gdk_draw_arc (window,
3076                     widget->style->fg_gc[state_type],
3077                     FALSE,
3078                     x, y,
3079                     width,
3080                     height,
3081                     0, 360*64);
3082
3083       if (shadow_type == GTK_SHADOW_IN)
3084         {
3085           gdk_draw_arc (window,
3086                         widget->style->fg_gc[state_type],
3087                         TRUE,
3088                         x + 2,
3089                         y + 2,
3090                         width - 4,
3091                         height - 4,
3092                         0, 360*64);
3093         }
3094     }
3095   else
3096     {
3097       x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3098       y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3099       
3100       if (strcmp (detail, "option") == 0)       /* Menu item */
3101         {
3102           if (shadow_type == GTK_SHADOW_IN)
3103             draw_part (window, style->fg_gc[state_type], area, x, y, RADIO_TEXT);
3104         }
3105       else
3106         {
3107           draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
3108           draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
3109           draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
3110           draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
3111           draw_part (window, style->base_gc[state_type], area, x, y, RADIO_BASE);
3112           
3113           if (shadow_type == GTK_SHADOW_IN)
3114             draw_part (window, style->text_gc[state_type], area, x, y, RADIO_TEXT);
3115         }
3116     }
3117 }
3118
3119 static void
3120 gtk_default_draw_tab (GtkStyle      *style,
3121                       GdkWindow     *window,
3122                       GtkStateType   state_type,
3123                       GtkShadowType  shadow_type,
3124                       GdkRectangle  *area,
3125                       GtkWidget     *widget,
3126                       const gchar   *detail,
3127                       gint           x,
3128                       gint           y,
3129                       gint           width,
3130                       gint           height)
3131 {
3132   GtkRequisition indicator_size;
3133   GtkBorder indicator_spacing;
3134   
3135   option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3136
3137   x += (width - indicator_size.width) / 2;
3138   y += (height - indicator_size.height) / 2 - 1;
3139
3140   draw_varrow (window, style->black_gc, shadow_type, area, GTK_ARROW_UP,
3141                x, y, indicator_size.width, 5);
3142   draw_varrow (window, style->black_gc, shadow_type, area, GTK_ARROW_DOWN,
3143                x, y + 8, indicator_size.width, 5);
3144 }
3145
3146 static void 
3147 gtk_default_draw_shadow_gap (GtkStyle       *style,
3148                              GdkWindow      *window,
3149                              GtkStateType    state_type,
3150                              GtkShadowType   shadow_type,
3151                              GdkRectangle   *area,
3152                              GtkWidget      *widget,
3153                              const gchar    *detail,
3154                              gint            x,
3155                              gint            y,
3156                              gint            width,
3157                              gint            height,
3158                              GtkPositionType gap_side,
3159                              gint            gap_x,
3160                              gint            gap_width)
3161 {
3162   GdkGC *gc1 = NULL;
3163   GdkGC *gc2 = NULL;
3164   GdkGC *gc3 = NULL;
3165   GdkGC *gc4 = NULL;
3166   
3167   g_return_if_fail (GTK_IS_STYLE (style));
3168   g_return_if_fail (window != NULL);
3169   
3170   sanitize_size (window, &width, &height);
3171   
3172   switch (shadow_type)
3173     {
3174     case GTK_SHADOW_NONE:
3175       return;
3176     case GTK_SHADOW_IN:
3177       gc1 = style->dark_gc[state_type];
3178       gc2 = style->black_gc;
3179       gc3 = style->bg_gc[state_type];
3180       gc4 = style->light_gc[state_type];
3181       break;
3182     case GTK_SHADOW_ETCHED_IN:
3183       gc1 = style->dark_gc[state_type];
3184       gc2 = style->light_gc[state_type];
3185       gc3 = style->dark_gc[state_type];
3186       gc4 = style->light_gc[state_type];
3187       break;
3188     case GTK_SHADOW_OUT:
3189       gc1 = style->light_gc[state_type];
3190       gc2 = style->bg_gc[state_type];
3191       gc3 = style->dark_gc[state_type];
3192       gc4 = style->black_gc;
3193       break;
3194     case GTK_SHADOW_ETCHED_OUT:
3195       gc1 = style->light_gc[state_type];
3196       gc2 = style->dark_gc[state_type];
3197       gc3 = style->light_gc[state_type];
3198       gc4 = style->dark_gc[state_type];
3199       break;
3200     }
3201   if (area)
3202     {
3203       gdk_gc_set_clip_rectangle (gc1, area);
3204       gdk_gc_set_clip_rectangle (gc2, area);
3205       gdk_gc_set_clip_rectangle (gc3, area);
3206       gdk_gc_set_clip_rectangle (gc4, area);
3207     }
3208   
3209   switch (shadow_type)
3210     {
3211     case GTK_SHADOW_NONE:
3212     case GTK_SHADOW_IN:
3213     case GTK_SHADOW_OUT:
3214     case GTK_SHADOW_ETCHED_IN:
3215     case GTK_SHADOW_ETCHED_OUT:
3216       switch (gap_side)
3217         {
3218         case GTK_POS_TOP:
3219           gdk_draw_line (window, gc1,
3220                          x, y, x, y + height - 1);
3221           gdk_draw_line (window, gc2,
3222                          x + 1, y, x + 1, y + height - 2);
3223           
3224           gdk_draw_line (window, gc3,
3225                          x + 1, y + height - 2, x + width - 2, y + height - 2);
3226           gdk_draw_line (window, gc3,
3227                          x + width - 2, y, x + width - 2, y + height - 2);
3228           gdk_draw_line (window, gc4,
3229                          x, y + height - 1, x + width - 1, y + height - 1);
3230           gdk_draw_line (window, gc4,
3231                          x + width - 1, y, x + width - 1, y + height - 1);
3232           if (gap_x > 0)
3233             {
3234               gdk_draw_line (window, gc1,
3235                              x, y, x + gap_x - 1, y);
3236               gdk_draw_line (window, gc2,
3237                              x + 1, y + 1, x + gap_x - 1, y + 1);
3238               gdk_draw_line (window, gc2,
3239                              x + gap_x, y, x + gap_x, y);
3240             }
3241           if ((width - (gap_x + gap_width)) > 0)
3242             {
3243               gdk_draw_line (window, gc1,
3244                              x + gap_x + gap_width, y, x + width - 2, y);
3245               gdk_draw_line (window, gc2,
3246                              x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3247               gdk_draw_line (window, gc2,
3248                              x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3249             }
3250           break;
3251         case GTK_POS_BOTTOM:
3252           gdk_draw_line (window, gc1,
3253                          x, y, x + width - 1, y);
3254           gdk_draw_line (window, gc1,
3255                          x, y, x, y + height - 1);
3256           gdk_draw_line (window, gc2,
3257                          x + 1, y + 1, x + width - 2, y + 1);
3258           gdk_draw_line (window, gc2,
3259                          x + 1, y + 1, x + 1, y + height - 1);
3260           
3261           gdk_draw_line (window, gc3,
3262                          x + width - 2, y + 1, x + width - 2, y + height - 1);
3263           gdk_draw_line (window, gc4,
3264                          x + width - 1, y, x + width - 1, y + height - 1);
3265           if (gap_x > 0)
3266             {
3267               gdk_draw_line (window, gc4,
3268                              x, y + height - 1, x + gap_x - 1, y + height - 1);
3269               gdk_draw_line (window, gc3,
3270                              x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3271               gdk_draw_line (window, gc3,
3272                              x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3273             }
3274           if ((width - (gap_x + gap_width)) > 0)
3275             {
3276               gdk_draw_line (window, gc4,
3277                              x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3278               gdk_draw_line (window, gc3,
3279                              x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3280               gdk_draw_line (window, gc3,
3281                              x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3282             }
3283           break;
3284         case GTK_POS_LEFT:
3285           gdk_draw_line (window, gc1,
3286                          x, y, x + width - 1, y);
3287           gdk_draw_line (window, gc2,
3288                          x, y + 1, x + width - 2, y + 1);
3289           
3290           gdk_draw_line (window, gc3,
3291                          x, y + height - 2, x + width - 2, y + height - 2);
3292           gdk_draw_line (window, gc3,
3293                          x + width - 2, y + 1, x + width - 2, y + height - 2);
3294           gdk_draw_line (window, gc4,
3295                          x, y + height - 1, x + width - 1, y + height - 1);
3296           gdk_draw_line (window, gc4,
3297                          x + width - 1, y, x + width - 1, y + height - 1);
3298           if (gap_x > 0)
3299             {
3300               gdk_draw_line (window, gc1,
3301                              x, y, x, y + gap_x - 1);
3302               gdk_draw_line (window, gc2,
3303                              x + 1, y + 1, x + 1, y + gap_x - 1);
3304               gdk_draw_line (window, gc2,
3305                              x, y + gap_x, x, y + gap_x);
3306             }
3307           if ((width - (gap_x + gap_width)) > 0)
3308             {
3309               gdk_draw_line (window, gc1,
3310                              x, y + gap_x + gap_width, x, y + height - 2);
3311               gdk_draw_line (window, gc2,
3312                              x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3313               gdk_draw_line (window, gc2,
3314                              x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3315             }
3316           break;
3317         case GTK_POS_RIGHT:
3318           gdk_draw_line (window, gc1,
3319                          x, y, x + width - 1, y);
3320           gdk_draw_line (window, gc1,
3321                          x, y, x, y + height - 1);
3322           gdk_draw_line (window, gc2,
3323                          x + 1, y + 1, x + width - 1, y + 1);
3324           gdk_draw_line (window, gc2,
3325                          x + 1, y + 1, x + 1, y + height - 2);
3326           
3327           gdk_draw_line (window, gc3,
3328                          x + 1, y + height - 2, x + width - 1, y + height - 2);
3329           gdk_draw_line (window, gc4,
3330                          x, y + height - 1, x + width - 1, y + height - 1);
3331           if (gap_x > 0)
3332             {
3333               gdk_draw_line (window, gc4,
3334                              x + width - 1, y, x + width - 1, y + gap_x - 1);
3335               gdk_draw_line (window, gc3,
3336                              x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3337               gdk_draw_line (window, gc3,
3338                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3339             }
3340           if ((width - (gap_x + gap_width)) > 0)
3341             {
3342               gdk_draw_line (window, gc4,
3343                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3344               gdk_draw_line (window, gc3,
3345                              x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3346               gdk_draw_line (window, gc3,
3347                              x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3348             }
3349           break;
3350         }
3351     }
3352
3353   if (area)
3354     {
3355       gdk_gc_set_clip_rectangle (gc1, NULL);
3356       gdk_gc_set_clip_rectangle (gc2, NULL);
3357       gdk_gc_set_clip_rectangle (gc3, NULL);
3358       gdk_gc_set_clip_rectangle (gc4, NULL);
3359     }
3360 }
3361
3362 static void 
3363 gtk_default_draw_box_gap (GtkStyle       *style,
3364                           GdkWindow      *window,
3365                           GtkStateType    state_type,
3366                           GtkShadowType   shadow_type,
3367                           GdkRectangle   *area,
3368                           GtkWidget      *widget,
3369                           const gchar    *detail,
3370                           gint            x,
3371                           gint            y,
3372                           gint            width,
3373                           gint            height,
3374                           GtkPositionType gap_side,
3375                           gint            gap_x,
3376                           gint            gap_width)
3377 {
3378   GdkGC *gc1 = NULL;
3379   GdkGC *gc2 = NULL;
3380   GdkGC *gc3 = NULL;
3381   GdkGC *gc4 = NULL;
3382   
3383   g_return_if_fail (GTK_IS_STYLE (style));
3384   g_return_if_fail (window != NULL);
3385   
3386   gtk_style_apply_default_background (style, window,
3387                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
3388                                       state_type, area, x, y, width, height);
3389   
3390   sanitize_size (window, &width, &height);
3391   
3392   switch (shadow_type)
3393     {
3394     case GTK_SHADOW_NONE:
3395       return;
3396     case GTK_SHADOW_IN:
3397       gc1 = style->dark_gc[state_type];
3398       gc2 = style->black_gc;
3399       gc3 = style->bg_gc[state_type];
3400       gc4 = style->light_gc[state_type];
3401       break;
3402     case GTK_SHADOW_ETCHED_IN:
3403       gc1 = style->dark_gc[state_type];
3404       gc2 = style->light_gc[state_type];
3405       gc3 = style->dark_gc[state_type];
3406       gc4 = style->light_gc[state_type];
3407       break;
3408     case GTK_SHADOW_OUT:
3409       gc1 = style->light_gc[state_type];
3410       gc2 = style->bg_gc[state_type];
3411       gc3 = style->dark_gc[state_type];
3412       gc4 = style->black_gc;
3413       break;
3414     case GTK_SHADOW_ETCHED_OUT:
3415       gc1 = style->light_gc[state_type];
3416       gc2 = style->dark_gc[state_type];
3417       gc3 = style->light_gc[state_type];
3418       gc4 = style->dark_gc[state_type];
3419       break;
3420     }
3421
3422   if (area)
3423     {
3424       gdk_gc_set_clip_rectangle (gc1, area);
3425       gdk_gc_set_clip_rectangle (gc2, area);
3426       gdk_gc_set_clip_rectangle (gc3, area);
3427       gdk_gc_set_clip_rectangle (gc4, area);
3428     }
3429   
3430   switch (shadow_type)
3431     {
3432     case GTK_SHADOW_NONE:
3433     case GTK_SHADOW_IN:
3434     case GTK_SHADOW_OUT:
3435     case GTK_SHADOW_ETCHED_IN:
3436     case GTK_SHADOW_ETCHED_OUT:
3437       switch (gap_side)
3438         {
3439         case GTK_POS_TOP:
3440           gdk_draw_line (window, gc1,
3441                          x, y, x, y + height - 1);
3442           gdk_draw_line (window, gc2,
3443                          x + 1, y, x + 1, y + height - 2);
3444           
3445           gdk_draw_line (window, gc3,
3446                          x + 1, y + height - 2, x + width - 2, y + height - 2);
3447           gdk_draw_line (window, gc3,
3448                          x + width - 2, y, x + width - 2, y + height - 2);
3449           gdk_draw_line (window, gc4,
3450                          x, y + height - 1, x + width - 1, y + height - 1);
3451           gdk_draw_line (window, gc4,
3452                          x + width - 1, y, x + width - 1, y + height - 1);
3453           if (gap_x > 0)
3454             {
3455               gdk_draw_line (window, gc1,
3456                              x, y, x + gap_x - 1, y);
3457               gdk_draw_line (window, gc2,
3458                              x + 1, y + 1, x + gap_x - 1, y + 1);
3459               gdk_draw_line (window, gc2,
3460                              x + gap_x, y, x + gap_x, y);
3461             }
3462           if ((width - (gap_x + gap_width)) > 0)
3463             {
3464               gdk_draw_line (window, gc1,
3465                              x + gap_x + gap_width, y, x + width - 2, y);
3466               gdk_draw_line (window, gc2,
3467                              x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
3468               gdk_draw_line (window, gc2,
3469                              x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3470             }
3471           break;
3472         case  GTK_POS_BOTTOM:
3473           gdk_draw_line (window, gc1,
3474                          x, y, x + width - 1, y);
3475           gdk_draw_line (window, gc1,
3476                          x, y, x, y + height - 1);
3477           gdk_draw_line (window, gc2,
3478                          x + 1, y + 1, x + width - 2, y + 1);
3479           gdk_draw_line (window, gc2,
3480                          x + 1, y + 1, x + 1, y + height - 1);
3481           
3482           gdk_draw_line (window, gc3,
3483                          x + width - 2, y + 1, x + width - 2, y + height - 1);
3484           gdk_draw_line (window, gc4,
3485                          x + width - 1, y, x + width - 1, y + height - 1);
3486           if (gap_x > 0)
3487             {
3488               gdk_draw_line (window, gc4,
3489                              x, y + height - 1, x + gap_x - 1, y + height - 1);
3490               gdk_draw_line (window, gc3,
3491                              x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
3492               gdk_draw_line (window, gc3,
3493                              x + gap_x, y + height - 1, x + gap_x, y + height - 1);
3494             }
3495           if ((width - (gap_x + gap_width)) > 0)
3496             {
3497               gdk_draw_line (window, gc4,
3498                              x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
3499               gdk_draw_line (window, gc3,
3500                              x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
3501               gdk_draw_line (window, gc3,
3502                              x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
3503             }
3504           break;
3505         case GTK_POS_LEFT:
3506           gdk_draw_line (window, gc1,
3507                          x, y, x + width - 1, y);
3508           gdk_draw_line (window, gc2,
3509                          x, y + 1, x + width - 2, y + 1);
3510           
3511           gdk_draw_line (window, gc3,
3512                          x, y + height - 2, x + width - 2, y + height - 2);
3513           gdk_draw_line (window, gc3,
3514                          x + width - 2, y + 1, x + width - 2, y + height - 2);
3515           gdk_draw_line (window, gc4,
3516                          x, y + height - 1, x + width - 1, y + height - 1);
3517           gdk_draw_line (window, gc4,
3518                          x + width - 1, y, x + width - 1, y + height - 1);
3519           if (gap_x > 0)
3520             {
3521               gdk_draw_line (window, gc1,
3522                              x, y, x, y + gap_x - 1);
3523               gdk_draw_line (window, gc2,
3524                              x + 1, y + 1, x + 1, y + gap_x - 1);
3525               gdk_draw_line (window, gc2,
3526                              x, y + gap_x, x, y + gap_x);
3527             }
3528           if ((width - (gap_x + gap_width)) > 0)
3529             {
3530               gdk_draw_line (window, gc1,
3531                              x, y + gap_x + gap_width, x, y + height - 2);
3532               gdk_draw_line (window, gc2,
3533                              x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
3534               gdk_draw_line (window, gc2,
3535                              x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
3536             }
3537           break;
3538         case GTK_POS_RIGHT:
3539           gdk_draw_line (window, gc1,
3540                          x, y, x + width - 1, y);
3541           gdk_draw_line (window, gc1,
3542                          x, y, x, y + height - 1);
3543           gdk_draw_line (window, gc2,
3544                          x + 1, y + 1, x + width - 1, y + 1);
3545           gdk_draw_line (window, gc2,
3546                          x + 1, y + 1, x + 1, y + height - 2);
3547           
3548           gdk_draw_line (window, gc3,
3549                          x + 1, y + height - 2, x + width - 1, y + height - 2);
3550           gdk_draw_line (window, gc4,
3551                          x, y + height - 1, x + width - 1, y + height - 1);
3552           if (gap_x > 0)
3553             {
3554               gdk_draw_line (window, gc4,
3555                              x + width - 1, y, x + width - 1, y + gap_x - 1);
3556               gdk_draw_line (window, gc3,
3557                              x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
3558               gdk_draw_line (window, gc3,
3559                              x + width - 1, y + gap_x, x + width - 1, y + gap_x);
3560             }
3561           if ((width - (gap_x + gap_width)) > 0)
3562             {
3563               gdk_draw_line (window, gc4,
3564                              x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
3565               gdk_draw_line (window, gc3,
3566                              x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
3567               gdk_draw_line (window, gc3,
3568                              x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
3569             }
3570           break;
3571         }
3572     }
3573
3574   if (area)
3575     {
3576       gdk_gc_set_clip_rectangle (gc1, NULL);
3577       gdk_gc_set_clip_rectangle (gc2, NULL);
3578       gdk_gc_set_clip_rectangle (gc3, NULL);
3579       gdk_gc_set_clip_rectangle (gc4, NULL);
3580     }
3581 }
3582
3583 static void 
3584 gtk_default_draw_extension (GtkStyle       *style,
3585                             GdkWindow      *window,
3586                             GtkStateType    state_type,
3587                             GtkShadowType   shadow_type,
3588                             GdkRectangle   *area,
3589                             GtkWidget      *widget,
3590                             const gchar    *detail,
3591                             gint            x,
3592                             gint            y,
3593                             gint            width,
3594                             gint            height,
3595                             GtkPositionType gap_side)
3596 {
3597   GdkGC *gc1 = NULL;
3598   GdkGC *gc2 = NULL;
3599   GdkGC *gc3 = NULL;
3600   GdkGC *gc4 = NULL;
3601   
3602   g_return_if_fail (GTK_IS_STYLE (style));
3603   g_return_if_fail (window != NULL);
3604   
3605   gtk_style_apply_default_background (style, window,
3606                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
3607                                       GTK_STATE_NORMAL, area, x, y, width, height);
3608   
3609   sanitize_size (window, &width, &height);
3610   
3611   switch (shadow_type)
3612     {
3613     case GTK_SHADOW_NONE:
3614       return;
3615     case GTK_SHADOW_IN:
3616       gc1 = style->dark_gc[state_type];
3617       gc2 = style->black_gc;
3618       gc3 = style->bg_gc[state_type];
3619       gc4 = style->light_gc[state_type];
3620       break;
3621     case GTK_SHADOW_ETCHED_IN:
3622       gc1 = style->dark_gc[state_type];
3623       gc2 = style->light_gc[state_type];
3624       gc3 = style->dark_gc[state_type];
3625       gc4 = style->light_gc[state_type];
3626       break;
3627     case GTK_SHADOW_OUT:
3628       gc1 = style->light_gc[state_type];
3629       gc2 = style->bg_gc[state_type];
3630       gc3 = style->dark_gc[state_type];
3631       gc4 = style->black_gc;
3632       break;
3633     case GTK_SHADOW_ETCHED_OUT:
3634       gc1 = style->light_gc[state_type];
3635       gc2 = style->dark_gc[state_type];
3636       gc3 = style->light_gc[state_type];
3637       gc4 = style->dark_gc[state_type];
3638       break;
3639     }
3640
3641   if (area)
3642     {
3643       gdk_gc_set_clip_rectangle (gc1, area);
3644       gdk_gc_set_clip_rectangle (gc2, area);
3645       gdk_gc_set_clip_rectangle (gc3, area);
3646       gdk_gc_set_clip_rectangle (gc4, area);
3647     }
3648
3649   switch (shadow_type)
3650     {
3651     case GTK_SHADOW_NONE:
3652     case GTK_SHADOW_IN:
3653     case GTK_SHADOW_OUT:
3654     case GTK_SHADOW_ETCHED_IN:
3655     case GTK_SHADOW_ETCHED_OUT:
3656       switch (gap_side)
3657         {
3658         case GTK_POS_TOP:
3659           gtk_style_apply_default_background (style, window,
3660                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3661                                               state_type, area,
3662                                               x + style->xthickness, 
3663                                               y, 
3664                                               width - (2 * style->xthickness), 
3665                                               height - (style->ythickness));
3666           gdk_draw_line (window, gc1,
3667                          x, y, x, y + height - 2);
3668           gdk_draw_line (window, gc2,
3669                          x + 1, y, x + 1, y + height - 2);
3670           
3671           gdk_draw_line (window, gc3,
3672                          x + 2, y + height - 2, x + width - 2, y + height - 2);
3673           gdk_draw_line (window, gc3,
3674                          x + width - 2, y, x + width - 2, y + height - 2);
3675           gdk_draw_line (window, gc4,
3676                          x + 1, y + height - 1, x + width - 2, y + height - 1);
3677           gdk_draw_line (window, gc4,
3678                          x + width - 1, y, x + width - 1, y + height - 2);
3679           break;
3680         case GTK_POS_BOTTOM:
3681           gtk_style_apply_default_background (style, window,
3682                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3683                                               state_type, area,
3684                                               x + style->xthickness, 
3685                                               y + style->ythickness, 
3686                                               width - (2 * style->xthickness), 
3687                                               height - (style->ythickness));
3688           gdk_draw_line (window, gc1,
3689                          x + 1, y, x + width - 2, y);
3690           gdk_draw_line (window, gc1,
3691                          x, y + 1, x, y + height - 1);
3692           gdk_draw_line (window, gc2,
3693                          x + 1, y + 1, x + width - 2, y + 1);
3694           gdk_draw_line (window, gc2,
3695                          x + 1, y + 1, x + 1, y + height - 1);
3696           
3697           gdk_draw_line (window, gc3,
3698                          x + width - 2, y + 2, x + width - 2, y + height - 1);
3699           gdk_draw_line (window, gc4,
3700                          x + width - 1, y + 1, x + width - 1, y + height - 1);
3701           break;
3702         case GTK_POS_LEFT:
3703           gtk_style_apply_default_background (style, window,
3704                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3705                                               state_type, area,
3706                                               x, 
3707                                               y + style->ythickness, 
3708                                               width - (style->xthickness), 
3709                                               height - (2 * style->ythickness));
3710           gdk_draw_line (window, gc1,
3711                          x, y, x + width - 2, y);
3712           gdk_draw_line (window, gc2,
3713                          x + 1, y + 1, x + width - 2, y + 1);
3714           
3715           gdk_draw_line (window, gc3,
3716                          x, y + height - 2, x + width - 2, y + height - 2);
3717           gdk_draw_line (window, gc3,
3718                          x + width - 2, y + 2, x + width - 2, y + height - 2);
3719           gdk_draw_line (window, gc4,
3720                          x, y + height - 1, x + width - 2, y + height - 1);
3721           gdk_draw_line (window, gc4,
3722                          x + width - 1, y + 1, x + width - 1, y + height - 2);
3723           break;
3724         case GTK_POS_RIGHT:
3725           gtk_style_apply_default_background (style, window,
3726                                               widget && !GTK_WIDGET_NO_WINDOW (widget),
3727                                               state_type, area,
3728                                               x + style->xthickness, 
3729                                               y + style->ythickness, 
3730                                               width - (style->xthickness), 
3731                                               height - (2 * style->ythickness));
3732           gdk_draw_line (window, gc1,
3733                          x + 1, y, x + width - 1, y);
3734           gdk_draw_line (window, gc1,
3735                          x, y + 1, x, y + height - 2);
3736           gdk_draw_line (window, gc2,
3737                          x + 1, y + 1, x + width - 1, y + 1);
3738           gdk_draw_line (window, gc2,
3739                          x + 1, y + 1, x + 1, y + height - 2);
3740           
3741           gdk_draw_line (window, gc3,
3742                          x + 2, y + height - 2, x + width - 1, y + height - 2);
3743           gdk_draw_line (window, gc4,
3744                          x + 1, y + height - 1, x + width - 1, y + height - 1);
3745           break;
3746         }
3747     }
3748
3749   if (area)
3750     {
3751       gdk_gc_set_clip_rectangle (gc1, NULL);
3752       gdk_gc_set_clip_rectangle (gc2, NULL);
3753       gdk_gc_set_clip_rectangle (gc3, NULL);
3754       gdk_gc_set_clip_rectangle (gc4, NULL);
3755     }
3756 }
3757
3758 static void 
3759 gtk_default_draw_focus (GtkStyle      *style,
3760                         GdkWindow     *window,
3761                         GdkRectangle  *area,
3762                         GtkWidget     *widget,
3763                         const gchar   *detail,
3764                         gint           x,
3765                         gint           y,
3766                         gint           width,
3767                         gint           height)
3768 {
3769   GdkPoint points[5];
3770   
3771   sanitize_size (window, &width, &height);
3772   
3773   if (area)
3774     gdk_gc_set_clip_rectangle (style->black_gc, area);
3775
3776   gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
3777
3778   if (detail && !strcmp (detail, "add-mode"))
3779     gdk_gc_set_dashes (style->black_gc, 0, "\4\4", 2);
3780   else
3781     gdk_gc_set_dashes (style->black_gc, 0, "\1\1", 2);
3782
3783   points[0].x = x;
3784   points[0].y = y;
3785   points[1].x = x + width;
3786   points[1].y = y;
3787   points[2].x = x + width;
3788   points[2].y = y + height;
3789   points[3].x = x;
3790   points[3].y = y + height;
3791   points[4] = points[0];
3792   
3793   gdk_draw_polygon (window, style->black_gc, FALSE, points, 4);
3794   gdk_gc_set_line_attributes (style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
3795
3796   if (area)
3797     gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3798 }
3799
3800 static void 
3801 gtk_default_draw_slider (GtkStyle      *style,
3802                          GdkWindow     *window,
3803                          GtkStateType   state_type,
3804                          GtkShadowType  shadow_type,
3805                          GdkRectangle  *area,
3806                          GtkWidget     *widget,
3807                          const gchar   *detail,
3808                          gint           x,
3809                          gint           y,
3810                          gint           width,
3811                          gint           height,
3812                          GtkOrientation orientation)
3813 {
3814   g_return_if_fail (GTK_IS_STYLE (style));
3815   g_return_if_fail (window != NULL);
3816   
3817   sanitize_size (window, &width, &height);
3818   
3819   gtk_paint_box (style, window, state_type, shadow_type,
3820                  area, widget, detail, x, y, width, height);
3821
3822   if (detail &&
3823       (strcmp ("hscale", detail) == 0 ||
3824        strcmp ("vscale", detail) == 0))
3825     {
3826       if (orientation == GTK_ORIENTATION_HORIZONTAL)
3827         gtk_paint_vline (style, window, state_type, area, widget, detail, 
3828                          y + style->ythickness, 
3829                          y + height - style->ythickness - 1, x + width / 2);
3830       else
3831         gtk_paint_hline (style, window, state_type, area, widget, detail, 
3832                          x + style->xthickness, 
3833                          x + width - style->xthickness - 1, y + height / 2);
3834     }
3835 }
3836
3837 static void
3838 draw_dot (GdkWindow    *window,
3839           GdkGC        *light_gc,
3840           GdkGC        *dark_gc,
3841           gint          x,
3842           gint          y,
3843           gushort       size)
3844 {
3845   
3846   size = CLAMP (size, 2, 3);
3847
3848   if (size == 2)
3849     {
3850       gdk_draw_point (window, light_gc, x, y);
3851       gdk_draw_point (window, light_gc, x+1, y+1);
3852     }
3853   else if (size == 3);
3854     {
3855       gdk_draw_point (window, light_gc, x, y);
3856       gdk_draw_point (window, light_gc, x+1, y);
3857       gdk_draw_point (window, light_gc, x, y+1);
3858       gdk_draw_point (window, dark_gc, x+1, y+2);
3859       gdk_draw_point (window, dark_gc, x+2, y+1);
3860       gdk_draw_point (window, dark_gc, x+2, y+2);
3861     }
3862 }
3863
3864 static void 
3865 gtk_default_draw_handle (GtkStyle      *style,
3866                          GdkWindow     *window,
3867                          GtkStateType   state_type,
3868                          GtkShadowType  shadow_type,
3869                          GdkRectangle  *area,
3870                          GtkWidget     *widget,
3871                          const gchar   *detail,
3872                          gint           x,
3873                          gint           y,
3874                          gint           width,
3875                          gint           height,
3876                          GtkOrientation orientation)
3877 {
3878   gint xx, yy;
3879   gint xthick, ythick;
3880   GdkGC *light_gc, *dark_gc;
3881   GdkRectangle rect;
3882   GdkRectangle dest;
3883   gint intersect;
3884   
3885   g_return_if_fail (GTK_IS_STYLE (style));
3886   g_return_if_fail (window != NULL);
3887   
3888   sanitize_size (window, &width, &height);
3889   
3890   gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
3891                  detail, x, y, width, height);
3892   
3893   
3894   if (!strcmp (detail, "paned"))
3895     {
3896       /* we want to ignore the shadow border in paned widgets */
3897       xthick = 0;
3898       ythick = 0;
3899
3900       light_gc = style->light_gc[state_type];
3901       dark_gc = style->black_gc;
3902     }
3903   else
3904     {
3905       xthick = style->xthickness;
3906       ythick = style->ythickness;
3907
3908       light_gc = style->light_gc[state_type];
3909       dark_gc = style->dark_gc[state_type];
3910     }
3911   
3912   rect.x = x + xthick;
3913   rect.y = y + ythick;
3914   rect.width = width - (xthick * 2);
3915   rect.height = height - (ythick * 2);
3916
3917   if (area)
3918       intersect = gdk_rectangle_intersect (area, &rect, &dest);
3919   else
3920     {
3921       intersect = TRUE;
3922       dest = rect;
3923     }
3924
3925   if (!intersect)
3926     return;
3927
3928   gdk_gc_set_clip_rectangle (light_gc, &dest);
3929   gdk_gc_set_clip_rectangle (dark_gc, &dest);
3930
3931   if (!strcmp (detail, "paned"))
3932     {
3933       gint window_width;
3934       gint window_height;
3935
3936       gdk_window_get_size (window, &window_width, &window_height);
3937
3938       if (orientation == GTK_ORIENTATION_HORIZONTAL)
3939         for (xx = window_width/2 - 15; xx <= window_width/2 + 15; xx += 5)
3940           draw_dot (window, light_gc, dark_gc, xx, window_height/2 - 1, 3);
3941       else
3942         for (yy = window_height/2 - 15; yy <= window_height/2 + 15; yy += 5)
3943           draw_dot (window, light_gc, dark_gc, window_width/2 - 1, yy, 3);
3944     }
3945   else
3946     {
3947       for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
3948         for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
3949           {
3950             draw_dot (window, light_gc, dark_gc, xx, yy, 2);
3951             draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
3952           }
3953     }
3954
3955   gdk_gc_set_clip_rectangle (light_gc, NULL);
3956   gdk_gc_set_clip_rectangle (dark_gc, NULL);
3957 }
3958
3959 static void
3960 create_expander_affine (gdouble affine[6],
3961                         gint    degrees,
3962                         gint    expander_size,
3963                         gint    x,
3964                         gint    y)
3965 {
3966   gdouble s, c;
3967   gdouble width;
3968   gdouble height;
3969
3970   width = expander_size / 4.0;
3971   height = expander_size / 2.0;
3972   
3973   s = sin (degrees * G_PI / 180.0);
3974   c = cos (degrees * G_PI / 180.0);
3975   
3976   affine[0] = c;
3977   affine[1] = s;
3978   affine[2] = -s;
3979   affine[3] = c;
3980   affine[4] = -width * c - height * -s + x;
3981   affine[5] = -width * s - height * c + y;
3982 }
3983
3984 static void
3985 apply_affine_on_point (double affine[6], GdkPoint *point)
3986 {
3987   gdouble x, y;
3988
3989   x = point->x * affine[0] + point->y * affine[2] + affine[4];
3990   y = point->x * affine[1] + point->y * affine[3] + affine[5];
3991
3992   point->x = x;
3993   point->y = y;
3994 }
3995
3996 static void
3997 gtk_default_draw_expander (GtkStyle        *style,
3998                            GdkWindow       *window,
3999                            GtkStateType     state_type,
4000                            GdkRectangle    *area,
4001                            GtkWidget       *widget,
4002                            const gchar     *detail,
4003                            gint             x,
4004                            gint             y,
4005                            GtkExpanderStyle expander_style)
4006 {
4007   gint expander_size;
4008   GdkPoint points[3];
4009   gint i;
4010   gdouble affine[6];
4011   gint degrees = 0;
4012   
4013   gtk_widget_style_get (widget,
4014                         "expander_size", &expander_size,
4015                         NULL);
4016
4017   if (area)
4018     {
4019       gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
4020       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
4021     }
4022
4023   points[0].x = 0;
4024   points[0].y = 0;
4025   points[1].x = expander_size / 2;
4026   points[1].y =  expander_size / 2;
4027   points[2].x = 0;
4028   points[2].y = expander_size;
4029
4030   switch (expander_style)
4031     {
4032     case GTK_EXPANDER_COLLAPSED:
4033       degrees = 0;
4034       break;
4035     case GTK_EXPANDER_SEMI_COLLAPSED:
4036       degrees = 30;
4037       break;
4038     case GTK_EXPANDER_SEMI_EXPANDED:
4039       degrees = 60;
4040       break;
4041     case GTK_EXPANDER_EXPANDED:
4042       degrees = 90;
4043       break;
4044     default:
4045       g_assert_not_reached ();
4046     }
4047   
4048   create_expander_affine (affine, degrees, expander_size, x, y);
4049
4050   for (i = 0; i < 3; i++)
4051     apply_affine_on_point (affine, &points[i]);
4052
4053   if (state_type == GTK_STATE_PRELIGHT)
4054     {
4055       gdk_draw_polygon (window, style->base_gc[GTK_STATE_NORMAL],
4056                         TRUE, points, 3);
4057       gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
4058                         FALSE, points, 3);
4059     }
4060   else if (state_type == GTK_STATE_ACTIVE)
4061     {
4062       gdk_draw_polygon (window, style->light_gc[GTK_STATE_ACTIVE],
4063                         TRUE, points, 3);
4064       gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
4065                         FALSE, points, 3);
4066     }
4067   else
4068     {
4069       gdk_draw_polygon (window, style->fg_gc[GTK_STATE_NORMAL],
4070                         TRUE, points, 3);
4071     }
4072   if (area)
4073     {
4074       gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
4075       gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
4076     }
4077 }
4078
4079 typedef struct _ByteRange ByteRange;
4080
4081 struct _ByteRange
4082 {
4083   guint start;
4084   guint end;
4085 };
4086
4087 static ByteRange*
4088 range_new (guint start,
4089            guint end)
4090 {
4091   ByteRange *br = g_new (ByteRange, 1);
4092
4093   br->start = start;
4094   br->end = end;
4095   
4096   return br;
4097 }
4098
4099 static PangoLayout*
4100 get_insensitive_layout (PangoLayout *layout)
4101 {
4102   GSList *embossed_ranges = NULL;
4103   GSList *stippled_ranges = NULL;
4104   PangoLayoutIter *iter;
4105   GSList *tmp_list = NULL;
4106   PangoLayout *new_layout;
4107   PangoAttrList *attrs;
4108   GdkBitmap *stipple = NULL;
4109   
4110   iter = pango_layout_get_iter (layout);
4111   
4112   do
4113     {
4114       PangoLayoutRun *run;
4115       PangoAttribute *attr;
4116       gboolean need_stipple = FALSE;
4117       ByteRange *br;
4118       
4119       run = pango_layout_iter_get_run (iter);
4120
4121       if (run)
4122         {
4123           tmp_list = run->item->analysis.extra_attrs;
4124
4125           while (tmp_list != NULL)
4126             {
4127               attr = tmp_list->data;
4128               switch (attr->klass->type)
4129                 {
4130                 case PANGO_ATTR_FOREGROUND:
4131                 case PANGO_ATTR_BACKGROUND:
4132                   need_stipple = TRUE;
4133                   break;
4134               
4135                 default:
4136                   break;
4137                 }
4138
4139               if (need_stipple)
4140                 break;
4141           
4142               tmp_list = g_slist_next (tmp_list);
4143             }
4144
4145           br = range_new (run->item->offset, run->item->offset + run->item->length);
4146       
4147           if (need_stipple)
4148             stippled_ranges = g_slist_prepend (stippled_ranges, br);
4149           else
4150             embossed_ranges = g_slist_prepend (embossed_ranges, br);
4151         }
4152     }
4153   while (pango_layout_iter_next_run (iter));
4154
4155   pango_layout_iter_free (iter);
4156
4157   new_layout = pango_layout_copy (layout);
4158
4159   attrs = pango_layout_get_attributes (new_layout);
4160
4161   if (attrs == NULL)
4162     {
4163       /* Create attr list if there wasn't one */
4164       attrs = pango_attr_list_new ();
4165       pango_layout_set_attributes (new_layout, attrs);
4166       pango_attr_list_unref (attrs);
4167     }
4168   
4169   tmp_list = embossed_ranges;
4170   while (tmp_list != NULL)
4171     {
4172       PangoAttribute *attr;
4173       ByteRange *br = tmp_list->data;
4174
4175       attr = gdk_pango_attr_embossed_new (TRUE);
4176
4177       attr->start_index = br->start;
4178       attr->end_index = br->end;
4179       
4180       pango_attr_list_change (attrs, attr);
4181
4182       g_free (br);
4183       
4184       tmp_list = g_slist_next (tmp_list);
4185     }
4186
4187   g_slist_free (embossed_ranges);
4188   
4189   tmp_list = stippled_ranges;
4190   while (tmp_list != NULL)
4191     {
4192       PangoAttribute *attr;
4193       ByteRange *br = tmp_list->data;
4194
4195       if (stipple == NULL)
4196         {
4197 #define gray50_width 2
4198 #define gray50_height 2
4199           static char gray50_bits[] = {
4200             0x02, 0x01
4201           };
4202
4203           stipple = gdk_bitmap_create_from_data (NULL,
4204                                                  gray50_bits, gray50_width,
4205                                                  gray50_height);
4206         }
4207       
4208       attr = gdk_pango_attr_stipple_new (stipple);
4209
4210       attr->start_index = br->start;
4211       attr->end_index = br->end;
4212       
4213       pango_attr_list_change (attrs, attr);
4214
4215       g_free (br);
4216       
4217       tmp_list = g_slist_next (tmp_list);
4218     }
4219
4220   g_slist_free (stippled_ranges);
4221   
4222   if (stipple)
4223     g_object_unref (G_OBJECT (stipple));
4224
4225   return new_layout;
4226 }
4227
4228 static void
4229 gtk_default_draw_layout (GtkStyle        *style,
4230                          GdkWindow       *window,
4231                          GtkStateType     state_type,
4232                          gboolean         use_text,
4233                          GdkRectangle    *area,
4234                          GtkWidget       *widget,
4235                          const gchar     *detail,
4236                          gint             x,
4237                          gint             y,
4238                          PangoLayout     *layout)
4239 {
4240   GdkGC *gc;
4241   
4242   g_return_if_fail (GTK_IS_STYLE (style));
4243   g_return_if_fail (window != NULL);
4244
4245   gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
4246   
4247   if (area)
4248     gdk_gc_set_clip_rectangle (gc, area);
4249
4250   if (state_type == GTK_STATE_INSENSITIVE)
4251     {
4252       PangoLayout *ins;
4253
4254       ins = get_insensitive_layout (layout);
4255       
4256       gdk_draw_layout (window, gc, x, y, ins);
4257
4258       g_object_unref (G_OBJECT (ins));
4259     }
4260   else
4261     {
4262       gdk_draw_layout (window, gc, x, y, layout);
4263     }
4264
4265   if (area)
4266     gdk_gc_set_clip_rectangle (gc, NULL);
4267 }
4268
4269 static void
4270 gtk_default_draw_resize_grip (GtkStyle       *style,
4271                               GdkWindow      *window,
4272                               GtkStateType    state_type,
4273                               GdkRectangle   *area,
4274                               GtkWidget      *widget,
4275                               const gchar    *detail,
4276                               GdkWindowEdge   edge,
4277                               gint            x,
4278                               gint            y,
4279                               gint            width,
4280                               gint            height)
4281 {
4282   g_return_if_fail (GTK_IS_STYLE (style));
4283   g_return_if_fail (window != NULL);
4284   
4285   if (area)
4286     {
4287       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
4288       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
4289       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
4290     }
4291
4292   /* make it square, aligning to bottom right */
4293   if (width < height)
4294     {
4295       y += (height - width);
4296       height = width;
4297     }
4298   else if (height < width)
4299     {
4300       x += (width - height);
4301       width = height;
4302     }
4303
4304   /* Clear background */
4305   gdk_draw_rectangle (window,
4306                       style->bg_gc[state_type],
4307                       TRUE,
4308                       x, y, width, height);
4309   
4310   switch (edge)
4311     {
4312     case GDK_WINDOW_EDGE_SOUTH_EAST:
4313       {
4314         gint xi, yi;
4315
4316         xi = x;
4317         yi = y;
4318
4319         while (xi < (x + width - 3))
4320           {
4321             gdk_draw_line (window,
4322                            style->light_gc[state_type],
4323                            xi, y + height,
4324                            x + width, yi);                           
4325
4326             ++xi;
4327             ++yi;
4328             
4329             gdk_draw_line (window,
4330                            style->dark_gc[state_type],
4331                            xi, y + height,
4332                            x + width, yi);                           
4333
4334             ++xi;
4335             ++yi;
4336             
4337             gdk_draw_line (window,
4338                            style->dark_gc[state_type],
4339                            xi, y + height,
4340                            x + width, yi);
4341
4342             xi += 3;
4343             yi += 3;
4344           }
4345       }
4346       break;
4347     default:
4348       g_assert_not_reached ();
4349       break;
4350     }
4351   
4352   if (area)
4353     {
4354       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
4355       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
4356       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
4357     }
4358 }
4359
4360 static void
4361 gtk_style_shade (GdkColor *a,
4362                  GdkColor *b,
4363                  gdouble   k)
4364 {
4365   gdouble red;
4366   gdouble green;
4367   gdouble blue;
4368   
4369   red = (gdouble) a->red / 65535.0;
4370   green = (gdouble) a->green / 65535.0;
4371   blue = (gdouble) a->blue / 65535.0;
4372   
4373   rgb_to_hls (&red, &green, &blue);
4374   
4375   green *= k;
4376   if (green > 1.0)
4377     green = 1.0;
4378   else if (green < 0.0)
4379     green = 0.0;
4380   
4381   blue *= k;
4382   if (blue > 1.0)
4383     blue = 1.0;
4384   else if (blue < 0.0)
4385     blue = 0.0;
4386   
4387   hls_to_rgb (&red, &green, &blue);
4388   
4389   b->red = red * 65535.0;
4390   b->green = green * 65535.0;
4391   b->blue = blue * 65535.0;
4392 }
4393
4394 static void
4395 rgb_to_hls (gdouble *r,
4396             gdouble *g,
4397             gdouble *b)
4398 {
4399   gdouble min;
4400   gdouble max;
4401   gdouble red;
4402   gdouble green;
4403   gdouble blue;
4404   gdouble h, l, s;
4405   gdouble delta;
4406   
4407   red = *r;
4408   green = *g;
4409   blue = *b;
4410   
4411   if (red > green)
4412     {
4413       if (red > blue)
4414         max = red;
4415       else
4416         max = blue;
4417       
4418       if (green < blue)
4419         min = green;
4420       else
4421         min = blue;
4422     }
4423   else
4424     {
4425       if (green > blue)
4426         max = green;
4427       else
4428         max = blue;
4429       
4430       if (red < blue)
4431         min = red;
4432       else
4433         min = blue;
4434     }
4435   
4436   l = (max + min) / 2;
4437   s = 0;
4438   h = 0;
4439   
4440   if (max != min)
4441     {
4442       if (l <= 0.5)
4443         s = (max - min) / (max + min);
4444       else
4445         s = (max - min) / (2 - max - min);
4446       
4447       delta = max -min;
4448       if (red == max)
4449         h = (green - blue) / delta;
4450       else if (green == max)
4451         h = 2 + (blue - red) / delta;
4452       else if (blue == max)
4453         h = 4 + (red - green) / delta;
4454       
4455       h *= 60;
4456       if (h < 0.0)
4457         h += 360;
4458     }
4459   
4460   *r = h;
4461   *g = l;
4462   *b = s;
4463 }
4464
4465 static void
4466 hls_to_rgb (gdouble *h,
4467             gdouble *l,
4468             gdouble *s)
4469 {
4470   gdouble hue;
4471   gdouble lightness;
4472   gdouble saturation;
4473   gdouble m1, m2;
4474   gdouble r, g, b;
4475   
4476   lightness = *l;
4477   saturation = *s;
4478   
4479   if (lightness <= 0.5)
4480     m2 = lightness * (1 + saturation);
4481   else
4482     m2 = lightness + saturation - lightness * saturation;
4483   m1 = 2 * lightness - m2;
4484   
4485   if (saturation == 0)
4486     {
4487       *h = lightness;
4488       *l = lightness;
4489       *s = lightness;
4490     }
4491   else
4492     {
4493       hue = *h + 120;
4494       while (hue > 360)
4495         hue -= 360;
4496       while (hue < 0)
4497         hue += 360;
4498       
4499       if (hue < 60)
4500         r = m1 + (m2 - m1) * hue / 60;
4501       else if (hue < 180)
4502         r = m2;
4503       else if (hue < 240)
4504         r = m1 + (m2 - m1) * (240 - hue) / 60;
4505       else
4506         r = m1;
4507       
4508       hue = *h;
4509       while (hue > 360)
4510         hue -= 360;
4511       while (hue < 0)
4512         hue += 360;
4513       
4514       if (hue < 60)
4515         g = m1 + (m2 - m1) * hue / 60;
4516       else if (hue < 180)
4517         g = m2;
4518       else if (hue < 240)
4519         g = m1 + (m2 - m1) * (240 - hue) / 60;
4520       else
4521         g = m1;
4522       
4523       hue = *h - 120;
4524       while (hue > 360)
4525         hue -= 360;
4526       while (hue < 0)
4527         hue += 360;
4528       
4529       if (hue < 60)
4530         b = m1 + (m2 - m1) * hue / 60;
4531       else if (hue < 180)
4532         b = m2;
4533       else if (hue < 240)
4534         b = m1 + (m2 - m1) * (240 - hue) / 60;
4535       else
4536         b = m1;
4537       
4538       *h = r;
4539       *l = g;
4540       *s = b;
4541     }
4542 }
4543
4544 void 
4545 gtk_paint_hline (GtkStyle      *style,
4546                  GdkWindow     *window,
4547                  GtkStateType   state_type,
4548                  GdkRectangle  *area,
4549                  GtkWidget     *widget,
4550                  const gchar   *detail,
4551                  gint          x1,
4552                  gint          x2,
4553                  gint          y)
4554 {
4555   g_return_if_fail (GTK_IS_STYLE (style));
4556   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
4557   
4558   GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
4559 }
4560
4561 void
4562 gtk_paint_vline (GtkStyle      *style,
4563                  GdkWindow     *window,
4564                  GtkStateType   state_type,
4565                  GdkRectangle  *area,
4566                  GtkWidget     *widget,
4567                  const gchar   *detail,
4568                  gint          y1,
4569                  gint          y2,
4570                  gint          x)
4571 {
4572   g_return_if_fail (GTK_IS_STYLE (style));
4573   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
4574   
4575   GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1, y2, x);
4576 }
4577
4578 void
4579 gtk_paint_shadow (GtkStyle     *style,
4580                   GdkWindow    *window,
4581                   GtkStateType  state_type,
4582                   GtkShadowType shadow_type,
4583                   GdkRectangle *area,
4584                   GtkWidget    *widget,
4585                   const gchar  *detail,
4586                   gint          x,
4587                   gint          y,
4588                   gint          width,
4589                   gint          height)
4590 {
4591   g_return_if_fail (GTK_IS_STYLE (style));
4592   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4593   
4594   GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4595 }
4596
4597 void
4598 gtk_paint_polygon (GtkStyle      *style,
4599                    GdkWindow     *window,
4600                    GtkStateType   state_type,
4601                    GtkShadowType  shadow_type,
4602                    GdkRectangle  *area,
4603                    GtkWidget     *widget,
4604                    const gchar   *detail,
4605                    GdkPoint      *points,
4606                    gint           npoints,
4607                    gboolean       fill)
4608 {
4609   g_return_if_fail (GTK_IS_STYLE (style));
4610   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
4611   
4612   GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
4613 }
4614
4615 void
4616 gtk_paint_arrow (GtkStyle      *style,
4617                  GdkWindow     *window,
4618                  GtkStateType   state_type,
4619                  GtkShadowType  shadow_type,
4620                  GdkRectangle  *area,
4621                  GtkWidget     *widget,
4622                  const gchar   *detail,
4623                  GtkArrowType   arrow_type,
4624                  gboolean       fill,
4625                  gint           x,
4626                  gint           y,
4627                  gint           width,
4628                  gint           height)
4629 {
4630   g_return_if_fail (GTK_IS_STYLE (style));
4631   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
4632   
4633   GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
4634 }
4635
4636 void
4637 gtk_paint_diamond (GtkStyle      *style,
4638                    GdkWindow     *window,
4639                    GtkStateType   state_type,
4640                    GtkShadowType  shadow_type,
4641                    GdkRectangle  *area,
4642                    GtkWidget     *widget,
4643                    const gchar   *detail,
4644                    gint        x,
4645                    gint        y,
4646                    gint        width,
4647                    gint        height)
4648 {
4649   g_return_if_fail (GTK_IS_STYLE (style));
4650   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
4651   
4652   GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4653 }
4654
4655 void
4656 gtk_paint_string (GtkStyle      *style,
4657                   GdkWindow     *window,
4658                   GtkStateType   state_type,
4659                   GdkRectangle  *area,
4660                   GtkWidget     *widget,
4661                   const gchar   *detail,
4662                   gint           x,
4663                   gint           y,
4664                   const gchar   *string)
4665 {
4666   g_return_if_fail (GTK_IS_STYLE (style));
4667   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
4668   
4669   GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
4670 }
4671
4672 void
4673 gtk_paint_box (GtkStyle      *style,
4674                GdkWindow     *window,
4675                GtkStateType   state_type,
4676                GtkShadowType  shadow_type,
4677                GdkRectangle  *area,
4678                GtkWidget     *widget,
4679                const gchar   *detail,
4680                gint           x,
4681                gint           y,
4682                gint           width,
4683                gint           height)
4684 {
4685   g_return_if_fail (GTK_IS_STYLE (style));
4686   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
4687   
4688   GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4689 }
4690
4691 void
4692 gtk_paint_flat_box (GtkStyle      *style,
4693                     GdkWindow     *window,
4694                     GtkStateType   state_type,
4695                     GtkShadowType  shadow_type,
4696                     GdkRectangle  *area,
4697                     GtkWidget     *widget,
4698                     const gchar   *detail,
4699                     gint           x,
4700                     gint           y,
4701                     gint           width,
4702                     gint           height)
4703 {
4704   g_return_if_fail (GTK_IS_STYLE (style));
4705   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
4706   
4707   GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4708 }
4709
4710 void
4711 gtk_paint_check (GtkStyle      *style,
4712                  GdkWindow     *window,
4713                  GtkStateType   state_type,
4714                  GtkShadowType  shadow_type,
4715                  GdkRectangle  *area,
4716                  GtkWidget     *widget,
4717                  const gchar   *detail,
4718                  gint           x,
4719                  gint           y,
4720                  gint           width,
4721                  gint           height)
4722 {
4723   g_return_if_fail (GTK_IS_STYLE (style));
4724   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
4725   
4726   GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4727 }
4728
4729 void
4730 gtk_paint_option (GtkStyle      *style,
4731                   GdkWindow     *window,
4732                   GtkStateType   state_type,
4733                   GtkShadowType  shadow_type,
4734                   GdkRectangle  *area,
4735                   GtkWidget     *widget,
4736                   const gchar   *detail,
4737                   gint           x,
4738                   gint           y,
4739                   gint           width,
4740                   gint           height)
4741 {
4742   g_return_if_fail (GTK_IS_STYLE (style));
4743   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
4744   
4745   GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4746 }
4747
4748 void
4749 gtk_paint_tab (GtkStyle      *style,
4750                GdkWindow     *window,
4751                GtkStateType   state_type,
4752                GtkShadowType  shadow_type,
4753                GdkRectangle  *area,
4754                GtkWidget     *widget,
4755                const gchar   *detail,
4756                gint           x,
4757                gint           y,
4758                gint           width,
4759                gint           height)
4760 {
4761   g_return_if_fail (GTK_IS_STYLE (style));
4762   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
4763   
4764   GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
4765 }
4766
4767 void
4768 gtk_paint_shadow_gap (GtkStyle       *style,
4769                       GdkWindow      *window,
4770                       GtkStateType    state_type,
4771                       GtkShadowType   shadow_type,
4772                       GdkRectangle   *area,
4773                       GtkWidget      *widget,
4774                       gchar          *detail,
4775                       gint            x,
4776                       gint            y,
4777                       gint            width,
4778                       gint            height,
4779                       GtkPositionType gap_side,
4780                       gint            gap_x,
4781                       gint            gap_width)
4782 {
4783   g_return_if_fail (GTK_IS_STYLE (style));
4784   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
4785   
4786   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);
4787 }
4788
4789
4790 void
4791 gtk_paint_box_gap (GtkStyle       *style,
4792                    GdkWindow      *window,
4793                    GtkStateType    state_type,
4794                    GtkShadowType   shadow_type,
4795                    GdkRectangle   *area,
4796                    GtkWidget      *widget,
4797                    gchar          *detail,
4798                    gint            x,
4799                    gint            y,
4800                    gint            width,
4801                    gint            height,
4802                    GtkPositionType gap_side,
4803                    gint            gap_x,
4804                    gint            gap_width)
4805 {
4806   g_return_if_fail (GTK_IS_STYLE (style));
4807   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
4808   
4809   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);
4810 }
4811
4812 void
4813 gtk_paint_extension (GtkStyle       *style,
4814                      GdkWindow      *window,
4815                      GtkStateType    state_type,
4816                      GtkShadowType   shadow_type,
4817                      GdkRectangle   *area,
4818                      GtkWidget      *widget,
4819                      gchar          *detail,
4820                      gint            x,
4821                      gint            y,
4822                      gint            width,
4823                      gint            height,
4824                      GtkPositionType gap_side)
4825 {
4826   g_return_if_fail (GTK_IS_STYLE (style));
4827   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
4828   
4829   GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
4830 }
4831
4832 void
4833 gtk_paint_focus (GtkStyle      *style,
4834                  GdkWindow     *window,
4835                  GdkRectangle  *area,
4836                  GtkWidget     *widget,
4837                  const gchar   *detail,
4838                  gint           x,
4839                  gint           y,
4840                  gint           width,
4841                  gint           height)
4842 {
4843   g_return_if_fail (GTK_IS_STYLE (style));
4844   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
4845   
4846   GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, detail, x, y, width, height);
4847 }
4848
4849 void
4850 gtk_paint_slider (GtkStyle      *style,
4851                   GdkWindow     *window,
4852                   GtkStateType   state_type,
4853                   GtkShadowType  shadow_type,
4854                   GdkRectangle  *area,
4855                   GtkWidget     *widget,
4856                   const gchar   *detail,
4857                   gint           x,
4858                   gint           y,
4859                   gint           width,
4860                   gint           height,
4861                   GtkOrientation orientation)
4862 {
4863   g_return_if_fail (GTK_IS_STYLE (style));
4864   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
4865   
4866   GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
4867 }
4868
4869 void
4870 gtk_paint_handle (GtkStyle      *style,
4871                   GdkWindow     *window,
4872                   GtkStateType   state_type,
4873                   GtkShadowType  shadow_type,
4874                   GdkRectangle  *area,
4875                   GtkWidget     *widget,
4876                   const gchar   *detail,
4877                   gint           x,
4878                   gint           y,
4879                   gint           width,
4880                   gint           height,
4881                   GtkOrientation orientation)
4882 {
4883   g_return_if_fail (GTK_IS_STYLE (style));
4884   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
4885   
4886   GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
4887 }
4888
4889 void
4890 gtk_paint_expander (GtkStyle        *style,
4891                     GdkWindow       *window,
4892                     GtkStateType     state_type,
4893                     GdkRectangle    *area,
4894                     GtkWidget       *widget,
4895                     const gchar     *detail,
4896                     gint             x,
4897                     gint             y,
4898                     GtkExpanderStyle expander_style)
4899 {
4900   g_return_if_fail (GTK_IS_STYLE (style));
4901   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
4902   
4903   GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
4904                                               widget, detail, x, y, expander_style);
4905 }
4906
4907 void
4908 gtk_paint_layout (GtkStyle        *style,
4909                   GdkWindow       *window,
4910                   GtkStateType     state_type,
4911                   gboolean         use_text,
4912                   GdkRectangle    *area,
4913                   GtkWidget       *widget,
4914                   const gchar     *detail,
4915                   gint             x,
4916                   gint             y,
4917                   PangoLayout     *layout)
4918 {
4919   g_return_if_fail (GTK_IS_STYLE (style));
4920   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
4921   
4922   GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
4923                                             widget, detail, x, y, layout);
4924 }
4925
4926 void
4927 gtk_paint_resize_grip (GtkStyle      *style,
4928                        GdkWindow     *window,
4929                        GtkStateType   state_type,
4930                        GdkRectangle  *area,
4931                        GtkWidget     *widget,
4932                        const gchar   *detail,
4933                        GdkWindowEdge  edge,
4934                        gint           x,
4935                        gint           y,
4936                        gint           width,
4937                        gint           height)
4938
4939 {
4940   g_return_if_fail (GTK_IS_STYLE (style));
4941   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
4942
4943   GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
4944                                                  area, widget, detail,
4945                                                  edge, x, y, width, height);
4946 }
4947
4948 GtkBorder *
4949 gtk_border_copy (const GtkBorder *border)
4950 {
4951   return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
4952 }
4953
4954 void
4955 gtk_border_free (GtkBorder *border)
4956 {
4957   g_free (border);
4958 }
4959
4960 /**
4961  * gtk_style_get_font:
4962  * @style: a #GtkStyle
4963  * 
4964  * Gets the #GdkFont to use for the given style. This is
4965  * meant only as a replacement for direct access to style->font
4966  * and should not be used in new code. New code should
4967  * use style->font_desc instead.
4968  * 
4969  * Return value: the #GdkFont for the style. This font is owned
4970  *   by the style; if you want to keep around a copy, you must
4971  *   call gdk_font_ref().
4972  **/
4973 GdkFont *
4974 gtk_style_get_font (GtkStyle *style)
4975 {
4976   g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
4977
4978   if (style->private_font && style->private_font_desc)
4979     {
4980       if (!style->font_desc ||
4981           !pango_font_description_equal (style->private_font_desc, style->font_desc))
4982         {
4983           gdk_font_unref (style->private_font);
4984           style->private_font = NULL;
4985           
4986           if (style->private_font_desc)
4987             {
4988               pango_font_description_free (style->private_font_desc);
4989               style->private_font_desc = NULL;
4990             }
4991         }
4992     }
4993   
4994   if (!style->private_font)
4995     {
4996       if (style->font_desc)
4997         {
4998           style->private_font = gdk_font_from_description (style->font_desc);
4999           style->private_font_desc = pango_font_description_copy (style->font_desc);
5000         }
5001
5002       if (!style->private_font)
5003         style->private_font = gdk_font_load ("fixed");
5004
5005       if (!style->private_font) 
5006         g_error ("Unable to load \"fixed\" font");
5007     }
5008
5009   return style->private_font;
5010 }
5011
5012 /**
5013  * gtk_style_set_font:
5014  * @style: a #GtkStyle.
5015  * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
5016  *   to style->font_desc.
5017  * 
5018  * Sets the #GdkFont to use for a given style. This is
5019  * meant only as a replacement for direct access to style->font
5020  * and should not be used in new code. New code should
5021  * use style->font_desc instead.
5022  **/
5023 void
5024 gtk_style_set_font (GtkStyle *style,
5025                     GdkFont  *font)
5026 {
5027   GdkFont *old_font;
5028
5029   g_return_if_fail (GTK_IS_STYLE (style));
5030
5031   old_font = style->private_font;
5032
5033   style->private_font = font;
5034   if (font)
5035     gdk_font_ref (font);
5036
5037   if (old_font)
5038     gdk_font_unref (old_font);
5039
5040   if (style->private_font_desc)
5041     {
5042       pango_font_description_free (style->private_font_desc);
5043       style->private_font_desc = NULL;
5044     }
5045 }
5046
5047 /**
5048  * _gtk_draw_insertion_cursor:
5049  * @drawable: a #GdkDrawable
5050  * @gc: a #GdkGC
5051  * @location: location where to draw the cursor (@location->width is ignored)
5052  * @dir: text direction for the cursor, used to decide whether to draw a
5053  *       directional arrow on the cursor and in what direction. Unless both
5054  *       strong and weak cursors are displayed, this should be %GTK_TEXT_DIR_NONE.
5055  * 
5056  * Draws a text caret on @drawable at @location. This is not a style function
5057  * but merely a convenience function for drawing the standard cursor shape.
5058  **/
5059 void
5060 _gtk_draw_insertion_cursor (GdkDrawable      *drawable,
5061                             GdkGC            *gc,
5062                             GdkRectangle     *location,
5063                             GtkTextDirection  dir)
5064 {
5065   gint stem_width = location->height / 30 + 1;
5066   gint arrow_width = stem_width + 1;
5067   gint x, y;
5068   gint i;
5069
5070   for (i = 0; i < stem_width; i++)
5071     gdk_draw_line (drawable, gc,
5072                    location->x + i - stem_width / 2, location->y,
5073                    location->x + i - stem_width / 2, location->y + location->height);
5074
5075   if (dir == GTK_TEXT_DIR_RTL)
5076     {
5077       x = location->x - stem_width / 2 - 1;
5078       y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5079   
5080       for (i = 0; i < arrow_width; i++)
5081         {
5082           gdk_draw_line (drawable, gc,
5083                          x, y + i + 1,
5084                          x, y + 2 * arrow_width - i - 1);
5085           x --;
5086         }
5087     }
5088   else if (dir == GTK_TEXT_DIR_LTR)
5089     {
5090       x = location->x + stem_width - stem_width / 2;
5091       y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
5092   
5093       for (i = 0; i < arrow_width; i++) 
5094         {
5095           gdk_draw_line (drawable, gc,
5096                          x, y + i + 1,
5097                          x, y + 2 * arrow_width - i - 1);
5098           x++;
5099         }
5100     }
5101 }
5102