]> Pileus Git - ~andy/gtk/blob - gtk/gtkstyle.c
configure.in acheader.h gdk/gdkwindow.c Check for Shape extension both on
[~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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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 #include <math.h>
20 #include "gtkgc.h"
21 #include "gtkstyle.h"
22 #include "gtkwidget.h"
23
24
25 #define LIGHTNESS_MULT  1.3
26 #define DARKNESS_MULT   0.7
27
28
29 typedef struct _GtkStyleKey GtkStyleKey;
30
31 struct _GtkStyleKey
32 {
33   GdkColor fg[5];
34   GdkColor bg[5];
35   GdkColor text[5];
36   GdkColor base[5];
37
38   GdkPixmap *bg_pixmap[5];
39
40   GdkFont *font;
41
42   gint depth;
43   GdkColormap *colormap;
44   GtkStyleClass *klass;
45 };
46
47
48 static void         gtk_style_init         (GtkStyle    *style);
49 static void         gtk_styles_init        (void);
50 static void         gtk_style_remove       (GtkStyle    *style);
51 static GtkStyle*    gtk_style_find         (GtkStyle    *style,
52                                             GdkColormap *cmap,
53                                             gint         depth);
54 static GtkStyle*    gtk_style_new_from_key (GtkStyleKey *key);
55 static GtkStyleKey* gtk_style_key_dup      (GtkStyleKey *key);
56 static void         gtk_style_destroy      (GtkStyle    *style);
57 static void         gtk_style_key_destroy  (GtkStyleKey *key);
58 static guint        gtk_style_key_hash     (GtkStyleKey *key);
59 static guint        gtk_style_value_hash   (GtkStyle    *style);
60 static gint         gtk_style_key_compare  (GtkStyleKey *a,
61                                             GtkStyleKey *b);
62
63 static void gtk_default_draw_hline   (GtkStyle      *style,
64                                       GdkWindow     *window,
65                                       GtkStateType   state_type,
66                                       gint           x1,
67                                       gint           x2,
68                                       gint           y);
69 static void gtk_default_draw_vline   (GtkStyle      *style,
70                                       GdkWindow     *window,
71                                       GtkStateType   state_type,
72                                       gint           y1,
73                                       gint           y2,
74                                       gint           x);
75 static void gtk_default_draw_shadow  (GtkStyle      *style,
76                                       GdkWindow     *window,
77                                       GtkStateType   state_type,
78                                       GtkShadowType  shadow_type,
79                                       gint           x,
80                                       gint           y,
81                                       gint           width,
82                                       gint           height);
83 static void gtk_default_draw_polygon (GtkStyle      *style,
84                                       GdkWindow     *window,
85                                       GtkStateType   state_type,
86                                       GtkShadowType  shadow_type,
87                                       GdkPoint      *points,
88                                       gint           npoints,
89                                       gint           fill);
90 static void gtk_default_draw_arrow   (GtkStyle      *style,
91                                       GdkWindow     *window,
92                                       GtkStateType   state_type,
93                                       GtkShadowType  shadow_type,
94                                       GtkArrowType   arrow_type,
95                                       gint           fill,
96                                       gint           x,
97                                       gint           y,
98                                       gint           width,
99                                       gint           height);
100 static void gtk_default_draw_diamond (GtkStyle      *style,
101                                       GdkWindow     *window,
102                                       GtkStateType   state_type,
103                                       GtkShadowType  shadow_type,
104                                       gint           x,
105                                       gint           y,
106                                       gint           width,
107                                       gint           height);
108 static void gtk_default_draw_oval    (GtkStyle      *style,
109                                       GdkWindow     *window,
110                                       GtkStateType   state_type,
111                                       GtkShadowType  shadow_type,
112                                       gint           x,
113                                       gint           y,
114                                       gint           width,
115                                       gint           height);
116 static void gtk_default_draw_string  (GtkStyle      *style,
117                                       GdkWindow     *window,
118                                       GtkStateType   state_type,
119                                       gint           x,
120                                       gint           y,
121                                       const gchar   *string);
122
123 static void gtk_style_shade (GdkColor *a, GdkColor *b, gdouble k);
124 static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b);
125 static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s);
126
127
128 static GtkStyleClass default_class =
129 {
130   2,
131   2,
132   gtk_default_draw_hline,
133   gtk_default_draw_vline,
134   gtk_default_draw_shadow,
135   gtk_default_draw_polygon,
136   gtk_default_draw_arrow,
137   gtk_default_draw_diamond,
138   gtk_default_draw_oval,
139   gtk_default_draw_string,
140 };
141
142 static GdkColor gtk_default_normal_fg =      { 0,      0,      0,      0 };
143 static GdkColor gtk_default_active_fg =      { 0,      0,      0,      0 };
144 static GdkColor gtk_default_prelight_fg =    { 0,      0,      0,      0 };
145 static GdkColor gtk_default_selected_fg =    { 0, 0xffff, 0xffff, 0xffff };
146 static GdkColor gtk_default_insensitive_fg = { 0, 0x7530, 0x7530, 0x7530 };
147
148 static GdkColor gtk_default_normal_bg =      { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
149 static GdkColor gtk_default_active_bg =      { 0, 0xc350, 0xc350, 0xc350 };
150 static GdkColor gtk_default_prelight_bg =    { 0, 0xea60, 0xea60, 0xea60 };
151 static GdkColor gtk_default_selected_bg =    { 0,      0,      0, 0x9c40 };
152 static GdkColor gtk_default_insensitive_bg = { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
153
154 static GdkFont *default_font = NULL;
155
156 static gint initialize = TRUE;
157 static GCache *style_cache = NULL;
158 static GSList *unattached_styles = NULL;
159
160 static GMemChunk *key_mem_chunk = NULL;
161
162 GtkStyle*
163 gtk_style_copy (GtkStyle     *style)
164 {
165   GtkStyle *new_style;
166   guint i;
167
168   g_return_val_if_fail (style != NULL, NULL);
169
170   new_style = gtk_style_new ();
171
172   for (i = 0; i < 5; i++)
173     {
174       new_style->fg[i] = style->fg[i];
175       new_style->bg[i] = style->bg[i];
176       new_style->text[i] = style->text[i];
177       new_style->base[i] = style->base[i];
178
179       new_style->bg_pixmap[i] = style->bg_pixmap[i];
180     }
181
182   new_style->font = style->font;
183   gdk_font_ref (new_style->font);
184
185   return new_style;
186 }
187
188 GtkStyle*
189 gtk_style_new (void)
190 {
191   GtkStyle *style;
192   gint i;
193
194   style = g_new0 (GtkStyle, 1);
195
196   if (!default_font)
197     default_font =
198       gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*");
199
200   style->font = default_font;
201   gdk_font_ref (style->font);
202
203   style->ref_count = 1;
204   style->attach_count = 0;
205   style->colormap = NULL;
206   style->depth = -1;
207   style->klass = &default_class;
208
209   style->black.red = 0;
210   style->black.green = 0;
211   style->black.blue = 0;
212
213   style->white.red = 65535;
214   style->white.green = 65535;
215   style->white.blue = 65535;
216
217   style->black_gc = NULL;
218   style->white_gc = NULL;
219
220   style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
221   style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
222   style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
223   style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
224   style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
225
226   style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
227   style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
228   style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
229   style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
230   style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
231
232   for (i = 0; i < 5; i++)
233     {
234       style->text[i] = style->fg[i];
235       style->base[i] = style->white;
236     }
237
238   for (i = 0; i < 5; i++)
239     style->bg_pixmap[i] = NULL;
240
241   for (i = 0; i < 5; i++)
242     {
243       style->fg_gc[i] = NULL;
244       style->bg_gc[i] = NULL;
245       style->light_gc[i] = NULL;
246       style->dark_gc[i] = NULL;
247       style->mid_gc[i] = NULL;
248       style->text_gc[i] = NULL;
249       style->base_gc[i] = NULL;
250     }
251
252   unattached_styles = g_slist_prepend (unattached_styles, style);
253
254   return style;
255 }
256
257 GtkStyle*
258 gtk_style_attach (GtkStyle  *style,
259                   GdkWindow *window)
260 {
261   GtkStyle *new_style;
262   GdkColormap *colormap;
263   gint depth;
264
265   g_return_val_if_fail (style != NULL, NULL);
266   g_return_val_if_fail (window != NULL, NULL);
267
268   colormap = gdk_window_get_colormap (window);
269   depth = gdk_window_get_visual (window)->depth;
270
271   new_style = gtk_style_find (style, colormap, depth);
272
273   if (new_style && (new_style != style))
274     {
275       gtk_style_unref (style);
276       style = new_style;
277       gtk_style_ref (style);
278     }
279
280   if (style->attach_count == 0)
281     unattached_styles = g_slist_remove (unattached_styles, style);
282
283   style->attach_count += 1;
284
285   return style;
286 }
287
288 void
289 gtk_style_detach (GtkStyle *style)
290 {
291   gint i;
292
293   g_return_if_fail (style != NULL);
294
295   style->attach_count -= 1;
296   if (style->attach_count == 0)
297     {
298       unattached_styles = g_slist_prepend (unattached_styles, style);
299
300       gtk_gc_release (style->black_gc);
301       gtk_gc_release (style->white_gc);
302
303       style->black_gc = NULL;
304       style->white_gc = NULL;
305
306       for (i = 0; i < 5; i++)
307         {
308           gtk_gc_release (style->fg_gc[i]);
309           gtk_gc_release (style->bg_gc[i]);
310           gtk_gc_release (style->light_gc[i]);
311           gtk_gc_release (style->dark_gc[i]);
312           gtk_gc_release (style->mid_gc[i]);
313           gtk_gc_release (style->text_gc[i]);
314           gtk_gc_release (style->base_gc[i]);
315
316           style->fg_gc[i] = NULL;
317           style->bg_gc[i] = NULL;
318           style->light_gc[i] = NULL;
319           style->dark_gc[i] = NULL;
320           style->mid_gc[i] = NULL;
321           style->text_gc[i] = NULL;
322           style->base_gc[i] = NULL;
323         }
324
325       style->depth = -1;
326       style->colormap = NULL;
327     }
328
329   gtk_style_remove (style);
330 }
331
332 GtkStyle*
333 gtk_style_ref (GtkStyle *style)
334 {
335   g_return_val_if_fail (style != NULL, NULL);
336
337   style->ref_count += 1;
338   return style;
339 }
340
341 void
342 gtk_style_unref (GtkStyle *style)
343 {
344   g_return_if_fail (style != NULL);
345
346   style->ref_count -= 1;
347   if (style->ref_count == 0)
348     gtk_style_destroy (style);
349 }
350
351 void
352 gtk_style_set_background (GtkStyle     *style,
353                           GdkWindow    *window,
354                           GtkStateType  state_type)
355 {
356   GdkPixmap *pixmap;
357   gint parent_relative;
358
359   g_return_if_fail (style != NULL);
360   g_return_if_fail (window != NULL);
361
362   if (style->bg_pixmap[state_type])
363     {
364       if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
365         {
366           pixmap = NULL;
367           parent_relative = TRUE;
368         }
369       else
370         {
371           pixmap = style->bg_pixmap[state_type];
372           parent_relative = FALSE;
373         }
374
375       gdk_window_set_back_pixmap (window, pixmap, parent_relative);
376     }
377   else
378     gdk_window_set_background (window, &style->bg[state_type]);
379 }
380
381
382 void
383 gtk_draw_hline (GtkStyle     *style,
384                 GdkWindow    *window,
385                 GtkStateType  state_type,
386                 gint          x1,
387                 gint          x2,
388                 gint          y)
389 {
390   g_return_if_fail (style != NULL);
391   g_return_if_fail (style->klass != NULL);
392   g_return_if_fail (style->klass->draw_hline != NULL);
393
394   (*style->klass->draw_hline) (style, window, state_type, x1, x2, y);
395 }
396
397
398 void
399 gtk_draw_vline (GtkStyle     *style,
400                 GdkWindow    *window,
401                 GtkStateType  state_type,
402                 gint          y1,
403                 gint          y2,
404                 gint          x)
405 {
406   g_return_if_fail (style != NULL);
407   g_return_if_fail (style->klass != NULL);
408   g_return_if_fail (style->klass->draw_vline != NULL);
409
410   (*style->klass->draw_vline) (style, window, state_type, y1, y2, x);
411 }
412
413
414 void
415 gtk_draw_shadow (GtkStyle      *style,
416                  GdkWindow     *window,
417                  GtkStateType   state_type,
418                  GtkShadowType  shadow_type,
419                  gint           x,
420                  gint           y,
421                  gint           width,
422                  gint           height)
423 {
424   g_return_if_fail (style != NULL);
425   g_return_if_fail (style->klass != NULL);
426   g_return_if_fail (style->klass->draw_shadow != NULL);
427
428   (*style->klass->draw_shadow) (style, window, state_type, shadow_type, x, y, width, height);
429 }
430
431 void
432 gtk_draw_polygon (GtkStyle      *style,
433                   GdkWindow     *window,
434                   GtkStateType   state_type,
435                   GtkShadowType  shadow_type,
436                   GdkPoint      *points,
437                   gint           npoints,
438                   gint           fill)
439 {
440   g_return_if_fail (style != NULL);
441   g_return_if_fail (style->klass != NULL);
442   g_return_if_fail (style->klass->draw_shadow != NULL);
443
444   (*style->klass->draw_polygon) (style, window, state_type, shadow_type, points, npoints, fill);
445 }
446
447 void
448 gtk_draw_arrow (GtkStyle      *style,
449                 GdkWindow     *window,
450                 GtkStateType   state_type,
451                 GtkShadowType  shadow_type,
452                 GtkArrowType   arrow_type,
453                 gint           fill,
454                 gint           x,
455                 gint           y,
456                 gint           width,
457                 gint           height)
458 {
459   g_return_if_fail (style != NULL);
460   g_return_if_fail (style->klass != NULL);
461   g_return_if_fail (style->klass->draw_arrow != NULL);
462
463   (*style->klass->draw_arrow) (style, window, state_type, shadow_type, arrow_type, fill, x, y, width, height);
464 }
465
466
467 void
468 gtk_draw_diamond (GtkStyle      *style,
469                   GdkWindow     *window,
470                   GtkStateType   state_type,
471                   GtkShadowType  shadow_type,
472                   gint           x,
473                   gint           y,
474                   gint           width,
475                   gint           height)
476 {
477   g_return_if_fail (style != NULL);
478   g_return_if_fail (style->klass != NULL);
479   g_return_if_fail (style->klass->draw_diamond != NULL);
480
481   (*style->klass->draw_diamond) (style, window, state_type, shadow_type, x, y, width, height);
482 }
483
484
485 void
486 gtk_draw_oval (GtkStyle      *style,
487                GdkWindow     *window,
488                GtkStateType   state_type,
489                GtkShadowType  shadow_type,
490                gint           x,
491                gint           y,
492                gint           width,
493                gint           height)
494 {
495   g_return_if_fail (style != NULL);
496   g_return_if_fail (style->klass != NULL);
497   g_return_if_fail (style->klass->draw_oval != NULL);
498
499   (*style->klass->draw_oval) (style, window, state_type, shadow_type, x, y, width, height);
500 }
501
502 void
503 gtk_draw_string (GtkStyle      *style,
504                  GdkWindow     *window,
505                  GtkStateType   state_type,
506                  gint           x,
507                  gint           y,
508                  const gchar   *string)
509 {
510   g_return_if_fail (style != NULL);
511   g_return_if_fail (style->klass != NULL);
512   g_return_if_fail (style->klass->draw_oval != NULL);
513
514   (*style->klass->draw_string) (style, window, state_type, x, y, string);
515 }
516
517
518 static void
519 gtk_style_init (GtkStyle *style)
520 {
521   GdkGCValues gc_values;
522   GdkGCValuesMask gc_values_mask;
523   GdkColormap *colormap;
524   gint i;
525
526   g_return_if_fail (style != NULL);
527
528   if (style->attach_count == 0)
529     {
530       for (i = 0; i < 5; i++)
531         {
532           gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
533           gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
534
535           style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
536           style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
537           style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
538         }
539
540       colormap = style->colormap;
541
542       gdk_color_black (colormap, &style->black);
543       gdk_color_white (colormap, &style->white);
544
545       gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
546       if (style->font->type == GDK_FONT_FONT)
547         {
548           gc_values.font = style->font;
549         }
550       else if (style->font->type == GDK_FONT_FONTSET)
551         {
552           gc_values.font = default_font;
553         }
554
555       gc_values.foreground = style->black;
556       style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
557
558       gc_values.foreground = style->white;
559       style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
560
561       for (i = 0; i < 5; i++)
562         {
563           if (!gdk_color_alloc (colormap, &style->fg[i]))
564             g_warning ("unable to allocate color: ( %d %d %d )",
565                        style->fg[i].red, style->fg[i].green, style->fg[i].blue);
566           if (!gdk_color_alloc (colormap, &style->bg[i]))
567             g_warning ("unable to allocate color: ( %d %d %d )",
568                        style->bg[i].red, style->bg[i].green, style->bg[i].blue);
569           if (!gdk_color_alloc (colormap, &style->light[i]))
570             g_warning ("unable to allocate color: ( %d %d %d )",
571                        style->light[i].red, style->light[i].green, style->light[i].blue);
572           if (!gdk_color_alloc (colormap, &style->dark[i]))
573             g_warning ("unable to allocate color: ( %d %d %d )",
574                        style->dark[i].red, style->dark[i].green, style->dark[i].blue);
575           if (!gdk_color_alloc (colormap, &style->mid[i]))
576             g_warning ("unable to allocate color: ( %d %d %d )",
577                        style->mid[i].red, style->mid[i].green, style->mid[i].blue);
578           if (!gdk_color_alloc (colormap, &style->text[i]))
579             g_warning ("unable to allocate color: ( %d %d %d )",
580                        style->text[i].red, style->text[i].green, style->text[i].blue);
581           if (!gdk_color_alloc (colormap, &style->base[i]))
582             g_warning ("unable to allocate color: ( %d %d %d )",
583                        style->base[i].red, style->base[i].green, style->base[i].blue);
584
585           gc_values.foreground = style->fg[i];
586           style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
587
588           gc_values.foreground = style->bg[i];
589           style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
590
591           gc_values.foreground = style->light[i];
592           style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
593
594           gc_values.foreground = style->dark[i];
595           style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
596
597           gc_values.foreground = style->mid[i];
598           style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
599
600           gc_values.foreground = style->text[i];
601           style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
602
603           gc_values.foreground = style->base[i];
604           style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
605         }
606     }
607 }
608
609 static void
610 gtk_styles_init (void)
611 {
612   if (initialize)
613     {
614       initialize = FALSE;
615
616       style_cache = g_cache_new ((GCacheNewFunc) gtk_style_new_from_key,
617                                  (GCacheDestroyFunc) gtk_style_unref,
618                                  (GCacheDupFunc) gtk_style_key_dup,
619                                  (GCacheDestroyFunc) gtk_style_key_destroy,
620                                  (GHashFunc) gtk_style_key_hash,
621                                  (GHashFunc) gtk_style_value_hash,
622                                  (GCompareFunc) gtk_style_key_compare);
623     }
624 }
625
626 static void
627 gtk_style_remove (GtkStyle *style)
628 {
629   if (initialize)
630     gtk_styles_init ();
631   g_cache_remove (style_cache, style);
632 }
633
634 static GtkStyle*
635 gtk_style_find (GtkStyle    *style,
636                 GdkColormap *cmap,
637                 gint         depth)
638 {
639   GtkStyleKey key;
640   gint i;
641
642   if (initialize)
643     gtk_styles_init ();
644
645   for (i = 0; i < 5; i++)
646     {
647       key.fg[i] = style->fg[i];
648       key.bg[i] = style->bg[i];
649       key.text[i] = style->text[i];
650       key.base[i] = style->base[i];
651       key.bg_pixmap[i] = style->bg_pixmap[i];
652     }
653
654   key.font = style->font;
655   key.klass = style->klass;
656   key.depth = depth;
657   key.colormap = cmap;
658
659   style = g_cache_insert (style_cache, &key);
660
661   return style;
662 }
663
664 static GtkStyle*
665 gtk_style_new_from_key (GtkStyleKey *key)
666 {
667   GtkStyle *style;
668   GSList *list;
669   gint i;
670
671   style = NULL;
672   list = unattached_styles;
673
674   while (list)
675     {
676       style = list->data;
677       list = list->next;
678
679       if ((style->depth != -1) && (style->depth != key->depth))
680         {
681           style = NULL;
682           continue;
683         }
684       if (style->colormap && (style->colormap != key->colormap))
685         {
686           style = NULL;
687           continue;
688         }
689       if (style->klass != key->klass)
690         {
691           style = NULL;
692           continue;
693         }
694       if (!gdk_font_equal (style->font, key->font))
695         {
696           style = NULL;
697           continue;
698         }
699
700       for (i = 0; style && (i < 5); i++)
701         {
702           if (style->bg_pixmap[i] != key->bg_pixmap[i])
703             {
704               style = NULL;
705               continue;
706             }
707
708           if ((style->fg[i].red != key->fg[i].red) ||
709               (style->fg[i].green != key->fg[i].green) ||
710               (style->fg[i].blue != key->fg[i].blue))
711             {
712               style = NULL;
713               continue;
714             }
715
716           if ((style->bg[i].red != key->bg[i].red) ||
717               (style->bg[i].green != key->bg[i].green) ||
718               (style->bg[i].blue != key->bg[i].blue))
719             {
720               style = NULL;
721               continue;
722             }
723
724           if ((style->text[i].red != key->text[i].red) ||
725               (style->text[i].green != key->text[i].green) ||
726               (style->text[i].blue != key->text[i].blue))
727             {
728               style = NULL;
729               continue;
730             }
731
732           if ((style->base[i].red != key->base[i].red) ||
733               (style->base[i].green != key->base[i].green) ||
734               (style->base[i].blue != key->base[i].blue))
735             {
736               style = NULL;
737               continue;
738             }
739         }
740
741       if (style)
742         {
743           gtk_style_ref (style);
744           break;
745         }
746     }
747
748   if (!style)
749     {
750       style = g_new0 (GtkStyle, 1);
751
752       style->ref_count = 1;
753       style->attach_count = 0;
754
755       style->font = key->font;
756       gdk_font_ref (style->font);
757
758       style->depth = key->depth;
759       style->colormap = key->colormap;
760       style->klass = key->klass;
761
762       style->black.red = 0;
763       style->black.green = 0;
764       style->black.blue = 0;
765
766       style->white.red = 65535;
767       style->white.green = 65535;
768       style->white.blue = 65535;
769
770       style->black_gc = NULL;
771       style->white_gc = NULL;
772
773       for (i = 0; i < 5; i++)
774         {
775           style->fg[i] = key->fg[i];
776           style->bg[i] = key->bg[i];
777           style->text[i] = key->text[i];
778           style->base[i] = key->base[i];
779         }
780
781       for (i = 0; i < 5; i++)
782         style->bg_pixmap[i] = key->bg_pixmap[i];
783
784       for (i = 0; i < 5; i++)
785         {
786           style->fg_gc[i] = NULL;
787           style->bg_gc[i] = NULL;
788           style->light_gc[i] = NULL;
789           style->dark_gc[i] = NULL;
790           style->mid_gc[i] = NULL;
791           style->text_gc[i] = NULL;
792           style->base_gc[i] = NULL;
793         }
794     }
795
796   if (style->depth == -1)
797     style->depth = key->depth;
798   if (!style->colormap)
799     style->colormap = key->colormap;
800
801   gtk_style_init (style);
802
803   return style;
804 }
805
806 static GtkStyleKey*
807 gtk_style_key_dup (GtkStyleKey *key)
808 {
809   GtkStyleKey *new_key;
810
811   if (!key_mem_chunk)
812     key_mem_chunk = g_mem_chunk_new ("key mem chunk", sizeof (GtkStyleKey),
813                                      1024, G_ALLOC_AND_FREE);
814
815   new_key = g_chunk_new (GtkStyleKey, key_mem_chunk);
816
817   *new_key = *key;
818
819   return new_key;
820 }
821
822 static void
823 gtk_style_destroy (GtkStyle *style)
824 {
825   gint i;
826
827   if (style->attach_count > 0)
828     {
829       gtk_gc_release (style->black_gc);
830       gtk_gc_release (style->white_gc);
831
832       for (i = 0; i < 5; i++)
833         {
834           gtk_gc_release (style->fg_gc[i]);
835           gtk_gc_release (style->bg_gc[i]);
836           gtk_gc_release (style->light_gc[i]);
837           gtk_gc_release (style->dark_gc[i]);
838           gtk_gc_release (style->mid_gc[i]);
839           gtk_gc_release (style->text_gc[i]);
840           gtk_gc_release (style->base_gc[i]);
841         }
842     }
843
844   unattached_styles = g_slist_remove (unattached_styles, style);
845
846   gdk_font_unref (style->font);
847   g_free (style);
848 }
849
850 static void
851 gtk_style_key_destroy (GtkStyleKey *key)
852 {
853   g_mem_chunk_free (key_mem_chunk, key);
854 }
855
856 static guint
857 gtk_style_key_hash (GtkStyleKey *key)
858 {
859   guint hash_val;
860   gint i;
861
862   hash_val = 0;
863
864   for (i = 0; i < 5; i++)
865     {
866       hash_val += key->fg[i].red + key->fg[i].green + key->fg[i].blue;
867       hash_val += key->bg[i].red + key->bg[i].green + key->bg[i].blue;
868       hash_val += key->text[i].red + key->text[i].green + key->text[i].blue;
869       hash_val += key->base[i].red + key->base[i].green + key->base[i].blue;
870     }
871
872   hash_val += (guint) gdk_font_id (key->font);
873   hash_val += (guint) key->depth;
874   hash_val += (gulong) key->colormap;
875   hash_val += (gulong) key->klass;
876
877   return hash_val;
878 }
879
880 static guint
881 gtk_style_value_hash (GtkStyle *style)
882 {
883   guint hash_val;
884   gint i;
885
886   hash_val = 0;
887
888   for (i = 0; i < 5; i++)
889     {
890       hash_val += style->fg[i].red + style->fg[i].green + style->fg[i].blue;
891       hash_val += style->bg[i].red + style->bg[i].green + style->bg[i].blue;
892       hash_val += style->text[i].red + style->text[i].green + style->text[i].blue;
893       hash_val += style->base[i].red + style->base[i].green + style->base[i].blue;
894     }
895
896   hash_val += (guint) gdk_font_id (style->font);
897   hash_val += (gulong) style->klass;
898
899   return hash_val;
900 }
901
902 static gint
903 gtk_style_key_compare (GtkStyleKey *a,
904                        GtkStyleKey *b)
905 {
906   gint i;
907
908   if (a->depth != b->depth)
909     return FALSE;
910   if (a->colormap != b->colormap)
911     return FALSE;
912   if (a->klass != b->klass)
913     return FALSE;
914   if (!gdk_font_equal (a->font, b->font))
915     return FALSE;
916
917   for (i = 0; i < 5; i++)
918     {
919       if (a->bg_pixmap[i] != b->bg_pixmap[i])
920         return FALSE;
921
922       if ((a->fg[i].red != b->fg[i].red) ||
923           (a->fg[i].green != b->fg[i].green) ||
924           (a->fg[i].blue != b->fg[i].blue))
925         return FALSE;
926       if ((a->bg[i].red != b->bg[i].red) ||
927           (a->bg[i].green != b->bg[i].green) ||
928           (a->bg[i].blue != b->bg[i].blue))
929         return FALSE;
930       if ((a->text[i].red != b->text[i].red) ||
931           (a->text[i].green != b->text[i].green) ||
932           (a->text[i].blue != b->text[i].blue))
933         return FALSE;
934       if ((a->base[i].red != b->base[i].red) ||
935           (a->base[i].green != b->base[i].green) ||
936           (a->base[i].blue != b->base[i].blue))
937         return FALSE;
938     }
939
940   return TRUE;
941 }
942
943
944 static void
945 gtk_default_draw_hline (GtkStyle     *style,
946                         GdkWindow    *window,
947                         GtkStateType  state_type,
948                         gint          x1,
949                         gint          x2,
950                         gint          y)
951 {
952   gint thickness_light;
953   gint thickness_dark;
954   gint i;
955
956   g_return_if_fail (style != NULL);
957   g_return_if_fail (window != NULL);
958
959   thickness_light = style->klass->ythickness / 2;
960   thickness_dark = style->klass->ythickness - thickness_light;
961
962   for (i = 0; i < thickness_dark; i++)
963     {
964       gdk_draw_line (window, style->light_gc[state_type], x2 - i - 1, y + i, x2, y + i);
965       gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
966     }
967
968   y += thickness_dark;
969   for (i = 0; i < thickness_light; i++)
970     {
971       gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
972       gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i - 1, y + i, x2, y + i);
973     }
974 }
975
976
977 static void
978 gtk_default_draw_vline (GtkStyle     *style,
979                         GdkWindow    *window,
980                         GtkStateType  state_type,
981                         gint          y1,
982                         gint          y2,
983                         gint          x)
984 {
985   gint thickness_light;
986   gint thickness_dark;
987   gint i;
988
989   g_return_if_fail (style != NULL);
990   g_return_if_fail (window != NULL);
991
992   thickness_light = style->klass->xthickness / 2;
993   thickness_dark = style->klass->xthickness - thickness_light;
994
995   for (i = 0; i < thickness_dark; i++)
996     {
997       gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i - 1, x + i, y2);
998       gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
999     }
1000
1001   x += thickness_dark;
1002   for (i = 0; i < thickness_light; i++)
1003     {
1004       gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i);
1005       gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
1006     }
1007 }
1008
1009
1010 static void
1011 gtk_default_draw_shadow (GtkStyle      *style,
1012                          GdkWindow     *window,
1013                          GtkStateType   state_type,
1014                          GtkShadowType  shadow_type,
1015                          gint           x,
1016                          gint           y,
1017                          gint           width,
1018                          gint           height)
1019 {
1020   GdkGC *gc1;
1021   GdkGC *gc2;
1022   gint thickness_light;
1023   gint thickness_dark;
1024   gint i;
1025
1026   g_return_if_fail (style != NULL);
1027   g_return_if_fail (window != NULL);
1028
1029   if ((width == -1) && (height == -1))
1030     gdk_window_get_size (window, &width, &height);
1031   else if (width == -1)
1032     gdk_window_get_size (window, &width, NULL);
1033   else if (height == -1)
1034     gdk_window_get_size (window, NULL, &height);
1035
1036   switch (shadow_type)
1037     {
1038     case GTK_SHADOW_NONE:
1039       gc1 = NULL;
1040       gc2 = NULL;
1041       break;
1042     case GTK_SHADOW_IN:
1043     case GTK_SHADOW_ETCHED_IN:
1044       gc1 = style->light_gc[state_type];
1045       gc2 = style->dark_gc[state_type];
1046       break;
1047     case GTK_SHADOW_OUT:
1048     case GTK_SHADOW_ETCHED_OUT:
1049       gc1 = style->dark_gc[state_type];
1050       gc2 = style->light_gc[state_type];
1051       break;
1052     }
1053
1054   switch (shadow_type)
1055     {
1056     case GTK_SHADOW_NONE:
1057       break;
1058
1059     case GTK_SHADOW_IN:
1060       gdk_draw_line (window, gc1,
1061                      x, y + height - 1, x + width - 1, y + height - 1);
1062       gdk_draw_line (window, gc1,
1063                      x + width - 1, y, x + width - 1, y + height - 1);
1064
1065       gdk_draw_line (window, style->bg_gc[state_type],
1066                      x + 1, y + height - 2, x + width - 2, y + height - 2);
1067       gdk_draw_line (window, style->bg_gc[state_type],
1068                      x + width - 2, y + 1, x + width - 2, y + height - 2);
1069
1070       gdk_draw_line (window, style->black_gc,
1071                      x + 1, y + 1, x + width - 2, y + 1);
1072       gdk_draw_line (window, style->black_gc,
1073                      x + 1, y + 1, x + 1, y + height - 2);
1074
1075       gdk_draw_line (window, gc2,
1076                      x, y, x + width - 1, y);
1077       gdk_draw_line (window, gc2,
1078                      x, y, x, y + height - 1);
1079       break;
1080
1081     case GTK_SHADOW_OUT:
1082       gdk_draw_line (window, gc1,
1083                      x + 1, y + height - 2, x + width - 2, y + height - 2);
1084       gdk_draw_line (window, gc1,
1085                      x + width - 2, y + 1, x + width - 2, y + height - 2);
1086
1087       gdk_draw_line (window, gc2,
1088                      x, y, x + width - 1, y);
1089       gdk_draw_line (window, gc2,
1090                      x, y, x, y + height - 1);
1091
1092       gdk_draw_line (window, style->bg_gc[state_type],
1093                      x + 1, y + 1, x + width - 2, y + 1);
1094       gdk_draw_line (window, style->bg_gc[state_type],
1095                      x + 1, y + 1, x + 1, y + height - 2);
1096
1097       gdk_draw_line (window, style->black_gc,
1098                      x, y + height - 1, x + width - 1, y + height - 1);
1099       gdk_draw_line (window, style->black_gc,
1100                      x + width - 1, y, x + width - 1, y + height - 1);
1101       break;
1102
1103     case GTK_SHADOW_ETCHED_IN:
1104     case GTK_SHADOW_ETCHED_OUT:
1105       thickness_light = 1;
1106       thickness_dark = 1;
1107
1108       for (i = 0; i < thickness_dark; i++)
1109         {
1110           gdk_draw_line (window, gc1,
1111                          x + i,
1112                          y + height - i - 1,
1113                          x + width - i - 1,
1114                          y + height - i - 1);
1115           gdk_draw_line (window, gc1,
1116                          x + width - i - 1,
1117                          y + i,
1118                          x + width - i - 1,
1119                          y + height - i - 1);
1120
1121           gdk_draw_line (window, gc2,
1122                          x + i,
1123                          y + i,
1124                          x + width - i - 2,
1125                          y + i);
1126           gdk_draw_line (window, gc2,
1127                          x + i,
1128                          y + i,
1129                          x + i,
1130                          y + height - i - 2);
1131         }
1132
1133       for (i = 0; i < thickness_light; i++)
1134         {
1135           gdk_draw_line (window, gc1,
1136                          x + thickness_dark + i,
1137                          y + thickness_dark + i,
1138                          x + width - thickness_dark - i - 1,
1139                          y + thickness_dark + i);
1140           gdk_draw_line (window, gc1,
1141                          x + thickness_dark + i,
1142                          y + thickness_dark + i,
1143                          x + thickness_dark + i,
1144                          y + height - thickness_dark - i - 1);
1145
1146           gdk_draw_line (window, gc2,
1147                          x + thickness_dark + i,
1148                          y + height - thickness_light - i - 1,
1149                          x + width - thickness_light - 1,
1150                          y + height - thickness_light - i - 1);
1151           gdk_draw_line (window, gc2,
1152                          x + width - thickness_light - i - 1,
1153                          y + thickness_dark + i,
1154                          x + width - thickness_light - i - 1,
1155                          y + height - thickness_light - 1);
1156         }
1157       break;
1158     }
1159 }
1160
1161
1162 static void
1163 gtk_default_draw_polygon (GtkStyle      *style,
1164                           GdkWindow     *window,
1165                           GtkStateType   state_type,
1166                           GtkShadowType  shadow_type,
1167                           GdkPoint      *points,
1168                           gint           npoints,
1169                           gint           fill)
1170 {
1171 #ifndef M_PI
1172 #define M_PI    3.14159265358979323846
1173 #endif /* M_PI */
1174 #ifndef M_PI_4
1175 #define M_PI_4  0.78539816339744830962
1176 #endif /* M_PI_4 */
1177
1178   static const gdouble pi_over_4 = M_PI_4;
1179   static const gdouble pi_3_over_4 = M_PI_4 * 3;
1180
1181   GdkGC *gc1;
1182   GdkGC *gc2;
1183   GdkGC *gc3;
1184   GdkGC *gc4;
1185   gdouble angle;
1186   gint xadjust;
1187   gint yadjust;
1188   gint i;
1189
1190   g_return_if_fail (style != NULL);
1191   g_return_if_fail (window != NULL);
1192   g_return_if_fail (points != NULL);
1193
1194   switch (shadow_type)
1195     {
1196     case GTK_SHADOW_IN:
1197       gc1 = style->bg_gc[state_type];
1198       gc2 = style->dark_gc[state_type];
1199       gc3 = style->light_gc[state_type];
1200       gc4 = style->black_gc;
1201       break;
1202     case GTK_SHADOW_OUT:
1203       gc1 = style->dark_gc[state_type];
1204       gc2 = style->light_gc[state_type];
1205       gc3 = style->black_gc;
1206       gc4 = style->bg_gc[state_type];
1207       break;
1208     default:
1209       return;
1210     }
1211
1212   if (fill)
1213     gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
1214
1215   npoints--;
1216
1217   for (i = 0; i < npoints; i++)
1218     {
1219       if ((points[i].x == points[i+1].x) &&
1220           (points[i].y == points[i+1].y))
1221         {
1222           angle = 0;
1223         }
1224       else
1225         {
1226           angle = atan2 (points[i+1].y - points[i].y,
1227                          points[i+1].x - points[i].x);
1228         }
1229
1230       if ((angle > -pi_3_over_4) && (angle < pi_over_4))
1231         {
1232           if (angle > -pi_over_4)
1233             {
1234               xadjust = 0;
1235               yadjust = 1;
1236             }
1237           else
1238             {
1239               xadjust = 1;
1240               yadjust = 0;
1241             }
1242
1243           gdk_draw_line (window, gc1,
1244                          points[i].x-xadjust, points[i].y-yadjust,
1245                          points[i+1].x-xadjust, points[i+1].y-yadjust);
1246           gdk_draw_line (window, gc3,
1247                          points[i].x, points[i].y,
1248                          points[i+1].x, points[i+1].y);
1249         }
1250       else
1251         {
1252           if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
1253             {
1254               xadjust = 0;
1255               yadjust = 1;
1256             }
1257           else
1258             {
1259               xadjust = 1;
1260               yadjust = 0;
1261             }
1262
1263           gdk_draw_line (window, gc4,
1264                          points[i].x+xadjust, points[i].y+yadjust,
1265                          points[i+1].x+xadjust, points[i+1].y+yadjust);
1266           gdk_draw_line (window, gc2,
1267                          points[i].x, points[i].y,
1268                          points[i+1].x, points[i+1].y);
1269         }
1270     }
1271 }
1272
1273
1274 static void
1275 gtk_default_draw_arrow (GtkStyle      *style,
1276                         GdkWindow     *window,
1277                         GtkStateType   state_type,
1278                         GtkShadowType  shadow_type,
1279                         GtkArrowType   arrow_type,
1280                         gint           fill,
1281                         gint           x,
1282                         gint           y,
1283                         gint           width,
1284                         gint           height)
1285 {
1286   GdkGC *gc1;
1287   GdkGC *gc2;
1288   GdkGC *gc3;
1289   GdkGC *gc4;
1290   gint half_width;
1291   gint half_height;
1292   GdkPoint points[3];
1293
1294   g_return_if_fail (style != NULL);
1295   g_return_if_fail (window != NULL);
1296
1297   switch (shadow_type)
1298     {
1299     case GTK_SHADOW_IN:
1300       gc1 = style->bg_gc[state_type];
1301       gc2 = style->dark_gc[state_type];
1302       gc3 = style->light_gc[state_type];
1303       gc4 = style->black_gc;
1304       break;
1305     case GTK_SHADOW_OUT:
1306       gc1 = style->dark_gc[state_type];
1307       gc2 = style->light_gc[state_type];
1308       gc3 = style->black_gc;
1309       gc4 = style->bg_gc[state_type];
1310       break;
1311     default:
1312       return;
1313     }
1314
1315   if ((width == -1) && (height == -1))
1316     gdk_window_get_size (window, &width, &height);
1317   else if (width == -1)
1318     gdk_window_get_size (window, &width, NULL);
1319   else if (height == -1)
1320     gdk_window_get_size (window, NULL, &height);
1321
1322   half_width = width / 2;
1323   half_height = height / 2;
1324
1325   switch (arrow_type)
1326     {
1327     case GTK_ARROW_UP:
1328       if (fill)
1329         {
1330           points[0].x = x + half_width;
1331           points[0].y = y;
1332           points[1].x = x;
1333           points[1].y = y + height - 1;
1334           points[2].x = x + width - 1;
1335           points[2].y = y + height - 1;
1336
1337           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
1338         }
1339
1340       gdk_draw_line (window, gc1,
1341                      x + 1, y + height - 2,
1342                      x + width - 2, y + height - 2);
1343       gdk_draw_line (window, gc3,
1344                      x + 0, y + height - 1,
1345                      x + width - 1, y + height - 1);
1346
1347       gdk_draw_line (window, gc1,
1348                      x + width - 2, y + height - 1,
1349                      x + half_width, y + 1);
1350       gdk_draw_line (window, gc3,
1351                      x + width - 1, y + height - 1,
1352                      x + half_width, y);
1353
1354       gdk_draw_line (window, gc4,
1355                      x + half_width, y + 1,
1356                      x + 1, y + height - 1);
1357       gdk_draw_line (window, gc2,
1358                      x + half_width, y,
1359                      x, y + height - 1);
1360       break;
1361     case GTK_ARROW_DOWN:
1362       if (fill)
1363         {
1364           points[0].x = x + width - 1;
1365           points[0].y = y;
1366           points[1].x = x;
1367           points[1].y = y;
1368           points[2].x = x + half_width;
1369           points[2].y = y + height - 1;
1370
1371           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
1372         }
1373
1374       gdk_draw_line (window, gc4,
1375                      x + width - 2,
1376                      y + 1, x + 1, y + 1);
1377       gdk_draw_line (window, gc2,
1378                      x + width - 1, y,
1379                      x, y);
1380
1381       gdk_draw_line (window, gc4,
1382                      x + 1, y,
1383                      x + half_width, y + height - 2);
1384       gdk_draw_line (window, gc2,
1385                      x, y,
1386                      x + half_width, y + height - 1);
1387
1388       gdk_draw_line (window, gc1,
1389                      x + half_width, y + height - 2,
1390                      x + width - 2, y);
1391       gdk_draw_line (window, gc3,
1392                      x + half_width, y + height - 1,
1393                      x + width - 1, y);
1394       break;
1395     case GTK_ARROW_LEFT:
1396       if (fill)
1397         {
1398           points[0].x = x;
1399           points[0].y = y + half_height;
1400           points[1].x = x + width - 1;
1401           points[1].y = y + height - 1;
1402           points[2].x = x + width - 1;
1403           points[2].y = y;
1404
1405           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
1406         }
1407
1408       gdk_draw_line (window, gc1,
1409                      x + 1, y + half_height,
1410                      x + width - 1, y + height - 1);
1411       gdk_draw_line (window, gc3,
1412                      x, y + half_height,
1413                      x + width - 1, y + height - 1);
1414
1415       gdk_draw_line (window, gc1,
1416                      x + width - 2, y + height - 1,
1417                      x + width - 2, y + 1);
1418       gdk_draw_line (window, gc3,
1419                      x + width - 1, y + height - 1,
1420                      x + width - 1, y);
1421
1422       gdk_draw_line (window, gc4,
1423                      x + width - 1, y + 1,
1424                      x + 1, y + half_height);
1425       gdk_draw_line (window, gc2,
1426                      x + width - 1, y,
1427                      x, y + half_height);
1428       break;
1429     case GTK_ARROW_RIGHT:
1430       if (fill)
1431         {
1432           points[0].x = x + width - 1;
1433           points[0].y = y + half_height;
1434           points[1].x = x;
1435           points[1].y = y;
1436           points[2].x = x;
1437           points[2].y = y + height - 1;
1438
1439           gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
1440         }
1441
1442       gdk_draw_line (window, gc4,
1443                      x + width - 1, y + half_height,
1444                      x + 1, y + 1);
1445       gdk_draw_line (window, gc2,
1446                      x + width - 1, y + half_height,
1447                      x, y);
1448
1449       gdk_draw_line (window, gc4,
1450                      x + 1, y + 1,
1451                      x + 1, y + height - 2);
1452       gdk_draw_line (window, gc2,
1453                      x, y,
1454                      x, y + height - 1);
1455
1456       gdk_draw_line (window, gc1,
1457                      x + 1, y + height - 2,
1458                      x + width - 1, y + half_height);
1459       gdk_draw_line (window, gc3,
1460                      x, y + height - 1,
1461                      x + width - 1, y + half_height);
1462       break;
1463     }
1464 }
1465
1466
1467 static void
1468 gtk_default_draw_diamond (GtkStyle      *style,
1469                           GdkWindow     *window,
1470                           GtkStateType   state_type,
1471                           GtkShadowType  shadow_type,
1472                           gint           x,
1473                           gint           y,
1474                           gint           width,
1475                           gint           height)
1476 {
1477   gint half_width;
1478   gint half_height;
1479
1480   g_return_if_fail (style != NULL);
1481   g_return_if_fail (window != NULL);
1482
1483   if ((width == -1) && (height == -1))
1484     gdk_window_get_size (window, &width, &height);
1485   else if (width == -1)
1486     gdk_window_get_size (window, &width, NULL);
1487   else if (height == -1)
1488     gdk_window_get_size (window, NULL, &height);
1489
1490   half_width = width / 2;
1491   half_height = height / 2;
1492
1493   switch (shadow_type)
1494     {
1495     case GTK_SHADOW_IN:
1496       gdk_draw_line (window, style->bg_gc[state_type],
1497                      x + 2, y + half_height,
1498                      x + half_width, y + height - 2);
1499       gdk_draw_line (window, style->bg_gc[state_type],
1500                      x + half_width, y + height - 2,
1501                      x + width - 2, y + half_height);
1502       gdk_draw_line (window, style->light_gc[state_type],
1503                      x + 1, y + half_height,
1504                      x + half_width, y + height - 1);
1505       gdk_draw_line (window, style->light_gc[state_type],
1506                      x + half_width, y + height - 1,
1507                      x + width - 1, y + half_height);
1508       gdk_draw_line (window, style->light_gc[state_type],
1509                      x, y + half_height,
1510                      x + half_width, y + height);
1511       gdk_draw_line (window, style->light_gc[state_type],
1512                      x + half_width, y + height,
1513                      x + width, y + half_height);
1514
1515       gdk_draw_line (window, style->black_gc,
1516                      x + 2, y + half_height,
1517                      x + half_width, y + 2);
1518       gdk_draw_line (window, style->black_gc,
1519                      x + half_width, y + 2,
1520                      x + width - 2, y + half_height);
1521       gdk_draw_line (window, style->dark_gc[state_type],
1522                      x + 1, y + half_height,
1523                      x + half_width, y + 1);
1524       gdk_draw_line (window, style->dark_gc[state_type],
1525                      x + half_width, y + 1,
1526                      x + width - 1, y + half_height);
1527       gdk_draw_line (window, style->dark_gc[state_type],
1528                      x, y + half_height,
1529                      x + half_width, y);
1530       gdk_draw_line (window, style->dark_gc[state_type],
1531                      x + half_width, y,
1532                      x + width, y + half_height);
1533       break;
1534     case GTK_SHADOW_OUT:
1535       gdk_draw_line (window, style->dark_gc[state_type],
1536                      x + 2, y + half_height,
1537                      x + half_width, y + height - 2);
1538       gdk_draw_line (window, style->dark_gc[state_type],
1539                      x + half_width, y + height - 2,
1540                      x + width - 2, y + half_height);
1541       gdk_draw_line (window, style->dark_gc[state_type],
1542                      x + 1, y + half_height,
1543                      x + half_width, y + height - 1);
1544       gdk_draw_line (window, style->dark_gc[state_type],
1545                      x + half_width, y + height - 1,
1546                      x + width - 1, y + half_height);
1547       gdk_draw_line (window, style->black_gc,
1548                      x, y + half_height,
1549                      x + half_width, y + height);
1550       gdk_draw_line (window, style->black_gc,
1551                      x + half_width, y + height,
1552                      x + width, y + half_height);
1553
1554       gdk_draw_line (window, style->bg_gc[state_type],
1555                      x + 2, y + half_height,
1556                      x + half_width, y + 2);
1557       gdk_draw_line (window, style->bg_gc[state_type],
1558                      x + half_width, y + 2,
1559                      x + width - 2, y + half_height);
1560       gdk_draw_line (window, style->light_gc[state_type],
1561                      x + 1, y + half_height,
1562                      x + half_width, y + 1);
1563       gdk_draw_line (window, style->light_gc[state_type],
1564                      x + half_width, y + 1,
1565                      x + width - 1, y + half_height);
1566       gdk_draw_line (window, style->light_gc[state_type],
1567                      x, y + half_height,
1568                      x + half_width, y);
1569       gdk_draw_line (window, style->light_gc[state_type],
1570                      x + half_width, y,
1571                      x + width, y + half_height);
1572       break;
1573     default:
1574       break;
1575     }
1576 }
1577
1578
1579 static void
1580 gtk_default_draw_oval (GtkStyle      *style,
1581                        GdkWindow     *window,
1582                        GtkStateType   state_type,
1583                        GtkShadowType  shadow_type,
1584                        gint           x,
1585                        gint           y,
1586                        gint           width,
1587                        gint           height)
1588 {
1589   g_return_if_fail (style != NULL);
1590   g_return_if_fail (window != NULL);
1591 }
1592
1593 static void
1594 gtk_default_draw_string (GtkStyle      *style,
1595                          GdkWindow     *window,
1596                          GtkStateType   state_type,
1597                          gint           x,
1598                          gint           y,
1599                          const gchar   *string)
1600 {
1601   g_return_if_fail (style != NULL);
1602   g_return_if_fail (window != NULL);
1603
1604   if (state_type == GTK_STATE_INSENSITIVE)
1605     gdk_draw_string (window, style->font, style->white_gc, x + 1, y + 1, string);
1606   gdk_draw_string (window, style->font, style->fg_gc[state_type], x, y, string);
1607 }
1608
1609
1610 static void
1611 gtk_style_shade (GdkColor *a,
1612                  GdkColor *b,
1613                  gdouble   k)
1614 {
1615   gdouble red;
1616   gdouble green;
1617   gdouble blue;
1618
1619   red = (gdouble) a->red / 65535.0;
1620   green = (gdouble) a->green / 65535.0;
1621   blue = (gdouble) a->blue / 65535.0;
1622
1623   rgb_to_hls (&red, &green, &blue);
1624
1625   green *= k;
1626   if (green > 1.0)
1627     green = 1.0;
1628   else if (green < 0.0)
1629     green = 0.0;
1630
1631   blue *= k;
1632   if (blue > 1.0)
1633     blue = 1.0;
1634   else if (blue < 0.0)
1635     blue = 0.0;
1636
1637   hls_to_rgb (&red, &green, &blue);
1638
1639   b->red = red * 65535.0;
1640   b->green = green * 65535.0;
1641   b->blue = blue * 65535.0;
1642 }
1643
1644 static void
1645 rgb_to_hls (gdouble *r,
1646             gdouble *g,
1647             gdouble *b)
1648 {
1649   gdouble min;
1650   gdouble max;
1651   gdouble red;
1652   gdouble green;
1653   gdouble blue;
1654   gdouble h, l, s;
1655   gdouble delta;
1656
1657   red = *r;
1658   green = *g;
1659   blue = *b;
1660
1661   if (red > green)
1662     {
1663       if (red > blue)
1664         max = red;
1665       else
1666         max = blue;
1667
1668       if (green < blue)
1669         min = green;
1670       else
1671         min = blue;
1672     }
1673   else
1674     {
1675       if (green > blue)
1676         max = green;
1677       else
1678         max = blue;
1679
1680       if (red < blue)
1681         min = red;
1682       else
1683         min = blue;
1684     }
1685
1686   l = (max + min) / 2;
1687   s = 0;
1688   h = 0;
1689
1690   if (max != min)
1691     {
1692       if (l <= 0.5)
1693         s = (max - min) / (max + min);
1694       else
1695         s = (max - min) / (2 - max - min);
1696
1697       delta = max -min;
1698       if (red == max)
1699         h = (green - blue) / delta;
1700       else if (green == max)
1701         h = 2 + (blue - red) / delta;
1702       else if (blue == max)
1703         h = 4 + (red - green) / delta;
1704
1705       h *= 60;
1706       if (h < 0.0)
1707         h += 360;
1708     }
1709
1710   *r = h;
1711   *g = l;
1712   *b = s;
1713 }
1714
1715 static void
1716 hls_to_rgb (gdouble *h,
1717             gdouble *l,
1718             gdouble *s)
1719 {
1720   gdouble hue;
1721   gdouble lightness;
1722   gdouble saturation;
1723   gdouble m1, m2;
1724   gdouble r, g, b;
1725
1726   lightness = *l;
1727   saturation = *s;
1728
1729   if (lightness <= 0.5)
1730     m2 = lightness * (1 + saturation);
1731   else
1732     m2 = lightness + saturation - lightness * saturation;
1733   m1 = 2 * lightness - m2;
1734
1735   if (saturation == 0)
1736     {
1737       *h = lightness;
1738       *l = lightness;
1739       *s = lightness;
1740     }
1741   else
1742     {
1743       hue = *h + 120;
1744       while (hue > 360)
1745         hue -= 360;
1746       while (hue < 0)
1747         hue += 360;
1748
1749       if (hue < 60)
1750         r = m1 + (m2 - m1) * hue / 60;
1751       else if (hue < 180)
1752         r = m2;
1753       else if (hue < 240)
1754         r = m1 + (m2 - m1) * (240 - hue) / 60;
1755       else
1756         r = m1;
1757
1758       hue = *h;
1759       while (hue > 360)
1760         hue -= 360;
1761       while (hue < 0)
1762         hue += 360;
1763
1764       if (hue < 60)
1765         g = m1 + (m2 - m1) * hue / 60;
1766       else if (hue < 180)
1767         g = m2;
1768       else if (hue < 240)
1769         g = m1 + (m2 - m1) * (240 - hue) / 60;
1770       else
1771         g = m1;
1772
1773       hue = *h - 120;
1774       while (hue > 360)
1775         hue -= 360;
1776       while (hue < 0)
1777         hue += 360;
1778
1779       if (hue < 60)
1780         b = m1 + (m2 - m1) * hue / 60;
1781       else if (hue < 180)
1782         b = m2;
1783       else if (hue < 240)
1784         b = m1 + (m2 - m1) * (240 - hue) / 60;
1785       else
1786         b = m1;
1787
1788       *h = r;
1789       *l = g;
1790       *s = b;
1791     }
1792 }