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