fix crash when copy'ing latent plugins
[ardour.git] / libs / clearlooks-older / clearlooks_style.c
1 #include <gtk/gtk.h>
2
3 #include "clearlooks_style.h"
4 #include "clearlooks_rc_style.h"
5 #include "clearlooks_draw.h"
6
7 #include <math.h>
8 #include <string.h>
9
10 #include "bits.c"
11 #include "support.h"
12 //#include "config.h"
13
14 /* #define DEBUG 1 */
15
16 #define SCALE_SIZE 5
17
18 #define DETAIL(xx)   ((detail) && (!strcmp(xx, detail)))
19 #define COMPARE_COLORS(a,b) (a.red == b.red && a.green == b.green && a.blue == b.blue)
20
21 #define DRAW_ARGS    GtkStyle       *style, \
22                      GdkWindow      *window, \
23                      GtkStateType    state_type, \
24                      GtkShadowType   shadow_type, \
25                      GdkRectangle   *area, \
26                      GtkWidget      *widget, \
27                      const gchar    *detail, \
28                      gint            x, \
29                      gint            y, \
30                      gint            width, \
31                      gint            height
32
33 static GdkGC *realize_color (GtkStyle * style, GdkColor * color);
34 static GtkStyleClass *parent_class;
35 static GList *progressbars = NULL;
36 static gint8 pboffset = 10;
37 static int timer_id = 0;
38
39 static void cl_progressbar_remove (gpointer data)
40 {
41         if (g_list_find (progressbars, data) == NULL)
42                 return;
43
44         progressbars = g_list_remove (progressbars, data);
45         g_object_unref (data);
46
47         if (g_list_first(progressbars) == NULL) {
48                 g_source_remove(timer_id);
49                 timer_id = 0;
50         }
51 }
52
53 static void update_progressbar (gpointer data, gpointer user_data)
54 {
55         gfloat fraction;
56
57         if (data == NULL)
58                 return;
59
60         fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (data));
61
62         /* update only if not filled */
63         if (fraction < 1.0)
64                 gtk_widget_queue_resize ((GtkWidget*)data);
65
66         if (fraction >= 1.0 || GTK_PROGRESS (data)->activity_mode)
67                 cl_progressbar_remove (data);
68 }
69
70 static gboolean timer_func (gpointer data)
71 {
72         g_list_foreach (progressbars, update_progressbar, NULL);
73         if (--pboffset < 0) pboffset = 9;
74         return (g_list_first(progressbars) != NULL);
75 }
76
77 static gboolean cl_progressbar_known(gconstpointer data)
78 {
79         return (g_list_find (progressbars, data) != NULL);
80 }
81
82
83 static void cl_progressbar_add (gpointer data)
84 {
85         if (!GTK_IS_PROGRESS_BAR (data))
86                 return;
87
88         progressbars = g_list_append (progressbars, data);
89
90         g_object_ref (data);
91         g_signal_connect ((GObject*)data, "unrealize", G_CALLBACK (cl_progressbar_remove), data);
92
93         if (timer_id == 0)
94                 timer_id = g_timeout_add (100, timer_func, NULL);
95 }
96
97 static GdkColor *
98 clearlooks_get_spot_color (ClearlooksRcStyle *clearlooks_rc)
99 {
100         GtkRcStyle *rc = GTK_RC_STYLE (clearlooks_rc);
101
102         if (clearlooks_rc->has_spot_color)
103                 return &clearlooks_rc->spot_color;
104         else
105                 return &rc->base[GTK_STATE_SELECTED];
106 }
107
108 /**************************************************************************/
109
110 /* used for optionmenus... */
111 static void
112 draw_tab (GtkStyle      *style,
113           GdkWindow     *window,
114           GtkStateType   state_type,
115           GtkShadowType  shadow_type,
116           GdkRectangle  *area,
117           GtkWidget     *widget,
118           const gchar   *detail,
119           gint           x,
120           gint           y,
121           gint           width,
122           gint           height)
123 {
124 #define ARROW_SPACE 2
125 #define ARROW_LINE_HEIGHT 2
126 #define ARROW_LINE_WIDTH 5
127         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
128         GtkRequisition indicator_size;
129         GtkBorder indicator_spacing;
130         gint arrow_height;
131
132         option_menu_get_props (widget, &indicator_size, &indicator_spacing);
133
134         indicator_size.width += (indicator_size.width % 2) - 1;
135         arrow_height = indicator_size.width / 2 + 2;
136
137         x += (width - indicator_size.width) / 2;
138         y += height/2;
139
140         if (state_type == GTK_STATE_INSENSITIVE)
141         {
142                 draw_arrow (window, style->light_gc[state_type], area,
143                             GTK_ARROW_UP, 1+x, 1+y-arrow_height,
144                             indicator_size.width, arrow_height);
145
146                 draw_arrow (window, style->light_gc[state_type], area,
147                             GTK_ARROW_DOWN, 1+x, 1+y+1,
148                             indicator_size.width, arrow_height);
149         }
150
151         draw_arrow (window, style->fg_gc[state_type], area,
152                     GTK_ARROW_UP, x, y-arrow_height,
153                     indicator_size.width, arrow_height);
154
155         draw_arrow (window, style->fg_gc[state_type], area,
156                     GTK_ARROW_DOWN, x, y+1,
157                     indicator_size.width, arrow_height);
158 }
159
160 static void
161 clearlooks_draw_arrow (GtkStyle      *style,
162                        GdkWindow     *window,
163                        GtkStateType   state,
164                        GtkShadowType  shadow,
165                        GdkRectangle  *area,
166                        GtkWidget     *widget,
167                        const gchar   *detail,
168                        GtkArrowType   arrow_type,
169                        gboolean       fill,
170                        gint           x,
171                        gint           y,
172                        gint           width,
173                        gint           height)
174 {
175         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
176         gint original_width, original_x;
177         GdkGC *gc;
178
179         sanitize_size (window, &width, &height);
180
181         if (is_combo_box (widget))
182         {
183                 width = 7;
184                 height = 5;
185                 x+=2;
186                 y+=4;
187                 if (state == GTK_STATE_INSENSITIVE)
188                 {
189                         draw_arrow (window, style->light_gc[state], area,
190                                     GTK_ARROW_UP, 1+x, 1+y-height,
191                                     width, height);
192
193                         draw_arrow (window, style->light_gc[state], area,
194                                     GTK_ARROW_DOWN, 1+x, 1+y+1,
195                                     width, height);
196                 }
197
198                 draw_arrow (window, style->fg_gc[state], area,
199                             GTK_ARROW_UP, x, y-height,
200                             width, height);
201
202                 draw_arrow (window, style->fg_gc[state], area,
203                             GTK_ARROW_DOWN, x, y+1,
204                             width, height);
205
206                 return;
207         }
208
209         original_width = width;
210         original_x = x;
211
212         /* Make spinbutton arrows and arrows in menus
213         * slightly larger to get the right pixels drawn */
214         if (DETAIL ("spinbutton"))
215                 height += 1;
216
217         if (DETAIL("menuitem"))
218         {
219                 width = 6;
220                 height = 7;
221         }
222
223         /* Compensate arrow position for "sunken" look */
224         if (DETAIL ("spinbutton") && arrow_type == GTK_ARROW_DOWN &&
225             style->xthickness > 2 && style->ythickness > 2)
226                         y -= 1;
227
228         if (widget && widget->parent && GTK_IS_COMBO (widget->parent->parent))
229         {
230                 width -= 2;
231                 height -=2;
232                 x++;
233         }
234
235         calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
236
237         if (DETAIL ("menuitem"))
238                 x = original_x + original_width - width;
239
240         if (DETAIL ("spinbutton") && (arrow_type == GTK_ARROW_DOWN))
241                 y += 1;
242
243         if (state == GTK_STATE_INSENSITIVE)
244                 draw_arrow (window, style->light_gc[state], area, arrow_type, x + 1, y + 1, width, height);
245
246         gc = style->fg_gc[state];
247
248         draw_arrow (window, gc, area, arrow_type, x, y, width, height);
249 }
250
251
252 static void
253 draw_flat_box (DRAW_ARGS)
254 {
255         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
256
257         g_return_if_fail (GTK_IS_STYLE (style));
258         g_return_if_fail (window != NULL);
259
260         sanitize_size (window, &width, &height);
261
262         if (detail &&
263             clearlooks_style->listviewitemstyle == 1 &&
264             state_type == GTK_STATE_SELECTED && (
265             !strncmp ("cell_even", detail, strlen ("cell_even")) ||
266             !strncmp ("cell_odd", detail, strlen ("cell_odd"))))
267         {
268                 GdkGC    *gc;
269                 GdkColor  lower_color;
270                 GdkColor *upper_color;
271
272                 if (GTK_WIDGET_HAS_FOCUS (widget))
273                 {
274                         gc = style->base_gc[state_type];
275                         upper_color = &style->base[state_type];
276                 }
277                 else
278                 {
279                         gc = style->base_gc[GTK_STATE_ACTIVE];
280                         upper_color = &style->base[GTK_STATE_ACTIVE];
281                 }
282
283                 if (GTK_IS_TREE_VIEW (widget) && 0)
284                 {
285                         GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
286
287                         if (gtk_tree_selection_count_selected_rows (sel) > 1)
288                         {
289                                 parent_class->draw_flat_box (style, window, state_type, shadow_type,
290                                                              area, widget, detail,
291                                                              x, y, width, height);
292                                 return;
293                         }
294                 }
295
296                 shade (upper_color, &lower_color, 0.8);
297
298                 if (area)
299                         gdk_gc_set_clip_rectangle (gc, area);
300
301                 draw_hgradient (window, gc, style,
302                                 x, y, width, height, upper_color, &lower_color);
303
304                 if (area)
305                         gdk_gc_set_clip_rectangle (gc, NULL);
306         }
307         else
308         {
309                 parent_class->draw_flat_box (style, window, state_type,
310                                              shadow_type,
311                                              area, widget, detail,
312                                              x, y, width, height);
313         }
314 }
315 /**************************************************************************/
316
317 static void
318 draw_shadow (DRAW_ARGS)
319 {
320         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
321         CLRectangle r;
322
323         GdkGC *outer_gc = clearlooks_style->shade_gc[4];
324         GdkGC *gc1 = NULL;
325         GdkGC *gc2 = NULL;
326         gint thickness_light;
327         gint thickness_dark;
328         gboolean interior_focus = FALSE;
329
330 #if DEBUG
331                 printf("draw_shadow: %s %d %d %d %d\n", detail, x, y, width, height);
332 #endif
333
334         if (widget == NULL)
335         {
336                 gdk_draw_rectangle (window, outer_gc, FALSE,
337                                     x, y, width - 1, height - 1);
338                 return;
339         }
340
341         if ((width == -1) && (height == -1))
342                 gdk_window_get_size (window, &width, &height);
343         else if (width == -1)
344                 gdk_window_get_size (window, &width, NULL);
345         else if (height == -1)
346                 gdk_window_get_size (window, NULL, &height);
347
348         cl_rectangle_reset (&r, style);
349
350         if (DETAIL ("frame") && widget->parent &&
351             GTK_IS_STATUSBAR (widget->parent))
352         {
353                 gtk_style_apply_default_background (style, window,widget && !GTK_WIDGET_NO_WINDOW (widget),
354                                                     state_type, area, x, y, width, height);
355
356                 if (area)
357                 {
358                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area);
359                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area);
360                 }
361
362                 gdk_draw_line (window, clearlooks_style->shade_gc[3],
363                                x, y, x + width, y);
364                 gdk_draw_line (window, clearlooks_style->shade_gc[0],
365                                x, y + 1, x + width, y + 1);
366
367                 if (area)
368                 {
369                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL);
370                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL);
371                 }
372         }
373         else if (detail && !strcmp (detail, "entry"))
374         {
375                 if ( widget->parent && (GTK_IS_COMBO_BOX_ENTRY (widget->parent) ||
376                                         GTK_IS_SPIN_BUTTON(widget) ||
377                                         GTK_IS_COMBO (widget->parent)))
378                 {
379                         cl_draw_combobox_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height);
380                 }
381                 else
382                 {
383                         cl_draw_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height);
384                 }
385         }
386         else if (DETAIL ("viewport") || DETAIL ("scrolled_window"))
387         {
388                 gdk_draw_rectangle (window, clearlooks_style->shade_gc[4], FALSE,
389                                     x, y, width - 1, height - 1);
390         }
391         else
392         {
393                 if (DETAIL ("menuitem"))
394                         outer_gc = clearlooks_style->spot3_gc;
395                 else
396                         outer_gc = clearlooks_style->shade_gc[4];
397
398                 if (shadow_type == GTK_SHADOW_IN)
399                         gdk_draw_rectangle (window, outer_gc, FALSE,
400                                             x, y, width - 1, height - 1);
401                 else if (shadow_type == GTK_SHADOW_OUT)
402                 {
403                         gdk_draw_rectangle (window, outer_gc, FALSE,
404                                             x, y, width - 1, height - 1);
405                         gdk_draw_line (window, style->light_gc[state_type],
406                                        x+1, y+1, x+width-2, y+1);
407                         gdk_draw_line (window, style->light_gc[state_type],
408                                        x+1, y+1, x+1, y+height-2);
409                 }
410                 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
411                 {
412                         GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3];
413                         GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0];
414
415                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
416                                                       CL_CORNER_NONE, CL_CORNER_NONE);
417
418                         r.bordergc = a;
419                         cl_rectangle_set_clip_rectangle (&r, area);
420                         cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r);
421                         cl_rectangle_reset_clip_rectangle (&r);
422
423                         r.bordergc = b;
424                         cl_rectangle_set_clip_rectangle (&r, area);
425                         cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r);
426                         cl_rectangle_reset_clip_rectangle (&r);
427                 }
428                 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
429                 {
430                         GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0];
431                         GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3];
432
433                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
434                                                       CL_CORNER_NONE, CL_CORNER_NONE);
435
436                         r.bordergc = a;
437                         cl_rectangle_set_clip_rectangle (&r, area);
438                         cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r);
439                         cl_rectangle_reset_clip_rectangle (&r);
440
441                         r.bordergc = b;
442                         cl_rectangle_set_clip_rectangle (&r, area);
443                         cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r);
444                         cl_rectangle_reset_clip_rectangle (&r);
445                 }
446                 else
447                         parent_class->draw_shadow (style, window, state_type, shadow_type,
448                                                    area, widget, detail,
449                                                    x, y, width, height);
450         }
451 }
452
453 #define GDK_RECTANGLE_SET(rect,a,b,c,d) rect.x = a; \
454                                         rect.y = b; \
455                                         rect.width = c; \
456                                         rect.height = d;
457
458
459 static void
460 draw_box_gap (DRAW_ARGS,
461               GtkPositionType gap_side,
462               gint            gap_x,
463               gint            gap_width)
464 {
465         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
466         CLRectangle r;
467
468         GdkRegion *area_region = NULL,
469                   *gap_region  = NULL;
470         GdkRectangle light_rect;
471         GdkRectangle dark_rect;
472
473 #if DEBUG
474                 printf("draw_box_gap: %s %d %d %d %d\n", detail, x, y, width, height);
475 #endif
476
477         g_return_if_fail (GTK_IS_STYLE (style));
478         g_return_if_fail (window != NULL);
479
480         sanitize_size (window, &width, &height);
481
482         cl_rectangle_reset (&r, style);
483
484         r.bordergc = clearlooks_style->shade_gc[5];
485
486         r.topleft     = style->light_gc[state_type];
487         r.bottomright = clearlooks_style->shade_gc[1];
488
489         if (area)
490                 area_region = gdk_region_rectangle (area);
491         else
492         {
493                 GdkRectangle tmp = { x, y, width, height };
494                 area_region = gdk_region_rectangle (&tmp);
495         }
496
497         switch (gap_side)
498         {
499                 case GTK_POS_TOP:
500                 {
501                         GdkRectangle rect = { x+gap_x+1, y, gap_width-2, 2 };
502                         gap_region = gdk_region_rectangle (&rect);
503
504                         GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y, x+gap_x+1, y+1);
505                         GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y, x+gap_x+gap_width-2, y);
506
507                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
508                                                       CL_CORNER_ROUND, CL_CORNER_ROUND);
509
510                         break;
511                 }
512                 case GTK_POS_BOTTOM:
513                 {
514                         GdkRectangle rect = { x+gap_x+1, y+height-2, gap_width-2, 2 };
515                         gap_region = gdk_region_rectangle (&rect);
516
517                         GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y+height-2, x+gap_x+1, y+height-1);
518                         GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y+height-2, x+gap_x+gap_width-2, y+height-1);
519
520                         cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND,
521                                                       CL_CORNER_NONE, CL_CORNER_NONE);
522
523                         break;
524                 }
525                 case GTK_POS_LEFT:
526                 {
527                         GdkRectangle rect = { x, y+gap_x+1, 2, gap_width-2 };
528                         gap_region = gdk_region_rectangle (&rect);
529
530                         GDK_RECTANGLE_SET (light_rect, x, y+gap_x+1, x+1, y+gap_x+1);
531                         GDK_RECTANGLE_SET (dark_rect, x, y+gap_x+gap_width-2, x, y+gap_x+gap_width-2);
532
533                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND,
534                                                       CL_CORNER_NONE, CL_CORNER_ROUND);
535                         break;
536                 }
537                 case GTK_POS_RIGHT:
538                 {
539                         GdkRectangle rect = { x+width-2, y+gap_x+1, 2, gap_width-2 };
540                         gap_region = gdk_region_rectangle (&rect);
541
542                         GDK_RECTANGLE_SET (light_rect, x+width-2, y+gap_x+1, x+width-1, y+gap_x+1);
543                         GDK_RECTANGLE_SET (dark_rect, x+width-2, y+gap_x+gap_width-2, x+width-1, y+gap_x+gap_width-2);
544
545                         cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE,
546                                                       CL_CORNER_ROUND, CL_CORNER_NONE);
547                         break;
548                 }
549         }
550
551         gdk_region_subtract (area_region, gap_region);
552
553         gdk_gc_set_clip_region (r.bordergc,    area_region);
554         gdk_gc_set_clip_region (r.topleft,     area_region);
555         gdk_gc_set_clip_region (r.bottomright, area_region);
556
557         gdk_region_destroy (area_region);
558         gdk_region_destroy (gap_region);
559
560         gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE, x, y, width, height);
561
562         cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
563
564         cl_draw_shadow (window, widget, style, x, y, width, height, &r);
565
566         gdk_gc_set_clip_region (r.bordergc,    NULL);
567         gdk_gc_set_clip_region (r.topleft,     NULL);
568         gdk_gc_set_clip_region (r.bottomright, NULL);
569
570         /* it's a semi hack */
571         gdk_draw_line (window, style->light_gc[state_type],
572                        light_rect.x, light_rect.y,
573                        light_rect.width, light_rect.height);
574
575         gdk_draw_line (window, clearlooks_style->shade_gc[1],
576                        dark_rect.x, dark_rect.y,
577                        dark_rect.width, dark_rect.height);
578 }
579
580 /**************************************************************************/
581
582 static void
583 draw_extension (DRAW_ARGS, GtkPositionType gap_side)
584 {
585         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
586         int              my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0;
587         CLRectangle      r;
588
589 #if DEBUG
590                 printf("draw_extension: %s %d %d %d %d\n", detail, x, y, width, height);
591 #endif
592
593         g_return_if_fail (GTK_IS_STYLE (style));
594         g_return_if_fail (window != NULL);
595
596         sanitize_size (window, &width, &height);
597
598         if (DETAIL ("tab"))
599         {
600                 GdkRectangle new_area;
601                 GdkColor tmp_color;
602
603                 cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE,
604                                                                 CL_CORNER_ROUND, CL_CORNER_ROUND,
605                                                                 CL_CORNER_ROUND, CL_CORNER_ROUND);
606
607                 if (state_type == GTK_STATE_ACTIVE)
608                         shade (&style->bg[state_type], &tmp_color, 1.08);
609                 else
610                         shade (&style->bg[state_type], &tmp_color, 1.05);
611
612                 if (area)
613                 {
614                         new_area = *area;
615                 }
616                 else
617                 {
618                         new_area.x = x;
619                         new_area.y = y;
620                         new_area.width = width;
621                         new_area.height = height;
622                 }
623
624                 switch (gap_side)
625                 {
626                         case GTK_POS_BOTTOM:
627                                 height+=2;
628                                 new_area.y = y;
629                                 new_area.height = height-2;
630                                 r.gradient_type = CL_GRADIENT_VERTICAL;
631                                 cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]);
632                                 cl_rectangle_set_gradient (&r.border_gradient,
633                                                &clearlooks_style->border[CL_BORDER_UPPER+my_state_type],
634                                                &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]);
635                                 break;
636                         case GTK_POS_TOP:
637                                 y-=2;
638                                 height+=2;
639                                 new_area.y = y+2;
640                                 new_area.height = height;
641                                 r.gradient_type = CL_GRADIENT_VERTICAL;
642                                 cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color);
643                                 cl_rectangle_set_gradient (&r.border_gradient,
644                                                &clearlooks_style->border[CL_BORDER_LOWER+my_state_type],
645                                                &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]);
646                                 break;
647                         case GTK_POS_LEFT:
648                                 x-=2;
649                                 width+=2;
650                                 new_area.x = x+2;
651                                 new_area.width = width;
652                                 r.gradient_type = CL_GRADIENT_HORIZONTAL;
653                                 cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color);
654                                 cl_rectangle_set_gradient (&r.border_gradient,
655                                                &clearlooks_style->border[CL_BORDER_LOWER+my_state_type],
656                                                &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]);
657                                 break;
658                         case GTK_POS_RIGHT:
659                                 width+=2;
660                                 new_area.x = x;
661                                 new_area.width = width-2;
662                                 r.gradient_type = CL_GRADIENT_HORIZONTAL;
663                                 cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]);
664                                 cl_rectangle_set_gradient (&r.border_gradient,
665                                                &clearlooks_style->border[CL_BORDER_UPPER+my_state_type],
666                                                &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]);
667                                 break;
668                 }
669
670                 r.topleft = style->light_gc[state_type];
671                 r.bottomright = (state_type == GTK_STATE_NORMAL) ? clearlooks_style->shade_gc[1] : NULL;
672
673                 cl_rectangle_set_clip_rectangle (&r, &new_area);
674                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
675                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
676                 cl_rectangle_reset_clip_rectangle (&r);
677
678                 /* draw the selection stripe */
679                 if (state_type != GTK_STATE_ACTIVE) {
680                         cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL);
681                         r.fillgc = clearlooks_style->spot2_gc;
682
683                         switch (gap_side)
684                         {
685                                 case GTK_POS_BOTTOM:
686                                         cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND,
687                                                                       CL_CORNER_NONE, CL_CORNER_NONE);
688                                         cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2);
689                                         r.gradient_type = CL_GRADIENT_VERTICAL;
690
691                                         cl_rectangle_set_clip_rectangle (&r, &new_area);
692                                         cl_draw_rectangle (window, widget, style, x, y, width, 3, &r);
693                                         cl_rectangle_reset_clip_rectangle (&r);
694                                         break;
695                                 case GTK_POS_TOP:
696                                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
697                                                                       CL_CORNER_ROUND, CL_CORNER_ROUND);
698                                         cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3);
699                                         r.gradient_type = CL_GRADIENT_VERTICAL;
700
701                                         cl_rectangle_set_clip_rectangle (&r, &new_area);
702                                         cl_draw_rectangle (window, widget, style, x, y + height - 3, width, 3, &r);
703                                         cl_rectangle_reset_clip_rectangle (&r);
704                                         break;
705                                 case GTK_POS_LEFT:
706                                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND,
707                                                                       CL_CORNER_NONE, CL_CORNER_ROUND);
708                                         cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3);
709                                         r.gradient_type = CL_GRADIENT_HORIZONTAL;
710
711                                         cl_rectangle_set_clip_rectangle (&r, &new_area);
712                                         cl_draw_rectangle (window, widget, style, x + width - 3, y, 3, height, &r);
713                                         cl_rectangle_reset_clip_rectangle (&r);
714                                         break;
715                                 case GTK_POS_RIGHT:
716                                         cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE,
717                                                                       CL_CORNER_ROUND, CL_CORNER_NONE);
718                                         cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2);
719                                         r.gradient_type = CL_GRADIENT_HORIZONTAL;
720
721                                         cl_rectangle_set_clip_rectangle (&r, &new_area);
722                                         cl_draw_rectangle (window, widget, style, x, y, 3, height, &r);
723                                         cl_rectangle_reset_clip_rectangle (&r);
724                                         break;
725                         }
726                 }
727
728
729         }
730         else
731         {
732                 parent_class->draw_extension (style, window, state_type, shadow_type, area,
733                                               widget, detail, x, y, width, height,
734                                               gap_side);
735         }
736 }
737
738
739 /**************************************************************************/
740
741 static void
742 draw_handle (DRAW_ARGS, GtkOrientation orientation)
743 {
744         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
745         gint xx, yy;
746         gint xthick, ythick;
747         GdkGC *light_gc, *dark_gc;
748         GdkRectangle rect;
749         GdkRectangle dest;
750         gint intersect;
751         gint h;
752         int i;
753         int n_lines;
754         int offset;
755
756 #if DEBUG
757                 printf("draw_handle: %s %d %d %d %d\n", detail, x, y, width, height);
758 #endif
759
760         g_return_if_fail (GTK_IS_STYLE (style));
761         g_return_if_fail (window != NULL);
762
763         sanitize_size (window, &width, &height);
764
765         if (state_type == GTK_STATE_PRELIGHT)
766                 gtk_style_apply_default_background (style, window,
767                                           widget && !GTK_WIDGET_NO_WINDOW (widget),
768                                           state_type, area, x, y, width, height);
769
770         /* orientation is totally bugged, but this actually works... */
771         orientation = (width > height) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
772
773         if (!strcmp (detail, "paned"))
774         {
775                 /* we want to ignore the shadow border in paned widgets */
776                 xthick = 0;
777                 ythick = 0;
778         }
779         else
780         {
781                 xthick = style->xthickness;
782                 ythick = style->ythickness;
783         }
784
785         if ( ((DETAIL ("handlebox") && widget && GTK_IS_HANDLE_BOX (widget)) || DETAIL ("dockitem")) &&
786              orientation == GTK_ORIENTATION_VERTICAL )
787         {
788                 /* The line in the toolbar */
789
790                 light_gc = style->light_gc[state_type];
791                 dark_gc = clearlooks_style->shade_gc[3];
792
793                 if (area)
794                 {
795                         gdk_gc_set_clip_rectangle (light_gc, area);
796                         gdk_gc_set_clip_rectangle (dark_gc, area);
797                 }
798
799                 if (area)
800                 {
801                         gdk_gc_set_clip_rectangle (light_gc, NULL);
802                         gdk_gc_set_clip_rectangle (dark_gc, NULL);
803                 }
804
805                 if (area)
806                 {
807                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area);
808                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area);
809                 }
810
811                 gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y, x + width, y);
812                 gdk_draw_line (window, clearlooks_style->shade_gc[3], x, y + height - 1, x + width, y + height - 1);
813
814                 if (area)
815                 {
816                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL);
817                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL);
818                 }
819         }
820
821         light_gc = clearlooks_style->shade_gc[0];
822         dark_gc = clearlooks_style->shade_gc[4];
823
824         rect.x = x + xthick;
825         rect.y = y + ythick;
826         rect.width = width - (xthick * 2);
827         rect.height = height - (ythick * 2);
828
829         if (area)
830                 intersect = gdk_rectangle_intersect (area, &rect, &dest);
831         else
832         {
833                 intersect = TRUE;
834                 dest = rect;
835         }
836
837         if (!intersect)
838                 return;
839
840         gdk_gc_set_clip_rectangle (light_gc, &dest);
841         gdk_gc_set_clip_rectangle (dark_gc, &dest);
842
843         n_lines = (!strcmp (detail, "paned")) ? 21 : 11;
844
845         if (orientation == GTK_ORIENTATION_VERTICAL)
846         {
847                 h = width - 2 * xthick;
848                 h = MAX (3, h - 6);
849
850                 xx = x + (width - h) / 2;
851                 offset = (height - 2*ythick - 2*n_lines)/2 + 1;
852                 if (offset < 0)
853                         offset = 0;
854
855                 for (i = 0, yy = y + ythick + offset; yy <= (y + height - ythick - 1) && i < n_lines; yy += 2, i++)
856                 {
857                         gdk_draw_line (window, dark_gc, xx, yy, xx + h, yy);
858                         gdk_draw_line (window, light_gc, xx, yy + 1, xx + h, yy + 1);
859                 }
860         }
861         else
862         {
863                 h = height - 2 * ythick;
864                 h = MAX (3, h - 6);
865
866                 yy = y + (height - h) / 2;
867                 offset = (width - 2*xthick - 2*n_lines)/2 + 1;
868                 if (offset < 0)
869                         offset = 0;
870
871                 for (i = 0, xx = x + xthick + offset;  i < n_lines; xx += 2, i++)
872                 {
873                         gdk_draw_line (window, dark_gc, xx, yy, xx, yy + h);
874                         gdk_draw_line (window, light_gc, xx + 1, yy, xx + 1, yy + h);
875                 }
876         }
877
878         gdk_gc_set_clip_rectangle (light_gc, NULL);
879         gdk_gc_set_clip_rectangle (dark_gc, NULL);
880 }
881
882 /**************************************************************************/
883
884 static void
885 draw_box (DRAW_ARGS)
886 {
887         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
888         CLRectangle r;
889         gboolean false_size = FALSE;
890
891 #ifdef DEBUG
892                 printf("draw_box: %s %d %d %d %d\n", detail, x, y, width, height);
893 #endif
894
895         g_return_if_fail (style != NULL);
896         g_return_if_fail (window != NULL);
897
898         if (width == -1 || height == -1)
899                 false_size = TRUE;
900
901         if ((width == -1) && (height == -1))
902                 gdk_window_get_size (window, &width, &height);
903         else if (width == -1)
904                 gdk_window_get_size (window, &width, NULL);
905         else if (height == -1)
906                 gdk_window_get_size (window, NULL, &height);
907
908         cl_rectangle_reset (&r, style);
909
910         if (widget == NULL)
911                 return;
912
913         /* listview headers */
914         if (widget && DETAIL ("button") && widget->parent &&
915                  (GTK_IS_TREE_VIEW(widget->parent) ||
916                   GTK_IS_CLIST (widget->parent) ||
917                           strcmp(G_OBJECT_TYPE_NAME (widget->parent), "ETree") == 0))
918         {
919                 cl_draw_treeview_header (style, window, state_type, shadow_type,
920                                          area, widget, detail, x, y, width, height);
921         }
922         else if (detail && (!strcmp (detail, "button") ||
923                                 !strcmp (detail, "buttondefault")))
924         {
925                 if (GTK_IS_COMBO_BOX_ENTRY(widget->parent) || GTK_IS_COMBO(widget->parent))
926                 {
927                         cl_draw_combobox_button (style, window, state_type, shadow_type,
928                                                  area, widget,
929                                              detail, x, y, width, height);
930                 }
931                 else
932                 {
933                         cl_draw_button (style, window, state_type, shadow_type, area, widget,
934                                     detail, x, y, width, height);
935                 }
936         }
937         else if (detail && (
938                  !strcmp (detail, "spinbutton_up") ||
939                  !strcmp (detail, "spinbutton_down") ||
940                  !strcmp (detail, "spinbutton")))
941         {
942                 cl_draw_spinbutton (style, window, state_type, shadow_type, area,
943                                     widget, detail, x, y, width, height);
944         }
945         else if (detail && (
946                      !strcmp (detail, "hscale") || !strcmp (detail, "vscale")))
947         {
948                 cl_rectangle_set_button (&r, style, state_type,
949                                 GTK_WIDGET_HAS_DEFAULT  (widget), GTK_WIDGET_HAS_FOCUS (widget),
950                                 CL_CORNER_ROUND, CL_CORNER_ROUND,
951                                 CL_CORNER_ROUND, CL_CORNER_ROUND);
952
953                 if (!strcmp (detail, "hscale") || !strcmp (detail, "vscale"))
954                 {
955                         r.fill_gradient.to = &clearlooks_style->shade[2];
956                         r.bottomright = clearlooks_style->shade_gc[2];
957                 }
958
959                 cl_set_corner_sharpness (detail, widget, &r);
960
961                 if (!strcmp (detail, "spinbutton_up"))
962                 {
963                         r.border_gradient.to = r.border_gradient.from;
964                         height++;
965                         gtk_style_apply_default_background (style, window, FALSE, state_type,
966                                                             area, x, y, width, height);
967                 }
968                 else if (!strcmp (detail, "spinbutton_down"))
969                 {
970                         r.border_gradient.to = r.border_gradient.from;
971                         gtk_style_apply_default_background (style, window, FALSE, state_type,
972                                                             area, x, y, width, height);
973                 }
974
975                 cl_rectangle_set_clip_rectangle (&r, area);
976                 cl_draw_rectangle (window, widget, style, x+1, y+1, width-2, height-2, &r);
977                 cl_draw_shadow (window, widget, style, x+1, y+1, width-2, height-2, &r);
978                 cl_rectangle_reset_clip_rectangle (&r);
979         }
980         else if (DETAIL ("trough") && GTK_IS_PROGRESS_BAR (widget))
981         {
982                 GdkPoint points[4] = { {x,y}, {x+width-1,y}, {x,y+height-1}, {x+width-1,y+height-1} };
983
984                 gdk_draw_points (window, style->bg_gc[state_type], points, 4);
985
986                 r.bordergc = clearlooks_style->shade_gc[5];
987                 r.fillgc   = clearlooks_style->shade_gc[2];
988
989                 cl_rectangle_set_corners (&r, CL_CORNER_NARROW, CL_CORNER_NARROW,
990                                                   CL_CORNER_NARROW, CL_CORNER_NARROW);
991
992                 cl_rectangle_set_clip_rectangle (&r, area);
993                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
994                 cl_rectangle_reset_clip_rectangle (&r);
995         }
996         else if (DETAIL ("trough") &&
997                      (GTK_IS_VSCALE (widget) || GTK_IS_HSCALE (widget)))
998         {
999                 GdkGC   *inner  = clearlooks_style->shade_gc[3],
1000                         *outer  = clearlooks_style->shade_gc[5],
1001                             *shadow = clearlooks_style->shade_gc[4];
1002                 GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)),
1003                                  lower_color;
1004
1005                 GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (widget));
1006
1007                 GtkOrientation orientation = GTK_RANGE (widget)->orientation;
1008
1009                 gint fill_size = (orientation ? height : width) *
1010                                  (1 / ((adjustment->upper - adjustment->lower) /
1011                                       (adjustment->value - adjustment->lower)));
1012
1013                 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1014                 {
1015                         y += (height - SCALE_SIZE) / 2;
1016                         height = SCALE_SIZE;
1017                 }
1018                 else
1019                 {
1020                         x += (width - SCALE_SIZE) / 2;
1021                         width = SCALE_SIZE;
1022                 }
1023
1024                 if (state_type == GTK_STATE_INSENSITIVE)
1025                 {
1026                         outer  = clearlooks_style->shade_gc[4];
1027                         inner  = clearlooks_style->shade_gc[2];
1028                         shadow = clearlooks_style->shade_gc[3];
1029                 }
1030
1031                 cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE,
1032                                                      CL_CORNER_NONE, CL_CORNER_NONE );
1033
1034                 r.topleft = shadow;
1035
1036                 cl_rectangle_set_clip_rectangle (&r, area);
1037                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1038                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1039                 cl_rectangle_reset_clip_rectangle (&r);
1040
1041                 /* DRAW FILL */
1042                 shade (&upper_color, &lower_color, 1.3);
1043
1044                 r.bordergc = clearlooks_style->spot3_gc;
1045                 r.fillgc   = style->bg_gc[state_type];
1046
1047                 r.gradient_type = (orientation == GTK_ORIENTATION_HORIZONTAL ) ? CL_GRADIENT_VERTICAL
1048                                                                                                                                            : CL_GRADIENT_HORIZONTAL;
1049
1050                 cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color);
1051
1052                 cl_rectangle_set_clip_rectangle (&r, area);
1053                 if (orientation == GTK_ORIENTATION_HORIZONTAL && fill_size > 1)
1054                 {
1055                         if (gtk_range_get_inverted(GTK_RANGE(widget)) != (get_direction(widget) == GTK_TEXT_DIR_RTL))
1056                                 cl_draw_rectangle (window, widget, style, x+width-fill_size, y, fill_size, height, &r);
1057                         else
1058                                 cl_draw_rectangle (window, widget, style, x, y, fill_size, height, &r);
1059                 }
1060                 else if (fill_size > 1)
1061                 {
1062                         if (gtk_range_get_inverted (GTK_RANGE (widget)))
1063                                 cl_draw_rectangle (window, widget, style, x, y+height-fill_size, width, fill_size, &r);
1064                         else
1065                                 cl_draw_rectangle (window, widget, style, x, y, width, fill_size, &r);
1066                 }
1067                 cl_rectangle_reset_clip_rectangle (&r);
1068         }
1069         else if (DETAIL ("trough"))
1070         {
1071                 GdkGC *inner  = clearlooks_style->shade_gc[3],
1072                       *outer  = clearlooks_style->shade_gc[5];
1073
1074                 cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE,
1075                                                      CL_CORNER_NONE, CL_CORNER_NONE );
1076
1077                 if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_VERTICAL)
1078                 {
1079                         y+=1;
1080                         height-=2;
1081                 }
1082                 else
1083                 {
1084                         x+=1;
1085                         width-=2;
1086                 }
1087
1088                 cl_rectangle_set_clip_rectangle (&r, area);
1089                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1090                 cl_rectangle_reset_clip_rectangle (&r);
1091         }
1092         else if (detail && (!strcmp (detail, "vscrollbar") ||
1093                             !strcmp (detail, "hscrollbar") ||
1094                             !strcmp (detail, "stepper")))
1095         {
1096                 ClScrollButtonType button_type = CL_SCROLLBUTTON_OTHER;
1097                 gboolean horizontal = TRUE;
1098
1099                 if (GTK_IS_VSCROLLBAR(widget))
1100                 {
1101                         if (y == widget->allocation.y)
1102                                 button_type = CL_SCROLLBUTTON_BEGIN;
1103                         else if (y+height == widget->allocation.y+widget->allocation.height)
1104                                 button_type = CL_SCROLLBUTTON_END;
1105
1106                         horizontal = FALSE;
1107                 }
1108                 else if (GTK_IS_HSCROLLBAR(widget))
1109                 {
1110                         if (x == widget->allocation.x)
1111                                 button_type = CL_SCROLLBUTTON_BEGIN;
1112                         else if (x+width == widget->allocation.x+widget->allocation.width)
1113                                 button_type = CL_SCROLLBUTTON_END;
1114                 }
1115
1116                 cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE, 0,0,0,0);
1117
1118                 cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL);
1119                 cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type],
1120                                            &clearlooks_style->inset_dark[state_type]);
1121
1122
1123                 r.gradient_type = horizontal ? CL_GRADIENT_VERTICAL
1124                                              : CL_GRADIENT_HORIZONTAL;
1125
1126                 r.bottomright = clearlooks_style->shade_gc[1];
1127                 r.border_gradient.to = r.border_gradient.from;
1128
1129                 if (button_type == CL_SCROLLBUTTON_OTHER)
1130                 {
1131                         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1132                                                       CL_CORNER_NONE, CL_CORNER_NONE);
1133                 }
1134                 else if (button_type == CL_SCROLLBUTTON_BEGIN)
1135                 {
1136                         if (horizontal)
1137                                 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE,
1138                                                                                           CL_CORNER_ROUND, CL_CORNER_NONE);
1139                         else
1140                                 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND,
1141                                                                                           CL_CORNER_NONE,  CL_CORNER_NONE);
1142                 }
1143                 else
1144                 {
1145                         if (horizontal)
1146                                 cl_rectangle_set_corners (&r, CL_CORNER_NONE,  CL_CORNER_ROUND,
1147                                                                                           CL_CORNER_NONE,  CL_CORNER_ROUND);
1148                         else
1149                                 cl_rectangle_set_corners (&r, CL_CORNER_NONE,  CL_CORNER_NONE,
1150                                                                                           CL_CORNER_ROUND, CL_CORNER_ROUND);
1151                 }
1152
1153                 cl_rectangle_set_clip_rectangle (&r, area);
1154                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1155                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1156                 cl_rectangle_reset_clip_rectangle (&r);
1157
1158         }
1159         else if (DETAIL ("slider"))
1160         {
1161                 if (DETAIL("slider") && widget && GTK_IS_RANGE (widget))
1162                 {
1163                         GtkAdjustment *adj = GTK_RANGE (widget)->adjustment;
1164
1165                         if (adj->value <= adj->lower &&
1166                                 (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b))
1167                         {
1168                                 if (GTK_IS_VSCROLLBAR (widget))
1169                                 {
1170                                         y-=1;
1171                                         height+=1;
1172                                 }
1173                                 else if (GTK_IS_HSCROLLBAR (widget))
1174                                 {
1175                                         x-=1;
1176                                         width+=1;
1177                                 }
1178                         }
1179                         if (adj->value >= adj->upper - adj->page_size &&
1180                             (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d))
1181                         {
1182                                 if (GTK_IS_VSCROLLBAR (widget))
1183                                         height+=1;
1184                                 else if (GTK_IS_HSCROLLBAR (widget))
1185                                         width+=1;
1186                         }
1187                 }
1188
1189                 cl_rectangle_set_button (&r, style, state_type, FALSE, GTK_WIDGET_HAS_FOCUS (widget),
1190                                         CL_CORNER_NONE, CL_CORNER_NONE,
1191                                         CL_CORNER_NONE, CL_CORNER_NONE);
1192
1193                 r.gradient_type = GTK_IS_HSCROLLBAR (widget) ? CL_GRADIENT_VERTICAL
1194                                                              : CL_GRADIENT_HORIZONTAL;
1195
1196                 cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type],
1197                                            &clearlooks_style->inset_dark[state_type]);
1198
1199                 r.bottomright = clearlooks_style->shade_gc[1];
1200                 r.border_gradient.to = r.border_gradient.from;
1201
1202                 cl_rectangle_set_clip_rectangle (&r, area);
1203                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1204                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1205                 cl_rectangle_reset_clip_rectangle (&r);
1206         }
1207         else if (detail && !strcmp (detail, "optionmenu")) /* supporting deprecated */
1208         {
1209                 cl_draw_optionmenu(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
1210         }
1211         else if (DETAIL ("menuitem"))
1212         {
1213                 if (clearlooks_style->menuitemstyle == 0)
1214                 {
1215                         cl_draw_menuitem_flat (window, widget, style, area, state_type,
1216                                                x, y, width, height, &r);
1217                 }
1218                 else if (clearlooks_style->menuitemstyle == 1)
1219                 {
1220                         cl_draw_menuitem_gradient (window, widget, style, area, state_type,
1221                                                    x, y, width, height, &r);
1222                 }
1223                 else
1224                 {
1225                         cl_draw_menuitem_button (window, widget, style, area, state_type,
1226                                                  x, y, width, height, &r);
1227                 }
1228         }
1229         else if (DETAIL ("menubar") && (clearlooks_style->sunkenmenubar || clearlooks_style->menubarstyle > 0))
1230         {
1231                 GdkGC *dark = clearlooks_style->shade_gc[2];
1232                 GdkColor upper_color, lower_color;
1233
1234                 /* don't draw sunken menubar on gnome panel
1235                    IT'S A HACK! HORRIBLE HACK! HIDEOUS HACK!
1236                    BUT IT WORKS FOR ME(tm)! */
1237                 if (widget->parent &&
1238                         strcmp(G_OBJECT_TYPE_NAME (widget->parent), "PanelWidget") == 0)
1239                         return;
1240
1241                 shade(&style->bg[state_type], &upper_color, 1.0);
1242                 shade(&style->bg[state_type], &lower_color, 0.95);
1243
1244                 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1245                                               CL_CORNER_NONE, CL_CORNER_NONE);
1246
1247                 r.fillgc = style->bg_gc[state_type];
1248                 r.bordergc = clearlooks_style->shade_gc[2];
1249                 r.gradient_type = CL_GRADIENT_VERTICAL;
1250
1251                 cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->shade[2],
1252                                                                &clearlooks_style->shade[3]);
1253                 cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color);
1254
1255                 /* make vertical and top borders invisible for style 2 */
1256                 if (clearlooks_style->menubarstyle == 2) {
1257                         x--; width+=2;
1258                         y--; height+=1;
1259                 }
1260
1261                 cl_rectangle_set_clip_rectangle (&r, area);
1262                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1263                 cl_rectangle_reset_clip_rectangle (&r);
1264         }
1265         else if (DETAIL ("menu") && widget->parent &&
1266                  GDK_IS_WINDOW (widget->parent->window))
1267         {
1268                 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1269                                               CL_CORNER_NONE, CL_CORNER_NONE);
1270
1271                 r.bordergc    = clearlooks_style->border_gc[CL_BORDER_UPPER];
1272                 r.topleft     = style->light_gc[state_type];
1273                 r.bottomright = clearlooks_style->shade_gc[1];
1274
1275                 cl_rectangle_set_clip_rectangle (&r, area);
1276                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1277                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1278                 cl_rectangle_reset_clip_rectangle (&r);
1279
1280                 return;
1281         }
1282         else if (DETAIL ("bar") && widget && GTK_IS_PROGRESS_BAR (widget))
1283         {
1284                 GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)),
1285                          lower_color,
1286                          prev_foreground;
1287                 gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode;
1288
1289 #ifdef HAVE_ANIMATION
1290                 if (!activity_mode && gtk_progress_bar_get_fraction (widget) != 1.0 &&
1291                         !cl_progressbar_known((gconstpointer)widget))
1292                 {
1293                         cl_progressbar_add ((gpointer)widget);
1294                 }
1295 #endif
1296                 cl_progressbar_fill (window, widget, style, style->black_gc,
1297                                      x, y, width, height,
1298 #ifdef HAVE_ANIMATION
1299                                      activity_mode ? 0 : pboffset,
1300 #else
1301                                      0,
1302 #endif
1303                                      area);
1304
1305                 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1306                                               CL_CORNER_NONE, CL_CORNER_NONE);
1307
1308                 r.bordergc = clearlooks_style->spot3_gc;
1309                 r.topleft = clearlooks_style->spot2_gc;
1310
1311                 prev_foreground = cl_gc_set_fg_color_shade (clearlooks_style->spot2_gc,
1312                                                             style->colormap,
1313                                                             &clearlooks_style->spot2,
1314                                                             1.2);
1315
1316                 cl_rectangle_set_clip_rectangle (&r, area);
1317                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1318                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1319                 cl_rectangle_reset_clip_rectangle (&r);
1320
1321                 gdk_gc_set_foreground (clearlooks_style->spot2_gc, &prev_foreground);
1322         }
1323
1324         else if ( widget && (DETAIL ("menubar") || DETAIL ("toolbar") || DETAIL ("dockitem_bin") || DETAIL ("handlebox_bin")) && shadow_type != GTK_SHADOW_NONE) /* Toolbars and menus */
1325         {
1326                 if (area)
1327                 {
1328                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area);
1329                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area);
1330                 }
1331
1332                 gtk_style_apply_default_background (style, window,
1333                                 widget && !GTK_WIDGET_NO_WINDOW (widget),
1334                                 state_type, area, x, y, width, height);
1335
1336                 /* we only want the borders on horizontal toolbars */
1337                 if ( DETAIL ("menubar") || height < 2*width ) {
1338                         if (!DETAIL ("menubar"))
1339                                 gdk_draw_line (window, clearlooks_style->shade_gc[0],
1340                                                x, y, x + width, y); /* top */
1341
1342                         gdk_draw_line (window, clearlooks_style->shade_gc[3],
1343                                        x, y + height - 1, x + width, y + height - 1); /* bottom */
1344                 }
1345
1346                 if (area)
1347                 {
1348                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL);
1349                         gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL);
1350                 }
1351         }
1352         else
1353         {
1354                 parent_class->draw_box (style, window, state_type, shadow_type, area,
1355                                         widget, detail, x, y, width, height);
1356         }
1357 }
1358
1359 /**************************************************************************/
1360
1361 static void
1362 ensure_check_pixmaps (GtkStyle     *style,
1363                       GtkStateType  state,
1364                       GdkScreen    *screen,
1365                       gboolean      treeview)
1366 {
1367         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1368         ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style);
1369         GdkPixbuf *check, *base, *inconsistent, *composite;
1370         GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc);
1371
1372         if (clearlooks_style->check_pixmap_nonactive[state] != NULL)
1373                 return;
1374
1375         if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) {
1376                 check = generate_bit (check_alpha, &style->text[GTK_STATE_NORMAL], 1.0);
1377                 inconsistent = generate_bit (check_inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0);
1378         } else {
1379                 check = generate_bit (check_alpha, &style->text[state], 1.0);
1380                 inconsistent = generate_bit (check_inconsistent_alpha, &style->text[state], 1.0);
1381         }
1382
1383         if (state == GTK_STATE_ACTIVE && !treeview)
1384                 base = generate_bit (check_base_alpha, &style->bg[state], 1.0);
1385         else
1386                 base = generate_bit (check_base_alpha, &style->base[GTK_STATE_NORMAL], 1.0);
1387
1388         if (treeview)
1389                 composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0);
1390         else
1391                 composite = generate_bit (NULL, &clearlooks_style->shade[5], 1.0);
1392
1393         gdk_pixbuf_composite (base, composite,
1394                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1395                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1396
1397         clearlooks_style->check_pixmap_nonactive[state] =
1398                 pixbuf_to_pixmap (style, composite, screen);
1399
1400         gdk_pixbuf_composite (check, composite,
1401                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1402                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1403
1404         clearlooks_style->check_pixmap_active[state] =
1405                 pixbuf_to_pixmap (style, composite, screen);
1406
1407         g_object_unref (composite);
1408
1409         composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0);
1410
1411         gdk_pixbuf_composite (base, composite,
1412                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1413                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1414
1415         gdk_pixbuf_composite (inconsistent, composite,
1416                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1417                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1418
1419         clearlooks_style->check_pixmap_inconsistent[state] =
1420                 pixbuf_to_pixmap (style, composite, screen);
1421
1422         g_object_unref (composite);
1423         g_object_unref (base);
1424         g_object_unref (check);
1425         g_object_unref (inconsistent);
1426 }
1427
1428 static void
1429 draw_check (DRAW_ARGS)
1430 {
1431         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1432         GdkGC *gc = style->base_gc[state_type];
1433         GdkPixmap *pixmap;
1434         gboolean treeview;
1435
1436         if (DETAIL ("check")) /* Menu item */
1437         {
1438                 parent_class->draw_check (style, window, state_type, shadow_type, area,
1439                                         widget, detail, x, y, width, height);
1440                 return;
1441         }
1442
1443         treeview = widget && GTK_IS_TREE_VIEW(widget);
1444         ensure_check_pixmaps (style, state_type, gtk_widget_get_screen (widget), treeview);
1445
1446         if (area)
1447                 gdk_gc_set_clip_rectangle (gc, area);
1448
1449         if (shadow_type == GTK_SHADOW_IN)
1450                 pixmap = clearlooks_style->check_pixmap_active[state_type];
1451         else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
1452                 pixmap = clearlooks_style->check_pixmap_inconsistent[state_type];
1453         else
1454                 pixmap = clearlooks_style->check_pixmap_nonactive[state_type];
1455
1456         x += (width - CHECK_SIZE)/2;
1457         y += (height - CHECK_SIZE)/2;
1458
1459         gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y, CHECK_SIZE, CHECK_SIZE);
1460
1461         if (area)
1462                 gdk_gc_set_clip_rectangle (gc, NULL);
1463 }
1464
1465 /**************************************************************************/
1466 static void
1467 draw_slider (DRAW_ARGS, GtkOrientation orientation)
1468 {
1469         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1470         GdkGC *shade_gc = clearlooks_style->shade_gc[4];
1471         GdkGC *white_gc = clearlooks_style->shade_gc[0];
1472         int x1, y1;
1473
1474 #if DEBUG
1475                 printf("draw_slider: %s %d %d %d %d\n", detail, x, y, width, height);
1476 #endif
1477
1478         g_return_if_fail (GTK_IS_STYLE (style));
1479         g_return_if_fail (window != NULL);
1480
1481         sanitize_size (window, &width, &height);
1482
1483         gtk_paint_box (style, window, state_type, shadow_type,
1484                        area, widget, detail, x, y, width, height);
1485
1486         if ((orientation == GTK_ORIENTATION_VERTICAL && height < 20) ||
1487                 (orientation == GTK_ORIENTATION_HORIZONTAL && width < 20))
1488                 return;
1489
1490         if (detail && strcmp ("slider", detail) == 0)
1491         {
1492                 if (area)
1493                 {
1494                         gdk_gc_set_clip_rectangle (shade_gc, area);
1495                         gdk_gc_set_clip_rectangle (white_gc, area);
1496                 }
1497                 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1498                 {
1499                         x1 = x + width / 2 - 4;
1500                         y1 = y + (height - 6) / 2;
1501                         gdk_draw_line (window, shade_gc, x1, y1, x1, y1 + 6);
1502                         gdk_draw_line (window, white_gc, x1 + 1, y1, x1 + 1, y1 + 6);
1503                         gdk_draw_line (window, shade_gc, x1 + 3, y1, x1 + 3, y1 + 6);
1504                         gdk_draw_line (window, white_gc, x1 + 3 + 1, y1, x1 + 3 + 1, y1 + 6);
1505                         gdk_draw_line (window, shade_gc, x1 + 3*2, y1, x1 + 3*2, y1 + 6);
1506                         gdk_draw_line (window, white_gc, x1 + 3*2 + 1, y1, x1 + 3*2 + 1, y1 + 6);
1507                 }
1508                 else
1509                 {
1510                         x1 = x + (width - 6) / 2;
1511                         y1 = y + height / 2 - 4;
1512                         gdk_draw_line (window, shade_gc, x1 + 6, y1, x1, y1);
1513                         gdk_draw_line (window, white_gc, x1 + 6, y1 + 1, x1, y1 + 1);
1514                         gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3, x1, y1 + 3);
1515                         gdk_draw_line (window, white_gc, x1 + 6, y1 + 3 + 1, x1, y1 + 3 + 1);
1516                         gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3*2, x1, y1 + 3*2);
1517                         gdk_draw_line (window, white_gc, x1 + 6, y1 + 3*2 + 1, x1, y1 + 3*2 + 1);
1518                 }
1519                 if (area)
1520                 {
1521                         gdk_gc_set_clip_rectangle (shade_gc, NULL);
1522                         gdk_gc_set_clip_rectangle (white_gc, NULL);
1523                 }
1524         }
1525         else if (detail && (strcmp ("hscale", detail) == 0 || strcmp ("vscale", detail) == 0))
1526         {
1527                 if (area)
1528                 {
1529                         gdk_gc_set_clip_rectangle (shade_gc, area);
1530                         gdk_gc_set_clip_rectangle (white_gc, area);
1531                 }
1532
1533                 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1534                 {
1535                         x1 = x + width / 2 - 3;
1536                         y1 = y + (height - 7) / 2;
1537                         gdk_draw_line (window, shade_gc, x1 + 0, y1 + 5, x1 + 0, y1 + 1);
1538                         gdk_draw_line (window, white_gc, x1 + 1, y1 + 5, x1 + 1, y1 + 1);
1539                         gdk_draw_line (window, shade_gc, x1 + 3, y1 + 5, x1 + 3, y1 + 1);
1540                         gdk_draw_line (window, white_gc, x1 + 4, y1 + 5, x1 + 4, y1 + 1);
1541                         gdk_draw_line (window, shade_gc, x1 + 6,  y1 + 5, x1 + 6, y1 + 1);
1542                         gdk_draw_line (window, white_gc, x1 + 7,  y1 + 5, x1 + 7, y1 + 1);
1543                 }
1544                 else
1545                 {
1546                         x1 = x + (width - 7) / 2;
1547                         y1 = y + height / 2 - 3;
1548                         gdk_draw_line (window, shade_gc, x1 + 5, y1 + 0, x1 + 1, y1 + 0);
1549                         gdk_draw_line (window, white_gc, x1 + 5, y1 + 1, x1 + 1, y1 + 1);
1550                         gdk_draw_line (window, shade_gc, x1 + 5, y1 + 3, x1 + 1, y1 + 3);
1551                         gdk_draw_line (window, white_gc, x1 + 5, y1 + 4, x1 + 1, y1 + 4);
1552                         gdk_draw_line (window, shade_gc, x1 + 5, y1 + 6, x1 + 1, y1 + 6);
1553                         gdk_draw_line (window, white_gc, x1 + 5, y1 + 7, x1 + 1, y1 + 7);
1554                 }
1555                 if (area)
1556                 {
1557                         gdk_gc_set_clip_rectangle (shade_gc, NULL);
1558                         gdk_gc_set_clip_rectangle (white_gc, NULL);
1559                 }
1560         }
1561 }
1562
1563 /**************************************************************************/
1564 static void
1565 ensure_radio_pixmaps (GtkStyle     *style,
1566                       GtkStateType  state,
1567                       GdkScreen    *screen)
1568 {
1569         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1570         ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style);
1571         GdkPixbuf *dot, *circle, *outline, *inconsistent, *composite;
1572         GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc);
1573         GdkColor *composite_color;
1574
1575         if (clearlooks_style->radio_pixmap_nonactive[state] != NULL)
1576                 return;
1577
1578         if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) {
1579                 dot = colorize_bit (dot_intensity, dot_alpha, &style->text[GTK_STATE_NORMAL]);
1580                 inconsistent = generate_bit (inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0);
1581         } else {
1582                 dot = colorize_bit (dot_intensity, dot_alpha, &style->text[state]);
1583                 inconsistent = generate_bit (inconsistent_alpha, &style->text[state], 1.0);
1584         }
1585
1586         outline = generate_bit (outline_alpha, &clearlooks_style->shade[5], 1.0);
1587
1588         if (clearlooks_style->radio_pixmap_mask == NULL)
1589         {
1590                 gdk_pixbuf_render_pixmap_and_mask (outline,
1591                                                    NULL,
1592                                                    &clearlooks_style->radio_pixmap_mask,
1593                                                    1);
1594         }
1595
1596         if (state == GTK_STATE_ACTIVE)
1597         {
1598                 composite_color = &style->bg[GTK_STATE_PRELIGHT];
1599                 circle = generate_bit (circle_alpha, &style->bg[state], 1.0);
1600         }
1601         else
1602         {
1603                 composite_color = &style->bg[state];
1604                 circle = generate_bit (circle_alpha, &style->base[GTK_STATE_NORMAL], 1.0);
1605         }
1606
1607         composite = generate_bit (NULL, composite_color, 1.0);
1608
1609         gdk_pixbuf_composite (outline, composite,
1610                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1611                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1612
1613         gdk_pixbuf_composite (circle, composite,
1614                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1615                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1616
1617         clearlooks_style->radio_pixmap_nonactive[state] =
1618                 pixbuf_to_pixmap (style, composite, screen);
1619
1620         gdk_pixbuf_composite (dot, composite,
1621                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1622                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1623
1624         clearlooks_style->radio_pixmap_active[state] =
1625                 pixbuf_to_pixmap (style, composite, screen);
1626
1627         g_object_unref (composite);
1628
1629         composite = generate_bit (NULL, composite_color,1.0);
1630
1631         gdk_pixbuf_composite (outline, composite,
1632                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1633                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1634         gdk_pixbuf_composite (circle, composite,
1635                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1636                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1637         gdk_pixbuf_composite (inconsistent, composite,
1638                               0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1639                               1.0, 1.0, GDK_INTERP_NEAREST, 255);
1640
1641         clearlooks_style->radio_pixmap_inconsistent[state] =
1642                 pixbuf_to_pixmap (style, composite, screen);
1643
1644         g_object_unref (composite);
1645         g_object_unref (circle);
1646         g_object_unref (dot);
1647         g_object_unref (inconsistent);
1648         g_object_unref (outline);
1649 }
1650
1651 static void
1652 draw_option (DRAW_ARGS)
1653 {
1654         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1655         GdkGC *gc = style->base_gc[state_type];
1656         GdkPixmap *pixmap;
1657
1658         if (DETAIL ("option")) /* Menu item */
1659         {
1660                 parent_class->draw_option (style, window, state_type, shadow_type,
1661                                            area, widget, detail, x, y, width, height);
1662                 return;
1663         }
1664
1665         ensure_radio_pixmaps (style, state_type, gtk_widget_get_screen (widget));
1666
1667         if (area)
1668                 gdk_gc_set_clip_rectangle (gc, area);
1669
1670         if (shadow_type == GTK_SHADOW_IN)
1671                 pixmap = clearlooks_style->radio_pixmap_active[state_type];
1672         else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
1673                 pixmap = clearlooks_style->radio_pixmap_inconsistent[state_type];
1674         else
1675                 pixmap = clearlooks_style->radio_pixmap_nonactive[state_type];
1676
1677         x += (width - RADIO_SIZE)/2;
1678         y += (height - RADIO_SIZE)/2;
1679
1680 #ifndef GTKOSX
1681         gdk_gc_set_clip_mask (gc, clearlooks_style->radio_pixmap_mask);
1682         gdk_gc_set_clip_origin (gc, x, y);
1683 #endif
1684
1685         gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y,
1686                            RADIO_SIZE, RADIO_SIZE);
1687
1688 #ifndef GTKOSX
1689         gdk_gc_set_clip_origin (gc, 0, 0);
1690         gdk_gc_set_clip_mask (gc, NULL);
1691 #endif
1692
1693         if (area)
1694                 gdk_gc_set_clip_rectangle (gc, NULL);
1695 }
1696
1697 /**************************************************************************/
1698
1699 static void
1700 draw_shadow_gap (DRAW_ARGS,
1701                  GtkPositionType gap_side,
1702                  gint            gap_x,
1703                  gint            gap_width)
1704 {
1705         /* I need to improve this function. */
1706         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1707         CLRectangle r;
1708         GdkRegion *area_region = NULL,
1709                   *gap_region  = NULL;
1710
1711 #if DEBUG
1712                 printf("draw_shadow_gap: %s %d %d %d %d\n", detail, x, y, width, height);
1713 #endif
1714
1715         g_return_if_fail (GTK_IS_STYLE (style));
1716         g_return_if_fail (window != NULL);
1717
1718         sanitize_size (window, &width, &height);
1719
1720         cl_rectangle_reset (&r, style);
1721         cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1722                                                                   CL_CORNER_NONE, CL_CORNER_NONE);
1723
1724         if (area)
1725         {
1726                 area_region = gdk_region_rectangle (area);
1727
1728                 switch (gap_side)
1729                 {
1730                         case GTK_POS_TOP:
1731                         {
1732                                 GdkRectangle rect = { x+gap_x, y, gap_width, 2 };
1733                                 gap_region = gdk_region_rectangle (&rect);
1734                                 break;
1735                         }
1736                         case GTK_POS_BOTTOM:
1737                         {
1738                                 GdkRectangle rect = { x+gap_x, y+height-2, gap_width, 2 };
1739                                 gap_region = gdk_region_rectangle (&rect);
1740                                 break;
1741                         }
1742                         case GTK_POS_LEFT:
1743                         {
1744                                 GdkRectangle rect = { x, y+gap_x, 2, gap_width };
1745                                 gap_region = gdk_region_rectangle (&rect);
1746                                 break;
1747                         }
1748                         case GTK_POS_RIGHT:
1749                         {
1750                                 GdkRectangle rect = { x+width-2, y+gap_x, 2, gap_width };
1751                                 gap_region = gdk_region_rectangle (&rect);
1752                                 break;
1753                         }
1754                 }
1755
1756                 gdk_region_subtract (area_region, gap_region);
1757         }
1758
1759         if (shadow_type == GTK_SHADOW_ETCHED_IN ||
1760             shadow_type == GTK_SHADOW_ETCHED_OUT)
1761         {
1762                 GdkGC *a;
1763                 GdkGC *b;
1764
1765                 if (shadow_type == GTK_SHADOW_ETCHED_IN)
1766                 {
1767                         a = style->light_gc[state_type];
1768                         b = clearlooks_style->shade_gc[3];
1769                 }
1770                 else
1771                 {
1772                         a = clearlooks_style->shade_gc[3];
1773                         b = style->light_gc[state_type];
1774                 }
1775
1776                 gdk_gc_set_clip_region (a, area_region);
1777                 gdk_gc_set_clip_region (b, area_region);
1778
1779                 r.bordergc = a;
1780                 cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r);
1781
1782                 r.bordergc = b;
1783                 cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r);
1784
1785                 gdk_gc_set_clip_region (a, NULL);
1786                 gdk_gc_set_clip_region (b, NULL);
1787         }
1788         else if (shadow_type == GTK_SHADOW_IN || shadow_type == GTK_SHADOW_OUT)
1789         {
1790                 r.topleft     = (shadow_type == GTK_SHADOW_OUT) ? style->light_gc[state_type] : clearlooks_style->shade_gc[1];
1791                 r.bottomright = (shadow_type == GTK_SHADOW_OUT) ? clearlooks_style->shade_gc[1] : style->light_gc[state_type];
1792                 r.bordergc    = clearlooks_style->shade_gc[5];
1793
1794                 gdk_gc_set_clip_region (r.bordergc,    area_region);
1795                 gdk_gc_set_clip_region (r.topleft,     area_region);
1796                 gdk_gc_set_clip_region (r.bottomright, area_region);
1797
1798                 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1799
1800                 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1801
1802                 gdk_gc_set_clip_region (r.bordergc,    NULL);
1803                 gdk_gc_set_clip_region (r.topleft,     NULL);
1804                 gdk_gc_set_clip_region (r.bottomright, NULL);
1805         }
1806
1807         if (area_region)
1808                 gdk_region_destroy (area_region);
1809 }
1810
1811 /**************************************************************************/
1812 static void
1813 draw_hline (GtkStyle     *style,
1814             GdkWindow    *window,
1815             GtkStateType  state_type,
1816             GdkRectangle  *area,
1817             GtkWidget     *widget,
1818             const gchar   *detail,
1819             gint          x1,
1820             gint          x2,
1821             gint          y)
1822 {
1823         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1824
1825 #if DEBUG
1826                 printf("draw_hline\n");
1827 #endif
1828
1829         g_return_if_fail (GTK_IS_STYLE (style));
1830         g_return_if_fail (window != NULL);
1831
1832         if (area)
1833                 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area);
1834
1835         if (detail && !strcmp (detail, "label"))
1836         {
1837                 if (state_type == GTK_STATE_INSENSITIVE)
1838                         gdk_draw_line (window, style->light_gc[state_type], x1 + 1, y + 1, x2 + 1, y + 1);
1839
1840                 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
1841         }
1842         else
1843         {
1844                 gdk_draw_line (window, clearlooks_style->shade_gc[2], x1, y, x2, y);
1845
1846                 /* if (DETAIL ("menuitem")) */
1847                 gdk_draw_line (window, clearlooks_style->shade_gc[0], x1, y+1, x2, y+1);
1848         }
1849
1850         if (area)
1851                 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL);
1852 }
1853
1854 /**************************************************************************/
1855 static void
1856 draw_vline (GtkStyle     *style,
1857             GdkWindow    *window,
1858             GtkStateType  state_type,
1859             GdkRectangle  *area,
1860             GtkWidget     *widget,
1861             const gchar   *detail,
1862             gint          y1,
1863             gint          y2,
1864             gint          x)
1865 {
1866         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1867         gint thickness_light;
1868         gint thickness_dark;
1869
1870 #if DEBUG
1871                 printf("draw_vline\n");
1872 #endif
1873
1874         g_return_if_fail (GTK_IS_STYLE (style));
1875         g_return_if_fail (window != NULL);
1876
1877         thickness_light = style->xthickness / 2;
1878         thickness_dark = style->xthickness - thickness_light;
1879
1880         if (area)
1881                 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area);
1882
1883         gdk_draw_line (window, clearlooks_style->shade_gc[2], x, y1, x, y2 - 1);
1884         gdk_draw_line (window, clearlooks_style->shade_gc[0], x+1, y1, x+1, y2 - 1);
1885
1886         if (area)
1887                 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL);
1888 }
1889
1890 /**************************************************************************/
1891 static void
1892 draw_focus (GtkStyle      *style,
1893             GdkWindow     *window,
1894             GtkStateType   state_type,
1895             GdkRectangle  *area,
1896             GtkWidget     *widget,
1897             const gchar   *detail,
1898             gint           x,
1899             gint           y,
1900             gint           width,
1901             gint           height)
1902 {
1903         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1904         GdkPoint points[5];
1905         GdkGC    *gc;
1906         gboolean free_dash_list = FALSE;
1907         gint line_width = 1;
1908         gchar *dash_list = "\1\1";
1909         gint dash_len;
1910
1911 #if DEBUG
1912                 printf("draw_focus: %s %d %d %d %d\n", detail, x, y, width, height);
1913 #endif
1914
1915         gc = clearlooks_style->shade_gc[6];
1916
1917         if (widget)
1918         {
1919                 gtk_widget_style_get (widget,
1920                                       "focus-line-width", &line_width,
1921                                       "focus-line-pattern", (gchar *)&dash_list,
1922                                       NULL);
1923
1924                 free_dash_list = TRUE;
1925         }
1926
1927         sanitize_size (window, &width, &height);
1928
1929         if (area)
1930                 gdk_gc_set_clip_rectangle (gc, area);
1931
1932         gdk_gc_set_line_attributes (gc, line_width,
1933                                     dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
1934                                     GDK_CAP_BUTT, GDK_JOIN_MITER);
1935
1936
1937         if (detail && !strcmp (detail, "add-mode"))
1938         {
1939                 if (free_dash_list)
1940                         g_free (dash_list);
1941
1942                 dash_list = "\4\4";
1943                 free_dash_list = FALSE;
1944         }
1945
1946         points[0].x = x + line_width / 2;
1947         points[0].y = y + line_width / 2;
1948         points[1].x = x + width - line_width + line_width / 2;
1949         points[1].y = y + line_width / 2;
1950         points[2].x = x + width - line_width + line_width / 2;
1951         points[2].y = y + height - line_width + line_width / 2;
1952         points[3].x = x + line_width / 2;
1953         points[3].y = y + height - line_width + line_width / 2;
1954         points[4] = points[0];
1955
1956         if (!dash_list[0])
1957         {
1958                 gdk_draw_lines (window, gc, points, 5);
1959         }
1960         else
1961         {
1962                 dash_len = strlen (dash_list);
1963
1964                 if (dash_list[0])
1965                         gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
1966
1967                 gdk_draw_lines (window, gc, points, 3);
1968
1969                 points[2].x += 1;
1970
1971                 if (dash_list[0])
1972                 {
1973                         gint dash_pixels = 0;
1974                         gint i;
1975
1976                         /* Adjust the dash offset for the bottom and left so we
1977                         * match up at the upper left.
1978                         */
1979                         for (i = 0; i < dash_len; i++)
1980                                 dash_pixels += dash_list[i];
1981
1982                         if (dash_len % 2 == 1)
1983                                 dash_pixels *= 2;
1984
1985                         gdk_gc_set_dashes (gc,
1986                                                         dash_pixels - (width + height - 2 * line_width) % dash_pixels,
1987                                                         dash_list, dash_len);
1988                 }
1989
1990                 gdk_draw_lines (window, gc, points + 2, 3);
1991         }
1992
1993         gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
1994
1995         if (area)
1996                 gdk_gc_set_clip_rectangle (gc, NULL);
1997
1998         if (free_dash_list)
1999                 g_free (dash_list);
2000 }
2001
2002 static void
2003 draw_layout(GtkStyle * style,
2004             GdkWindow * window,
2005             GtkStateType state_type,
2006             gboolean use_text,
2007             GdkRectangle * area,
2008             GtkWidget * widget,
2009             const gchar * detail, gint x, gint y, PangoLayout * layout)
2010 {
2011         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2012
2013         g_return_if_fail(GTK_IS_STYLE (style));
2014         g_return_if_fail(window != NULL);
2015
2016         parent_class->draw_layout(style, window, state_type, use_text,
2017                                   area, widget, detail, x, y, layout);
2018
2019
2020 }
2021
2022 /**************************************************************************/
2023 static void
2024 draw_resize_grip (GtkStyle       *style,
2025                   GdkWindow      *window,
2026                   GtkStateType    state_type,
2027                   GdkRectangle   *area,
2028                   GtkWidget      *widget,
2029                   const gchar    *detail,
2030                   GdkWindowEdge   edge,
2031                   gint            x,
2032                   gint            y,
2033                   gint            width,
2034                   gint            height)
2035 {
2036   ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2037   g_return_if_fail (GTK_IS_STYLE (style));
2038   g_return_if_fail (window != NULL);
2039
2040   if (area)
2041     {
2042       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2043       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2044       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2045     }
2046
2047   switch (edge)
2048     {
2049     case GDK_WINDOW_EDGE_NORTH_WEST:
2050       /* make it square */
2051       if (width < height)
2052         {
2053           height = width;
2054         }
2055       else if (height < width)
2056         {
2057           width = height;
2058         }
2059       break;
2060     case GDK_WINDOW_EDGE_NORTH:
2061       if (width < height)
2062         {
2063           height = width;
2064         }
2065       break;
2066     case GDK_WINDOW_EDGE_NORTH_EAST:
2067       /* make it square, aligning to top right */
2068       if (width < height)
2069         {
2070           height = width;
2071         }
2072       else if (height < width)
2073         {
2074           x += (width - height);
2075           width = height;
2076         }
2077       break;
2078     case GDK_WINDOW_EDGE_WEST:
2079       if (height < width)
2080         {
2081            width = height;
2082         }
2083       break;
2084     case GDK_WINDOW_EDGE_EAST:
2085       /* aligning to right */
2086       if (height < width)
2087         {
2088           x += (width - height);
2089           width = height;
2090         }
2091       break;
2092     case GDK_WINDOW_EDGE_SOUTH_WEST:
2093       /* make it square, aligning to bottom left */
2094       if (width < height)
2095         {
2096           y += (height - width);
2097           height = width;
2098         }
2099       else if (height < width)
2100         {
2101           width = height;
2102         }
2103       break;
2104     case GDK_WINDOW_EDGE_SOUTH:
2105       /* align to bottom */
2106       if (width < height)
2107         {
2108           y += (height - width);
2109           height = width;
2110         }
2111       break;
2112     case GDK_WINDOW_EDGE_SOUTH_EAST:
2113       /* make it square, aligning to bottom right */
2114       if (width < height)
2115         {
2116           y += (height - width);
2117           height = width;
2118         }
2119       else if (height < width)
2120         {
2121           x += (width - height);
2122           width = height;
2123         }
2124       break;
2125     default:
2126       g_assert_not_reached ();
2127     }
2128
2129   /* Clear background */
2130   gtk_style_apply_default_background (style, window, FALSE,
2131                                       state_type, area,
2132                                       x, y, width, height);
2133
2134   switch (edge)
2135     {
2136     case GDK_WINDOW_EDGE_WEST:
2137     case GDK_WINDOW_EDGE_EAST:
2138       {
2139         gint xi;
2140
2141         xi = x;
2142
2143         while (xi < x + width)
2144           {
2145             gdk_draw_line (window,
2146                            style->light_gc[state_type],
2147                            xi, y,
2148                            xi, y + height);
2149
2150             xi++;
2151             gdk_draw_line (window,
2152                            clearlooks_style->shade_gc[4],
2153                            xi, y,
2154                            xi, y + height);
2155
2156             xi += 2;
2157           }
2158       }
2159       break;
2160     case GDK_WINDOW_EDGE_NORTH:
2161     case GDK_WINDOW_EDGE_SOUTH:
2162       {
2163         gint yi;
2164
2165         yi = y;
2166
2167         while (yi < y + height)
2168           {
2169             gdk_draw_line (window,
2170                            style->light_gc[state_type],
2171                            x, yi,
2172                            x + width, yi);
2173
2174             yi++;
2175             gdk_draw_line (window,
2176                            clearlooks_style->shade_gc[4],
2177                            x, yi,
2178                            x + width, yi);
2179
2180             yi+= 2;
2181           }
2182       }
2183       break;
2184     case GDK_WINDOW_EDGE_NORTH_WEST:
2185       {
2186         gint xi, yi;
2187
2188         xi = x + width;
2189         yi = y + height;
2190
2191         while (xi > x + 3)
2192           {
2193             gdk_draw_line (window,
2194                            clearlooks_style->shade_gc[4],
2195                            xi, y,
2196                            x, yi);
2197
2198             --xi;
2199             --yi;
2200
2201             gdk_draw_line (window,
2202                            style->light_gc[state_type],
2203                            xi, y,
2204                            x, yi);
2205
2206             xi -= 3;
2207             yi -= 3;
2208
2209           }
2210       }
2211       break;
2212     case GDK_WINDOW_EDGE_NORTH_EAST:
2213       {
2214         gint xi, yi;
2215
2216         xi = x;
2217         yi = y + height;
2218
2219         while (xi < (x + width - 3))
2220           {
2221             gdk_draw_line (window,
2222                            style->light_gc[state_type],
2223                            xi, y,
2224                            x + width, yi);
2225
2226             ++xi;
2227             --yi;
2228
2229             gdk_draw_line (window,
2230                            clearlooks_style->shade_gc[4],
2231                            xi, y,
2232                            x + width, yi);
2233
2234             xi += 3;
2235             yi -= 3;
2236           }
2237       }
2238       break;
2239     case GDK_WINDOW_EDGE_SOUTH_WEST:
2240       {
2241         gint xi, yi;
2242
2243         xi = x + width;
2244         yi = y;
2245
2246         while (xi > x + 3)
2247           {
2248             gdk_draw_line (window,
2249                            clearlooks_style->shade_gc[4],
2250                            x, yi,
2251                            xi, y + height);
2252
2253             --xi;
2254             ++yi;
2255
2256             gdk_draw_line (window,
2257                            style->light_gc[state_type],
2258                            x, yi,
2259                            xi, y + height);
2260
2261             xi -= 3;
2262             yi += 3;
2263
2264           }
2265       }
2266       break;
2267
2268     case GDK_WINDOW_EDGE_SOUTH_EAST:
2269       {
2270         gint xi, yi;
2271
2272         xi = x;
2273         yi = y;
2274
2275         while (xi < (x + width - 3))
2276           {
2277             gdk_draw_line (window,
2278                            style->light_gc[state_type],
2279                            xi, y + height,
2280                            x + width, yi);
2281
2282             ++xi;
2283             ++yi;
2284
2285             gdk_draw_line (window,
2286                            clearlooks_style->shade_gc[4],
2287                            xi, y + height,
2288                            x + width, yi);
2289
2290             xi += 3;
2291             yi += 3;
2292           }
2293       }
2294       break;
2295     default:
2296       g_assert_not_reached ();
2297       break;
2298     }
2299
2300   if (area)
2301     {
2302       gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2303       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2304       gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2305     }
2306 }
2307
2308 /**************************************************************************/
2309
2310 static void
2311 clearlooks_style_init_from_rc (GtkStyle * style,
2312                                GtkRcStyle * rc_style)
2313 {
2314         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2315         GdkColor *spot_color;
2316         double shades[] = {1.065, 0.93, 0.896, 0.85, 0.768, 0.665, 0.4, 0.205};
2317         int i;
2318         double contrast;
2319
2320         parent_class->init_from_rc (style, rc_style);
2321
2322         contrast = CLEARLOOKS_RC_STYLE (rc_style)->contrast;
2323
2324         clearlooks_style->sunkenmenubar = CLEARLOOKS_RC_STYLE (rc_style)->sunkenmenubar;
2325         clearlooks_style->progressbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->progressbarstyle;
2326         clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle;
2327         clearlooks_style->menuitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->menuitemstyle;
2328         clearlooks_style->listviewitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->listviewitemstyle;
2329
2330         /* Lighter to darker */
2331         for (i = 0; i < 8; i++)
2332         {
2333                 shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->shade[i],
2334                        (shades[i]-0.7) * contrast + 0.7);
2335         }
2336
2337         spot_color = clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (rc_style));
2338
2339         clearlooks_style->spot_color = *spot_color;
2340         shade (&clearlooks_style->spot_color, &clearlooks_style->spot1, 1.42);
2341         shade (&clearlooks_style->spot_color, &clearlooks_style->spot2, 1.05);
2342         shade (&clearlooks_style->spot_color, &clearlooks_style->spot3, 0.65);
2343
2344         shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_UPPER],        0.5);
2345         shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_LOWER],        0.62);
2346         shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_UPPER_ACTIVE], 0.5);
2347         shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_LOWER_ACTIVE], 0.55);
2348 }
2349
2350 static GdkGC *
2351 realize_color (GtkStyle * style,
2352                GdkColor * color)
2353 {
2354         GdkGCValues gc_values;
2355
2356         gdk_colormap_alloc_color (style->colormap, color, FALSE, TRUE);
2357
2358         gc_values.foreground = *color;
2359
2360         return gtk_gc_get (style->depth, style->colormap, &gc_values, GDK_GC_FOREGROUND);
2361 }
2362
2363 static void
2364 clearlooks_style_realize (GtkStyle * style)
2365 {
2366         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2367         int i;
2368
2369         parent_class->realize (style);
2370
2371         for (i = 0; i < 8; i++)
2372                 clearlooks_style->shade_gc[i] = realize_color (style, &clearlooks_style->shade[i]);
2373
2374         for (i=0; i < CL_BORDER_COUNT; i++)
2375                 clearlooks_style->border_gc[i] = realize_color (style, &clearlooks_style->border[i]);
2376
2377         clearlooks_style->spot1_gc = realize_color (style, &clearlooks_style->spot1);
2378         clearlooks_style->spot2_gc = realize_color (style, &clearlooks_style->spot2);
2379         clearlooks_style->spot3_gc = realize_color (style, &clearlooks_style->spot3);
2380
2381         /* set light inset color */
2382         for (i=0; i<5; i++)
2383         {
2384                 shade (&style->bg[i], &clearlooks_style->inset_dark[i], 0.93);
2385                 gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_dark[i]);
2386
2387                 shade (&style->bg[i], &clearlooks_style->inset_light[i], 1.055);
2388                 gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_light[i]);
2389
2390                 shade (&style->bg[i], &clearlooks_style->listview_bg[i], 1.015);
2391                 gdk_rgb_find_color (style->colormap, &clearlooks_style->listview_bg[i]);
2392
2393                 /* CREATE GRADIENT FOR BUTTONS */
2394                 shade (&style->bg[i], &clearlooks_style->button_g1[i], 1.055);
2395                 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g1[i]);
2396
2397                 shade (&style->bg[i], &clearlooks_style->button_g2[i], 1.005);
2398                 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g2[i]);
2399
2400                 shade (&style->bg[i], &clearlooks_style->button_g3[i], 0.98);
2401                 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g3[i]);
2402
2403                 shade (&style->bg[i], &clearlooks_style->button_g4[i], 0.91);
2404                 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g4[i]);
2405         }
2406
2407 }
2408
2409 static void
2410 clearlooks_style_unrealize (GtkStyle * style)
2411 {
2412         ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2413         int i;
2414
2415         /* We don't free the colors, because we don't know if
2416         * gtk_gc_release() actually freed the GC. FIXME - need
2417         * a way of ref'ing colors explicitely so GtkGC can
2418         * handle things properly.
2419         */
2420         for (i=0; i < 8; i++)
2421                 gtk_gc_release (clearlooks_style->shade_gc[i]);
2422
2423         gtk_gc_release (clearlooks_style->spot1_gc);
2424         gtk_gc_release (clearlooks_style->spot2_gc);
2425         gtk_gc_release (clearlooks_style->spot3_gc);
2426
2427         for (i = 0; i < 5; i++)
2428         {
2429                 if (clearlooks_style->radio_pixmap_nonactive[i] != NULL)
2430                 {
2431                         g_object_unref (clearlooks_style->radio_pixmap_nonactive[i]);
2432                         clearlooks_style->radio_pixmap_nonactive[i] = NULL;
2433                         g_object_unref (clearlooks_style->radio_pixmap_active[i]);
2434                         clearlooks_style->radio_pixmap_active[i] = NULL;
2435                         g_object_unref (clearlooks_style->radio_pixmap_inconsistent[i]);
2436                         clearlooks_style->radio_pixmap_inconsistent[i] = NULL;
2437                 }
2438
2439                 if (clearlooks_style->check_pixmap_nonactive[i] != NULL)
2440                 {
2441                         g_object_unref (clearlooks_style->check_pixmap_nonactive[i]);
2442                         clearlooks_style->check_pixmap_nonactive[i] = NULL;
2443                         g_object_unref (clearlooks_style->check_pixmap_active[i]);
2444                         clearlooks_style->check_pixmap_active[i] = NULL;
2445                         g_object_unref (clearlooks_style->check_pixmap_inconsistent[i]);
2446                         clearlooks_style->check_pixmap_inconsistent[i] = NULL;
2447                 }
2448         }
2449
2450         if (clearlooks_style->radio_pixmap_mask != NULL)
2451                 g_object_unref (clearlooks_style->radio_pixmap_mask);
2452
2453         clearlooks_style->radio_pixmap_mask = NULL;
2454
2455         while (progressbars = g_list_first (progressbars))
2456                 cl_progressbar_remove (progressbars->data);
2457
2458         if (timer_id != 0)
2459         {
2460                 g_source_remove(timer_id);
2461                 timer_id = 0;
2462         }
2463
2464         parent_class->unrealize (style);
2465 }
2466
2467 static GdkPixbuf *
2468 set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
2469 {
2470         GdkPixbuf *target;
2471         guchar *data, *current;
2472         guint x, y, rowstride, height, width;
2473
2474         g_return_val_if_fail (pixbuf != NULL, NULL);
2475         g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
2476
2477         /* Returns a copy of pixbuf with it's non-completely-transparent pixels to
2478            have an alpha level "alpha_percent" of their original value. */
2479
2480         target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
2481
2482         if (alpha_percent == 1.0)
2483                 return target;
2484         width = gdk_pixbuf_get_width (target);
2485         height = gdk_pixbuf_get_height (target);
2486         rowstride = gdk_pixbuf_get_rowstride (target);
2487         data = gdk_pixbuf_get_pixels (target);
2488
2489         for (y = 0; y < height; y++) {
2490                 for (x = 0; x < width; x++) {
2491                         /* The "4" is the number of chars per pixel, in this case, RGBA,
2492                            the 3 means "skip to the alpha" */
2493                         current = data + (y * rowstride) + (x * 4) + 3;
2494                         *(current) = (guchar) (*(current) * alpha_percent);
2495                 }
2496         }
2497
2498         return target;
2499 }
2500
2501 static GdkPixbuf*
2502 scale_or_ref (GdkPixbuf *src,
2503               int width,
2504               int height)
2505 {
2506         if (width == gdk_pixbuf_get_width (src) &&
2507             height == gdk_pixbuf_get_height (src)) {
2508                 return g_object_ref (src);
2509         } else {
2510                 return gdk_pixbuf_scale_simple (src,
2511                                                 width, height,
2512                                                 GDK_INTERP_BILINEAR);
2513         }
2514 }
2515
2516 static GdkPixbuf *
2517 render_icon (GtkStyle            *style,
2518              const GtkIconSource *source,
2519              GtkTextDirection     direction,
2520              GtkStateType         state,
2521              GtkIconSize          size,
2522              GtkWidget           *widget,
2523              const char          *detail)
2524 {
2525         int width = 1;
2526         int height = 1;
2527         GdkPixbuf *scaled;
2528         GdkPixbuf *stated;
2529         GdkPixbuf *base_pixbuf;
2530         GdkScreen *screen;
2531         GtkSettings *settings;
2532
2533         /* Oddly, style can be NULL in this function, because
2534          * GtkIconSet can be used without a style and if so
2535          * it uses this function.
2536          */
2537
2538         base_pixbuf = gtk_icon_source_get_pixbuf (source);
2539
2540         g_return_val_if_fail (base_pixbuf != NULL, NULL);
2541
2542         if (widget && gtk_widget_has_screen (widget)) {
2543                 screen = gtk_widget_get_screen (widget);
2544                 settings = gtk_settings_get_for_screen (screen);
2545         } else if (style->colormap) {
2546                 screen = gdk_colormap_get_screen (style->colormap);
2547                 settings = gtk_settings_get_for_screen (screen);
2548         } else {
2549                 settings = gtk_settings_get_default ();
2550                 GTK_NOTE (MULTIHEAD,
2551                           g_warning ("Using the default screen for gtk_default_render_icon()"));
2552         }
2553
2554
2555         if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) {
2556                 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2557                 return NULL;
2558         }
2559
2560         /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2561          * leave it alone.
2562          */
2563         if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2564                 scaled = scale_or_ref (base_pixbuf, width, height);
2565         else
2566                 scaled = g_object_ref (base_pixbuf);
2567
2568         /* If the state was wildcarded, then generate a state. */
2569         if (gtk_icon_source_get_state_wildcarded (source)) {
2570                 if (state == GTK_STATE_INSENSITIVE) {
2571                         stated = set_transparency (scaled, 0.3);
2572 #if 0
2573                         stated =
2574                                 gdk_pixbuf_composite_color_simple (scaled,
2575                                                                    gdk_pixbuf_get_width (scaled),
2576                                                                    gdk_pixbuf_get_height (scaled),
2577                                                                    GDK_INTERP_BILINEAR, 128,
2578                                                                    gdk_pixbuf_get_width (scaled),
2579                                                                    style->bg[state].pixel,
2580                                                                    style->bg[state].pixel);
2581 #endif
2582                         gdk_pixbuf_saturate_and_pixelate (stated, stated,
2583                                                           0.1, FALSE);
2584
2585                         g_object_unref (scaled);
2586                 } else if (state == GTK_STATE_PRELIGHT) {
2587                         stated = gdk_pixbuf_copy (scaled);
2588
2589                         gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2590                                                           1.2, FALSE);
2591
2592                         g_object_unref (scaled);
2593                 } else {
2594                         stated = scaled;
2595                 }
2596         }
2597         else
2598                 stated = scaled;
2599
2600   return stated;
2601 }
2602
2603 static void
2604 clearlooks_style_init (ClearlooksStyle * style)
2605 {
2606 }
2607
2608 static void
2609 clearlooks_style_class_init (ClearlooksStyleClass * klass)
2610 {
2611         GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
2612
2613         parent_class = g_type_class_peek_parent (klass);
2614
2615         style_class->realize = clearlooks_style_realize;
2616         style_class->unrealize = clearlooks_style_unrealize;
2617         style_class->init_from_rc = clearlooks_style_init_from_rc;
2618         style_class->draw_focus = draw_focus;
2619         style_class->draw_resize_grip = draw_resize_grip;
2620         style_class->draw_handle = draw_handle;
2621         style_class->draw_vline = draw_vline;
2622         style_class->draw_hline = draw_hline;
2623         style_class->draw_slider = draw_slider;
2624         style_class->draw_shadow_gap = draw_shadow_gap;
2625         style_class->draw_arrow = clearlooks_draw_arrow;
2626         style_class->draw_check = draw_check;
2627         style_class->draw_tab = draw_tab;
2628         style_class->draw_box = draw_box;
2629         style_class->draw_shadow = draw_shadow;
2630         style_class->draw_box_gap = draw_box_gap;
2631         style_class->draw_extension = draw_extension;
2632         style_class->draw_option = draw_option;
2633         style_class->draw_layout = draw_layout;
2634         style_class->render_icon = render_icon;
2635         style_class->draw_flat_box = draw_flat_box;
2636 }
2637
2638 GType clearlooks_type_style = 0;
2639
2640 void
2641 clearlooks_style_register_type (GTypeModule * module)
2642 {
2643         static const GTypeInfo object_info =
2644         {
2645                 sizeof (ClearlooksStyleClass),
2646                 (GBaseInitFunc) NULL,
2647                 (GBaseFinalizeFunc) NULL,
2648                 (GClassInitFunc) clearlooks_style_class_init,
2649                 NULL,         /* class_finalize */
2650                 NULL,         /* class_data */
2651                 sizeof (ClearlooksStyle),
2652                 0,            /* n_preallocs */
2653                 (GInstanceInitFunc) clearlooks_style_init,
2654                 NULL
2655         };
2656
2657         clearlooks_type_style = g_type_module_register_type (module,
2658                                                              GTK_TYPE_STYLE,
2659                                                              "ClearlooksStyle",
2660                                                              &object_info, 0);
2661 }