1 /* Redmond95 - a cairo based GTK+ engine
2  * Copyright (C) 2001 Red Hat, Inc.
3  * Copyright (C) 2006 Andrew Johnson <acjgenius@earthlink.net>
4  * Copyright (C) 2006-2007 Benjamin Berg <benjamin@sipsolutions.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * Project contact: <gnome-themes-list@gnome.org>
21  *
22  *
23  * Portions of the code based on/copied from the Bluecurve theme/engine,
24  *   License: LGPL2+
25  *   Copyright:
26  *     Alexander Larsson <alexl@redhat.com>
27  *     Garrett LeSage
28  *     Owen Taylor <otaylor@redhat.com>
29  *
30  * Portions of the code based on/copied from the Metal theme/engine,
31  *   License: LGPL2.1+
32  *   Copyright:
33  *     Randy Gordon, randy@integrand.com
34  *     Owen Taylor <otaylor@redhat.com>
35  *
36  * Portions of the code based on/copied from the Smooth Engine,
37  *   License: LGPL
38  *   Copyright:
39  *     Andrew Johnson <ajgenius@ajgenius.us
40  *
41  */
42 
43 
44 #include "redmond_gtk2_engine.h"
45 #include "redmond_gtk2_drawing.h"
46 #include "redmond_gtk2_misc.h"
47 
48 
49 /***********************************************
50  * redmond_draw_vline -
51  *
52  *   the Function used to draw horizontal spacers.
53  ***********************************************/
54 void
redmond_draw_hline(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x1,gint x2,gint y)55 redmond_draw_hline (GtkStyle * style,
56 	    GdkWindow * window,
57 	    GtkStateType state_type,
58 	    GdkRectangle * area,
59 	    GtkWidget * widget,
60 	    const gchar * detail,
61             gint x1,
62             gint x2,
63             gint y)
64 {
65   RedmondStyle *redmond_style = REDMOND_STYLE (style);
66   cairo_t *cr;
67 
68   CHECK_ARGS
69 
70   cr = ge_gdk_drawable_to_cairo (window, area);
71 
72   do_redmond_draw_line(cr,
73                        &redmond_style->color_cube.dark[state_type],
74                        &redmond_style->color_cube.light[state_type],
75                        area,
76                        x1, x2, y,
77                        TRUE);
78 
79   cairo_destroy(cr);
80 }
81 
82 /***********************************************
83  * redmond_draw_vline -
84  *
85  *   the Function used to draw vertical spacers.
86  ***********************************************/
87 void
redmond_draw_vline(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint y1,gint y2,gint x)88 redmond_draw_vline (GtkStyle * style,
89 	    GdkWindow * window,
90 	    GtkStateType state_type,
91 	    GdkRectangle * area,
92 	    GtkWidget * widget,
93 	    const gchar * detail,
94             gint y1,
95             gint y2,
96             gint x)
97 {
98   RedmondStyle *redmond_style = REDMOND_STYLE (style);
99   cairo_t *cr;
100 
101   if (ge_is_combo_box(widget, FALSE) && (!ge_is_combo_box_entry(widget)))
102     return;
103 
104   CHECK_ARGS
105 
106   cr = ge_gdk_drawable_to_cairo (window, area);
107 
108   do_redmond_draw_line(cr,
109                        &redmond_style->color_cube.dark[state_type],
110                        &redmond_style->color_cube.light[state_type],
111                        area,
112                        y1, y2, x,
113                        FALSE);
114 
115   cairo_destroy(cr);
116 }
117 
118 /***********************************************
119  * redmond_draw_check -
120  *
121  *   the Function used to draw all check boxes.
122  *
123  *   Redmond Check box has essentially 3 looks -
124  *
125  *   Normal/Prelight -
126  *     base[NORMAL] fill, fg[NORMAL] check
127  *
128  *   Selected/Active -
129  *     bg[NORMAL] fill, fg[NORMAL] check
130  *
131  *   Insensitive -
132  *     bg[NORMAL] fill, fg[INSENSITIVE] check
133  *
134  *   The Shadow Always draws with a state NORMAL.
135  ***********************************************/
136 void
redmond_draw_check(GtkStyle * style,GdkWindow * window,GtkStateType state,GtkShadowType shadow,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)137 redmond_draw_check (GtkStyle * style,
138 	    GdkWindow * window,
139 	    GtkStateType state,
140 	    GtkShadowType shadow,
141 	    GdkRectangle * area,
142 	    GtkWidget * widget,
143 	    const gchar * detail,
144             gint x,
145             gint y,
146             gint width,
147             gint height)
148 {
149   RedmondStyle *redmond_style = REDMOND_STYLE (style);
150   cairo_t *cr;
151 
152   CHECK_ARGS
153   SANITIZE_SIZE
154 
155   cr = ge_gdk_drawable_to_cairo (window, area);
156 
157   if (CHECK_DETAIL (detail, "check") && /* Special case for menu items. */
158      (shadow != GTK_SHADOW_ETCHED_IN))
159     {
160       if (shadow == GTK_SHADOW_IN)
161         do_redmond_draw_check (cr, &redmond_style->color_cube.text[GTK_STATE_NORMAL],
162                                x + 2, y + 2, width - 4, height - 4);
163     }
164   else
165     {
166       if (state == GTK_STATE_ACTIVE || state == GTK_STATE_INSENSITIVE)
167       {
168         ge_cairo_set_color(cr, &redmond_style->color_cube.bg[GTK_STATE_NORMAL]);
169 
170         cairo_rectangle(cr, x, y, width - 1, height - 1);
171 
172         cairo_fill(cr);
173       }
174       else
175       {
176         /* Draw stipples for inconsistent checkboxes. */
177         if (shadow == GTK_SHADOW_ETCHED_IN)
178           {
179             do_redmond_draw_masked_fill (cr, &redmond_style->hatch_mask,
180                                              &redmond_style->color_cube.bg[GTK_STATE_NORMAL],
181                                              &redmond_style->color_cube.light[GTK_STATE_NORMAL],
182                                              x, y, width, height);
183           }
184         else
185           {
186             /* ignore PRELIGHT state ... */
187             ge_cairo_set_color(cr, &redmond_style->color_cube.base[GTK_STATE_NORMAL]);
188 
189             cairo_rectangle(cr, x, y, width - 1, height - 1);
190 
191             cairo_fill(cr);
192           }
193       }
194 
195       if ((shadow == GTK_SHADOW_ETCHED_IN) || (state == GTK_STATE_INSENSITIVE))
196         {
197           /* force insensitive color for inconsistent checkboxes */
198           do_redmond_draw_check (cr, &redmond_style->color_cube.fg[GTK_STATE_INSENSITIVE],
199                                  x + 2, y + 2, width - 4, height - 4);
200         }
201       else if (shadow == GTK_SHADOW_IN)
202         {
203           do_redmond_draw_check (cr, &redmond_style->color_cube.fg[GTK_STATE_NORMAL],
204                                  x + 2, y + 2, width - 4, height - 4);
205         }
206 
207       redmond_draw_shadow (style, window, GTK_STATE_NORMAL, GTK_SHADOW_IN,
208 			area, widget, detail, x, y, width, height);
209     }
210 
211     cairo_destroy(cr);
212 }
213 
214 /***********************************************
215  * redmond_draw_option -
216  *
217  *   the Function used to draw all Option boxes
218  *
219  *   Redmond Option box has essentially 3 looks -
220  *
221  *   Normal/Prelight -
222  *     base[NORMAL] fill, fg[NORMAL] check
223  *
224  *   Selected/Active -
225  *     bg[NORMAL] fill, fg[NORMAL] check
226  *
227  *   Insensitive -
228  *     bg[NORMAL] fill, fg[INSENSITIVE] check
229  *
230  *   The Shadow Always draws with a state NORMAL.
231  ***********************************************/
232 void
redmond_draw_option(GtkStyle * style,GdkWindow * window,GtkStateType state,GtkShadowType shadow,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)233 redmond_draw_option (GtkStyle * style,
234 	     GdkWindow * window,
235 	     GtkStateType state,
236 	     GtkShadowType shadow,
237 	     GdkRectangle * area,
238 	     GtkWidget * widget,
239 	     const gchar * detail,
240              gint x,
241              gint y,
242              gint width,
243              gint height)
244 {
245   RedmondStyle *redmond_style = REDMOND_STYLE (style);
246   gdouble bullet_radius;
247   gint center_x;
248   gint center_y;
249   gint radius;
250 
251   cairo_t *cr;
252 
253   CHECK_ARGS
254   SANITIZE_SIZE
255 
256   center_x = x + width/2;
257   center_y = y + height/2;
258   radius = MAX(MIN(width, height)/2, 6);
259   bullet_radius = MAX((radius - 2) * 0.50, 1);
260 
261   cr = ge_gdk_drawable_to_cairo (window, area);
262 
263   if (CHECK_DETAIL (detail, "check") && /* Special case for menu items. */
264      (shadow != GTK_SHADOW_ETCHED_IN))
265     {
266       if (shadow == GTK_SHADOW_IN)
267         {
268           ge_cairo_set_color(cr, &redmond_style->color_cube.text[GTK_STATE_NORMAL]);
269           cairo_arc(cr, center_x, center_y, bullet_radius, 0, 2 * G_PI);
270           cairo_fill(cr);
271         }
272     }
273   else
274     {
275       do_redmond_draw_simple_circle (cr, &redmond_style->color_cube.dark[GTK_STATE_NORMAL],
276                                      &redmond_style->color_cube.light[GTK_STATE_NORMAL],
277                                      center_x, center_y, radius);
278 
279       do_redmond_draw_simple_circle (cr, &redmond_style->black_border[GTK_STATE_NORMAL],
280                                      &redmond_style->color_cube.bg[GTK_STATE_NORMAL],
281                                      center_x, center_y, radius - 1);
282 
283       if (state == GTK_STATE_ACTIVE || state == GTK_STATE_INSENSITIVE)
284       {
285         ge_cairo_set_color (cr, &redmond_style->color_cube.bg[GTK_STATE_NORMAL]);
286 
287         cairo_arc  (cr, center_x, center_y,  radius - 2, 0, 2*G_PI);
288 
289         cairo_fill (cr);
290       }
291       else
292       {
293         /* Draw stipples for inconsistent checkboxes. */
294         if (shadow == GTK_SHADOW_ETCHED_IN)
295           {
296             cairo_save (cr);
297             cairo_arc  (cr, center_x, center_y,  radius - 2, 0, 2*G_PI);
298             cairo_clip (cr);
299 
300             do_redmond_draw_masked_fill (cr, &redmond_style->hatch_mask,
301                                              &redmond_style->color_cube.bg[GTK_STATE_NORMAL],
302                                              &redmond_style->color_cube.light[GTK_STATE_NORMAL],
303                                              x, y, width, height);
304 
305             cairo_restore (cr);
306           }
307         else
308           {
309             /* ignore PRELIGHT state ... */
310             ge_cairo_set_color (cr, &redmond_style->color_cube.base[GTK_STATE_NORMAL]);
311 
312             cairo_arc  (cr, center_x, center_y,  radius - 2, 0, 2*G_PI);
313 
314             cairo_fill (cr);
315           }
316       }
317 
318       if ((shadow == GTK_SHADOW_ETCHED_IN) || (state == GTK_STATE_INSENSITIVE))
319         {
320           /* force insensitive color for inconsistent checkboxes */
321           ge_cairo_set_color(cr, &redmond_style->color_cube.fg[GTK_STATE_INSENSITIVE]);
322           cairo_arc(cr, center_x, center_y, bullet_radius, 0, 2 * G_PI);
323           cairo_fill(cr);
324         }
325       else if (shadow == GTK_SHADOW_IN)
326         {
327           ge_cairo_set_color(cr, &redmond_style->color_cube.text[GTK_STATE_NORMAL]);
328           cairo_arc(cr, center_x, center_y, bullet_radius, 0, 2 * G_PI);
329           cairo_fill(cr);
330         }
331     }
332 
333      cairo_destroy(cr);
334 }
335 
336 /***********************************************
337  * redmond_draw_arrow -
338  *
339  *   the Function used to draw all arrows
340  *
341  *   Redmond Arrows have 2 looks, Normal
342  *   & Insensitive
343  ***********************************************/
344 void
redmond_draw_arrow(GtkStyle * style,GdkWindow * window,GtkStateType state,GtkShadowType shadow,GdkRectangle * area,GtkWidget * widget,const gchar * detail,GtkArrowType arrow_type,gboolean fill,gint x,gint y,gint width,gint height)345 redmond_draw_arrow (GtkStyle * style,
346 	    GdkWindow * window,
347 	    GtkStateType state,
348 	    GtkShadowType shadow,
349 	    GdkRectangle * area,
350 	    GtkWidget * widget,
351 	    const gchar * detail,
352 	    GtkArrowType arrow_type,
353 	    gboolean fill,
354             gint x,
355             gint y,
356             gint width,
357             gint height)
358 {
359   RedmondStyle *redmond_style = REDMOND_STYLE (style);
360 
361   gboolean button_in = (shadow == GTK_SHADOW_IN);
362   gint child_offset_x = 1, child_offset_y = 1;
363   cairo_t *cr;
364 
365   if (ge_is_combo_box(widget, FALSE) && (!ge_is_combo_box_entry(widget)))
366     return;
367 
368   CHECK_ARGS
369   SANITIZE_SIZE
370 
371   if ((CHECK_DETAIL (detail, "spinbutton"))
372       || (CHECK_DETAIL (detail, "vscrollbar"))
373       || (CHECK_DETAIL (detail, "hscrollbar"))
374       || (CHECK_DETAIL (detail, "optionmenu"))
375       || GE_IS_SCROLLBAR(widget)
376       || (ge_is_in_combo_box (widget)))
377     {
378       if (state != GTK_STATE_INSENSITIVE)
379         state = GTK_STATE_NORMAL;
380 
381       if (CHECK_DETAIL (detail, "spinbutton") || CHECK_DETAIL (detail, "optionmenu"))
382 	{
383 	  if ((!widget) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR))
384 	    x -= 1;
385 	}
386       else if (ge_is_in_combo_box (widget) && ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)))
387 	{
388 	    x += 1;
389 	}
390 
391       if (ge_is_combo_box_entry(widget))
392         {
393 		x += 1;
394         }
395 
396       /* Redmond prefers to have smaller arrows relative too size
397        * for ComboBox/ComboBoxEntry, because its cleaner,
398        * even though it seems slightly inconsistant.
399        */
400       if (widget && ge_is_in_combo_box (widget))
401 	{
402 	  y += 1;
403 	  width -= 2;
404 	  height -= 2;
405 	}
406       else if (button_in)
407 	{
408   	  /* SpinButton & Scrollbar Arrows offset down/right on button press */
409 	  x += child_offset_x;
410 	  y += child_offset_y;
411 	}
412     }
413   else
414     {
415       if (CHECK_DETAIL(detail, "menuitem"))
416           x -= 1;
417       else if (state != GTK_STATE_INSENSITIVE)
418         state = GTK_STATE_NORMAL;
419     }
420 
421   cr = ge_gdk_drawable_to_cairo (window, area);
422 
423   if (state == GTK_STATE_INSENSITIVE)
424     {
425       do_redmond_draw_arrow (cr, &redmond_style->color_cube.light[state], arrow_type, TRUE, x+1, y+1, width, height);
426       do_redmond_draw_arrow (cr, &redmond_style->color_cube.fg[state], arrow_type, TRUE, x, y, width, height);
427     }
428   else
429     do_redmond_draw_arrow (cr, &redmond_style->color_cube.fg[state], arrow_type, TRUE, x, y, width, height);
430 
431   cairo_destroy(cr);
432 }
433 
434 /***********************************************
435  * redmond_draw_shadow -
436  *
437  *   Function used to draw the Shadow/Border
438  *   for most widgets/widget parts.
439  *
440  *   The Redmond Shadow is primarily constructed
441  *   with an outside border of light/extra_dark
442  *   and an internal border of bg/dark.
443  ***********************************************/
444 void
redmond_draw_shadow(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)445 redmond_draw_shadow (GtkStyle * style,
446 	     GdkWindow * window,
447 	     GtkStateType state_type,
448 	     GtkShadowType shadow_type,
449 	     GdkRectangle * area,
450 	     GtkWidget * widget,
451 	     const gchar * detail,
452              gint x,
453              gint y,
454              gint width,
455              gint height)
456 {
457   RedmondStyle *redmond_style = REDMOND_STYLE (style);
458   cairo_t *cr;
459 
460   CHECK_ARGS
461   SANITIZE_SIZE
462 
463   if (shadow_type == GTK_SHADOW_NONE)
464     return;
465 
466   cr = ge_gdk_drawable_to_cairo (window, area);
467 
468   switch (shadow_type)
469     {
470     case GTK_SHADOW_NONE:
471       break;
472     case GTK_SHADOW_ETCHED_IN:
473       ge_cairo_simple_border (cr, &redmond_style->color_cube.dark[state_type],
474 		      &redmond_style->color_cube.light[state_type], x, y, width, height, TRUE);
475       ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
476 		      &redmond_style->color_cube.dark[state_type], x + 1, y + 1, width - 2,
477 		      height - 2, TRUE);
478       break;
479     case GTK_SHADOW_ETCHED_OUT:
480       ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
481 		      &redmond_style->color_cube.dark[state_type], x, y, width, height, TRUE);
482       ge_cairo_simple_border (cr, &redmond_style->color_cube.dark[state_type],
483 		      &redmond_style->color_cube.light[state_type], x + 1, y + 1, width - 2,
484 		      height - 2, TRUE);
485       break;
486     case GTK_SHADOW_IN:
487       if (CHECK_DETAIL (detail, "buttondefault"))
488 	{
489 	  /* Instead of an inset outside border draw an extra black
490 	   * border arround focused defaultable buttons, this really
491 	   * needs some logic so no matter how big the default area
492 	   * it only draws exactly one pixel around button.
493 	   */
494            cairo_set_line_width (cr, 1);
495            ge_cairo_set_color(cr, &redmond_style->black_border[state_type]);
496            ge_cairo_stroke_rectangle(cr, x + 0.5, y + 0.5, width - 1, height - 1);
497 	}
498       else if (((CHECK_DETAIL (detail, "vscrollbar"))
499 		|| (CHECK_DETAIL (detail, "hscrollbar"))
500 		|| ((CHECK_DETAIL (detail, "button")) && (widget)
501 		    && GE_WIDGET_HAS_DEFAULT (widget))))
502 	{
503 	  /* Scrollbar steppers and Defaultable Buttons use a flat
504 	   * dark edge on pressed.
505 	   */
506            cairo_set_line_width (cr, 1);
507            ge_cairo_set_color(cr, &redmond_style->color_cube.dark[state_type]);
508            ge_cairo_stroke_rectangle(cr, x + 0.5, y + 0.5, width - 1, height - 1);
509 	}
510       else if (((CHECK_DETAIL (detail, "entry"))
511 		|| (CHECK_DETAIL (detail, "frame")))
512 	       && widget && ((GE_IS_SPIN_BUTTON (widget))
513 			     || (ge_is_in_combo_box (widget))))
514 	{
515 	  /* The Combo/ComboBoxEntry button and the SpingButton Steppers should apear
516 	   * to be inset into the entry, as opposed to next to it, so we fake it
517 	   * by drawing an extra 2 pixels here to ignore the right(or left)
518 	   * edge, which will be drawn by the buttons.
519 	   */
520 
521 	  if ((!widget) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR))
522 	    {
523 	      ge_cairo_simple_border (cr, &redmond_style->color_cube.dark[state_type],
524 			      &redmond_style->color_cube.light[state_type], x, y, width + 2,
525 			      height, FALSE);
526 	      ge_cairo_simple_border (cr,
527 			      &redmond_style->black_border[state_type],
528 			      &redmond_style->color_cube.bg[state_type], x + 1, y + 1, width,
529 			      height - 2, FALSE);
530 	    }
531 	  else
532 	    {
533 	      ge_cairo_simple_border (cr, &redmond_style->color_cube.dark[state_type],
534 			      &redmond_style->color_cube.light[state_type], x - 2, y,
535 			      width + 2, height, FALSE);
536 	      ge_cairo_simple_border (cr,
537 			      &redmond_style->black_border[state_type],
538 			      &redmond_style->color_cube.bg[state_type], x - 1, y + 1, width,
539 			      height - 2, FALSE);
540 	    }
541 	}
542       else if (((GE_IS_STATUSBAR (widget)))
543 	       || ((CHECK_DETAIL (detail, "frame")))
544 	       || ((CHECK_DETAIL (detail, "button"))
545 		   && (ge_is_toolbar_item (widget))))
546 	{
547 	  /* Toolbar Buttons, Status Bars, Frames, and Troughs are drawn with a thin border */
548 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.dark[state_type],
549 			  &redmond_style->color_cube.light[state_type], x, y, width, height,
550 			  FALSE);
551 	}
552       else
553 	{
554 	  /* Normal IN Border */
555 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.dark[state_type],
556 			  &redmond_style->color_cube.light[state_type], x, y, width, height,
557 			  FALSE);
558 	  ge_cairo_simple_border (cr,
559 			  &redmond_style->black_border[state_type],
560 			  &redmond_style->color_cube.bg[state_type], x + 1, y + 1, width - 2,
561 			  height - 2, FALSE);
562 	}
563       break;
564     case GTK_SHADOW_OUT:
565       if ((CHECK_DETAIL (detail, "vscrollbar"))
566 	  || (CHECK_DETAIL (detail, "hscrollbar"))
567 	  || (CHECK_DETAIL (detail, "slider"))
568 	  || (CHECK_DETAIL (detail, "spinbutton_up"))
569 	  || (CHECK_DETAIL (detail, "spinbutton_down"))
570 	  || ((CHECK_DETAIL (detail, "button")) && ge_is_in_combo_box (widget)))
571 	{
572 	  /* In the case of Scrollbars steppers, Sliders, Spinbutton steppers,
573 	   * and Combo/ComboBoxEntry buttons, the internal & external borders are
574 	   * inverted when OUT since they are inset into another widgets IN edge.
575 	   */
576 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.bg[state_type],
577 			  &redmond_style->black_border[state_type], x, y,
578 			  width, height, FALSE);
579 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
580 			  &redmond_style->color_cube.dark[state_type], x + 1, y + 1, width - 2,
581 			  height - 2, FALSE);
582 	}
583       else if ((CHECK_DETAIL (detail, "frame"))
584 	       || ((CHECK_DETAIL (detail, "button"))
585 		   && (ge_is_toolbar_item (widget))))
586 	{
587 	  /* Toolbar Buttons and Frames are drawn with a thin border */
588 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
589 			  &redmond_style->color_cube.dark[state_type], x, y, width, height,
590 			  FALSE);
591 	}
592       else if (CHECK_DETAIL (detail, "menu"))
593         {
594           ge_cairo_simple_border (cr, &redmond_style->color_cube.bg[state_type],
595                           &redmond_style->black_border[state_type], x, y,
596                           width, height, FALSE);
597           ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
598                           &redmond_style->color_cube.dark[state_type], x + 1, y + 1, width - 2,
599                           height - 2, FALSE);
600         }
601       else
602 	{
603 	  /* Normal OUT Border */
604 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
605 			  &redmond_style->black_border[state_type], x, y,
606 			  width, height, FALSE);
607 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.bg[state_type],
608 			  &redmond_style->color_cube.dark[state_type], x + 1, y + 1, width - 2,
609 			  height - 2, FALSE);
610 	}
611       break;
612     }
613 
614     cairo_destroy(cr);
615 }
616 
617 /***********************************************
618  * redmond_draw_combobox_button-
619  *
620  *   Function used to draw the ComboBox button
621  *   "inset" into "entry.
622  *
623  *   Slightly Evil Hack #1
624  ***********************************************/
625 static void
redmond_draw_combobox_button(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)626 redmond_draw_combobox_button (GtkStyle * style,
627 		      GdkWindow * window,
628 		      GtkStateType state_type,
629 		      GtkShadowType shadow_type,
630 		      GdkRectangle * area,
631 		      GtkWidget * widget,
632 		      const gchar * detail,
633 		      gint x,
634                       gint y,
635                       gint width,
636                       gint height)
637 {
638   RedmondStyle *redmond_style = REDMOND_STYLE (style);
639   cairo_t *cr;
640 
641   /* The Combo/ComboBoxEntry button should apear to be inset into the entry,
642    * as opposed to next to it, so we fake it by drawing an entry fill
643    * then an entry border - but 2 pixels bigger so it overlaps real border
644    * and so left( or right) edge doesn't actually get drawn on screen;
645    * and THEN draw the button, but essentially 4 pixels smaller.
646    */
647   GtkStyle * parent_style = style;
648   GtkStateType parent_state = state_type;
649 
650   if ((!(widget)) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR))
651     {
652       if (ge_is_combo_box_entry (widget)
653           || ge_is_combo_box (widget, TRUE))
654         {
655           if (!ge_is_combo_box_entry (widget))
656             {
657               if ((widget->parent))
658                 {
659                   gtk_widget_ensure_style(widget->parent);
660 
661                   parent_style = widget->parent->style;
662                   parent_state = widget->parent->state;
663                 }
664 
665 	      if (parent_state != GTK_STATE_INSENSITIVE)
666                 parent_state = GTK_STATE_NORMAL;
667 
668 	      gdk_draw_rectangle (window,
669 	      	                  parent_style->base_gc[parent_state],
670 			          TRUE, x - 2, y, width + 2, height);
671 
672             }
673           else
674             gtk_paint_flat_box (style, window, state_type,
675 			        GTK_SHADOW_NONE, area, widget, "entry_bg", x - 2,
676 			        y, width + 2, height);
677 
678           gtk_paint_shadow (style, window, state_type, GTK_SHADOW_IN,
679   		            area, widget, "entry", x - 2, y, width, height);
680         }
681 #ifndef GTK_DISABLE_DEPRECATED
682       else if (ge_is_combo(widget))
683         {
684           GtkWidget *entry = widget;
685 
686 	  if (GE_IS_WIDGET(widget) && GE_IS_WIDGET(widget->parent) && GE_IS_ENTRY(GTK_COMBO (widget->parent)->entry))
687             {
688                entry = GTK_COMBO (widget->parent)->entry;
689                gtk_widget_ensure_style(entry);
690 
691                parent_style = entry->style;
692                parent_state = entry->state;
693              }
694           else
695                 if (GE_IS_WIDGET(widget->parent))
696             {
697                entry = widget->parent;
698                gtk_widget_ensure_style(entry);
699 
700                parent_style = entry->style;
701                parent_state = entry->state;
702             }
703 
704 	  if (parent_state != GTK_STATE_INSENSITIVE)
705             parent_state = GTK_STATE_NORMAL;
706 
707           gtk_paint_flat_box (parent_style, window, parent_state,
708 	 		      GTK_SHADOW_NONE, area, entry, "entry_bg", x - 2,
709 			      y, width + 2, height);
710 
711           {
712             GdkRectangle shadow, clip;
713 
714             shadow.x = x - 2;
715             shadow.y = y;
716             shadow.width = width + 2;
717             shadow.height = height;
718 
719            if (area)
720               gdk_rectangle_intersect(area, &shadow, &clip);
721             else
722               clip = shadow;
723 
724             gtk_paint_shadow (parent_style, window, parent_state, GTK_SHADOW_IN,
725 	 	              &clip, entry, "entry", x - 4, y, width + 2, height);
726           }
727         }
728 #else
729 #warning Disabling GtkCombo support because GTK_DISABLE_DEPRECATED is enabled.
730 #endif
731       else
732         {
733           GtkWidget *parent = widget;
734 
735           if (widget->parent)
736             parent = widget->parent;
737 
738           if ((parent))
739             {
740               gtk_widget_ensure_style(parent);
741 
742               parent_style = parent->style;
743               parent_state = parent->state;
744             }
745 
746           if (parent_state != GTK_STATE_INSENSITIVE)
747             parent_state = GTK_STATE_NORMAL;
748 
749           gtk_paint_flat_box (parent_style, window, parent_state,
750 			      GTK_SHADOW_NONE, area, parent, "entry_bg", x - 2,
751 			      y, width + 2, height);
752           gtk_paint_shadow (parent_style, window, parent_state, GTK_SHADOW_IN,
753 		   	    area, parent, "entry", x - 2, y, width, height);
754         }
755 
756        cr = ge_gdk_drawable_to_cairo (window, area);
757 
758         ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
759 				          x, y + 2, width - 2, height - 4);
760       cairo_destroy(cr);
761 
762       if (shadow_type == GTK_SHADOW_IN)
763         gdk_draw_rectangle (window, style->dark_gc[state_type], FALSE, x,
764 	   		    y + 2, width - 3, height - 5);
765       else
766         gtk_paint_shadow (style, window, state_type, shadow_type, area,
767 		          widget, detail, x, y + 2, width - 2, height - 4);
768     }
769   else
770     {
771       if (ge_is_combo_box_entry (widget)
772           || ge_is_combo_box (widget, TRUE))
773         {
774           if (!ge_is_combo_box_entry (widget))
775             {
776               if ((widget->parent))
777                 {
778                   gtk_widget_ensure_style(widget->parent);
779 
780                   parent_style = widget->parent->style;
781                   parent_state = widget->parent->state;
782                 }
783 
784               if (parent_state != GTK_STATE_INSENSITIVE)
785                 parent_state = GTK_STATE_NORMAL;
786 
787 	      gdk_draw_rectangle (window,
788 		  	          parent_style->base_gc[parent_state],
789 			          TRUE, x + 2, y, width + 2, height);
790             }
791           else
792             gtk_paint_flat_box (style, window, state_type,
793 	  	                GTK_SHADOW_NONE, area, widget, "entry_bg", x + 2,
794 			        y, width + 2, height);
795 
796           gtk_paint_shadow (style, window, state_type, GTK_SHADOW_IN,
797 	  		    area, widget, "entry", x + 2, y, width, height);
798         }
799 #ifndef GTK_DISABLE_DEPRECATED
800       else if (ge_is_combo(widget))
801         {
802           GtkWidget *entry = widget;
803 
804 	  if (GE_IS_WIDGET(widget) && GE_IS_WIDGET(widget->parent) && GE_IS_ENTRY(GTK_COMBO (widget->parent)->entry))
805             {
806                entry = GTK_COMBO (widget->parent)->entry;
807                gtk_widget_ensure_style(entry);
808 
809                parent_style = entry->style;
810                parent_state = entry->state;
811              }
812           else if (GE_IS_WIDGET(widget->parent))
813             {
814                entry = widget->parent;
815                gtk_widget_ensure_style(entry);
816 
817                parent_style = entry->style;
818                parent_state = entry->state;
819             }
820 
821            if (parent_state != GTK_STATE_INSENSITIVE)
822              parent_state = GTK_STATE_NORMAL;
823 
824            gtk_paint_flat_box (parent_style, window, parent_state,
825 			       GTK_SHADOW_NONE, area, entry, "entry_bg", x + 2,
826                                y, width + 2, height);
827            gtk_paint_shadow (parent_style, window, parent_state, GTK_SHADOW_IN,
828 			     area, entry, "entry", x + 2, y, width, height);
829         }
830 #else
831 #warning Disabling GtkCombo support because GTK_DISABLE_DEPRECATED is enabled.
832 #endif /* GTK_DISABLE_DEPRECATED */
833       else
834         {
835           GtkWidget *parent = widget;
836 
837           if (widget->parent)
838             parent = widget->parent;
839 
840           if ((parent))
841             {
842               gtk_widget_ensure_style(parent);
843 
844               parent_style = parent->style;
845               parent_state = parent->state;
846             }
847 
848           if (parent_state != GTK_STATE_INSENSITIVE)
849             parent_state = GTK_STATE_NORMAL;
850 
851           gtk_paint_flat_box (parent_style, window, parent_state,
852 			      GTK_SHADOW_NONE, area, parent, "entry_bg", x + 2,
853 			      y, width + 2, height);
854           gtk_paint_shadow (parent_style, window, parent_state, GTK_SHADOW_IN,
855 		   	    area, parent, "entry", x + 2, y, width, height);
856         }
857 
858       cr = ge_gdk_drawable_to_cairo (window, area);
859 
860       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
861 				          x + 2, y + 2, width - 2, height - 4);
862 
863       cairo_destroy(cr);
864 
865       if (shadow_type == GTK_SHADOW_IN)
866         gdk_draw_rectangle (window, style->dark_gc[state_type], FALSE, x + 2,
867 			    y + 2, width - 3, height - 5);
868       else
869         gtk_paint_shadow (style, window, state_type, shadow_type, area,
870 		          widget, detail, x + 2, y + 2, width - 2, height - 4);
871     }
872 }
873 
874 /***********************************************
875  * redmond_draw_spinbutton_stepper-
876  *
877  *   Function used to draw the spinbutton
878  *   steppers "inset" into entry.
879  *
880  *   Slightly Evil Hack #2
881  ***********************************************/
882 static void
redmond_draw_spinbutton_stepper(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)883 redmond_draw_spinbutton_stepper (GtkStyle * style,
884 			 GdkWindow * window,
885 			 GtkStateType state_type,
886 			 GtkShadowType shadow_type,
887 			 GdkRectangle * area,
888 			 GtkWidget * widget,
889 			 const gchar * detail,
890 			 gint x,
891                          gint y,
892                          gint width,
893                          gint height)
894 {
895   RedmondStyle *redmond_style = REDMOND_STYLE (style);
896   GdkRectangle spin_area;
897   cairo_t *cr;
898 
899   /* The SpinButton Steppers should apear to be inset into the entry,
900    * as opposed to next to it, so we fake it by drawing en entry fill
901    * and then entry border - but 2 pixels bigger so it overlaps real border
902    * and so left( or right) edge doesn't actually get drawn on screen -
903    * and THEN draw the Stepper. Since we have two steppers this is slightly
904    * more complicated because we can only do half for each stepper.
905    */
906 
907   spin_area.x = x;
908   spin_area.y = y;
909   spin_area.width = width;
910   spin_area.height = height;
911 
912   if (state_type != GTK_STATE_INSENSITIVE)
913     state_type = GTK_STATE_NORMAL;
914 
915   if ((!(widget)) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR))
916     {
917       if (CHECK_DETAIL (detail, "spinbutton_up"))
918 	{
919 	  gtk_paint_flat_box (style, window, state_type,
920 			      GTK_SHADOW_NONE, &spin_area, widget,
921 			      "entry_bg", x - 2, y, width + 2, height);
922 	  gtk_paint_shadow (style, window, state_type, GTK_SHADOW_IN,
923 			    &spin_area, widget, detail, x - 2, y,
924 			    width + 2, height + 2);
925           cr = ge_gdk_drawable_to_cairo (window, area);
926 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
927 					      x, y + 2, width - 2, height - 2);
928           cairo_destroy(cr);
929 	  gtk_paint_shadow (style, window, state_type, shadow_type,
930 			    area, widget, detail, x, y + 2, width - 2,
931 			    height - 2);
932 	}
933       else
934 	{
935 	  gtk_paint_flat_box (style, window, state_type,
936 			      GTK_SHADOW_NONE, &spin_area, widget,
937 			      "entry_bg", x - 2, y, width + 2, height);
938 	  gtk_paint_shadow (style, window, state_type, GTK_SHADOW_IN,
939 			    &spin_area, widget, detail, x - 2, y - 2,
940 			    width + 2, height + 2);
941           cr = ge_gdk_drawable_to_cairo (window, area);
942 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
943 					      x, y, width - 2, height - 2);
944           cairo_destroy(cr);
945 	  gtk_paint_shadow (style, window, state_type, shadow_type,
946 			    area, widget, detail, x, y, width - 2,
947 			    height - 2);
948 	}
949     }
950   else
951     {
952       if (CHECK_DETAIL (detail, "spinbutton_up"))
953 	{
954 	  gtk_paint_flat_box (style, window, state_type,
955 			      GTK_SHADOW_NONE, &spin_area, widget,
956 			      "entry_bg", x, y, width + 4, height);
957 	  gtk_paint_shadow (style, window, state_type, GTK_SHADOW_IN,
958 			    &spin_area, widget, detail, x, y,
959 			    width + 4, height + 2);
960           cr = ge_gdk_drawable_to_cairo (window, area);
961 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
962 					      x + 2, y + 2, width - 2, height - 2);
963           cairo_destroy(cr);
964 	  gtk_paint_shadow (style, window, state_type, shadow_type,
965 			    area, widget, detail, x + 2, y + 2, width - 2,
966 			    height - 2);
967 	}
968       else
969 	{
970 	  gtk_paint_flat_box (style, window, state_type,
971 			      GTK_SHADOW_NONE, &spin_area, widget,
972 			      "entry_bg", x, y, width + 4, height);
973 	  gtk_paint_shadow (style, window, state_type, GTK_SHADOW_IN,
974 			    &spin_area, widget, detail, x, y - 2,
975 			    width + 4, height + 2);
976           cr = ge_gdk_drawable_to_cairo (window, area);
977 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
978 					      x + 2, y, width - 2, height - 2);
979           cairo_destroy(cr);
980 	  gtk_paint_shadow (style, window, state_type, shadow_type,
981 			    area, widget, detail, x + 2, y, width - 2,
982 			    height - 2);
983 	}
984     }
985 }
986 
987 /***********************************************
988  * redmond_draw_box -
989  *
990  *   Function used to draw the box portion of
991  *   general widgets (buttons, entries).
992  *
993  *  In general this is the same as calling
994  *  apply background and then draw shadow,
995  *  so the bulk of this routine is actually
996  *  to handle drawing the peculiarities of
997  *  specific widgets which don't follow this
998  *  in redmond.
999  ***********************************************/
1000 void
redmond_draw_box(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)1001 redmond_draw_box (GtkStyle * style,
1002 	  GdkWindow * window,
1003 	  GtkStateType state_type,
1004 	  GtkShadowType shadow_type,
1005 	  GdkRectangle * area,
1006 	  GtkWidget * widget,
1007 	  const gchar * detail,
1008           gint x,
1009           gint y,
1010           gint width,
1011           gint height)
1012 {
1013   RedmondStyle *redmond_style = REDMOND_STYLE (style);
1014   cairo_t *cr;
1015 
1016   CHECK_ARGS
1017   SANITIZE_SIZE
1018 
1019   if (GE_IS_MENU_SHELL(widget))
1020     {
1021       redmond_gtk2_engine_hack_menu_shell_setup_signals(widget);
1022     }
1023 
1024   if ((CHECK_DETAIL (detail, "trough")) &&
1025       (widget && GE_IS_SCROLLBAR (widget)))
1026     {
1027       /* Scrollbar Troughs have a thin cross-hatch
1028        * background fill. Technically its supposed
1029        * to change colors when actively pressed, but
1030        * since  thats a little hard to handle, skip it.
1031        */
1032       cr = ge_gdk_drawable_to_cairo (window, area);
1033       do_redmond_draw_masked_fill (cr, &redmond_style->hatch_mask,
1034                                          &redmond_style->color_cube.bg[state_type],
1035                                          &redmond_style->color_cube.light[state_type],
1036                                          x, y, width, height);
1037 
1038       cairo_destroy(cr);
1039 
1040     }
1041   else if ((CHECK_DETAIL (detail, "trough"))
1042 	   && (widget && GE_IS_SCALE (widget)))
1043     {
1044       /* Scale Troughs are only 4 pixels thick
1045        * i.e. just a border, so make sure the background
1046        * is filled properly, then draw the border.
1047        */
1048       cr = ge_gdk_drawable_to_cairo (window, area);
1049 
1050       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, GTK_STATE_NORMAL),
1051                                     x, y, width, height);
1052       if (GE_IS_HSCALE (widget))
1053 	{
1054           ge_cairo_set_color(cr, &redmond_style->black_border[state_type]);
1055           cairo_rectangle(cr, x, y + (height / 2), width - 2, 1);
1056           cairo_fill(cr);
1057 
1058 	  redmond_draw_shadow (style, window, state_type, GTK_SHADOW_IN, area,
1059 			    widget, detail, x, y + (height / 2) - 1, width,
1060 			    4);
1061 	}
1062       else
1063 	{
1064           ge_cairo_set_color(cr, &redmond_style->black_border[state_type]);
1065           cairo_rectangle(cr, x + (width / 2), y, 1, height - 2);
1066           cairo_fill(cr);
1067 
1068 	  redmond_draw_shadow (style, window, state_type, GTK_SHADOW_IN, area,
1069 			    widget, detail, x + (width / 2) - 1, y, 4,
1070 			    height);
1071 	}
1072       cairo_destroy(cr);
1073     }
1074   else if ((CHECK_DETAIL (detail, "toolbar"))
1075 	   || (CHECK_DETAIL (detail, "menubar"))
1076 	   || (GE_IS_BONOBO_TOOLBAR (widget))
1077 	   || (CHECK_DETAIL (detail, "dockitem"))
1078 	   || (CHECK_DETAIL (detail, "dockitem_bin"))
1079 	   || (CHECK_DETAIL (detail, "handlebox_bin"))
1080 	   || (CHECK_DETAIL (detail, "handlebox")))
1081     {
1082       /* Toolbars have a simple thin border, so custom
1083        * case to handle the various widgets used as
1084        * toolbars.
1085        */
1086        gboolean left_cutoff = FALSE, right_cutoff = FALSE,
1087                 top_cutoff = FALSE, bottom_cutoff = FALSE;
1088 
1089       if (((CHECK_DETAIL (detail, "dockitem_bin")) &&
1090            (GE_IS_BONOBO_DOCK_ITEM(widget))) ||
1091           ((widget) && (ge_is_bonobo_dock_item(widget->parent))))
1092 	{
1093 	  GList *children = NULL, *child = NULL;
1094 	  GtkWidget *dockitem = widget;
1095 	  gboolean has_grip = FALSE, ltr = TRUE;
1096 
1097 	  if ((!GE_IS_BONOBO_DOCK_ITEM(widget)) && (!GE_IS_BOX(widget)))
1098 	    dockitem = widget->parent;
1099 
1100 	  has_grip = GE_IS_CONTAINER(dockitem);
1101 
1102 	  ltr = (!widget) || (gtk_widget_get_direction (dockitem) == GTK_TEXT_DIR_LTR);
1103 
1104 	  if (has_grip)
1105 	  {
1106             has_grip = FALSE;
1107 
1108             children = gtk_container_get_children(GTK_CONTAINER(dockitem));
1109 
1110             for (child = g_list_first(children); child; child = g_list_next(child))
1111               {
1112 	        if (GE_IS_BONOBO_DOCK_ITEM_GRIP(child->data))
1113                   has_grip = (GTK_WIDGET_VISIBLE(child->data) &&
1114                               GTK_WIDGET_REALIZED(child->data) &&
1115                               GTK_WIDGET(child->data)->allocation.width > 1) &&
1116                               (GTK_WIDGET(child->data)->allocation.height > 1);
1117               }
1118 
1119             if (children)
1120   	      g_list_free(children);
1121           }
1122 
1123           if (has_grip)
1124             {
1125 	      /* bonobo dock items draw the handle bar grip different from
1126 	       * other toolbars - namely it draws the bin the whole size
1127 	       * and then the handle bar on top, which make the edge overlap
1128 	       * look wrong, especially relative to bonobo toolbars and
1129 	       * gtk handle bars etc. luckily the handle bar size
1130 	       * is fixed at 10, and the orientation can be grabbed
1131 	       * via gobject, so we just make sure the bin is drawn
1132 	       * NEXT to the handle bar, not beneath it
1133 	       */
1134 
1135    	      GtkOrientation tmp = GTK_ORIENTATION_HORIZONTAL;
1136 
1137 	      if GE_IS_HBOX(dockitem)
1138 	        tmp = GTK_ORIENTATION_VERTICAL;
1139 	      else if (GE_IS_BONOBO_DOCK_ITEM(dockitem))
1140 	        g_object_get (dockitem, "orientation", &tmp, NULL);
1141 
1142 	      if (tmp == GTK_ORIENTATION_HORIZONTAL)
1143 	        {
1144 	          if (dockitem == widget)
1145 	            {
1146 	              x += 8*ltr;
1147 	              width -= 8;
1148 	            }
1149 	          else
1150 	            {
1151 	              x -= 2*ltr;
1152 	              width += 2;
1153 	            }
1154 
1155 	          left_cutoff = ltr;
1156 	          right_cutoff = !left_cutoff;
1157 	        }
1158 	      else
1159 	        {
1160 	          if (dockitem == widget)
1161 	            {
1162 	              y += 8;
1163 	              height -= 8;
1164 	            }
1165 	          else
1166 	            {
1167 	              y -= 2;
1168 	              height += 2;
1169 	            }
1170 	          top_cutoff = TRUE;
1171 	        }
1172 	    }
1173 	}
1174       else if (GE_IS_HANDLE_BOX(widget))
1175         {
1176 	  switch (gtk_handle_box_get_handle_position
1177 		  (GTK_HANDLE_BOX (widget)))
1178 	    {
1179 	      case GTK_POS_LEFT:
1180                 left_cutoff = (!widget) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR);
1181 	        right_cutoff = !left_cutoff;
1182               break;
1183 
1184 	      case GTK_POS_RIGHT:
1185                 left_cutoff = (widget) && (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1186 	        right_cutoff = !left_cutoff;
1187 	      break;
1188 
1189 	      case GTK_POS_TOP:
1190                 top_cutoff = TRUE;
1191 	      break;
1192 
1193               case GTK_POS_BOTTOM:
1194 	        bottom_cutoff = TRUE;
1195 	      break;
1196 	    }
1197         }
1198       else if (GE_IS_HANDLE_BOX_ITEM(widget) && GTK_WIDGET_REALIZED(widget->parent) && GTK_WIDGET_VISIBLE(widget->parent))
1199         {
1200 	  switch (gtk_handle_box_get_handle_position
1201 		  (GTK_HANDLE_BOX (widget->parent)))
1202 	    {
1203 	      case GTK_POS_LEFT:
1204                 left_cutoff = (!widget) || (gtk_widget_get_direction (widget->parent) == GTK_TEXT_DIR_LTR);
1205                 right_cutoff= !left_cutoff;
1206               break;
1207 
1208 	      case GTK_POS_RIGHT:
1209                 left_cutoff = (widget) && (gtk_widget_get_direction (widget->parent) == GTK_TEXT_DIR_RTL);
1210 	        right_cutoff = !left_cutoff;
1211 	      break;
1212 
1213 	      case GTK_POS_TOP:
1214                 top_cutoff = TRUE;
1215                 y -= 2;
1216                 height += 2;
1217 	      break;
1218 
1219               case GTK_POS_BOTTOM:
1220 	        bottom_cutoff = TRUE;
1221                 height += 2;
1222 	      break;
1223 	    }
1224 
1225           if (left_cutoff)
1226             {
1227                x -= 2;
1228                width += 2;
1229 	    }
1230           else
1231             {
1232                width += 2;
1233   	    }
1234         }
1235 
1236       cr = ge_gdk_drawable_to_cairo (window, area);
1237       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1238 					  x, y, width, height);
1239 
1240       /* If this is a menu embedded in the gnome-panel, we don't
1241        *  draw a border since it looks cleaner without one.
1242        */
1243       if ((widget) && (widget->parent) &&
1244 	  ((!((CHECK_DETAIL (detail, "menubar")) &&
1245 	  ge_is_panel_widget_item (widget)))))
1246         {
1247           cairo_save(cr);
1248 
1249           cairo_rectangle(cr, x + 2*left_cutoff, y + 2*top_cutoff, width - 2*left_cutoff, height - 2*top_cutoff);
1250 
1251           cairo_clip(cr);
1252 
1253 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
1254 			          &redmond_style->color_cube.dark[state_type], x, y,
1255                                   width + 2*right_cutoff,
1256                                   height + 2*bottom_cutoff,
1257 			          FALSE);
1258 
1259            cairo_restore(cr);
1260         }
1261       cairo_destroy(cr);
1262     }
1263   else if ((CHECK_DETAIL (detail, "menuitem")) && widget && widget->parent
1264 	   && GE_IS_MENU_BAR (widget->parent))
1265     {
1266       /* Primary Menu Items on Menu bars are drawn with
1267        * a thin inset border on select/active,
1268        * and a thin outset border on prelight
1269        */
1270       CairoColor *top, *bottom;
1271 
1272       if (state_type != GTK_STATE_INSENSITIVE)
1273 	state_type = GTK_STATE_NORMAL;
1274 
1275       cr = ge_gdk_drawable_to_cairo (window, area);
1276 
1277       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1278 					  x, y, width, height);
1279 
1280       if ((!GE_IS_MENU(GTK_MENU_ITEM(widget)->submenu)) ||
1281           (!(GTK_WIDGET_REALIZED(GTK_MENU_ITEM(widget)->submenu) &&
1282              GTK_WIDGET_VISIBLE(GTK_MENU_ITEM(widget)->submenu) &&
1283              GTK_WIDGET_REALIZED(GTK_MENU(GTK_MENU_ITEM(widget)->submenu)->toplevel) &&
1284              GTK_WIDGET_VISIBLE(GTK_MENU(GTK_MENU_ITEM(widget)->submenu)->toplevel))))
1285         {
1286           top = &redmond_style->color_cube.light[state_type];
1287           bottom = &redmond_style->color_cube.dark[state_type];
1288         }
1289       else
1290         {
1291           top = &redmond_style->color_cube.dark[state_type];
1292           bottom = &redmond_style->color_cube.light[state_type];
1293         }
1294 
1295       ge_cairo_simple_border (cr, top, bottom,
1296 		      x, y, width, height,
1297 		      FALSE);
1298 
1299       cairo_destroy(cr);
1300     }
1301   else if ((CHECK_DETAIL (detail, "bar"))
1302 	   && (widget && GE_IS_PROGRESS_BAR (widget)))
1303     {
1304       /* Progress bar status is always flat, and only has two states
1305        * NORMAL and INSENSITIVE, so check the state, and then do a
1306        * default draw background.
1307        */
1308       if (state_type != GTK_STATE_INSENSITIVE)
1309 	state_type = GTK_STATE_NORMAL;
1310 
1311       cr = ge_gdk_drawable_to_cairo (window, area);
1312       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, GTK_STATE_SELECTED),
1313                                     x, y, width, height);
1314       cairo_destroy(cr);
1315     }
1316   else if ((CHECK_DETAIL (detail, "button")) && widget
1317 	   && ge_is_in_combo_box (widget))
1318     {
1319       /* ComboBox Buttons are an especially complex case
1320        * so call our special function for them.
1321        */
1322       redmond_draw_combobox_button (style, window, state_type, shadow_type, area,
1323 			    widget, detail, x, y, width, height);
1324     }
1325   else if ((CHECK_DETAIL (detail, "spinbutton_up"))
1326 	   || (CHECK_DETAIL (detail, "spinbutton_down")))
1327     {
1328       /* SpinButton Steppers are an especially complex case
1329        * so call our special function for them.
1330        */
1331       redmond_draw_spinbutton_stepper (style, window, state_type, shadow_type, area,
1332 			       widget, detail, x, y, width, height);
1333     }
1334   else if (GE_IS_TOGGLE_BUTTON (widget) && (shadow_type == GTK_SHADOW_IN))
1335     {
1336       gint pointer_x, pointer_y;
1337       GdkModifierType pointer_mask;
1338 
1339       gdk_window_get_pointer(widget->window, &pointer_x, &pointer_y, &pointer_mask);
1340 
1341       cr = ge_gdk_drawable_to_cairo (window, area);
1342       if ((pointer_x >= widget->allocation.x) &&
1343 	  (pointer_y >= widget->allocation.y) &&
1344 	  (pointer_x < (widget->allocation.x +
1345 	                widget->allocation.width)) &&
1346 	  (pointer_y < (widget->allocation.y +
1347 	                widget->allocation.height)))
1348         {
1349           ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1350                                         x, y, width, height);
1351         }
1352       else
1353       {
1354            do_redmond_draw_masked_fill (cr, &redmond_style->hatch_mask,
1355                                          &redmond_style->color_cube.bg[GTK_STATE_NORMAL],
1356                                          &redmond_style->color_cube.light[GTK_STATE_NORMAL],
1357                                          x, y, width, height);
1358       }
1359 
1360       cairo_destroy(cr);
1361       redmond_draw_shadow (style, window, state_type, shadow_type, area,
1362 			widget, detail, x, y, width, height);
1363     }
1364   else
1365     {
1366       /* default box apearance */
1367       cr = ge_gdk_drawable_to_cairo (window, area);
1368 
1369       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1370                                     x, y, width,height);
1371       cairo_destroy(cr);
1372       redmond_draw_shadow (style, window, state_type, shadow_type, area,
1373 			widget, detail, x, y, width, height);
1374     }
1375 
1376   if (CHECK_DETAIL(detail, "optionmenu") ||  (CHECK_DETAIL(detail, "button") &&
1377        (ge_is_combo_box(widget, FALSE)) && !(ge_is_combo_box_entry(widget))))
1378     {
1379       GtkRequisition indicator_size;
1380       GtkBorder indicator_spacing;
1381       gint vline_x;
1382 
1383       if (state_type != GTK_STATE_INSENSITIVE)
1384         state_type = GTK_STATE_NORMAL;
1385 
1386       ge_option_menu_get_props (widget, &indicator_size, &indicator_spacing);
1387 
1388       if ((!widget) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL))
1389 	vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
1390       else
1391 	vline_x = x + width - (indicator_size.width + indicator_spacing.left +
1392                                indicator_spacing.right) - style->xthickness;
1393 
1394       cr = ge_gdk_drawable_to_cairo (window, area);
1395 
1396       do_redmond_draw_line(cr, &redmond_style->color_cube.dark[state_type], &redmond_style->color_cube.light[state_type],
1397                            area, y + style->ythickness + 1, y + height - style->ythickness - 2,
1398                            vline_x, FALSE);
1399 
1400       cairo_destroy(cr);
1401 
1402       if ((widget) && (gtk_widget_get_direction (GTK_WIDGET (widget)) == GTK_TEXT_DIR_RTL))
1403          x +=  indicator_spacing.right + style->xthickness;
1404       else
1405          x += width - indicator_size.width - indicator_spacing.right - style->xthickness;
1406 
1407       y += ((height - indicator_size.height) / 2) + 1;
1408 
1409       width = indicator_size.width;
1410       height = indicator_size.height;
1411 
1412       redmond_draw_arrow (style, window, state_type, shadow_type, area, NULL, "optionmenu",
1413 	                      GTK_ARROW_DOWN, TRUE,  x,  y,  width,  height);
1414    }
1415 }
1416 
1417 /***********************************************
1418  * redmond_draw_tab -
1419  *
1420  *   Function pretty much only called to draw
1421  *   the arrow "tab" in the option menu
1422  ***********************************************/
1423 void
redmond_draw_tab(GtkStyle * style,GdkWindow * window,GtkStateType state,GtkShadowType shadow,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height)1424 redmond_draw_tab (GtkStyle * style,
1425 	  GdkWindow * window,
1426 	  GtkStateType state,
1427 	  GtkShadowType shadow,
1428 	  GdkRectangle * area,
1429 	  GtkWidget * widget,
1430 	  const gchar * detail,
1431           gint x,
1432           gint y,
1433           gint width,
1434           gint height)
1435 {
1436 }
1437 
1438 /***********************************************
1439  * redmond_draw_slider -
1440  *
1441  *   Function which draws scale/scrollbar slider
1442  ***********************************************/
1443 void
redmond_draw_slider(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)1444 redmond_draw_slider (GtkStyle * style,
1445 	     GdkWindow * window,
1446 	     GtkStateType state_type,
1447 	     GtkShadowType shadow_type,
1448 	     GdkRectangle * area,
1449 	     GtkWidget * widget,
1450 	     const gchar * detail,
1451 	     gint x,
1452 	     gint y,
1453              gint width,
1454              gint height,
1455              GtkOrientation orientation)
1456 {
1457   RedmondStyle *redmond_style = REDMOND_STYLE (style);
1458 
1459   CHECK_ARGS
1460   SANITIZE_SIZE
1461 
1462   if ((CHECK_DETAIL (detail, "hscale")) || (CHECK_DETAIL (detail, "vscale")))
1463     {
1464       cairo_t *cr = ge_gdk_drawable_to_cairo (window, area);
1465       ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1466                                     x, y, width, height);
1467 
1468       cairo_destroy(cr);
1469       redmond_draw_shadow (style, window, state_type, GTK_SHADOW_OUT, area,
1470                            widget, detail, x, y, width, height);
1471     }
1472   else
1473     redmond_draw_box (style, window, state_type, shadow_type, area,
1474                       widget, detail, x, y, width, height);
1475 }
1476 
1477 /***********************************************
1478  * redmond_draw_extension -
1479  *
1480  *   Function which draws notebook extensions -
1481  *   aka, tabs.
1482  *
1483  *  This routine is so complex mostly because
1484  *  it tries to draw a faked 1-2 pixel rounded
1485  *  corner.
1486  ***********************************************/
1487 void
redmond_draw_extension(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkPositionType gap_side)1488 redmond_draw_extension (GtkStyle * style,
1489 		GdkWindow * window,
1490 		GtkStateType state_type,
1491 		GtkShadowType shadow_type,
1492 		GdkRectangle * area,
1493 		GtkWidget * widget,
1494 		const gchar * detail,
1495 		gint x,
1496 		gint y,
1497                 gint width,
1498                 gint height,
1499                 GtkPositionType gap_side)
1500 {
1501   RedmondStyle *redmond_style = REDMOND_STYLE (style);
1502 
1503   CairoColor *color1 = NULL;
1504   CairoColor *color2 = NULL;
1505   CairoColor *color3 = NULL;
1506   CairoColor *color4 = NULL;
1507   cairo_t *cr;
1508   gint tab_overlap = 0;
1509 
1510   CHECK_ARGS
1511   SANITIZE_SIZE
1512 
1513   if (GE_IS_NOTEBOOK (widget))
1514     gtk_widget_style_get (widget, "tab-overlap", &tab_overlap, NULL);
1515 
1516   /* If the tab_overlap is large, then decrease the size of active tabs. */
1517   if (state_type == GTK_STATE_ACTIVE && tab_overlap >= 4)
1518     {
1519       if (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)
1520         {
1521           x += 2;
1522           width -= 4;
1523         }
1524       else
1525         {
1526           y += 2;
1527           height -= 4;
1528         }
1529     }
1530 
1531   cr = ge_gdk_drawable_to_cairo (window, area);
1532   ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, GTK_STATE_NORMAL),
1533                                 x, y, width, height);
1534   switch (shadow_type)
1535     {
1536     case GTK_SHADOW_NONE:
1537       /* need to destroy the cairo context */
1538       cairo_destroy (cr);
1539       return;
1540     case GTK_SHADOW_IN:
1541       color1 = &redmond_style->color_cube.dark[state_type];
1542       color2 = &redmond_style->black_border[state_type];
1543       color3 = &redmond_style->color_cube.bg[state_type];
1544       color4 = &redmond_style->color_cube.light[state_type];
1545       break;
1546     case GTK_SHADOW_ETCHED_IN:
1547       color1 = &redmond_style->color_cube.dark[state_type];
1548       color2 = &redmond_style->color_cube.light[state_type];
1549       color3 = &redmond_style->color_cube.dark[state_type];
1550       color4 = &redmond_style->color_cube.light[state_type];
1551       break;
1552     case GTK_SHADOW_OUT:
1553       color1 = &redmond_style->color_cube.light[state_type];
1554       color2 = &redmond_style->color_cube.bg[state_type];
1555       color3 = &redmond_style->color_cube.dark[state_type];
1556       color4 = &redmond_style->black_border[state_type];
1557       break;
1558     case GTK_SHADOW_ETCHED_OUT:
1559       color1 = &redmond_style->color_cube.light[state_type];
1560       color2 = &redmond_style->color_cube.dark[state_type];
1561       color3 = &redmond_style->color_cube.light[state_type];
1562       color4 = &redmond_style->color_cube.dark[state_type];
1563       break;
1564     }
1565 
1566   switch (shadow_type)
1567     {
1568     case GTK_SHADOW_NONE:
1569     case GTK_SHADOW_IN:
1570     case GTK_SHADOW_OUT:
1571     case GTK_SHADOW_ETCHED_IN:
1572     case GTK_SHADOW_ETCHED_OUT:
1573       switch (gap_side)
1574 	{
1575 	case GTK_POS_TOP:
1576 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1577                                         x + style->xthickness,
1578                                         y,
1579                                         width - (2 * style->xthickness),
1580                                         height - (style->ythickness));
1581 
1582 	  ge_cairo_line (cr, color1, x, y, x, y + height - 2);
1583 	  ge_cairo_line (cr, color2, x + 1, y, x + 1, y + height - 2);
1584 
1585 	  ge_cairo_line (cr, color3,
1586 			 x + 2, y + height - 2, x + width - 2,
1587 			 y + height - 2);
1588 	  ge_cairo_line (cr, color3, x + width - 2, y, x + width - 2,
1589 			 y + height - 2);
1590 	  ge_cairo_line (cr, color4, x + 1, y + height - 1, x + width - 2,
1591 			 y + height - 1);
1592 	  ge_cairo_line (cr, color4, x + width - 1, y, x + width - 1,
1593 			 y + height - 2);
1594 	  break;
1595 	case GTK_POS_BOTTOM:
1596 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1597                                         x + style->xthickness,
1598                                         y + style->ythickness,
1599                                         width - (2 * style->xthickness),
1600                                         height - (style->ythickness));
1601 
1602 	  ge_cairo_line (cr, color1, x + 2, y, x + width - 3, y);
1603 	  ge_cairo_line (cr, color1, x, y + 2, x, y + height - 1);
1604 
1605 	  ge_cairo_line (cr, color2, x + 1, y + 1, x + width - 2, y + 1);
1606 	  ge_cairo_line (cr, color2, x + 1, y + 1, x + 1, y + height - 1);
1607 	  ge_cairo_line (cr, color1, x, y + 2, x + 1, y + 1);
1608 
1609 	  ge_cairo_line (cr, color3,
1610 			 x + width - 2, y + 2, x + width - 2, y + height - 1);
1611 	  ge_cairo_line (cr, color4, x + width - 1, y + 2, x + width - 1,
1612 			 y + height - 1);
1613 	  ge_cairo_line (cr, color4, x + width - 1, y + 2, x + width - 2,
1614 			 y + 1);
1615 	  break;
1616 	case GTK_POS_LEFT:
1617 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1618                                         x,
1619                                         y + style->ythickness,
1620                                         width - (style->xthickness),
1621                                         height - (2 * style->ythickness));
1622 
1623 	  ge_cairo_line (cr, color1, x, y, x + width - 2, y);
1624 	  ge_cairo_line (cr, color2, x + 1, y + 1, x + width - 2, y + 1);
1625 
1626 	  ge_cairo_line (cr, color3,
1627 			 x, y + height - 2, x + width - 2, y + height - 2);
1628 	  ge_cairo_line (cr, color3,
1629 			 x + width - 2, y + 2, x + width - 2, y + height - 2);
1630 	  ge_cairo_line (cr, color4, x, y + height - 1, x + width - 2,
1631 			 y + height - 1);
1632 	  ge_cairo_line (cr, color4, x + width - 1, y + 1, x + width - 1,
1633 			 y + height - 2);
1634 	  break;
1635 	case GTK_POS_RIGHT:
1636 	  ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1637                                         x + style->xthickness,
1638                                         y + style->ythickness,
1639                                         width - (style->xthickness),
1640                                         height - (2 * style->ythickness));
1641 
1642 	  ge_cairo_line (cr, color1, x + 1, y, x + width - 1, y);
1643 	  ge_cairo_line (cr, color1, x, y + 1, x, y + height - 2);
1644 	  ge_cairo_line (cr, color2, x + 1, y + 1, x + width - 1, y + 1);
1645 	  ge_cairo_line (cr, color2, x + 1, y + 1, x + 1, y + height - 2);
1646 
1647 	  ge_cairo_line (cr, color3,
1648 			 x + 2, y + height - 2, x + width - 1,
1649 			 y + height - 2);
1650 	  ge_cairo_line (cr, color4, x + 1, y + height - 1, x + width - 1,
1651 			 y + height - 1);
1652 	  break;
1653 	}
1654     }
1655 
1656     cairo_destroy(cr);
1657 }
1658 
1659 /***********************************************
1660  * redmond_draw_handle -
1661  *
1662  *   Function which draws Handle box-
1663  *   aka toolbar drag grip/paned drag grip
1664  ***********************************************/
1665 void
redmond_draw_handle(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)1666 redmond_draw_handle (GtkStyle * style,
1667 	     GdkWindow * window,
1668 	     GtkStateType state_type,
1669 	     GtkShadowType shadow_type,
1670 	     GdkRectangle * area,
1671 	     GtkWidget * widget,
1672 	     const gchar * detail,
1673 	     gint x,
1674 	     gint y,
1675              gint width,
1676              gint height,
1677              GtkOrientation orientation)
1678 {
1679   RedmondStyle *redmond_style = REDMOND_STYLE (style);
1680   cairo_t *cr;
1681 
1682   gboolean left_cutoff = FALSE, right_cutoff = FALSE, top_cutoff = FALSE, bottom_cutoff = FALSE;
1683 
1684   CHECK_ARGS
1685   SANITIZE_SIZE
1686 
1687   if (GE_IS_BONOBO_DOCK_ITEM_GRIP(widget) &&
1688      (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) &&
1689      (orientation == (GTK_ORIENTATION_HORIZONTAL)) &&
1690      (widget->parent != NULL))
1691   {
1692     x = widget->parent->allocation.width - widget->allocation.width;
1693     y = widget->parent->allocation.height - widget->allocation.height;
1694     width = widget->allocation.width;
1695     height = widget->allocation.height;
1696 
1697     area = NULL;
1698   }
1699 
1700   cr = ge_gdk_drawable_to_cairo (window, area);
1701   ge_cairo_pattern_fill (cr, DEFAULT_BACKGROUND_PATTERN(redmond_style, state_type),
1702                                 x, y, width, height);
1703 
1704   if (widget && !(GE_IS_PANED (widget)))
1705     {
1706       if (GE_IS_HANDLE_BOX (widget))
1707 	{
1708 	  /* handle box apears to be broken in that
1709 	   * it doesn't pass the orientation properly,
1710 	   * but always passes as vertical, so we look
1711 	   * it up ourselves.
1712 	   */
1713 	  switch (gtk_handle_box_get_handle_position
1714 		  (GTK_HANDLE_BOX (widget)))
1715 	    {
1716 	    case GTK_POS_LEFT:
1717 	    case GTK_POS_RIGHT:
1718 	      orientation = GTK_ORIENTATION_HORIZONTAL;
1719 	      break;
1720 
1721 	    case GTK_POS_TOP:
1722 	    case GTK_POS_BOTTOM:
1723 	      orientation = GTK_ORIENTATION_VERTICAL;
1724 	      break;
1725 	    }
1726 	}
1727       else
1728 	{
1729 	  if ((CHECK_DETAIL (detail, "handlebox")
1730 	       && (!GE_IS_HANDLE_BOX_ITEM (widget))))
1731 	    {
1732 	      /* panel_applet_frame used by the panel is broken,
1733 	       * always passes orientation == horizontal
1734 	       * since we don't know anything about the panel
1735 	       * here, we just determine orientation by size.
1736 	       *
1737 	       * If this is on a PanelWidget, we also offset the
1738 	       * actual drag bar by 2 pixels, since we draw
1739 	       * a line next to it instead of drawing a border
1740 	       * around it.
1741 	       */
1742 	      if (width < height)
1743 		{
1744 		  orientation = GTK_ORIENTATION_HORIZONTAL;
1745 		  if (ge_is_panel_widget_item (widget))
1746 		    x += 2;
1747 		}
1748 	      else
1749 		{
1750 		  orientation = GTK_ORIENTATION_VERTICAL;
1751 		  if (ge_is_panel_widget_item (widget))
1752 		    y += 2;
1753 		}
1754 	    }
1755 	}
1756 
1757       /* draw the drag bar */
1758       if (orientation == GTK_ORIENTATION_VERTICAL)
1759         {
1760 
1761 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
1762 			          &redmond_style->color_cube.dark[state_type],
1763 			          x + style->xthickness + 1, y + height / 2 - 1,
1764 			          width - style->xthickness - 3, 3, FALSE);
1765 
1766           bottom_cutoff = TRUE;
1767         }
1768       else
1769         {
1770           right_cutoff = (!widget) || (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR);
1771           left_cutoff = !right_cutoff;
1772 
1773 	  ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
1774 			          &redmond_style->color_cube.dark[state_type], x + width / 2 - 1,
1775 			          y + style->ythickness + 1, 3,
1776 			          height - style->ythickness - 3, FALSE);
1777         }
1778 
1779       if (ge_is_panel_widget_item (widget)
1780 	  && (CHECK_DETAIL (detail, "handlebox")
1781 	      && (!GE_IS_HANDLE_BOX_ITEM (widget)))
1782 	  && (!(GE_IS_HANDLE_BOX (widget))))
1783 	{
1784 	  /* If this is on a PanelWidget, we draw a line
1785 	   * next to it instead of drawing a border around it.
1786 	   */
1787 	  if (orientation == GTK_ORIENTATION_VERTICAL)
1788 	    {
1789 	      ge_cairo_line (cr, &redmond_style->color_cube.dark[state_type], x + 1, y + 0,
1790 			     x + width - 2, y + 0);
1791 	      ge_cairo_line (cr, &redmond_style->color_cube.light[state_type], x + 1,
1792 			     y + 1, x + width - 2, y + 1);
1793 	    }
1794 	  else
1795 	    {
1796 	      ge_cairo_line (cr, &redmond_style->color_cube.dark[state_type], x + 0, y + 1,
1797 			     x + 0, y + height - 2);
1798 	      ge_cairo_line (cr, &redmond_style->color_cube.light[state_type], x + 1,
1799 			     y + 1, x + 1, y + height - 2);
1800 	    }
1801 	}
1802       else
1803 	{
1804 	  GdkRectangle shadow, clip;
1805 	  gboolean skip_shadow = FALSE;
1806 
1807 	  shadow.x = x;
1808           shadow.y = y;
1809           shadow.width = width;
1810           shadow.height = height;
1811 
1812           if (area)
1813             gdk_rectangle_intersect(area, &shadow, &clip);
1814           else
1815             clip = shadow;
1816 
1817           if (GE_IS_BONOBO_DOCK_ITEM_GRIP(widget))
1818             {
1819               if GE_IS_BOX(widget->parent)
1820                 {
1821                   GList *children = NULL, *child = NULL;
1822 
1823                   children = gtk_container_get_children(GTK_CONTAINER(widget->parent));
1824 
1825                   for (child = g_list_first(children); child; child = g_list_next(child))
1826                     {
1827 	              if (GE_IS_BOX(child->data))
1828 	                {
1829 	                  skip_shadow = TRUE;
1830 	                  child = NULL;
1831 	                }
1832                     }
1833 
1834                   if (children)
1835   	            g_list_free(children);
1836                 }
1837             }
1838 
1839           if (!skip_shadow)
1840             {
1841    	       ge_cairo_simple_border (cr, &redmond_style->color_cube.light[state_type],
1842 			               &redmond_style->color_cube.dark[state_type],
1843                                        x - 2*left_cutoff,
1844                                        y - 2*top_cutoff,
1845                                        width + 2*left_cutoff + 2*right_cutoff,
1846 			               height + 2*top_cutoff + 2*bottom_cutoff,
1847 			               FALSE);
1848             }
1849 	}
1850     }
1851     cairo_destroy(cr);
1852 }
1853