source: trunk/third/gtk-engines/metal/metal_style.c @ 18625

Revision 18625, 88.0 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18624, which included commits to RCS files with non-trunk default branches.
Line 
1#include <math.h>
2#include <string.h>
3#include <gtk/gtk.h>
4#include "metal_style.h"
5
6
7#define DETAIL(xx)   ((detail) && (!strcmp(xx, detail)))
8
9/**************************************************************************
10* GTK Metal Theme
11*
12* Version 0.9, Oct 2, 1998
13*
14* Copyright 1998: Randy Gordon, Integrand Systems
15*                 http://www.integrand.com
16*                 mailto://randy@integrand.com
17*
18* Heavily modified by Owen Taylor <otaylor@redhat.com>
19*
20* License: GPL (Gnu Public License)
21*
22*
23**************************************************************************/
24
25static void draw_box               (GtkStyle       *style,
26                                    GdkWindow      *window,
27                                    GtkStateType    state_type,
28                                    GtkShadowType   shadow_type,
29                                    GdkRectangle   *area,
30                                    GtkWidget      *widget,
31                                    const gchar    *detail,
32                                    gint            x,
33                                    gint            y,
34                                    gint            width,
35                                    gint            height);
36static gboolean sanitize_size      (GdkWindow      *window,
37                                    gint           *width,
38                                    gint           *height);
39static void metal_arrow            (GdkWindow      *window,
40                                    GtkWidget      *widget,
41                                    GdkGC          *gc,
42                                    GtkArrowType    arrow_type,
43                                    gint            x,
44                                    gint            y,
45                                    gint            width,
46                                    gint            height);
47static void metal_scrollbar_trough (GtkStyle       *style,
48                                    GdkWindow      *window,
49                                    GtkStateType    state_type,
50                                    GtkShadowType   shadow_type,
51                                    GdkRectangle   *area,
52                                    GtkWidget      *widget,
53                                    const gchar    *detail,
54                                    gint            x,
55                                    gint            y,
56                                    gint            width,
57                                    gint            height);
58static void metal_scrollbar_slider (GtkStyle       *style,
59                                    GdkWindow      *window,
60                                    GtkStateType    state_type,
61                                    GtkShadowType   shadow_type,
62                                    GdkRectangle   *area,
63                                    GtkWidget      *widget,
64                                    const gchar    *detail,
65                                    gint            x,
66                                    gint            y,
67                                    gint            width,
68                                    gint            height);
69static void metal_scale_trough     (GtkStyle       *style,
70                                    GdkWindow      *window,
71                                    GtkStateType    state_type,
72                                    GtkShadowType   shadow_type,
73                                    GdkRectangle   *area,
74                                    GtkWidget      *widget,
75                                    const gchar    *detail,
76                                    gint            x,
77                                    gint            y,
78                                    gint            width,
79                                    gint            height);
80static void metal_scale_slider     (GtkStyle       *style,
81                                    GdkWindow      *window,
82                                    GtkStateType    state_type,
83                                    GtkShadowType   shadow_type,
84                                    GdkRectangle   *area,
85                                    GtkWidget      *widget,
86                                    const gchar    *detail,
87                                    gint            x,
88                                    gint            y,
89                                    gint            width,
90                                    gint            height,
91                                    GtkOrientation  orientation);
92static void metal_menu             (GtkStyle       *style,
93                                    GdkWindow      *window,
94                                    GtkStateType    state_type,
95                                    GtkShadowType   shadow_type,
96                                    GdkRectangle   *area,
97                                    GtkWidget      *widget,
98                                    const gchar    *detail,
99                                    gint            x,
100                                    gint            y,
101                                    gint            width,
102                                    gint            height);
103static void metal_menu_item        (GtkStyle       *style,
104                                    GdkWindow      *window,
105                                    GtkStateType    state_type,
106                                    GtkShadowType   shadow_type,
107                                    GdkRectangle   *area,
108                                    GtkWidget      *widget,
109                                    const gchar    *detail,
110                                    gint            x,
111                                    gint            y,
112                                    gint            width,
113                                    gint            height);
114static void metal_notebook         (GtkStyle       *style,
115                                    GdkWindow      *window,
116                                    GtkStateType    state_type,
117                                    GtkShadowType   shadow_type,
118                                    GdkRectangle   *area,
119                                    GtkWidget      *widget,
120                                    const gchar    *detail,
121                                    gint            x,
122                                    gint            y,
123                                    gint            width,
124                                    gint            height);
125static void metal_tab              (GtkStyle       *style,
126                                    GdkWindow      *window,
127                                    GtkStateType    state_type,
128                                    GtkShadowType   shadow_type,
129                                    GdkRectangle   *area,
130                                    GtkWidget      *widget,
131                                    const gchar    *detail,
132                                    gint            x,
133                                    gint            y,
134                                    gint            width,
135                                    gint            height);
136static gboolean is_first_tab       (GtkNotebook    *notebook,
137                                    gint             x,
138                                    gint             y);
139static void metal_button           (GtkStyle       *style,
140                                    GdkWindow      *window,
141                                    GtkStateType    state_type,
142                                    GtkShadowType   shadow_type,
143                                    GdkRectangle   *area,
144                                    GtkWidget      *widget,
145                                    const gchar    *detail,
146                                    gint            x,
147                                    gint            y,
148                                    gint            width,
149                                    gint            height);
150
151static GtkStyleClass *parent_class;
152
153static gboolean
154sanitize_size (GdkWindow      *window,
155               gint           *width,
156               gint           *height)
157{
158  gboolean set_bg = FALSE;
159
160  if ((*width == -1) && (*height == -1))
161    {
162      set_bg = GDK_IS_WINDOW (window);
163      gdk_window_get_size (window, width, height);
164    }
165  else if (*width == -1)
166    gdk_window_get_size (window, width, NULL);
167  else if (*height == -1)
168    gdk_window_get_size (window, NULL, height);
169
170  return set_bg;
171}
172
173static void
174draw_hline (GtkStyle * style,
175            GdkWindow * window,
176            GtkStateType state_type,
177            GdkRectangle * area,
178            GtkWidget * widget,
179            const gchar * detail,
180            gint x1,
181            gint x2,
182            gint y)
183{
184  gint thickness_light;
185  gint thickness_dark;
186  gint i;
187  GdkGC *lightgc, *darkgc;
188
189  g_return_if_fail (style != NULL);
190  g_return_if_fail (window != NULL);
191
192  thickness_light = style->ythickness / 2;
193  thickness_dark = style->ythickness - thickness_light;
194
195  lightgc = style->light_gc[state_type];
196  darkgc = style->dark_gc[state_type];
197
198  if (area)
199    {
200      gdk_gc_set_clip_rectangle (lightgc, area);
201      gdk_gc_set_clip_rectangle (darkgc, area);
202    }
203
204  for (i = 0; i < thickness_dark; i++)
205    {
206      gdk_draw_line (window, lightgc, x2 - i - 1, y + i, x2, y + i);
207      gdk_draw_line (window, darkgc, x1, y + i, x2 - i - 1, y + i);
208    }
209
210  y += thickness_dark;
211  for (i = 0; i < thickness_light; i++)
212    {
213      gdk_draw_line (window, darkgc, x1, y + i, x1 + thickness_light - i -
214                     1, y + i);
215      gdk_draw_line (window, lightgc, x1 + thickness_light - i - 1, y + i,
216                     x2, y + i);
217    }
218
219  if (area)
220    {
221      gdk_gc_set_clip_rectangle (lightgc, NULL);
222      gdk_gc_set_clip_rectangle (darkgc, NULL);
223    }
224}
225/**************************************************************************/
226static void
227draw_vline (GtkStyle * style,
228            GdkWindow * window,
229            GtkStateType state_type,
230            GdkRectangle * area,
231            GtkWidget * widget,
232            const gchar * detail,
233            gint y1,
234            gint y2,
235            gint x)
236{
237  gint thickness_light;
238  gint thickness_dark;
239  gint i;
240  GdkGC *lightgc, *darkgc;
241
242  g_return_if_fail (style != NULL);
243  g_return_if_fail (window != NULL);
244
245  thickness_light = style->xthickness / 2;
246  thickness_dark = style->xthickness - thickness_light;
247
248  lightgc = style->light_gc[state_type];
249  darkgc = style->dark_gc[state_type];
250
251  if (area)
252    {
253      gdk_gc_set_clip_rectangle (lightgc, area);
254      gdk_gc_set_clip_rectangle (darkgc, area);
255    }
256
257  for (i = 0; i < thickness_dark; i++)
258    {
259      gdk_draw_line (window, lightgc, x + i, y2 - i - 1, x + i, y2);
260      gdk_draw_line (window, darkgc, x + i, y1, x + i, y2 - i - 1);
261    }
262
263  x += thickness_dark;
264
265  for (i = 0; i < thickness_light; i++)
266    {
267      gdk_draw_line (window, darkgc, x + i, y1, x + i, y1 + thickness_light
268                     - i);
269      gdk_draw_line (window, lightgc, x + i, y1 + thickness_light - i, x +
270                     i, y2);
271    }
272
273  if (area)
274    {
275      gdk_gc_set_clip_rectangle (lightgc, NULL);
276      gdk_gc_set_clip_rectangle (darkgc, NULL);
277    }
278}
279/**************************************************************************/
280static void
281draw_shadow (GtkStyle     *style,
282             GdkWindow    *window,
283             GtkStateType  state_type,
284             GtkShadowType shadow_type,
285             GdkRectangle *area,
286             GtkWidget    *widget,
287             const gchar  *detail,
288             gint          x,
289             gint          y,
290             gint          width,
291             gint          height)
292{
293  GdkGC *gc1 = NULL;            /* Initialize to quiet GCC */
294  GdkGC *gc2 = NULL;
295  GdkGC *gc3 = NULL;
296  GdkGC *gc4 = NULL;
297 
298  gint thickness_light;
299  gint thickness_dark;
300  gint i;
301
302  g_return_if_fail (style != NULL);
303  g_return_if_fail (window != NULL);
304
305/* return; */
306#if DEBUG
307  printf ("draw_shadow: %p %p %s %i %i %i %i\n", widget, window, detail, x,
308          y, width, height);
309#endif
310
311  if (shadow_type == GTK_SHADOW_NONE)
312    return;
313
314  if ((width == -1) && (height == -1))
315    gdk_window_get_size (window, &width, &height);
316  else if (width == -1)
317    gdk_window_get_size (window, &width, NULL);
318  else if (height == -1)
319    gdk_window_get_size (window, NULL, &height);
320
321  /* Override shadow-type for Metal button */
322  if (DETAIL ("button") || DETAIL ("buttondefault"))
323    shadow_type = GTK_SHADOW_ETCHED_IN;
324  if (DETAIL ("optionmenu"))
325    shadow_type = GTK_SHADOW_ETCHED_IN;
326  if (DETAIL ("handlebox_bin"))
327    shadow_type = GTK_SHADOW_ETCHED_IN;
328
329  /* Short-circuit some metal styles for now */
330  if (DETAIL ("frame"))
331    {
332      gc1 = style->dark_gc[state_type];
333      if (area)
334        gdk_gc_set_clip_rectangle (gc1, area);
335      gdk_draw_rectangle (window, gc1, FALSE, x, y, width - 1, height - 1);
336      if (area)
337        gdk_gc_set_clip_rectangle (gc1, NULL);
338      return;                   /* tbd */
339    }
340  if (DETAIL ("optionmenutab"))
341    {
342      gc1 = style->black_gc;
343      if (area)
344        gdk_gc_set_clip_rectangle (gc1, area);
345      gdk_draw_line (window, gc1, x, y, x + 10, y);
346      gdk_draw_line (window, gc1, x + 1, y + 1, x + 9, y + 1);
347      gdk_draw_line (window, gc1, x + 2, y + 2, x + 8, y + 2);
348      gdk_draw_line (window, gc1, x + 3, y + 3, x + 7, y + 3);
349      gdk_draw_line (window, gc1, x + 4, y + 4, x + 6, y + 4);
350      gdk_draw_line (window, gc1, x + 5, y + 5, x + 5, y + 4);
351      if (area)
352        gdk_gc_set_clip_rectangle (gc1, NULL);
353      return;                   /* tbd */
354    }
355
356  switch (shadow_type)
357    {
358    case GTK_SHADOW_NONE:
359      /* Handled above */
360    case GTK_SHADOW_IN:
361    case GTK_SHADOW_ETCHED_IN:
362      gc1 = style->light_gc[state_type];
363      gc2 = style->dark_gc[state_type];
364      gc3 = style->black_gc;
365      gc4 = style->bg_gc[state_type];
366      break;
367    case GTK_SHADOW_OUT:
368    case GTK_SHADOW_ETCHED_OUT:
369      gc1 = style->dark_gc[state_type];
370      gc2 = style->light_gc[state_type];
371      gc3 = style->black_gc;
372      gc4 = style->bg_gc[state_type];
373      break;
374    }
375
376  if (area)
377    {
378      gdk_gc_set_clip_rectangle (gc1, area);
379      gdk_gc_set_clip_rectangle (gc2, area);
380      gdk_gc_set_clip_rectangle (gc3, area);
381      gdk_gc_set_clip_rectangle (gc4, area);
382    }
383
384  switch (shadow_type)
385    {
386    case GTK_SHADOW_NONE:
387      break;
388    case GTK_SHADOW_IN:
389      gdk_draw_line (window, gc1,
390                     x, y + height - 1, x + width - 1, y + height - 1);
391      gdk_draw_line (window, gc1,
392                     x + width - 1, y, x + width - 1, y + height - 1);
393
394      gdk_draw_line (window, gc4,
395                     x + 1, y + height - 2, x + width - 2, y + height - 2);
396      gdk_draw_line (window, gc4,
397                     x + width - 2, y + 1, x + width - 2, y + height - 2);
398
399      gdk_draw_line (window, gc3,
400                     x + 1, y + 1, x + width - 2, y + 1);
401      gdk_draw_line (window, gc3,
402                     x + 1, y + 1, x + 1, y + height - 2);
403
404      gdk_draw_line (window, gc2,
405                     x, y, x + width - 1, y);
406      gdk_draw_line (window, gc2,
407                     x, y, x, y + height - 1);
408      break;
409
410    case GTK_SHADOW_OUT:
411      gdk_draw_line (window, gc1,
412                     x + 1, y + height - 2, x + width - 2, y + height - 2);
413      gdk_draw_line (window, gc1,
414                     x + width - 2, y + 1, x + width - 2, y + height - 2);
415
416      gdk_draw_line (window, gc2,
417                     x, y, x + width - 1, y);
418      gdk_draw_line (window, gc2,
419                     x, y, x, y + height - 1);
420
421      gdk_draw_line (window, gc4,
422                     x + 1, y + 1, x + width - 2, y + 1);
423      gdk_draw_line (window, gc4,
424                     x + 1, y + 1, x + 1, y + height - 2);
425
426      gdk_draw_line (window, gc3,
427                     x, y + height - 1, x + width - 1, y + height - 1);
428      gdk_draw_line (window, gc3,
429                     x + width - 1, y, x + width - 1, y + height - 1);
430      break;
431    case GTK_SHADOW_ETCHED_IN:
432    case GTK_SHADOW_ETCHED_OUT:
433      thickness_light = 1;
434      thickness_dark = 1;
435
436      for (i = 0; i < thickness_dark; i++)
437        {
438          gdk_draw_line (window, gc1,
439                         x + i,
440                         y + height - i - 1,
441                         x + width - i - 1,
442                         y + height - i - 1);
443          gdk_draw_line (window, gc1,
444                         x + width - i - 1,
445                         y + i,
446                         x + width - i - 1,
447                         y + height - i - 1);
448
449          gdk_draw_line (window, gc2,
450                         x + i,
451                         y + i,
452                         x + width - i - 2,
453                         y + i);
454          gdk_draw_line (window, gc2,
455                         x + i,
456                         y + i,
457                         x + i,
458                         y + height - i - 2);
459        }
460
461      for (i = 0; i < thickness_light; i++)
462        {
463          gdk_draw_line (window, gc1,
464                         x + thickness_dark + i,
465                         y + thickness_dark + i,
466                         x + width - thickness_dark - i - 1,
467                         y + thickness_dark + i);
468          gdk_draw_line (window, gc1,
469                         x + thickness_dark + i,
470                         y + thickness_dark + i,
471                         x + thickness_dark + i,
472                         y + height - thickness_dark - i - 1);
473
474          gdk_draw_line (window, gc2,
475                         x + thickness_dark + i,
476                         y + height - thickness_light - i - 1,
477                         x + width - thickness_light - 1,
478                         y + height - thickness_light - i - 1);
479          gdk_draw_line (window, gc2,
480                         x + width - thickness_light - i - 1,
481                         y + thickness_dark + i,
482                         x + width - thickness_light - i - 1,
483                         y + height - thickness_light - 1);
484        }
485      break;
486    }
487
488  if (area)
489    {
490      gdk_gc_set_clip_rectangle (gc1, NULL);
491      gdk_gc_set_clip_rectangle (gc2, NULL);
492      gdk_gc_set_clip_rectangle (gc3, NULL);
493      gdk_gc_set_clip_rectangle (gc4, NULL);
494    }
495}
496/**************************************************************************/
497static void
498draw_polygon (GtkStyle * style,
499              GdkWindow * window,
500              GtkStateType state_type,
501              GtkShadowType shadow_type,
502              GdkRectangle * area,
503              GtkWidget * widget,
504              const gchar * detail,
505              GdkPoint * points,
506              gint npoints,
507              gint fill)
508{
509#ifndef M_PI
510#define M_PI    3.14159265358979323846
511#endif /* M_PI */
512#ifndef M_PI_4
513#define M_PI_4  0.78539816339744830962
514#endif /* M_PI_4 */
515
516  static const gdouble pi_over_4 = M_PI_4;
517  static const gdouble pi_3_over_4 = M_PI_4 * 3;
518
519  GdkGC *gc1;
520  GdkGC *gc2;
521  GdkGC *gc3;
522  GdkGC *gc4;
523  gdouble angle;
524  gint xadjust;
525  gint yadjust;
526  gint i;
527
528  g_return_if_fail (style != NULL);
529  g_return_if_fail (window != NULL);
530  g_return_if_fail (points != NULL);
531
532#if DEBUG
533  printf ("draw_polygon: %p %p %s\n", widget, window, detail);
534#endif
535
536  switch (shadow_type)
537    {
538    case GTK_SHADOW_IN:
539      gc1 = style->bg_gc[state_type];
540      gc2 = style->dark_gc[state_type];
541      gc3 = style->light_gc[state_type];
542      gc4 = style->black_gc;
543      break;
544    case GTK_SHADOW_ETCHED_IN:
545      gc1 = style->light_gc[state_type];
546      gc2 = style->dark_gc[state_type];
547      gc3 = style->dark_gc[state_type];
548      gc4 = style->light_gc[state_type];
549      break;
550    case GTK_SHADOW_OUT:
551      gc1 = style->dark_gc[state_type];
552      gc2 = style->light_gc[state_type];
553      gc3 = style->black_gc;
554      gc4 = style->bg_gc[state_type];
555      break;
556    case GTK_SHADOW_ETCHED_OUT:
557      gc1 = style->dark_gc[state_type];
558      gc2 = style->light_gc[state_type];
559      gc3 = style->light_gc[state_type];
560      gc4 = style->dark_gc[state_type];
561      break;
562    default:
563      return;
564    }
565
566  if (area)
567    {
568      gdk_gc_set_clip_rectangle (gc1, area);
569      gdk_gc_set_clip_rectangle (gc2, area);
570      gdk_gc_set_clip_rectangle (gc3, area);
571      gdk_gc_set_clip_rectangle (gc4, area);
572    }
573
574  if (fill)
575    gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
576
577  npoints--;
578
579  for (i = 0; i < npoints; i++)
580    {
581      if ((points[i].x == points[i + 1].x) &&
582          (points[i].y == points[i + 1].y))
583        {
584          angle = 0;
585        }
586      else
587        {
588          angle = atan2 (points[i + 1].y - points[i].y,
589                         points[i + 1].x - points[i].x);
590        }
591
592      if ((angle > -pi_3_over_4) && (angle < pi_over_4))
593        {
594          if (angle > -pi_over_4)
595            {
596              xadjust = 0;
597              yadjust = 1;
598            }
599          else
600            {
601              xadjust = 1;
602              yadjust = 0;
603            }
604
605          gdk_draw_line (window, gc1,
606                         points[i].x - xadjust, points[i].y - yadjust,
607                         points[i + 1].x - xadjust, points[i + 1].y - yadjust);
608          gdk_draw_line (window, gc3,
609                         points[i].x, points[i].y,
610                         points[i + 1].x, points[i + 1].y);
611        }
612      else
613        {
614          if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
615            {
616              xadjust = 0;
617              yadjust = 1;
618            }
619          else
620            {
621              xadjust = 1;
622              yadjust = 0;
623            }
624
625          gdk_draw_line (window, gc4,
626                         points[i].x + xadjust, points[i].y + yadjust,
627                         points[i + 1].x + xadjust, points[i + 1].y + yadjust);
628          gdk_draw_line (window, gc2,
629                         points[i].x, points[i].y,
630                         points[i + 1].x, points[i + 1].y);
631        }
632    }
633  if (area)
634    {
635      gdk_gc_set_clip_rectangle (gc1, NULL);
636      gdk_gc_set_clip_rectangle (gc2, NULL);
637      gdk_gc_set_clip_rectangle (gc3, NULL);
638      gdk_gc_set_clip_rectangle (gc4, NULL);
639    }
640}
641
642static void
643scrollbar_stepper (GtkStyle     *style,
644                   GdkWindow    *window,
645                   GtkStateType  state_type,
646                   GdkRectangle *area,
647                   GtkWidget    *widget,
648                   const gchar  *detail,
649                   GtkArrowType  arrow_type,
650                   gint          x,
651                   gint          y,
652                   gint          width,
653                   gint          height)
654{
655  GdkRectangle clip;
656 
657  MetalStyle *metal_style = METAL_STYLE (style);
658 
659  clip.x = x;
660  clip.y = y;
661  clip.width = width;
662  clip.height = height;
663
664  if (area)
665    gdk_rectangle_intersect (&clip, area, &clip);
666 
667  /* We draw the last couple of pixels of the sliders on
668   * the trough, since the slider should go over them at
669   * the ends.
670   */
671  switch (arrow_type)
672    {
673    case GTK_ARROW_RIGHT:
674      x -= 2;
675      /* fall through */
676    case GTK_ARROW_LEFT:
677      width += 2;
678      break;
679    case GTK_ARROW_DOWN:
680      y -= 2;
681      /* fall through */
682    case GTK_ARROW_UP:
683      height += 2;
684      break;
685    }
686
687  gdk_gc_set_clip_rectangle (metal_style->dark_gray_gc, &clip);
688  gdk_gc_set_clip_rectangle (metal_style->light_gray_gc, &clip);
689  gdk_gc_set_clip_rectangle (style->white_gc, &clip);
690
691  gdk_draw_rectangle (window, style->white_gc, FALSE,
692                      x + 1, y + 1, width - 2, height - 2);
693  gdk_draw_rectangle (window, metal_style->dark_gray_gc, FALSE,
694                      x, y, width - 2, height - 2);
695
696  if (arrow_type != GTK_ARROW_RIGHT)
697    gdk_draw_point (window, metal_style->light_gray_gc,
698                    x + 1, y + height - 2);
699 
700  if (arrow_type != GTK_ARROW_DOWN)
701    gdk_draw_point (window, metal_style->light_gray_gc,
702                    x + width - 2, y + 1);
703                 
704  gdk_gc_set_clip_rectangle (metal_style->dark_gray_gc, NULL);
705  gdk_gc_set_clip_rectangle (metal_style->light_gray_gc, NULL);
706  gdk_gc_set_clip_rectangle (style->white_gc, NULL);
707}
708
709/* This function makes up for some brokeness in gtkrange.c
710 * where we never get the full arrow of the stepper button
711 * and the type of button in a single drawing function.
712 *
713 * It doesn't work correctly when the scrollbar is squished
714 * to the point we don't have room for full-sized steppers.
715 */
716static void
717reverse_engineer_stepper_box (GtkWidget    *range,
718                              GtkArrowType  arrow_type,
719                              gint         *x,
720                              gint         *y,
721                              gint         *width,
722                              gint         *height)
723{
724  gint slider_width = 17, stepper_size = 15;
725  gint box_width;
726  gint box_height;
727 
728  if (range)
729    {
730      gtk_widget_style_get (range,
731                            "slider_width", &slider_width,
732                            "stepper_size", &stepper_size,
733                            NULL);
734    }
735       
736  if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
737    {
738      box_width = slider_width;
739      box_height = stepper_size;
740    }
741  else
742    {
743      box_width = stepper_size;
744      box_height = slider_width;
745    }
746
747  *x = *x - (box_width - *width) / 2;
748  *y = *y - (box_height - *height) / 2;
749  *width = box_width;
750  *height = box_height;
751}
752
753/**************************************************************************/
754static void
755draw_arrow (GtkStyle * style,
756            GdkWindow * window,
757            GtkStateType state_type,
758            GtkShadowType shadow_type,
759            GdkRectangle * area,
760            GtkWidget * widget,
761            const gchar * detail,
762            GtkArrowType arrow_type,
763            gint fill,
764            gint x,
765            gint y,
766            gint width,
767            gint height)
768{
769  GdkGC *gc;
770  gboolean set_bg;
771
772  g_return_if_fail (style != NULL);
773  g_return_if_fail (window != NULL);
774
775  set_bg = sanitize_size (window, &width, &height);
776 
777  gc = style->black_gc;
778
779  if (DETAIL ("menuitem"))
780    gc = style->fg_gc[state_type];
781
782  if (DETAIL ("hscrollbar") || DETAIL ("vscrollbar"))
783    {
784      /* We need to restore the full area of the entire box,
785       * not just the restricted area of the stepper.
786       */
787      reverse_engineer_stepper_box (widget, arrow_type,
788                                    &x, &y, &width, &height);
789     
790      scrollbar_stepper (style, window, state_type, area,
791                         widget, detail, arrow_type,
792                         x, y, width, height);
793
794      x += 4;
795      y += 4;
796      width -= 9;
797      height -= 9;
798    }
799  else if (DETAIL ("spinbutton"))
800    {
801      x += 2;
802      width -= 4;
803    }
804
805  if (area)
806    gdk_gc_set_clip_rectangle (gc, area);
807
808  metal_arrow (window, widget, gc, arrow_type, x, y, width, height);
809
810  if (area)
811    gdk_gc_set_clip_rectangle (gc, NULL);
812}
813/**************************************************************************/
814static void
815metal_arrow (GdkWindow * window, GtkWidget * widget, GdkGC * gc,
816             GtkArrowType arrow_type,
817             gint x, gint y, gint width, gint height)
818{
819  int base, span, xoffset, yoffset;
820  int i;
821
822  switch (arrow_type)
823    {
824    case GTK_ARROW_UP:
825      base = width;
826      // if (base % 2 == 0)
827      //        base--;
828      xoffset = (width - base) / 2;
829      span = (base + 1) / 2;
830      yoffset = (height + span) / 2 - 1;
831      for (i = 0; i < span; i++)
832        {
833          gdk_draw_line (window, gc, x + xoffset + i, y + yoffset - i,
834                         x + xoffset + base - 1 - i, y + yoffset - i);
835        }
836      break;
837    case GTK_ARROW_DOWN:
838      base = width;
839      // if (base % 2 == 0)
840      // base--;
841      xoffset = (width - base) / 2;
842      span = (base + 1) / 2;
843      yoffset = (height - span) / 2;
844      for (i = 0; i < span; i++)
845        {
846          gdk_draw_line (window, gc, x + xoffset + i, y + yoffset + i,
847                         x + xoffset + base - 1 - i, y + yoffset + i);
848        }
849      break;
850    case GTK_ARROW_RIGHT:
851      if (GTK_CHECK_TYPE (widget, gtk_menu_item_get_type ()))
852        {
853          base = 7;
854        }
855      else
856        {
857          base = height;
858          // if (base % 2 == 0)
859          //        base--;
860        }
861      yoffset = (height - base) / 2;
862      span = (base + 1) / 2;
863      xoffset = (width - span) / 2;
864      for (i = 0; i < span; i++)
865        {
866          gdk_draw_line (window, gc, x + xoffset + i, y + yoffset + i,
867                         x + xoffset + i, y + yoffset + base - 1 - i);
868        }
869      break;
870    case GTK_ARROW_LEFT:
871      base = height;
872      //      if (base % 2 == 0)
873      //        base--;
874      yoffset = (height - base) / 2;
875      span = (base + 1) / 2;
876      xoffset = (width + span) / 2 - 1;
877      for (i = 0; i < span; i++)
878        {
879          gdk_draw_line (window, gc, x + xoffset - i, y + yoffset + i,
880                         x + xoffset - i, y + yoffset + base - 1 - i);
881        }
882      break;
883    }
884}
885/**************************************************************************/
886static void
887draw_diamond (GtkStyle * style,
888              GdkWindow * window,
889              GtkStateType state_type,
890              GtkShadowType shadow_type,
891              GdkRectangle * area,
892              GtkWidget * widget,
893              const gchar * detail,
894              gint x,
895              gint y,
896              gint width,
897              gint height)
898{
899  gint half_width;
900  gint half_height;
901
902  g_return_if_fail (style != NULL);
903  g_return_if_fail (window != NULL);
904
905  sanitize_size (window, &width, &height);
906
907  half_width = width / 2;
908  half_height = height / 2;
909
910  if (area)
911    {
912      gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
913      gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
914      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
915      gdk_gc_set_clip_rectangle (style->black_gc, area);
916    }
917
918  switch (shadow_type)
919    {
920    case GTK_SHADOW_IN:
921      gdk_draw_line (window, style->bg_gc[state_type],
922                     x + 2, y + half_height,
923                     x + half_width, y + height - 2);
924      gdk_draw_line (window, style->bg_gc[state_type],
925                     x + half_width, y + height - 2,
926                     x + width - 2, y + half_height);
927      gdk_draw_line (window, style->light_gc[state_type],
928                     x + 1, y + half_height,
929                     x + half_width, y + height - 1);
930      gdk_draw_line (window, style->light_gc[state_type],
931                     x + half_width, y + height - 1,
932                     x + width - 1, y + half_height);
933      gdk_draw_line (window, style->light_gc[state_type],
934                     x, y + half_height,
935                     x + half_width, y + height);
936      gdk_draw_line (window, style->light_gc[state_type],
937                     x + half_width, y + height,
938                     x + width, y + half_height);
939
940      gdk_draw_line (window, style->black_gc,
941                     x + 2, y + half_height,
942                     x + half_width, y + 2);
943      gdk_draw_line (window, style->black_gc,
944                     x + half_width, y + 2,
945                     x + width - 2, y + half_height);
946      gdk_draw_line (window, style->dark_gc[state_type],
947                     x + 1, y + half_height,
948                     x + half_width, y + 1);
949      gdk_draw_line (window, style->dark_gc[state_type],
950                     x + half_width, y + 1,
951                     x + width - 1, y + half_height);
952      gdk_draw_line (window, style->dark_gc[state_type],
953                     x, y + half_height,
954                     x + half_width, y);
955      gdk_draw_line (window, style->dark_gc[state_type],
956                     x + half_width, y,
957                     x + width, y + half_height);
958      break;
959    case GTK_SHADOW_OUT:
960      gdk_draw_line (window, style->dark_gc[state_type],
961                     x + 2, y + half_height,
962                     x + half_width, y + height - 2);
963      gdk_draw_line (window, style->dark_gc[state_type],
964                     x + half_width, y + height - 2,
965                     x + width - 2, y + half_height);
966      gdk_draw_line (window, style->dark_gc[state_type],
967                     x + 1, y + half_height,
968                     x + half_width, y + height - 1);
969      gdk_draw_line (window, style->dark_gc[state_type],
970                     x + half_width, y + height - 1,
971                     x + width - 1, y + half_height);
972      gdk_draw_line (window, style->black_gc,
973                     x, y + half_height,
974                     x + half_width, y + height);
975      gdk_draw_line (window, style->black_gc,
976                     x + half_width, y + height,
977                     x + width, y + half_height);
978
979      gdk_draw_line (window, style->bg_gc[state_type],
980                     x + 2, y + half_height,
981                     x + half_width, y + 2);
982      gdk_draw_line (window, style->bg_gc[state_type],
983                     x + half_width, y + 2,
984                     x + width - 2, y + half_height);
985      gdk_draw_line (window, style->light_gc[state_type],
986                     x + 1, y + half_height,
987                     x + half_width, y + 1);
988      gdk_draw_line (window, style->light_gc[state_type],
989                     x + half_width, y + 1,
990                     x + width - 1, y + half_height);
991      gdk_draw_line (window, style->light_gc[state_type],
992                     x, y + half_height,
993                     x + half_width, y);
994      gdk_draw_line (window, style->light_gc[state_type],
995                     x + half_width, y,
996                     x + width, y + half_height);
997      break;
998    default:
999      break;
1000    }
1001
1002  if (area)
1003    {
1004      gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
1005      gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
1006      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
1007      gdk_gc_set_clip_rectangle (style->black_gc, NULL);
1008    }
1009}
1010/**************************************************************************/
1011static void
1012draw_string (GtkStyle * style,
1013             GdkWindow * window,
1014             GtkStateType state_type,
1015             GdkRectangle * area,
1016             GtkWidget * widget,
1017             const gchar * detail,
1018             gint x,
1019             gint y,
1020             const gchar * string)
1021{
1022  GdkGC *fggc, *whitegc, *midgc;
1023  MetalStyle *metal_style = METAL_STYLE (style);
1024
1025  g_return_if_fail (style != NULL);
1026  g_return_if_fail (window != NULL);
1027
1028#if DEBUG
1029  printf ("draw_string: %p %p %s %i %i\n", widget, window, detail, x, y);
1030#endif
1031
1032  if (DETAIL ("label"))
1033    {
1034      fggc = style->black_gc;
1035      whitegc = style->white_gc;
1036      midgc = metal_style->mid_gray_gc;
1037    }
1038  else
1039    {
1040      fggc = style->fg_gc[state_type];
1041      whitegc = style->white_gc;
1042      midgc = metal_style->mid_gray_gc;
1043    }
1044
1045  if (area)
1046    {
1047      gdk_gc_set_clip_rectangle (fggc, area);
1048      gdk_gc_set_clip_rectangle (whitegc, area);
1049      gdk_gc_set_clip_rectangle (midgc, area);
1050    }
1051
1052 
1053  if (state_type == GTK_STATE_INSENSITIVE)
1054    {
1055      gdk_draw_string (window, gtk_style_get_font (style), whitegc, x + 1, y + 1, string);
1056      gdk_draw_string (window, gtk_style_get_font (style), midgc, x, y, string);
1057    }
1058  else
1059    {
1060      gdk_draw_string (window, gtk_style_get_font (style), fggc, x, y, string);
1061    }
1062
1063  if (area)
1064    {
1065      gdk_gc_set_clip_rectangle (fggc, NULL);
1066      gdk_gc_set_clip_rectangle (whitegc, NULL);
1067      gdk_gc_set_clip_rectangle (midgc, NULL);
1068    }
1069}
1070
1071/**************************************************************************/
1072static void
1073draw_box (GtkStyle      *style,
1074          GdkWindow     *window,
1075          GtkStateType   state_type,
1076          GtkShadowType  shadow_type,
1077          GdkRectangle  *area,
1078          GtkWidget     *widget,
1079          const gchar   *detail,
1080          gint           x,
1081          gint           y,
1082          gint           width,
1083          gint           height)
1084{
1085  g_return_if_fail (style != NULL);
1086  g_return_if_fail (window != NULL);
1087
1088  if ((width == -1) && (height == -1))
1089    gdk_window_get_size (window, &width, &height);
1090  else if (width == -1)
1091    gdk_window_get_size (window, &width, NULL);
1092  else if (height == -1)
1093    gdk_window_get_size (window, NULL, &height);
1094
1095#if DEBUG
1096  printf ("draw_box: %p %p %s %i %i %i %i\n", widget, window, detail, x, y,
1097          width, height);
1098#endif
1099
1100  /* ===================================================================== */
1101
1102  if (widget && DETAIL ("trough"))
1103    {
1104
1105      if (GTK_IS_PROGRESS_BAR (widget))
1106        {
1107          if (area)
1108            gdk_gc_set_clip_rectangle (style->light_gc[GTK_STATE_NORMAL], area);
1109          gdk_draw_rectangle (window, style->light_gc[GTK_STATE_NORMAL],
1110                              TRUE, x, y, width, height);
1111          if (area)
1112            gdk_gc_set_clip_rectangle (style->light_gc[GTK_STATE_NORMAL], NULL);
1113          gtk_paint_shadow (style, window, state_type, shadow_type, area,
1114                            widget, detail,
1115                            x, y, width, height);
1116        }
1117      else if (GTK_IS_SCROLLBAR (widget))
1118        {
1119          metal_scrollbar_trough (style, window, state_type, shadow_type,
1120                                  area, widget, detail, x, y, width, height);
1121        }
1122      else if (GTK_IS_SCALE (widget))
1123        {
1124          metal_scale_trough (style, window, state_type, shadow_type,
1125                              area, widget, detail, x, y, width, height);
1126        }
1127      else
1128        {
1129#if 0
1130          GdkPixmap *pm;
1131          gint xthik;
1132          gint ythik;
1133
1134          xthik = style->xthickness;
1135          ythik = style->ythickness;
1136
1137          pm = gdk_pixmap_new (window, 2, 2, -1);
1138
1139          gdk_draw_point (pm, style->bg_gc[GTK_STATE_NORMAL], 0, 0);
1140          gdk_draw_point (pm, style->bg_gc[GTK_STATE_NORMAL], 1, 1);
1141          gdk_draw_point (pm, style->light_gc[GTK_STATE_NORMAL], 1, 0);
1142          gdk_draw_point (pm, style->light_gc[GTK_STATE_NORMAL], 0, 1);
1143          gdk_window_set_back_pixmap (window, pm, FALSE);
1144          gdk_window_clear (window);
1145
1146          gdk_pixmap_unref (pm);
1147#endif /* 0 */
1148        }
1149    }
1150  else if (DETAIL ("menu"))
1151    {
1152      metal_menu (style, window, state_type, shadow_type,
1153                  area, widget, detail, x, y, width, height);
1154    }
1155  else if (DETAIL ("menuitem"))
1156    {
1157      metal_menu_item (style, window, state_type, shadow_type,
1158                       area, widget, detail, x, y, width, height);
1159    }
1160  else if (DETAIL ("bar"))
1161    {
1162      if (area)
1163        gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_SELECTED], area);
1164      gdk_draw_rectangle (window, style->bg_gc[GTK_STATE_SELECTED],
1165                          TRUE, x + 1, y + 1, width - 2, height - 2);
1166      if (area)
1167        gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_SELECTED], NULL);
1168    }
1169  else if (DETAIL ("menubar"))
1170    {
1171      if (area)
1172        gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
1173      gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE,
1174                          x, y, width, height);
1175      if (area)
1176        gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
1177    }
1178  else if (DETAIL ("notebook"))
1179    {
1180      metal_notebook (style, window, state_type, shadow_type,
1181                      area, widget, detail, x, y, width, height);
1182    }
1183  else if (DETAIL ("tab"))
1184    {
1185      metal_tab (style, window, state_type, shadow_type,
1186                 area, widget, detail, x, y, width, height);
1187    }
1188  else if (DETAIL ("button") || DETAIL ("togglebutton"))
1189    {
1190      metal_button (style, window, state_type, shadow_type,
1191                    area, widget, detail, x, y, width, height);
1192    }
1193  else if (DETAIL ("buttondefault"))
1194    {
1195    }
1196  else if (DETAIL ("hscrollbar") || DETAIL ("vscrollbar"))
1197    {
1198      /* We do all the drawing in draw_arrow () */
1199    }
1200  else
1201    {
1202      if ((!style->bg_pixmap[state_type]) || GDK_IS_PIXMAP (window))
1203        {
1204          if (area)
1205            gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
1206          gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE,
1207                              x, y, width, height);
1208          if (area)
1209            gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
1210        }
1211      else
1212        {
1213          gtk_style_apply_default_pixmap (style, window, state_type, area,
1214                                          x, y, width, height);
1215        }
1216      gtk_paint_shadow (style, window, state_type, shadow_type, area,
1217                        widget, detail,
1218                        x, y, width, height);
1219    }
1220}
1221/**************************************************************************/
1222static void
1223metal_scrollbar_trough (GtkStyle     *style,
1224                        GdkWindow    *window,
1225                        GtkStateType  state_type,
1226                        GtkShadowType shadow_type,
1227                        GdkRectangle *area,
1228                        GtkWidget    *widget,
1229                        const char   *detail,
1230                        gint          x,
1231                        gint          y,
1232                        gint          width,
1233                        gint          height)
1234{
1235  MetalStyle *metal_style = METAL_STYLE (style);
1236  GdkGC *lightgc, *midgc, *darkgc, *whitegc;
1237  gint stepper_size = 15;
1238
1239  if (widget && GTK_IS_RANGE (widget))
1240    gtk_widget_style_get (widget, "stepper_size", &stepper_size, NULL);
1241
1242  stepper_size += 2;
1243
1244  /* Get colors */
1245  lightgc = metal_style->light_gray_gc;
1246  midgc = metal_style->mid_gray_gc;
1247  darkgc = metal_style->dark_gray_gc;
1248  whitegc = style->white_gc;
1249
1250  /* Set Clip Region */
1251  if (area)
1252    {
1253      gdk_gc_set_clip_rectangle (lightgc, area);
1254      gdk_gc_set_clip_rectangle (midgc, area);
1255      gdk_gc_set_clip_rectangle (darkgc, area);
1256      gdk_gc_set_clip_rectangle (whitegc, area);
1257    }
1258
1259  /* Draw backgound */
1260  gdk_draw_rectangle (window, lightgc, TRUE, x, y, width, height);
1261
1262  /* Draw border */
1263  gdk_draw_rectangle (window, darkgc, FALSE, x, y, width - 2, height - 2);
1264 
1265  /* Draw inset shadow */
1266  if (GTK_CHECK_TYPE (widget, gtk_hscrollbar_get_type ()))
1267    {
1268      gdk_draw_line (window, whitegc,
1269                     x + 1,         y + height - 1,
1270                     x + width - 1, y + height - 1);
1271      gdk_draw_line (window, darkgc,
1272                     x + stepper_size - 2, y + 2,
1273                     x + stepper_size - 2, y + height - 2);     
1274      gdk_draw_line (window, midgc,
1275                     x + stepper_size - 1,         y + 1,
1276                     x + width - stepper_size - 1, y + 1);
1277      gdk_draw_line (window, darkgc,
1278                     x + width - stepper_size, y + 2,
1279                     x + width - stepper_size, y + height - 2);
1280      gdk_draw_line (window, whitegc,
1281                     x + width - stepper_size + 1, y + 1,
1282                     x + width - stepper_size + 1, y + height - 2);
1283      gdk_draw_line (window, midgc,
1284                     x + stepper_size - 1, y + 1,
1285                     x + stepper_size - 1, y + height - 3);
1286    }
1287  else
1288    {
1289      gdk_draw_line (window, whitegc,
1290                     x + width - 1, y + 1,
1291                     x + width - 1, y + height - 1);
1292      gdk_draw_line (window, darkgc,
1293                     x + 2,         y + stepper_size - 2,
1294                     x + width - 2, y + stepper_size - 2);     
1295      gdk_draw_line (window, midgc,
1296                     x + 1, y + stepper_size - 1,
1297                     x + 1, y + height - stepper_size - 1);
1298      gdk_draw_line (window, darkgc,
1299                     x + 2,         y + height - stepper_size,
1300                     x + width - 2, y + height - stepper_size);
1301      gdk_draw_line (window, whitegc,
1302                     x + 1,         y + height - stepper_size + 1,
1303                     x + width - 2, y + height - stepper_size + 1);
1304      gdk_draw_line (window, midgc,
1305                     x + 1,         y + stepper_size - 1,
1306                     x + width - 3, y + stepper_size - 1);
1307    }
1308
1309  /* Reset Clip Region */
1310  if (area)
1311    {
1312      gdk_gc_set_clip_rectangle (lightgc, NULL);
1313      gdk_gc_set_clip_rectangle (midgc, NULL);
1314      gdk_gc_set_clip_rectangle (darkgc, NULL);
1315      gdk_gc_set_clip_rectangle (whitegc, NULL);
1316    }
1317}
1318/**************************************************************************/
1319static void
1320metal_scrollbar_slider (GtkStyle * style,
1321                        GdkWindow * window,
1322                        GtkStateType state_type,
1323                        GtkShadowType shadow_type,
1324                        GdkRectangle * area,
1325                        GtkWidget * widget,
1326                        const gchar * detail,
1327                        gint x,
1328                        gint y,
1329                        gint width,
1330                        gint height)
1331{
1332  MetalStyle *metal_style = METAL_STYLE (style);
1333  GdkPixmap *pm;
1334  GdkGC *fillgc;
1335  GdkGCValues values;
1336  GdkGC *lightgc, *midgc, *darkgc, *whitegc;
1337  int w, h;
1338
1339  gint stepper_size = 15;
1340
1341  if (widget && GTK_IS_RANGE (widget))
1342    gtk_widget_style_get (widget, "stepper_size", &stepper_size, NULL);
1343
1344  stepper_size += 2;
1345
1346  lightgc = style->bg_gc[GTK_STATE_PRELIGHT];
1347  midgc = style->bg_gc[GTK_STATE_SELECTED];
1348  darkgc = style->fg_gc[GTK_STATE_PRELIGHT];
1349  whitegc = style->white_gc;
1350
1351  /* Draw textured surface */
1352  pm = gdk_pixmap_new (window, 4, 4, -1);
1353
1354  gdk_draw_rectangle (pm, midgc, TRUE, 0, 0, 4, 4);
1355
1356  gdk_draw_point (pm, darkgc, 0, 0);
1357  gdk_draw_point (pm, lightgc, 1, 1);
1358  gdk_draw_point (pm, darkgc, 2, 2);
1359  gdk_draw_point (pm, lightgc, 3, 3);
1360
1361  values.fill = GDK_TILED;
1362  values.ts_x_origin = (x + 5) % 4;
1363  values.ts_y_origin = (y + 3) % 4;
1364  fillgc = gdk_gc_new_with_values (window, &values,
1365                                   GDK_GC_FILL | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
1366  gdk_gc_set_tile (fillgc, pm);
1367
1368  /* Set Clip Region */
1369  if (area)
1370    {
1371      gdk_gc_set_clip_rectangle (lightgc, area);
1372      gdk_gc_set_clip_rectangle (midgc, area);
1373      gdk_gc_set_clip_rectangle (darkgc, area);
1374      gdk_gc_set_clip_rectangle (whitegc, area);
1375      gdk_gc_set_clip_rectangle (fillgc, area);
1376    }
1377
1378  /* Draw backgound */
1379  gdk_draw_rectangle (window, midgc, TRUE, x, y, width, height);
1380
1381  /* Draw border */
1382  gdk_draw_rectangle (window, lightgc, FALSE, x + 1, y + 1,
1383                      width - 2, height - 2);
1384  gdk_draw_rectangle (window, darkgc, FALSE, x + 0, y + 0,
1385                      width - 2, height - 2);
1386
1387  if (GTK_CHECK_TYPE (widget, gtk_hscrollbar_get_type ()))
1388    {
1389      gdk_draw_line (window, whitegc,
1390                     x + 0,         y + height - 1,
1391                     x + width - 1, y + height - 1);
1392      gdk_draw_line (window, metal_style->dark_gray_gc,
1393                     x,         y + height - 2,
1394                     x + width, y + height - 2);
1395      gdk_draw_point (window, metal_style->dark_gray_gc, x + width - 1, y);
1396
1397      /* At the right end of the scrollbar, don't draw the shadow beneath
1398       * the scrollbar, instead draw the highlight of the button
1399       */
1400      if (widget &&
1401          (x + width + stepper_size - 2 == widget->allocation.x + widget->allocation.width))
1402        gdk_draw_line (window, whitegc,
1403                       x + width - 1, y + 1,
1404                       x + width - 1, y + height - 3);
1405      else
1406        gdk_draw_line (window, metal_style->mid_gray_gc,
1407                       x + width - 1, y + 1,
1408                       x + width - 1, y + height - 3);
1409    }
1410  else
1411    {
1412      gdk_draw_line (window, whitegc,
1413                     x + width - 1, y + 0,
1414                     x + width - 1, y + height - 1);
1415      gdk_draw_line (window, metal_style->dark_gray_gc,
1416                     x + width - 2, y,
1417                     x + width - 2, y + height);
1418      gdk_draw_point (window, metal_style->dark_gray_gc, x, y + height - 1);
1419
1420      /* At the lower end of the scrollbar, don't draw the shadow beneath
1421       * the scrollbar, instead draw the highlight of the button
1422       */
1423      if (widget &&
1424          (y + height + stepper_size - 2 == widget->allocation.y + widget->allocation.height))
1425        gdk_draw_line (window, whitegc,
1426                       x + 1,         y + height - 1,
1427                       x + width - 3, y + height - 1);
1428      else
1429        gdk_draw_line (window, metal_style->mid_gray_gc,
1430                       x + 1,         y + height - 1,
1431                       x + width - 3, y + height - 1);
1432    }
1433
1434  if (GTK_CHECK_TYPE (widget, gtk_hscrollbar_get_type ()))
1435    {
1436      w = width & 1 ? width - 11 : width - 10;
1437      h = height & 1 ? height - 7 : height - 8;
1438      gdk_draw_rectangle (window, fillgc, TRUE, x + 5, y + 3, w, h);
1439    }
1440  else
1441    {
1442      w = width & 1 ? width - 7 : width - 8;
1443      h = height & 1 ? height - 11 : height - 10;
1444      gdk_draw_rectangle (window, fillgc, TRUE, x + 3, y + 5, w, h);
1445    }
1446  gdk_gc_unref (fillgc);
1447  gdk_pixmap_unref (pm);
1448
1449  /* Reset Clip Region */
1450  if (area)
1451    {
1452      gdk_gc_set_clip_rectangle (lightgc, NULL);
1453      gdk_gc_set_clip_rectangle (midgc, NULL);
1454      gdk_gc_set_clip_rectangle (darkgc, NULL);
1455      gdk_gc_set_clip_rectangle (whitegc, NULL);
1456    }
1457}
1458/**************************************************************************/
1459static void
1460metal_scale_trough (GtkStyle * style,
1461                    GdkWindow * window,
1462                    GtkStateType state_type,
1463                    GtkShadowType shadow_type,
1464                    GdkRectangle * area,
1465                    GtkWidget * widget,
1466                    const gchar * detail,
1467                    gint x,
1468                    gint y,
1469                    gint width,
1470                    gint height)
1471{
1472  MetalStyle *metal_style = METAL_STYLE (style);
1473  GdkGC *lightgc, *midgc, *darkgc, *whitegc;
1474
1475  /* Get colors */
1476  lightgc = metal_style->light_gray_gc;
1477  midgc = style->bg_gc[GTK_STATE_SELECTED];
1478  darkgc = metal_style->mid_gray_gc;
1479  whitegc = style->white_gc;
1480
1481  /* Set Clip Region */
1482  if (area)
1483    {
1484      gdk_gc_set_clip_rectangle (lightgc, area);
1485      gdk_gc_set_clip_rectangle (midgc, area);
1486      gdk_gc_set_clip_rectangle (darkgc, area);
1487      gdk_gc_set_clip_rectangle (whitegc, area);
1488    }
1489
1490  if (GTK_CHECK_TYPE (widget, gtk_hscale_get_type ()))
1491    {
1492      /* Draw backgound */
1493      gdk_draw_rectangle (window, midgc, TRUE, x, y + 4, width - 2, 9);
1494
1495      /* Draw border */
1496      gdk_draw_rectangle (window, darkgc, FALSE, x, y + 4, width - 2, 7);
1497      gdk_draw_rectangle (window, whitegc, FALSE, x + 1, y + 5, width - 2, 7);
1498    }
1499  else
1500    {
1501      /* Draw backgound */
1502      gdk_draw_rectangle (window, midgc, TRUE, x + 4, y, 9, height - 2);
1503
1504      /* Draw border */
1505      gdk_draw_rectangle (window, darkgc, FALSE, x + 4, y, 7, height - 2);
1506      gdk_draw_rectangle (window, whitegc, FALSE, x + 5, y + 1, 7, height - 2);
1507    }
1508
1509  /* Reset Clip Region */
1510  if (area)
1511    {
1512      gdk_gc_set_clip_rectangle (lightgc, NULL);
1513      gdk_gc_set_clip_rectangle (midgc, NULL);
1514      gdk_gc_set_clip_rectangle (darkgc, NULL);
1515      gdk_gc_set_clip_rectangle (whitegc, NULL);
1516    }
1517}
1518/**************************************************************************/
1519static void
1520metal_scale_slider (GtkStyle * style,
1521                    GdkWindow * window,
1522                    GtkStateType state_type,
1523                    GtkShadowType shadow_type,
1524                    GdkRectangle * area,
1525                    GtkWidget * widget,
1526                    const gchar * detail,
1527                    gint x,
1528                    gint y,
1529                    gint width,
1530                    gint height,
1531                    GtkOrientation orientation)
1532{
1533  MetalStyle *metal_style = METAL_STYLE (style);
1534  GdkPixmap *pm;
1535  GdkGC *fillgc;
1536  GdkGCValues values;
1537  GdkGC *lightgc, *midgc, *darkgc, *whitegc, *blackgc;
1538  int w, h;
1539
1540  /* Get colors */
1541  lightgc = style->bg_gc[GTK_STATE_PRELIGHT];
1542  midgc = style->bg_gc[GTK_STATE_SELECTED];
1543  darkgc = style->fg_gc[GTK_STATE_PRELIGHT];
1544  whitegc = style->white_gc;
1545  blackgc = style->black_gc;
1546
1547  /* Set Clip Region */
1548  if (area)
1549    {
1550      gdk_gc_set_clip_rectangle (lightgc, area);
1551      gdk_gc_set_clip_rectangle (midgc, area);
1552      gdk_gc_set_clip_rectangle (darkgc, area);
1553      gdk_gc_set_clip_rectangle (whitegc, area);
1554      gdk_gc_set_clip_rectangle (blackgc, area);
1555      gdk_gc_set_clip_rectangle (metal_style->light_gray_gc, area);
1556    }
1557
1558#if 1
1559  /* Draw backgound */
1560  gdk_draw_rectangle (window, midgc, TRUE, x, y, width, height);
1561
1562  /* Draw border */
1563  gdk_draw_rectangle (window, lightgc, FALSE, x + 1, y + 1, x + width - 2, y
1564                      + height - 2);
1565  gdk_draw_rectangle (window, darkgc, FALSE, x + 0, y + 0, x + width - 2, y
1566                      + height - 2);
1567  if (GTK_CHECK_TYPE (widget, gtk_hscale_get_type ()))
1568    {
1569      gdk_draw_line (window, whitegc, x + 0, y + height - 1, x + width - 1,
1570                     y + height - 1);
1571      gdk_draw_line (window, midgc, x + width - 1, y + 1, x + width - 1, y +
1572                     height - 2);
1573    }
1574  else
1575    {
1576      gdk_draw_line (window, whitegc, x + width - 1, y + 0, x + width - 1, y
1577                     + height - 1);
1578      gdk_draw_line (window, midgc, x + 0, y + height - 1, x + width - 2, y
1579                     + height - 1);
1580    }
1581
1582  /* Draw textured surface */
1583  pm = gdk_pixmap_new (window, 4, 4, -1);
1584
1585  gdk_draw_rectangle (pm, midgc, TRUE, 0, 0, 4, 4);
1586  gdk_draw_point (pm, darkgc, 0, 0);
1587  gdk_draw_point (pm, lightgc, 1, 1);
1588  gdk_draw_point (pm, darkgc, 2, 2);
1589  gdk_draw_point (pm, lightgc, 3, 3);
1590
1591  values.fill = GDK_TILED;
1592  values.ts_x_origin = x + 5;
1593  values.ts_y_origin = y + 3;
1594  fillgc = gdk_gc_new_with_values (window, &values,
1595                                   GDK_GC_FILL | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
1596  if (area)
1597    gdk_gc_set_clip_rectangle (fillgc, area);
1598  gdk_gc_set_tile (fillgc, pm);
1599  if (GTK_CHECK_TYPE (widget, gtk_hscale_get_type ()))
1600    {
1601      w = width & 1 ? width - 11 : width - 10;
1602      h = height & 1 ? height - 7 : height - 8;
1603      gdk_draw_rectangle (window, fillgc, TRUE, x + 5, y + 3, w, h);
1604    }
1605  else
1606    {
1607      w = width & 1 ? width - 7 : width - 8;
1608      h = height & 1 ? height - 11 : height - 10;
1609      gdk_draw_rectangle (window, fillgc, TRUE, x + 3, y + 5, w, h);
1610    }
1611  gdk_gc_unref (fillgc);
1612  gdk_pixmap_unref (pm);
1613
1614  /* Draw middle line */
1615  if (GTK_CHECK_TYPE (widget, gtk_hscale_get_type ()))
1616    {
1617      if (state_type == GTK_STATE_PRELIGHT)
1618        {
1619          gdk_draw_line (window, darkgc, x + width / 2, y + 2, x + width /
1620                         2, y + height - 4);
1621          gdk_draw_line (window, whitegc, x + width / 2 + 1, y + 2, x +
1622                         width / 2 + 1, y + height - 4);
1623        }
1624      else
1625        {
1626          gdk_draw_line (window, darkgc, x + width / 2, y + 2, x + width /
1627                         2, y + height - 4);
1628          gdk_draw_line (window, lightgc, x + width / 2 + 1, y + 2, x +
1629                         width / 2 + 1, y + height - 4);
1630        }
1631    }
1632  else
1633    {
1634      if (state_type == GTK_STATE_PRELIGHT)
1635        {
1636          gdk_draw_line (window, darkgc, x + 2, y + height / 2, x + width -
1637                         4, y + height / 2);
1638          gdk_draw_line (window, whitegc, x + 2, y + height / 2 + 1, x +
1639                         width - 4, y + height / 2 + 1);
1640        }
1641      else
1642        {
1643          gdk_draw_line (window, darkgc, x + 2, y + height / 2, x + width -
1644                         4, y + height / 2);
1645          gdk_draw_line (window, lightgc, x + 2, y + height / 2 + 1, x +
1646                         width - 4, y + height / 2 + 1);
1647        }
1648    }
1649
1650#else
1651  /* The following code draws the sliders more faithfully to the
1652     JL&F spec, but I think it looks bad. */
1653
1654  /* Requires GtkScale::slider-length of 15 */
1655
1656  GdkPoint points[5];
1657
1658  /* Draw backgound */
1659  gdk_draw_rectangle (window, lightgc, TRUE, x, y, width - 1, height - 1);
1660
1661  /* Draw textured surface */
1662  pm = gdk_pixmap_new (window, 4, 4, -1);
1663
1664  gdk_draw_rectangle (pm, midgc, TRUE, 0, 0, 4, 4);
1665  if (state_type == GTK_STATE_PRELIGHT)
1666    {
1667      gdk_draw_point (pm, darkgc, 0, 0);
1668      gdk_draw_point (pm, whitegc, 1, 1);
1669      gdk_draw_point (pm, darkgc, 2, 2);
1670      gdk_draw_point (pm, whitegc, 3, 3);
1671    }
1672  else
1673    {
1674      gdk_draw_point (pm, darkgc, 0, 0);
1675      gdk_draw_point (pm, lightgc, 1, 1);
1676      gdk_draw_point (pm, darkgc, 2, 2);
1677      gdk_draw_point (pm, lightgc, 3, 3);
1678    }
1679
1680  values.fill = GDK_TILED;
1681  values.ts_x_origin = x + 5;
1682  values.ts_y_origin = y + 3;
1683  fillgc = gdk_gc_new_with_values (window, &values,
1684                                   GDK_GC_FILL | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
1685  if (area)
1686    gdk_gc_set_clip_rectangle (fillgc, area);
1687  gdk_gc_set_tile (fillgc, pm);
1688  w = width - 4;
1689  h = height - 4;
1690  gdk_draw_rectangle (window, fillgc, TRUE, x + 2, y + 2, w, h);
1691  gdk_gc_unref (fillgc);
1692  gdk_pixmap_unref (pm);
1693
1694  if (GTK_CHECK_TYPE (widget, gtk_hscale_get_type ()))
1695    {
1696      /* Draw border */
1697      points[0].x = x;
1698      points[0].y = y;
1699      points[1].x = x + 14;
1700      points[1].y = y;
1701      points[2].x = x + 14;
1702      points[2].y = y + 7;
1703      points[3].x = x + 7;
1704      points[3].y = y + 14;
1705      points[4].x = x;
1706      points[4].y = y + 7;
1707      gdk_draw_polygon (window, blackgc, FALSE, points, 5);
1708      points[0].x = x + 1;
1709      points[0].y = y + 1;
1710      points[1].x = x + 13;
1711      points[1].y = y + 1;
1712      points[2].x = x + 13;
1713      points[2].y = y + 7;
1714      points[3].x = x + 7;
1715      points[3].y = y + 13;
1716      points[4].x = x + 1;
1717      points[4].y = y + 7;
1718      gdk_draw_polygon (window, lightgc, FALSE, points, 5);
1719
1720      /* Fix bottom corners */
1721      points[0].x = x;
1722      points[0].y = y + 14;
1723      points[1].x = x;
1724      points[1].y = y + 8;
1725      points[2].x = x + 6;
1726      points[2].y = y + 14;
1727      gdk_draw_polygon (window, metal_style->light_gray_gc, FALSE, points, 3);
1728      gdk_draw_polygon (window, metal_style->light_gray_gc, TRUE, points, 3);
1729      points[0].x = x + 14;
1730      points[0].y = y + 14;
1731      points[1].x = x + 14;
1732      points[1].y = y + 8;
1733      points[2].x = x + 8;
1734      points[2].y = y + 14;
1735      gdk_draw_polygon (window, metal_style->light_gray_gc, FALSE, points, 3);
1736      gdk_draw_polygon (window, metal_style->light_gray_gc, TRUE, points, 3);
1737      gdk_draw_rectangle (window, metal_style->light_gray_gc, TRUE, x, y +
1738                          15, width, height - 15);
1739    }
1740  else
1741    {
1742      /* Draw border */
1743      points[0].x = x;
1744      points[0].y = y + 7;
1745      points[1].x = x + 7;
1746      points[1].y = y;
1747      points[2].x = x + 14;
1748      points[2].y = y;
1749      points[3].x = x + 14;
1750      points[3].y = y + 14;
1751      points[4].x = x + 7;
1752      points[4].y = y + 14;
1753      gdk_draw_polygon (window, blackgc, FALSE, points, 5);
1754
1755      points[0].x = x + 1;
1756      points[0].y = y + 7;
1757      points[1].x = x + 7;
1758      points[1].y = y + 1;
1759      points[2].x = x + 13;
1760      points[2].y = y + 1;
1761      points[3].x = x + 13;
1762      points[3].y = y + 13;
1763      points[4].x = x + 7;
1764      points[4].y = y + 13;
1765      gdk_draw_polygon (window, lightgc, FALSE, points, 5);
1766
1767      /* Fix corners */
1768      points[0].x = x;
1769      points[0].y = y;
1770      points[1].x = x + 6;
1771      points[1].y = y;
1772      points[2].x = x;
1773      points[2].y = y + 6;
1774      gdk_draw_polygon (window, metal_style->light_gray_gc, FALSE, points, 3);
1775      gdk_draw_polygon (window, metal_style->light_gray_gc, TRUE, points, 3);
1776      points[0].x = x;
1777      points[0].y = y + 8;
1778      points[1].x = x;
1779      points[1].y = y + 14;
1780      points[2].x = x + 6;
1781      points[2].y = y + 14;
1782      gdk_draw_polygon (window, metal_style->light_gray_gc, FALSE, points, 3);
1783      gdk_draw_polygon (window, metal_style->light_gray_gc, TRUE, points, 3);
1784/*      gdk_draw_rectangle(window, metal_style->light_gray_gc, TRUE,  x, y+15, width, height-15); */
1785    }
1786#endif
1787
1788  /* Reset Clip Region */
1789  if (area)
1790    {
1791      gdk_gc_set_clip_rectangle (lightgc, NULL);
1792      gdk_gc_set_clip_rectangle (midgc, NULL);
1793      gdk_gc_set_clip_rectangle (darkgc, NULL);
1794      gdk_gc_set_clip_rectangle (whitegc, NULL);
1795      gdk_gc_set_clip_rectangle (blackgc, NULL);
1796      gdk_gc_set_clip_rectangle (metal_style->light_gray_gc, NULL);
1797    }
1798}
1799/**************************************************************************/
1800static void
1801metal_menu (GtkStyle * style,
1802            GdkWindow * window,
1803            GtkStateType state_type,
1804            GtkShadowType shadow_type,
1805            GdkRectangle * area,
1806            GtkWidget * widget,
1807            const gchar * detail,
1808            gint x,
1809            gint y,
1810            gint width,
1811            gint height)
1812{
1813  GdkGC *midgc, *whitegc;
1814
1815  midgc = style->bg_gc[GTK_STATE_SELECTED];
1816  whitegc = style->white_gc;
1817
1818  /* Set Clip Region */
1819  if (area)
1820    {
1821      gdk_gc_set_clip_rectangle (midgc, area);
1822      gdk_gc_set_clip_rectangle (whitegc, area);
1823    }
1824
1825  gdk_draw_rectangle (window, whitegc, FALSE, x + 1, y + 1, width - 2,
1826                      height - 2);
1827  gdk_draw_rectangle (window, midgc, FALSE, x, y, width - 1, height - 1);
1828
1829  /* Reset Clip Region */
1830  if (area)
1831    {
1832      gdk_gc_set_clip_rectangle (midgc, NULL);
1833      gdk_gc_set_clip_rectangle (whitegc, NULL);
1834    }
1835}
1836/**************************************************************************/
1837static void
1838metal_menu_item (GtkStyle * style,
1839                 GdkWindow * window,
1840                 GtkStateType state_type,
1841                 GtkShadowType shadow_type,
1842                 GdkRectangle * area,
1843                 GtkWidget * widget,
1844                 const gchar * detail,
1845                 gint x,
1846                 gint y,
1847                 gint width,
1848                 gint height)
1849{
1850  /* Set Clip Region */
1851  if (area)
1852    {
1853      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_SELECTED], area);
1854      gdk_gc_set_clip_rectangle (style->dark_gc[GTK_STATE_SELECTED], area);
1855      gdk_gc_set_clip_rectangle (style->light_gc[GTK_STATE_SELECTED], area);
1856    }
1857
1858  gdk_draw_rectangle (window, style->bg_gc[GTK_STATE_SELECTED], TRUE, x, y,
1859                      width, height);
1860  gdk_draw_line (window, style->dark_gc[GTK_STATE_SELECTED], x, y, x +
1861                 width, y);
1862  gdk_draw_line (window, style->light_gc[GTK_STATE_SELECTED], x, y + height
1863                 - 1, x + width, y + height - 1);
1864
1865  /* Reset Clip Region */
1866  if (area)
1867    {
1868      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_SELECTED], NULL);
1869      gdk_gc_set_clip_rectangle (style->dark_gc[GTK_STATE_SELECTED], NULL);
1870      gdk_gc_set_clip_rectangle (style->light_gc[GTK_STATE_SELECTED], NULL);
1871    }
1872}
1873/**************************************************************************/
1874static void
1875metal_notebook (GtkStyle * style,
1876                GdkWindow * window,
1877                GtkStateType state_type,
1878                GtkShadowType shadow_type,
1879                GdkRectangle * area,
1880                GtkWidget * widget,
1881                const gchar * detail,
1882                gint x,
1883                gint y,
1884                gint width,
1885                gint height)
1886{
1887  MetalStyle *metal_style = METAL_STYLE (style);
1888  GdkGC *lightgc, *midgc, *darkgc, *whitegc;
1889
1890  /* Get colors */
1891  if (state_type == GTK_STATE_PRELIGHT)
1892    {
1893      lightgc = style->bg_gc[GTK_STATE_PRELIGHT];
1894      midgc = style->bg_gc[GTK_STATE_SELECTED];
1895      darkgc = style->fg_gc[GTK_STATE_PRELIGHT];
1896      whitegc = style->white_gc;
1897    }
1898  else
1899    {
1900      lightgc = metal_style->light_gray_gc;
1901      midgc = metal_style->mid_gray_gc;
1902      darkgc = metal_style->mid_gray_gc;
1903      whitegc = style->white_gc;
1904    }
1905
1906  /* Set Clip Region */
1907  if (area)
1908    {
1909      gdk_gc_set_clip_rectangle (lightgc, area);
1910      gdk_gc_set_clip_rectangle (midgc, area);
1911      gdk_gc_set_clip_rectangle (darkgc, area);
1912      gdk_gc_set_clip_rectangle (whitegc, area);
1913    }
1914
1915  /* Draw backgound */
1916  gdk_draw_rectangle (window, lightgc, TRUE, x, y, width, height);
1917
1918  /* Draw border */
1919  gdk_draw_rectangle (window, darkgc, FALSE, x, y, width - 2, height - 2);
1920  gdk_draw_rectangle (window, style->white_gc, FALSE, x + 1, y + 1, width -
1921                      2, height - 2);
1922
1923  /* Reset Clip Region */
1924  if (area)
1925    {
1926      gdk_gc_set_clip_rectangle (lightgc, NULL);
1927      gdk_gc_set_clip_rectangle (midgc, NULL);
1928      gdk_gc_set_clip_rectangle (darkgc, NULL);
1929      gdk_gc_set_clip_rectangle (whitegc, NULL);
1930    }
1931}
1932/**************************************************************************/
1933static void
1934adjust_notebook_tab_size (GtkPositionType tab_pos,
1935                          gint           *width,
1936                          gint           *height)
1937{
1938  /* The default overlap is two pixels, but we only want a one pixel overlap
1939   */
1940  switch (tab_pos)
1941    {
1942    case GTK_POS_TOP:
1943    case GTK_POS_BOTTOM:
1944      *width -= 1;
1945      break;
1946    case GTK_POS_LEFT:
1947    case GTK_POS_RIGHT:
1948      *height -= 1;
1949      break;
1950    }
1951}
1952
1953static void
1954metal_tab (GtkStyle * style,
1955           GdkWindow * window,
1956           GtkStateType state_type,
1957           GtkShadowType shadow_type,
1958           GdkRectangle * area,
1959           GtkWidget * widget,
1960           const gchar * detail,
1961           gint x,
1962           gint y,
1963           gint width,
1964           gint height)
1965{
1966  MetalStyle *metal_style = METAL_STYLE (style);
1967  GtkNotebook *notebook;
1968  GdkGC *lightgc, *midgc, *darkgc, *brightgc, *bggc;
1969  GdkPoint points[5];
1970  int orientation;
1971  gboolean is_first, selected;
1972
1973  notebook = GTK_NOTEBOOK (widget);
1974  orientation = notebook->tab_pos;
1975
1976  is_first = is_first_tab (notebook, x, y);
1977  selected = state_type == GTK_STATE_NORMAL;
1978
1979  lightgc = metal_style->light_gray_gc;
1980  midgc = metal_style->mid_gray_gc;
1981  brightgc = style->white_gc;
1982  bggc = metal_style->light_gray_gc;
1983
1984  if (selected)
1985    {
1986      brightgc = style->white_gc;
1987      darkgc = metal_style->mid_gray_gc;
1988    }
1989  else
1990    {
1991      brightgc = metal_style->light_gray_gc;
1992      darkgc = metal_style->dark_gray_gc;
1993    }
1994
1995  /* Set Clip Region */
1996  if (area)
1997    {
1998      gdk_gc_set_clip_rectangle (lightgc, area);
1999      gdk_gc_set_clip_rectangle (midgc, area);
2000      gdk_gc_set_clip_rectangle (darkgc, area);
2001      gdk_gc_set_clip_rectangle (brightgc, area);
2002      gdk_gc_set_clip_rectangle (bggc, area);
2003    }
2004
2005  adjust_notebook_tab_size (orientation, &width, &height);
2006
2007  /* Fill area */
2008  gdk_draw_rectangle (window, bggc, TRUE, x + 0, y + 0, width, height);
2009
2010  switch (orientation)
2011    {
2012    case GTK_POS_TOP:
2013      /* Draw background */
2014      points[0].x = x + 2;
2015      points[0].y = y + height;
2016      points[1].x = x + 2;
2017      points[1].y = y + 6;
2018      points[2].x = x + 6;
2019      points[2].y = y + 2;
2020      points[3].x = x + width - 1;
2021      points[3].y = y + 2;
2022      points[4].x = x + width - 1;
2023      points[4].y = y + height;
2024      if (selected)
2025        gdk_draw_polygon (window, lightgc, TRUE, points, 5);
2026      else
2027        gdk_draw_polygon (window, midgc, TRUE, points, 5);
2028
2029      /* Draw border */
2030      if (is_first)
2031        gdk_draw_line (window, darkgc, x + 0, y + 6, x + 0, y + height + 1);
2032      else if (selected)
2033        gdk_draw_line (window, darkgc, x + 0, y + 6, x + 0, y + height - 1);
2034      gdk_draw_line (window, darkgc, x + 0, y + 6, x + 6, y + 0);
2035      gdk_draw_line (window, darkgc, x + 6, y + 0, x + width - 2, y + 0);
2036      gdk_draw_line (window, darkgc, x + width - 1, y + 1, x + width - 1, y
2037                     + height - 1);
2038
2039      if (is_first)
2040        gdk_draw_line (window, brightgc, x + 1, y + 6, x + 1, y + height + 1);
2041      else
2042        gdk_draw_line (window, brightgc, x + 1, y + 6, x + 1, y + height - 1);
2043      gdk_draw_line (window, brightgc, x + 1, y + 6, x + 6, y + 1);
2044      gdk_draw_line (window, brightgc, x + 6, y + 1, x + width - 2, y + 1);
2045      break;
2046    case GTK_POS_LEFT:
2047      /* Draw background */
2048      points[0].x = x + 2;
2049      points[0].y = y + height;
2050      points[1].x = x + 2;
2051      points[1].y = y + 6;
2052      points[2].x = x + 6;
2053      points[2].y = y + 2;
2054      points[3].x = x + width - 1;
2055      points[3].y = y + 2;
2056      points[4].x = x + width - 1;
2057      points[4].y = y + height;
2058      if (selected)
2059        gdk_draw_polygon (window, lightgc, TRUE, points, 5);
2060      else
2061        gdk_draw_polygon (window, midgc, TRUE, points, 5);
2062
2063      /* Draw border */
2064      gdk_draw_line (window, darkgc, x + 0, y + 6, x + 0, y + height - 1);
2065      gdk_draw_line (window, darkgc, x + 0, y + 6, x + 6, y + 0);
2066      if (is_first)
2067        gdk_draw_line (window, darkgc, x + 6, y + 0, x + width + 1, y + 0);
2068      else
2069        gdk_draw_line (window, darkgc, x + 6, y + 0, x + width - 1, y + 0);
2070      gdk_draw_line (window, darkgc, x + 0, y + height - 1, x + width - 1, y
2071                     + height - 1);
2072
2073      gdk_draw_line (window, brightgc, x + 1, y + 6, x + 6, y + 1);
2074      if (is_first)
2075        gdk_draw_line (window, brightgc, x + 6, y + 1, x + width + 1, y + 1);
2076      else
2077        gdk_draw_line (window, brightgc, x + 6, y + 1, x + width - 1, y + 1);
2078      break;
2079    case GTK_POS_RIGHT:
2080      /* Draw background */
2081      points[0].x = x + width - 2;
2082      points[0].y = y + height - 1;
2083      points[1].x = x + width - 2;
2084      points[1].y = y + 6;
2085      points[2].x = x + width - 6;
2086      points[2].y = y + 2;
2087      points[3].x = x - 1;
2088      points[3].y = y + 2;
2089      points[4].x = x - 1;
2090      points[4].y = y + height - 1;
2091      if (selected)
2092        gdk_draw_polygon (window, lightgc, TRUE, points, 5);
2093      else
2094        gdk_draw_polygon (window, midgc, TRUE, points, 5);
2095
2096      /* Draw border */
2097      gdk_draw_line (window, darkgc, x + width - 1, y + 6, x + width - 1, y
2098                     + height - 1);
2099      gdk_draw_line (window, darkgc, x + width - 1, y + 6, x + width - 7, y
2100                     + 0);
2101      if (is_first)
2102        gdk_draw_line (window, darkgc, x - 2, y + 0, x + width - 7, y + 0);
2103      else
2104        gdk_draw_line (window, darkgc, x - 1, y + 0, x + width - 7, y + 0);
2105      gdk_draw_line (window, darkgc, x - 1, y + height - 1, x + width - 1, y
2106                     + height - 1);
2107
2108      gdk_draw_line (window, brightgc, x + width - 2, y + 6, x + width - 7, y
2109                     + 1);
2110      if (is_first)
2111        gdk_draw_line (window, brightgc, x + width - 7, y + 1, x - 2, y + 1);
2112      else
2113        gdk_draw_line (window, brightgc, x + width - 7, y + 1, x - 1, y + 1);
2114      break;
2115    case GTK_POS_BOTTOM:
2116      /* Draw background */
2117      points[0].x = x + 2;
2118      points[0].y = y + 0;
2119      points[1].x = x + 2;
2120      points[1].y = y + height - 6;
2121      points[2].x = x + 6;
2122      points[2].y = y + height - 2;
2123      points[3].x = x + width - 1;
2124      points[3].y = y + height - 2;
2125      points[4].x = x + width - 1;
2126      points[4].y = y + 0;
2127      if (selected)
2128        gdk_draw_polygon (window, lightgc, TRUE, points, 5);
2129      else
2130        gdk_draw_polygon (window, midgc, TRUE, points, 5);
2131
2132      /* Draw border */
2133      if (is_first)
2134        gdk_draw_line (window, darkgc, x + 0, y + height - 6, x + 0, y - 2);
2135      else if (selected)
2136        gdk_draw_line (window, darkgc, x + 0, y + height - 6, x + 0, y - 1);
2137      gdk_draw_line (window, darkgc, x + 0, y + height - 6, x + 6, y + height);
2138      gdk_draw_line (window, darkgc, x + 5, y + height - 1, x + width - 2, y
2139                     + height - 1);
2140      gdk_draw_line (window, darkgc, x + width - 1, y + height - 1, x +
2141                     width - 1, y - 1);
2142
2143      if (is_first)
2144        gdk_draw_line (window, brightgc, x + 1, y + height - 6, x + 1, y - 2);
2145      else
2146        gdk_draw_line (window, brightgc, x + 1, y + height - 6, x + 1, y - 1);
2147      gdk_draw_line (window, brightgc, x + 1, y + height - 6, x + 5, y +
2148                     height - 2);
2149      break;
2150    }
2151
2152  /* Reset Clip Region */
2153  if (area)
2154    {
2155      gdk_gc_set_clip_rectangle (lightgc, NULL);
2156      gdk_gc_set_clip_rectangle (midgc, NULL);
2157      gdk_gc_set_clip_rectangle (darkgc, NULL);
2158      gdk_gc_set_clip_rectangle (brightgc, NULL);
2159      gdk_gc_set_clip_rectangle (bggc, NULL);
2160    }
2161}
2162/**************************************************************************/
2163static gboolean
2164is_first_tab (GtkNotebook *notebook,
2165              int          x,
2166              int          y)
2167{
2168  GtkWidget *widget = GTK_WIDGET (notebook);
2169  int border_width = GTK_CONTAINER (notebook)->border_width;
2170
2171  switch (notebook->tab_pos)
2172    {
2173    case GTK_POS_TOP:
2174    case GTK_POS_BOTTOM:
2175      return x == widget->allocation.x + border_width;
2176    case GTK_POS_LEFT:
2177    case GTK_POS_RIGHT:
2178      return y == widget->allocation.y + border_width;
2179    }
2180
2181  return FALSE;
2182}
2183/**************************************************************************/
2184static void
2185metal_button (GtkStyle * style,
2186              GdkWindow * window,
2187              GtkStateType state_type,
2188              GtkShadowType shadow_type,
2189              GdkRectangle * area,
2190              GtkWidget * widget,
2191              const gchar * detail,
2192              gint x,
2193              gint y,
2194              gint width,
2195              gint height)
2196{
2197  MetalStyle *metal_style = METAL_STYLE (style);
2198  GdkGC *dark_gc, *medium_gc, *light_gc;
2199  gboolean active_toggle = FALSE;
2200
2201  /* Set Clip Region */
2202  if (area)
2203    {
2204      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_PRELIGHT], area);
2205      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_SELECTED], area);
2206      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_NORMAL], area);
2207      gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2208      gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2209      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2210    }
2211
2212  if (widget && GTK_IS_TOGGLE_BUTTON (widget) &&
2213      GTK_TOGGLE_BUTTON (widget)->active)
2214    {
2215      active_toggle = TRUE;
2216      gdk_draw_rectangle (window, metal_style->mid_gray_gc, TRUE, x, y,
2217                          width, height);
2218    }
2219  else if (state_type == GTK_STATE_ACTIVE)
2220    {
2221      gdk_draw_rectangle (window, metal_style->mid_gray_gc, TRUE, x, y,
2222                          width, height);
2223    }
2224  else
2225    {
2226      gdk_draw_rectangle (window, metal_style->light_gray_gc, TRUE, x, y,
2227                          width, height);
2228    }
2229
2230  dark_gc = (state_type == GTK_STATE_INSENSITIVE) ? metal_style->mid_gray_gc : metal_style->dark_gray_gc;
2231  medium_gc = metal_style->light_gray_gc;
2232  light_gc = style->white_gc;
2233
2234  gdk_draw_rectangle (window, dark_gc, FALSE, x, y, width
2235                      - 2, height - 2);
2236
2237  if (state_type == GTK_STATE_INSENSITIVE)
2238    {
2239      /* Nothing */
2240    }
2241  else if (widget && GTK_WIDGET_HAS_DEFAULT (widget))
2242    {
2243      if (state_type == GTK_STATE_ACTIVE || active_toggle)
2244        {
2245          if (active_toggle)
2246            {
2247              gdk_draw_line (window, medium_gc,
2248                             x + 2,     y + 2,
2249                             x + 2,     y + height);
2250              gdk_draw_line (window, medium_gc,
2251                             x + 2,     y + 2,
2252                             x + width, y + 2);
2253            }
2254
2255          gdk_draw_line (window, light_gc,
2256                         x + 2,     y + height,
2257                         x + width, y + height);
2258          gdk_draw_line (window, light_gc,
2259                         x + width, y + 2,
2260                         x + width, y + height);
2261        }
2262      else
2263        {
2264          gdk_draw_rectangle (window, light_gc, FALSE, x + 2, y + 2,
2265                              width - 2, height - 2);
2266        }
2267     
2268      gdk_draw_rectangle (window, dark_gc, FALSE, x + 1, y + 1, width
2269                          - 2, height - 2);
2270     
2271      gdk_draw_point (window, medium_gc, x + 2, y + height - 2);
2272      gdk_draw_point (window, medium_gc, x + width - 2, y + 2);
2273      gdk_draw_point (window, dark_gc, x, y + height - 1);
2274      gdk_draw_point (window, dark_gc, x + width - 1, y);
2275    }
2276  else
2277    {
2278      if (state_type == GTK_STATE_ACTIVE || active_toggle)
2279        {
2280          if (active_toggle)
2281            {
2282              gdk_draw_line (window, medium_gc,
2283                             x + 1, y + 1,
2284                             x + 1, y + height - 1);
2285              gdk_draw_line (window, medium_gc,
2286                             x + 1,         y + 1,
2287                             x + width - 1, y + 1);
2288            }
2289
2290          gdk_draw_line (window, light_gc,
2291                         x + 1,     y + height - 1,
2292                         x + width, y + height - 1);
2293          gdk_draw_line (window, light_gc,
2294                         x + width - 1, y + 1,
2295                         x + width - 1, y + height);
2296        }
2297      else
2298        gdk_draw_rectangle (window, light_gc, FALSE, x + 1, y + 1,
2299                            width - 2, height - 2);
2300
2301      gdk_draw_point (window, medium_gc, x + 1, y + height - 2);
2302      gdk_draw_point (window, medium_gc, x + width - 2, y + 1);
2303    }
2304
2305  /* Reset Clip Region */
2306  if (area)
2307    {
2308      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_PRELIGHT], NULL);
2309      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_SELECTED], NULL);
2310      gdk_gc_set_clip_rectangle (style->bg_gc[GTK_STATE_NORMAL], NULL);
2311      gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2312      gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2313      gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2314    }
2315}
2316/**************************************************************************/
2317static void
2318draw_check (GtkStyle * style,
2319            GdkWindow * window,
2320            GtkStateType state_type,
2321            GtkShadowType shadow_type,
2322            GdkRectangle * area,
2323            GtkWidget * widget,
2324            const gchar * detail,
2325            gint x,
2326            gint y,
2327            gint width,
2328            gint height)
2329{
2330  GdkGC *gc1, *gc2, *gc3, *gc4;
2331
2332  /* Fixed size only */
2333
2334#if DEBUG
2335  printf ("draw_check: %p %p %s %i %i %i %i\n", widget, window, detail, x,
2336          y, width, height);
2337#endif
2338
2339  gc1 = style->black_gc;
2340  gc2 = style->bg_gc[GTK_STATE_NORMAL];
2341  gc3 = style->dark_gc[state_type];
2342  gc4 = style->light_gc[state_type];
2343
2344  if (area)
2345    {
2346      gdk_gc_set_clip_rectangle (gc1, area);
2347      gdk_gc_set_clip_rectangle (gc2, area);
2348      gdk_gc_set_clip_rectangle (gc3, area);
2349      gdk_gc_set_clip_rectangle (gc4, area);
2350    }
2351
2352  /* Draw box */
2353  if (GTK_CHECK_TYPE (widget, gtk_menu_item_get_type ()))
2354    {
2355      gdk_draw_rectangle (window, gc3, FALSE, x - 2, y - 2, 8, 8);
2356      gdk_draw_rectangle (window, gc4, FALSE, x - 1, y - 1, 8, 8);
2357
2358      if (shadow_type == GTK_SHADOW_IN)
2359        {
2360          gdk_draw_line (window, gc1, x + 1, y + 0, x + 1, y + 4);
2361          gdk_draw_line (window, gc1, x + 2, y + 0, x + 2, y + 4);
2362          gdk_draw_line (window, gc1, x + 3, y + 3, x + 7, y - 1);
2363          gdk_draw_line (window, gc1, x + 3, y + 2, x + 7, y - 2);
2364        }
2365    }
2366  else
2367    {
2368      gdk_draw_rectangle (window, gc2, TRUE, x, y, width, height);
2369
2370      gdk_draw_rectangle (window, gc3, FALSE, x - 2, y - 2, 11, 11);
2371      gdk_draw_rectangle (window, gc4, FALSE, x - 1, y - 1, 11, 11);
2372
2373      if (shadow_type == GTK_SHADOW_IN)
2374        {
2375          gdk_draw_line (window, gc1, x + 1, y + 3, x + 1, y + 7);
2376          gdk_draw_line (window, gc1, x + 2, y + 3, x + 2, y + 7);
2377          gdk_draw_line (window, gc1, x + 3, y + 6, x + 7, y + 2);
2378          gdk_draw_line (window, gc1, x + 3, y + 5, x + 7, y + 1);
2379        }
2380    }
2381
2382  if (area)
2383    {
2384      gdk_gc_set_clip_rectangle (gc1, NULL);
2385      gdk_gc_set_clip_rectangle (gc2, NULL);
2386      gdk_gc_set_clip_rectangle (gc3, NULL);
2387      gdk_gc_set_clip_rectangle (gc4, NULL);
2388    }
2389}
2390/**************************************************************************/
2391static void
2392draw_option (GtkStyle * style,
2393             GdkWindow * window,
2394             GtkStateType state_type,
2395             GtkShadowType shadow_type,
2396             GdkRectangle * area,
2397             GtkWidget * widget,
2398             const gchar * detail,
2399             gint x,
2400             gint y,
2401             gint width,
2402             gint height)
2403{
2404  GdkGC *gc0;
2405  GdkGC *gc1;
2406  GdkGC *gc2;
2407  GdkGC *gc3;
2408  GdkGC *gc4;
2409
2410  x -= 1;
2411  y -= 1;
2412  width += 2;
2413  height += 2;
2414
2415  gc0 = style->white_gc;
2416  gc1 = style->light_gc[GTK_STATE_NORMAL];
2417  gc2 = style->bg_gc[GTK_STATE_NORMAL];
2418  gc3 = style->dark_gc[GTK_STATE_NORMAL];
2419  gc4 = style->black_gc;
2420
2421  if (area)
2422    {
2423      gdk_gc_set_clip_rectangle (gc0, area);
2424      gdk_gc_set_clip_rectangle (gc1, area);
2425      gdk_gc_set_clip_rectangle (gc2, area);
2426      gdk_gc_set_clip_rectangle (gc3, area);
2427      gdk_gc_set_clip_rectangle (gc4, area);
2428    }
2429
2430  /* Draw radio button, metal-stle
2431     There is probably a better way to do this
2432     with pixmaps. Fix later. */
2433
2434  if (GTK_CHECK_TYPE (widget, gtk_menu_item_get_type ()))
2435    {
2436      /* dark */
2437      gdk_draw_line (window, gc3, x + 2, y, x + 6, y);
2438      gdk_draw_line (window, gc3, x + 1, y + 1, x + 1, y + 1);
2439      gdk_draw_line (window, gc3, x + 7, y + 1, x + 7, y + 1);
2440      gdk_draw_line (window, gc3, x + 2, y + 8, x + 2, y + 8);
2441      gdk_draw_line (window, gc3, x + 7, y + 7, x + 7, y + 7);
2442      gdk_draw_line (window, gc3, x + 2, y + 8, x + 6, y + 8);
2443      gdk_draw_line (window, gc3, x, y + 2, x, y + 6);
2444      gdk_draw_line (window, gc3, x + 8, y + 2, x + 8, y + 6);
2445
2446      /* white */
2447      gdk_draw_line (window, gc0, x + 3, y + 1, x + 6, y + 1);
2448      gdk_draw_line (window, gc0, x + 8, y + 1, x + 8, y + 1);
2449      gdk_draw_line (window, gc0, x + 2, y + 2, x + 2, y + 2);
2450      gdk_draw_line (window, gc0, x + 1, y + 3, x + 1, y + 6);
2451      gdk_draw_line (window, gc0, x + 9, y + 2, x + 9, y + 7);
2452      gdk_draw_line (window, gc0, x + 1, y + 8, x + 1, y + 8);
2453      gdk_draw_line (window, gc0, x + 8, y + 8, x + 8, y + 8);
2454      gdk_draw_line (window, gc0, x + 2, y + 9, x + 7, y + 9);
2455
2456      if (shadow_type == GTK_SHADOW_IN)
2457        {
2458          gdk_draw_rectangle (window, gc4, TRUE, x + 2, y + 3, 5, 3);
2459          gdk_draw_rectangle (window, gc4, TRUE, x + 3, y + 2, 3, 5);
2460        }
2461    }
2462  else
2463    {
2464      /* background */
2465      gdk_draw_rectangle (window, gc2, TRUE, x, y, width, height);
2466
2467      /* dark */
2468      gdk_draw_line (window, gc3, x + 4, y, x + 7, y);
2469      gdk_draw_line (window, gc3, x + 2, y + 1, x + 3, y + 1);
2470      gdk_draw_line (window, gc3, x + 8, y + 1, x + 9, y + 1);
2471      gdk_draw_line (window, gc3, x + 2, y + 10, x + 3, y + 10);
2472      gdk_draw_line (window, gc3, x + 8, y + 10, x + 9, y + 10);
2473      gdk_draw_line (window, gc3, x + 4, y + 11, x + 7, y + 11);
2474
2475
2476      gdk_draw_line (window, gc3, x, y + 4, x, y + 7);
2477      gdk_draw_line (window, gc3, x + 1, y + 2, x + 1, y + 3);
2478      gdk_draw_line (window, gc3, x + 1, y + 8, x + 1, y + 9);
2479      gdk_draw_line (window, gc3, x + 10, y + 2, x + 10, y + 3);
2480      gdk_draw_line (window, gc3, x + 10, y + 8, x + 10, y + 9);
2481      gdk_draw_line (window, gc3, x + 11, y + 4, x + 11, y + 7);
2482
2483      /* white */
2484      gdk_draw_line (window, gc0, x + 4, y + 1, x + 7, y + 1);
2485      gdk_draw_line (window, gc0, x + 2, y + 2, x + 3, y + 2);
2486      gdk_draw_line (window, gc0, x + 8, y + 2, x + 9, y + 2);
2487      gdk_draw_line (window, gc0, x + 2, y + 11, x + 3, y + 11);
2488      gdk_draw_line (window, gc0, x + 8, y + 11, x + 9, y + 11);
2489      gdk_draw_line (window, gc0, x + 4, y + 12, x + 7, y + 12);
2490
2491
2492      gdk_draw_line (window, gc0, x + 1, y + 4, x + 1, y + 7);
2493      gdk_draw_line (window, gc0, x + 2, y + 2, x + 2, y + 3);
2494      gdk_draw_line (window, gc0, x + 2, y + 8, x + 2, y + 9);
2495      gdk_draw_line (window, gc0, x + 11, y + 2, x + 11, y + 3);
2496      gdk_draw_line (window, gc0, x + 11, y + 8, x + 11, y + 9);
2497      gdk_draw_line (window, gc0, x + 12, y + 4, x + 12, y + 7);
2498      gdk_draw_point (window, gc0, x + 10, y + 1);
2499      gdk_draw_point (window, gc0, x + 10, y + 10);
2500
2501      if (shadow_type == GTK_SHADOW_IN)
2502        {
2503          gdk_draw_rectangle (window, gc4, TRUE, x + 3, y + 4, 6, 4);
2504          gdk_draw_rectangle (window, gc4, TRUE, x + 4, y + 3, 4, 6);
2505        }
2506    }
2507
2508  if (area)
2509    {
2510      gdk_gc_set_clip_rectangle (gc0, NULL);
2511      gdk_gc_set_clip_rectangle (gc1, NULL);
2512      gdk_gc_set_clip_rectangle (gc2, NULL);
2513      gdk_gc_set_clip_rectangle (gc3, NULL);
2514      gdk_gc_set_clip_rectangle (gc4, NULL);
2515    }
2516}
2517/**************************************************************************/
2518static void
2519draw_tab (GtkStyle * style,
2520          GdkWindow * window,
2521          GtkStateType state_type,
2522          GtkShadowType shadow_type,
2523          GdkRectangle * area,
2524          GtkWidget * widget,
2525          const gchar * detail,
2526          gint x,
2527          gint y,
2528          gint width,
2529          gint height)
2530{
2531  g_return_if_fail (style != NULL);
2532  g_return_if_fail (window != NULL);
2533
2534#if DEBUG
2535  printf ("draw_tab: %p %s %i %i\n", detail, detail, width, height);
2536#endif
2537
2538  gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
2539                 x, y, width, height);
2540}
2541
2542/**************************************************************************/
2543static void
2544draw_shadow_gap (GtkStyle * style,
2545                 GdkWindow * window,
2546                 GtkStateType state_type,
2547                 GtkShadowType shadow_type,
2548                 GdkRectangle * area,
2549                 GtkWidget * widget,
2550                 const gchar * detail,
2551                 gint x,
2552                 gint y,
2553                 gint width,
2554                 gint height,
2555                 GtkPositionType gap_side,
2556                 gint gap_x,
2557                 gint gap_width)
2558{
2559  GdkRectangle rect;
2560
2561  g_return_if_fail (style != NULL);
2562  g_return_if_fail (window != NULL);
2563
2564#if DEBUG
2565  printf ("draw_shadow_gap: %p %p %s %i %i %i %i\n", widget, window, detail,
2566          x, y, width, height);
2567#endif
2568
2569  gap_width -= 1;
2570
2571  gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
2572                    x, y, width, height);
2573
2574  switch (gap_side)
2575    {
2576    case GTK_POS_TOP:
2577      rect.x = x + gap_x;
2578      rect.y = y;
2579      rect.width = gap_width;
2580      rect.height = 2;
2581      break;
2582    case GTK_POS_BOTTOM:
2583      rect.x = x + gap_x;
2584      rect.y = y + height - 2;
2585      rect.width = gap_width;
2586      rect.height = 2;
2587      break;
2588    case GTK_POS_LEFT:
2589      rect.x = x;
2590      rect.y = y + gap_x;
2591      rect.width = 2;
2592      rect.height = gap_width;
2593      break;
2594    case GTK_POS_RIGHT:
2595      rect.x = x + width - 2;
2596      rect.y = y + gap_x;
2597      rect.width = 2;
2598      rect.height = gap_width;
2599      break;
2600    }
2601
2602  gtk_style_apply_default_pixmap (style, window, state_type, area,
2603                                  rect.x, rect.y, rect.width, rect.height);
2604}
2605/**************************************************************************/
2606static void
2607draw_box_gap (GtkStyle       *style,
2608              GdkWindow      *window,
2609              GtkStateType    state_type,
2610              GtkShadowType   shadow_type,
2611              GdkRectangle   *area,
2612              GtkWidget      *widget,
2613              const gchar    *detail,
2614              gint            x,
2615              gint            y,
2616              gint            width,
2617              gint            height,
2618              GtkPositionType gap_side,
2619              gint            gap_x,
2620              gint            gap_width)
2621{
2622  GdkRectangle rect;
2623
2624  g_return_if_fail (style != NULL);
2625  g_return_if_fail (window != NULL);
2626
2627#if DEBUG
2628  printf ("draw_box_gap: %p %p %s %i %i %i %i\n", widget, window, detail, x,
2629          y, width, height);
2630#endif
2631
2632  gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
2633                 x, y, width, height);
2634
2635  /* The default overlap is two pixels, but we only want a one pixel overlap
2636   */
2637  gap_width -= 1;
2638
2639  switch (gap_side)
2640    {
2641    case GTK_POS_TOP:
2642      rect.x = x + gap_x;
2643      rect.y = y;
2644      rect.width = gap_width;
2645      rect.height = 2;
2646      break;
2647    case GTK_POS_BOTTOM:
2648      rect.x = x + gap_x;
2649      rect.y = y + height - 2;
2650      rect.width = gap_width;
2651      rect.height = 2;
2652      break;
2653    case GTK_POS_LEFT:
2654      rect.x = x;
2655      rect.y = y + gap_x;
2656      rect.width = 2;
2657      rect.height = gap_width;
2658      break;
2659    case GTK_POS_RIGHT:
2660      rect.x = x + width - 2;
2661      rect.y = y + gap_x;
2662      rect.width = 2;
2663      rect.height = gap_width;
2664      break;
2665    }
2666
2667  gtk_style_apply_default_pixmap (style, window, state_type, area,
2668                                  rect.x, rect.y, rect.width, rect.height);
2669}
2670/**************************************************************************/
2671static void
2672draw_extension (GtkStyle * style,
2673                GdkWindow * window,
2674                GtkStateType state_type,
2675                GtkShadowType shadow_type,
2676                GdkRectangle * area,
2677                GtkWidget * widget,
2678                const gchar * detail,
2679                gint x,
2680                gint y,
2681                gint width,
2682                gint height,
2683                GtkPositionType gap_side)
2684{
2685  g_return_if_fail (style != NULL);
2686  g_return_if_fail (window != NULL);
2687
2688#if DEBUG
2689  printf ("draw_extension: %p %p %s %i %i %i %i\n", widget, window, detail,
2690          x, y, width, height);
2691#endif
2692
2693  gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
2694                 x, y, width, height);
2695}
2696/**************************************************************************/
2697static void
2698draw_notebook_focus (GtkWidget *widget,
2699                     GdkWindow *window,
2700                     GdkGC     *gc,
2701                     gint       x,
2702                     gint       y,
2703                     gint       width,
2704                     gint       height)
2705{
2706  GtkPositionType tab_position = GTK_POS_TOP;
2707  GdkPoint points[6];
2708  gint tab_hborder = 2;
2709  gint tab_vborder = 2;
2710
2711  if (widget && GTK_IS_NOTEBOOK (widget))
2712    {
2713      GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2714     
2715      tab_hborder = notebook->tab_hborder;
2716      tab_vborder = notebook->tab_vborder;
2717      tab_position = gtk_notebook_get_tab_pos (notebook);
2718    }
2719
2720  adjust_notebook_tab_size (tab_position, &width, &height);
2721
2722  x -= tab_hborder;
2723  y -= tab_vborder;
2724  width += 2 * tab_hborder;
2725  height += 2 * tab_vborder;
2726
2727  switch (tab_position)
2728    {
2729    default:
2730    case GTK_POS_TOP:
2731      points[0].x = x + 4;          points[0].y = y;
2732      points[1].x = x + width - 1;  points[1].y = y;
2733      points[2].x = x + width - 1;  points[2].y = y + height;
2734      points[3].x = x;              points[3].y = y + height;
2735      points[4].x = x;              points[4].y = y + 4;
2736      break;
2737    case GTK_POS_LEFT:
2738      points[0].x = x + 4;          points[0].y = y - 1;
2739      points[1].x = x + width - 1;  points[1].y = y - 1;
2740      points[2].x = x + width - 1;  points[2].y = y + height;
2741      points[3].x = x;              points[3].y = y + height;
2742      points[4].x = x;              points[4].y = y + 3;
2743      break;
2744    case GTK_POS_RIGHT:
2745      points[0].x = x;              points[0].y = y - 1;
2746      points[1].x = x + width - 5;  points[1].y = y - 1;
2747      points[2].x = x + width - 1;  points[2].y = y + 3;
2748      points[3].x = x + width - 1;  points[3].y = y + height;
2749      points[4].x = x;              points[4].y = y + height;
2750      break;
2751    case GTK_POS_BOTTOM:
2752      points[0].x = x;              points[0].y = y;
2753      points[1].x = x + width - 1;  points[1].y = y;
2754      points[2].x = x + width - 1;  points[2].y = y + height - 1;
2755      points[3].x = x + 4;          points[3].y = y + height - 1;
2756      points[4].x = x;              points[4].y = y + height - 5;
2757      break;
2758    }
2759
2760  points[5] = points[0];
2761 
2762  gdk_draw_polygon (window, gc, FALSE, points, 6);
2763}
2764
2765static void
2766draw_focus (GtkStyle * style,
2767            GdkWindow * window,
2768            GtkStateType state_type,
2769            GdkRectangle * area,
2770            GtkWidget * widget,
2771            const gchar * detail,
2772            gint x,
2773            gint y,
2774            gint width,
2775            gint height)
2776{
2777  GdkGC *focusgc;
2778 
2779#if DEBUG
2780  printf ("draw_focus: %p %p %s %i %i %i %i\n", widget, window, detail, x,
2781          y, width, height);
2782#endif
2783
2784  if (detail && strcmp (detail, "add-mode") == 0)
2785    {
2786      parent_class->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
2787      return;
2788    }
2789
2790  if (width == -1 && height == -1)
2791    gdk_window_get_size (window, &width, &height);
2792  else if (width == -1)
2793    gdk_window_get_size (window, &width, NULL);
2794  else if (height == -1)
2795    gdk_window_get_size (window, NULL, &height);
2796
2797  focusgc = style->bg_gc[GTK_STATE_SELECTED];
2798
2799  if (area)
2800    gdk_gc_set_clip_rectangle (focusgc, area);
2801
2802  if (DETAIL ("tab"))
2803    draw_notebook_focus (widget, window, focusgc, x, y, width, height);
2804  else
2805    gdk_draw_rectangle (window, focusgc, FALSE, x, y, width - 1, height - 1);
2806
2807  if (area)
2808    gdk_gc_set_clip_rectangle (focusgc, NULL);
2809}
2810/**************************************************************************/
2811static void
2812draw_slider (GtkStyle * style,
2813             GdkWindow * window,
2814             GtkStateType state_type,
2815             GtkShadowType shadow_type,
2816             GdkRectangle * area,
2817             GtkWidget * widget,
2818             const gchar * detail,
2819             gint x,
2820             gint y,
2821             gint width,
2822             gint height,
2823             GtkOrientation orientation)
2824{
2825  g_return_if_fail (style != NULL);
2826  g_return_if_fail (window != NULL);
2827
2828  if ((width == -1) && (height == -1))
2829    gdk_window_get_size (window, &width, &height);
2830  else if (width == -1)
2831    gdk_window_get_size (window, &width, NULL);
2832  else if (height == -1)
2833    gdk_window_get_size (window, NULL, &height);
2834
2835  if (DETAIL ("slider"))
2836    metal_scrollbar_slider (style, window, state_type, shadow_type,
2837                            area, widget, detail, x, y, width, height);
2838  else
2839    metal_scale_slider (style, window, state_type, shadow_type,
2840                        area, widget, detail, x, y, width, height, orientation);
2841}
2842/**************************************************************************/
2843static void
2844draw_paned_handle (GtkStyle      *style,
2845                   GdkWindow     *window,
2846                   GtkStateType   state_type,
2847                   GtkShadowType  shadow_type,
2848                   GdkRectangle  *area,
2849                   GtkWidget     *widget,
2850                   gint           x,
2851                   gint           y,
2852                   gint           width,
2853                   gint           height,
2854                   GtkOrientation orientation)
2855{
2856  MetalStyle *metal_style = METAL_STYLE (style);
2857  GdkPixmap *pm;
2858  GdkGC *fillgc;
2859  GdkGCValues values;
2860  GdkGC *lightgc, *darkgc, *whitegc;
2861
2862  /* Get colors */
2863  if (state_type == GTK_STATE_PRELIGHT)
2864    {
2865      lightgc = style->bg_gc[GTK_STATE_PRELIGHT];
2866      darkgc = style->fg_gc[GTK_STATE_PRELIGHT];
2867      whitegc = style->white_gc;
2868    }
2869  else
2870    {
2871      lightgc = metal_style->light_gray_gc;
2872      darkgc = metal_style->dark_gray_gc;
2873      whitegc = style->white_gc;
2874    }
2875
2876  /* Draw textured surface */
2877  pm = gdk_pixmap_new (window, 4, 4, -1);
2878
2879  gdk_draw_rectangle (pm, lightgc, TRUE, 0, 0, 4, 4);
2880 
2881  gdk_draw_point (pm, whitegc, 0, 0);
2882  gdk_draw_point (pm, darkgc, 1, 1);
2883  gdk_draw_point (pm, whitegc, 2, 2);
2884  gdk_draw_point (pm, darkgc, 3, 3);
2885
2886  values.fill = GDK_TILED;
2887  values.ts_x_origin = x + 2;
2888  values.ts_y_origin = y + 2;
2889  fillgc = gdk_gc_new_with_values (window, &values,
2890                                   GDK_GC_FILL | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
2891
2892  if (area)
2893    gdk_gc_set_clip_rectangle (fillgc, area);
2894  gdk_gc_set_tile (fillgc, pm);
2895
2896  gdk_draw_rectangle (window, fillgc, TRUE, x + 2, y + 2, width - 4, height - 4);
2897
2898  gdk_gc_unref (fillgc);
2899  gdk_pixmap_unref (pm);
2900}
2901/**************************************************************************/
2902static void
2903draw_handle (GtkStyle      *style,
2904             GdkWindow     *window,
2905             GtkStateType   state_type,
2906             GtkShadowType  shadow_type,
2907             GdkRectangle  *area,
2908             GtkWidget     *widget,
2909             const gchar   *detail,
2910             gint           x,
2911             gint           y,
2912             gint           width,
2913             gint           height,
2914             GtkOrientation orientation)
2915{
2916  MetalStyle *metal_style = METAL_STYLE (style);
2917  GdkPixmap *pm;
2918  GdkGC *fillgc;
2919  GdkGCValues values;
2920  GdkGC *lightgc, *midgc, *darkgc, *whitegc, *blackgc;
2921
2922  sanitize_size (window, &width, &height);
2923
2924  if (DETAIL ("paned"))
2925    {
2926      draw_paned_handle (style, window, state_type, shadow_type,
2927                         area, widget, x, y, width, height,
2928                         orientation);
2929      return;
2930    }
2931   
2932  /* Get colors */
2933  if (state_type == GTK_STATE_PRELIGHT)
2934    {
2935      lightgc = style->bg_gc[GTK_STATE_PRELIGHT];
2936      midgc = style->bg_gc[GTK_STATE_SELECTED];
2937      darkgc = style->fg_gc[GTK_STATE_PRELIGHT];
2938      whitegc = style->white_gc;
2939      blackgc = style->black_gc;
2940    }
2941  else
2942    {
2943      lightgc = metal_style->light_gray_gc;
2944      midgc = metal_style->mid_gray_gc;
2945      darkgc = metal_style->mid_gray_gc;
2946      whitegc = style->white_gc;
2947      blackgc = style->black_gc;
2948    }
2949
2950  /* Draw textured surface */
2951  pm = gdk_pixmap_new (window, 8, 3, -1);
2952
2953  gdk_draw_rectangle (pm, lightgc, TRUE, 0, 0, 8, 3);
2954  gdk_draw_point (pm, whitegc, 3, 0);
2955  gdk_draw_point (pm, whitegc, 0, 1);
2956  gdk_draw_point (pm, blackgc, 4, 1);
2957  gdk_draw_point (pm, blackgc, 1, 2);
2958
2959  values.fill = GDK_TILED;
2960  values.ts_x_origin = x + 2;   /*5; */
2961  values.ts_y_origin = y + 2;   /*3; */
2962  fillgc = gdk_gc_new_with_values (window, &values,
2963                                   GDK_GC_FILL | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
2964
2965  /* Set Clip Region */
2966  if (area)
2967    {
2968      gdk_gc_set_clip_rectangle (lightgc, area);
2969      gdk_gc_set_clip_rectangle (midgc, area);
2970      gdk_gc_set_clip_rectangle (darkgc, area);
2971      gdk_gc_set_clip_rectangle (whitegc, area);
2972      gdk_gc_set_clip_rectangle (blackgc, area);
2973    }
2974
2975  /* Draw backgound */
2976  gdk_draw_rectangle (window, lightgc, TRUE, x, y, width, height);
2977
2978  /* Draw border */
2979  gdk_draw_rectangle (window, whitegc, FALSE, x + 1, y + 1, width - 2,
2980                      height - 2);
2981  gdk_draw_rectangle (window, darkgc, FALSE, x + 0, y + 0, width - 2, height
2982                      - 2);
2983
2984  if (area)
2985    gdk_gc_set_clip_rectangle (fillgc, area);
2986  gdk_gc_set_tile (fillgc, pm);
2987  gdk_draw_rectangle (window, fillgc, TRUE, x + 2, y + 2, width - 4, height
2988                      - 4);
2989
2990  gdk_gc_unref (fillgc);
2991  gdk_pixmap_unref (pm);
2992
2993  /* Reset Clip Region */
2994  if (area)
2995    {
2996      gdk_gc_set_clip_rectangle (lightgc, NULL);
2997      gdk_gc_set_clip_rectangle (midgc, NULL);
2998      gdk_gc_set_clip_rectangle (darkgc, NULL);
2999      gdk_gc_set_clip_rectangle (whitegc, NULL);
3000      gdk_gc_set_clip_rectangle (blackgc, NULL);
3001    }
3002}
3003
3004static void
3005shade (GdkColor * oldcolor, GdkColor * newcolor, float mult)
3006{
3007  newcolor->red = oldcolor->red * mult;
3008  newcolor->green = oldcolor->green * mult;
3009  newcolor->blue = oldcolor->blue * mult;
3010}
3011
3012static void
3013metal_style_init_from_rc (GtkStyle * style,
3014                          GtkRcStyle * rc_style)
3015{
3016  MetalStyle *metal_style = METAL_STYLE (style);
3017
3018  parent_class->init_from_rc (style, rc_style);
3019
3020  /* Light Gray */
3021  shade (&style->white, &metal_style->light_gray, 0.8);
3022  shade (&style->white, &metal_style->mid_gray, 0.6);
3023  shade (&style->white, &metal_style->dark_gray, 0.4);
3024}
3025
3026static GdkGC *
3027realize_color (GtkStyle * style,
3028               GdkColor * color)
3029{
3030  GdkGCValues gc_values;
3031
3032  gdk_colormap_alloc_color (style->colormap, color,
3033                            FALSE, TRUE);
3034
3035  gc_values.foreground = *color;
3036
3037  return gtk_gc_get (style->depth, style->colormap,
3038                     &gc_values, GDK_GC_FOREGROUND);
3039}
3040
3041static void
3042metal_style_realize (GtkStyle * style)
3043{
3044  MetalStyle *metal_style = METAL_STYLE (style);
3045
3046  parent_class->realize (style);
3047
3048  metal_style->light_gray_gc = realize_color (style, &metal_style->light_gray);
3049  metal_style->mid_gray_gc = realize_color (style, &metal_style->mid_gray);
3050  metal_style->dark_gray_gc = realize_color (style, &metal_style->dark_gray);
3051}
3052
3053static void
3054metal_style_unrealize (GtkStyle * style)
3055{
3056  MetalStyle *metal_style = METAL_STYLE (style);
3057
3058  /* We don't free the colors, because we don't know if
3059   * gtk_gc_release() actually freed the GC. FIXME - need
3060   * a way of ref'ing colors explicitely so GtkGC can
3061   * handle things properly.
3062   */
3063  gtk_gc_release (metal_style->light_gray_gc);
3064  gtk_gc_release (metal_style->mid_gray_gc);
3065  gtk_gc_release (metal_style->dark_gray_gc);
3066
3067  parent_class->unrealize (style);
3068}
3069
3070static void
3071metal_style_init (MetalStyle * style)
3072{
3073}
3074
3075static void
3076metal_style_class_init (MetalStyleClass * klass)
3077{
3078  GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3079
3080  parent_class = g_type_class_peek_parent (klass);
3081
3082  style_class->realize = metal_style_realize;
3083  style_class->unrealize = metal_style_unrealize;
3084  style_class->init_from_rc = metal_style_init_from_rc;
3085
3086  style_class->draw_hline = draw_hline;
3087  style_class->draw_vline = draw_vline;
3088  style_class->draw_shadow = draw_shadow;
3089  style_class->draw_polygon = draw_polygon;
3090  style_class->draw_arrow = draw_arrow;
3091  style_class->draw_diamond = draw_diamond;
3092  style_class->draw_string = draw_string;
3093  style_class->draw_box = draw_box;
3094  style_class->draw_check = draw_check;
3095  style_class->draw_option = draw_option;
3096  style_class->draw_tab = draw_tab;
3097  style_class->draw_shadow_gap = draw_shadow_gap;
3098  style_class->draw_box_gap = draw_box_gap;
3099  style_class->draw_extension = draw_extension;
3100  style_class->draw_focus = draw_focus;
3101  style_class->draw_slider = draw_slider;
3102  style_class->draw_handle = draw_handle;
3103}
3104
3105GType metal_type_style = 0;
3106
3107void
3108metal_style_register_type (GTypeModule * module)
3109{
3110  static const GTypeInfo object_info =
3111  {
3112    sizeof (MetalStyleClass),
3113    (GBaseInitFunc) NULL,
3114    (GBaseFinalizeFunc) NULL,
3115    (GClassInitFunc) metal_style_class_init,
3116    NULL,                       /* class_finalize */
3117    NULL,                       /* class_data */
3118    sizeof (MetalStyle),
3119    0,                          /* n_preallocs */
3120    (GInstanceInitFunc) metal_style_init,
3121  };
3122
3123  metal_type_style = g_type_module_register_type (module,
3124                                                  GTK_TYPE_STYLE,
3125                                                  "MetalStyle",
3126                                                  &object_info, 0);
3127}
Note: See TracBrowser for help on using the repository browser.