+static void
+draw_shadow_rhombus (mw, window, x, y, width, height, erase_p, down_p)
+ XlwMenuWidget mw;
+ Window window;
+ int x;
+ int y;
+ int width;
+ int height;
+ int erase_p;
+ int down_p;
+{
+ Display *dpy = XtDisplay (mw);
+ GC top_gc = !erase_p ? mw->menu.shadow_top_gc : mw->menu.background_gc;
+ GC bottom_gc = !erase_p ? mw->menu.shadow_bottom_gc : mw->menu.background_gc;
+ int thickness = mw->menu.shadow_thickness;
+ XPoint points [4];
+
+ if (!erase_p && down_p)
+ {
+ GC temp;
+ temp = top_gc;
+ top_gc = bottom_gc;
+ bottom_gc = temp;
+ }
+
+ points [0].x = x;
+ points [0].y = y + height / 2;
+ points [1].x = x + thickness;
+ points [1].y = y + height / 2;
+ points [2].x = x + width / 2;
+ points [2].y = y + thickness;
+ points [3].x = x + width / 2;
+ points [3].y = y;
+ XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin);
+ points [0].x = x + width / 2;
+ points [0].y = y;
+ points [1].x = x + width / 2;
+ points [1].y = y + thickness;
+ points [2].x = x + width - thickness;
+ points [2].y = y + height / 2;
+ points [3].x = x + width;
+ points [3].y = y + height / 2;
+ XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin);
+ points [0].x = x;
+ points [0].y = y + height / 2;
+ points [1].x = x + thickness;
+ points [1].y = y + height / 2;
+ points [2].x = x + width / 2;
+ points [2].y = y + height - thickness;
+ points [3].x = x + width / 2;
+ points [3].y = y + height;
+ XFillPolygon (dpy, window, bottom_gc, points, 4, Convex, CoordModeOrigin);
+ points [0].x = x + width / 2;
+ points [0].y = y + height;
+ points [1].x = x + width / 2;
+ points [1].y = y + height - thickness;
+ points [2].x = x + width - thickness;
+ points [2].y = y + height / 2;
+ points [3].x = x + width;
+ points [3].y = y + height / 2;
+ XFillPolygon (dpy, window, bottom_gc, points, 4, Convex, CoordModeOrigin);
+}
+
+
+/* Draw a toggle button on widget MW, X window WINDOW. X/Y is the
+ top-left corner of the menu item. SELECTED_P non-zero means the
+ toggle button is selected. */
+
+static void
+draw_toggle (mw, window, x, y, selected_p)
+ XlwMenuWidget mw;
+ Window window;
+ int x, y, selected_p;
+{
+ int width, height;
+
+ width = toggle_button_width (mw);
+ height = width;
+ x += mw->menu.horizontal_spacing;
+ y += (mw->menu.font->ascent - height) / 2;
+ draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p);
+}
+
+
+/* Draw a radio button on widget MW, X window WINDOW. X/Y is the
+ top-left corner of the menu item. SELECTED_P non-zero means the
+ toggle button is selected. */
+
+static void
+draw_radio (mw, window, x, y, selected_p)
+ XlwMenuWidget mw;
+ Window window;
+ int x, y, selected_p;
+{
+ int width, height;
+
+ width = radio_button_width (mw);
+ height = width;
+ x += mw->menu.horizontal_spacing;
+ y += (mw->menu.font->ascent - height) / 2;
+ draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p);
+}
+
+
+/* Draw a menu separator on widget MW, X window WINDOW. X/Y is the
+ top-left corner of the menu item. WIDTH is the width of the
+ separator to draw. TYPE is the separator type. */
+
+static void
+draw_separator (mw, window, x, y, width, type)
+ XlwMenuWidget mw;
+ Window window;
+ int x, y, width;
+ enum menu_separator type;
+{
+ Display *dpy = XtDisplay (mw);
+ XGCValues xgcv;
+
+ switch (type)
+ {
+ case SEPARATOR_NO_LINE:
+ break;
+
+ case SEPARATOR_SINGLE_LINE:
+ XDrawLine (dpy, window, mw->menu.foreground_gc,
+ x, y, x + width, y);
+ break;
+
+ case SEPARATOR_DOUBLE_LINE:
+ draw_separator (mw, window, x, y, width, SEPARATOR_SINGLE_LINE);
+ draw_separator (mw, window, x, y + 2, width, SEPARATOR_SINGLE_LINE);
+ break;
+
+ case SEPARATOR_SINGLE_DASHED_LINE:
+ xgcv.line_style = LineOnOffDash;
+ XChangeGC (dpy, mw->menu.foreground_gc, GCLineStyle, &xgcv);
+ XDrawLine (dpy, window, mw->menu.foreground_gc,
+ x, y, x + width, y);
+ xgcv.line_style = LineSolid;
+ XChangeGC (dpy, mw->menu.foreground_gc, GCLineStyle, &xgcv);
+ break;
+
+ case SEPARATOR_DOUBLE_DASHED_LINE:
+ draw_separator (mw, window, x, y, width,
+ SEPARATOR_SINGLE_DASHED_LINE);
+ draw_separator (mw, window, x, y + 2, width,
+ SEPARATOR_SINGLE_DASHED_LINE);
+ break;
+
+ case SEPARATOR_SHADOW_ETCHED_IN:
+ XDrawLine (dpy, window, mw->menu.shadow_bottom_gc,
+ x, y, x + width, y);
+ XDrawLine (dpy, window, mw->menu.shadow_top_gc,
+ x, y + 1, x + width, y + 1);
+ break;
+
+ case SEPARATOR_SHADOW_ETCHED_OUT:
+ XDrawLine (dpy, window, mw->menu.shadow_top_gc,
+ x, y, x + width, y);
+ XDrawLine (dpy, window, mw->menu.shadow_bottom_gc,
+ x, y + 1, x + width, y + 1);
+ break;
+
+ case SEPARATOR_SHADOW_ETCHED_IN_DASH:
+ xgcv.line_style = LineOnOffDash;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ draw_separator (mw, window, x, y, width, SEPARATOR_SHADOW_ETCHED_IN);
+ xgcv.line_style = LineSolid;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ break;
+
+ case SEPARATOR_SHADOW_ETCHED_OUT_DASH:
+ xgcv.line_style = LineOnOffDash;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ draw_separator (mw, window, x, y, width, SEPARATOR_SHADOW_ETCHED_OUT);
+ xgcv.line_style = LineSolid;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ break;
+
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_IN:
+ draw_separator (mw, window, x, y, width, SEPARATOR_SHADOW_ETCHED_IN);
+ draw_separator (mw, window, x, y + 3, width, SEPARATOR_SHADOW_ETCHED_IN);
+ break;
+
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT:
+ draw_separator (mw, window, x, y, width,
+ SEPARATOR_SHADOW_ETCHED_OUT);
+ draw_separator (mw, window, x, y + 3, width,
+ SEPARATOR_SHADOW_ETCHED_OUT);
+ break;
+
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH:
+ xgcv.line_style = LineOnOffDash;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ draw_separator (mw, window, x, y, width,
+ SEPARATOR_SHADOW_DOUBLE_ETCHED_IN);
+ xgcv.line_style = LineSolid;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ break;
+
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH:
+ xgcv.line_style = LineOnOffDash;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ draw_separator (mw, window, x, y, width,
+ SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT);
+ xgcv.line_style = LineSolid;
+ XChangeGC (dpy, mw->menu.shadow_bottom_gc, GCLineStyle, &xgcv);
+ XChangeGC (dpy, mw->menu.shadow_top_gc, GCLineStyle, &xgcv);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
+/* Return the pixel height of menu separator SEPARATOR. */
+
+static int
+separator_height (separator)
+ enum menu_separator separator;
+{
+ switch (separator)
+ {
+ case SEPARATOR_NO_LINE:
+ return 2;
+
+ case SEPARATOR_SINGLE_LINE:
+ case SEPARATOR_SINGLE_DASHED_LINE:
+ return 1;
+
+ case SEPARATOR_DOUBLE_LINE:
+ case SEPARATOR_DOUBLE_DASHED_LINE:
+ return 3;
+
+ case SEPARATOR_SHADOW_ETCHED_IN:
+ case SEPARATOR_SHADOW_ETCHED_OUT:
+ case SEPARATOR_SHADOW_ETCHED_IN_DASH:
+ case SEPARATOR_SHADOW_ETCHED_OUT_DASH:
+ return 2;
+
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_IN:
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT:
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH:
+ case SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH:
+ return 5;
+
+ default:
+ abort ();
+ }
+}
+
+