/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved		by Bram Moolenaar
 *				GUI/Motif support by Robert Webb
 *				Athena port by Bill Foster
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#ifdef FEAT_GUI_NEXTAW
# include <X11/neXtaw/Form.h>
# include <X11/neXtaw/SimpleMenu.h>
# include <X11/neXtaw/MenuButton.h>
# include <X11/neXtaw/SmeBSB.h>
# include <X11/neXtaw/SmeLine.h>
# include <X11/neXtaw/Box.h>
# include <X11/neXtaw/Dialog.h>
# include <X11/neXtaw/Text.h>
# include <X11/neXtaw/AsciiText.h>
# include <X11/neXtaw/Scrollbar.h>
#else
# include <X11/Xaw/Form.h>
# include <X11/Xaw/SimpleMenu.h>
# include <X11/Xaw/MenuButton.h>
# include <X11/Xaw/SmeBSB.h>
# include <X11/Xaw/SmeLine.h>
# include <X11/Xaw/Box.h>
# include <X11/Xaw/Dialog.h>
# include <X11/Xaw/Text.h>
# include <X11/Xaw/AsciiText.h>
#endif /* FEAT_GUI_NEXTAW */

#include "vim.h"
#ifndef FEAT_GUI_NEXTAW
# include "gui_at_sb.h"
#endif

extern Widget vimShell;

static Widget vimForm = (Widget)0;
Widget textArea = (Widget)0;
#ifdef FEAT_MENU
static Widget menuBar = (Widget)0;
static XtIntervalId timer = 0;	    /* 0 = expired, otherwise active */

/* Used to figure out menu ordering */
static vimmenu_T *a_cur_menu = NULL;
static Cardinal	athena_calculate_ins_pos __ARGS((Widget));

static Pixmap gui_athena_create_pullright_pixmap __ARGS((Widget));
static void gui_athena_menu_timeout __ARGS((XtPointer, XtIntervalId *));
static void gui_athena_popup_callback __ARGS((Widget, XtPointer, XtPointer));
static void gui_athena_delayed_arm_action __ARGS((Widget, XEvent *, String *,
						 Cardinal *));
static void gui_athena_popdown_submenus_action __ARGS((Widget, XEvent *,
						      String *, Cardinal *));
static XtActionsRec	pullAction[2] = {
    { "menu-delayedpopup", (XtActionProc)gui_athena_delayed_arm_action},
    { "menu-popdownsubmenus", (XtActionProc)gui_athena_popdown_submenus_action}
};
#endif

#ifdef FEAT_TOOLBAR
static void gui_mch_reset_focus __ARGS((void));
static Widget toolBar = (Widget)0;
#endif

static void gui_athena_scroll_cb_jump	__ARGS((Widget, XtPointer, XtPointer));
static void gui_athena_scroll_cb_scroll __ARGS((Widget, XtPointer, XtPointer));
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU)
static void gui_athena_menu_colors __ARGS((Widget id));
#endif
static void gui_athena_scroll_colors __ARGS((Widget id));

#ifdef FEAT_MENU
static XtTranslations	popupTrans, parentTrans, menuTrans, supermenuTrans;
static Pixmap		pullerBitmap = None;
static int		puller_width = 0;
#endif

/*
 * Scrollbar callback (XtNjumpProc) for when the scrollbar is dragged with the
 * left or middle mouse button.
 */
    static void
gui_athena_scroll_cb_jump(w, client_data, call_data)
    Widget	w UNUSED;
    XtPointer	client_data, call_data;
{
    scrollbar_T *sb, *sb_info;
    long	value;

    sb = gui_find_scrollbar((long)client_data);

    if (sb == NULL)
	return;
    else if (sb->wp != NULL)	    /* Left or right scrollbar */
    {
	/*
	 * Careful: need to get scrollbar info out of first (left) scrollbar
	 * for window, but keep real scrollbar too because we must pass it to
	 * gui_drag_scrollbar().
	 */
	sb_info = &sb->wp->w_scrollbars[0];
    }
    else	    /* Bottom scrollbar */
	sb_info = sb;

    value = (long)(*((float *)call_data) * (float)(sb_info->max + 1) + 0.001);
    if (value > sb_info->max)
	value = sb_info->max;

    gui_drag_scrollbar(sb, value, TRUE);
}

/*
 * Scrollbar callback (XtNscrollProc) for paging up or down with the left or
 * right mouse buttons.
 */
    static void
gui_athena_scroll_cb_scroll(w, client_data, call_data)
    Widget	w UNUSED;
    XtPointer	client_data, call_data;
{
    scrollbar_T *sb, *sb_info;
    long	value;
    int		data = (int)(long)call_data;
    int		page;

    sb = gui_find_scrollbar((long)client_data);

    if (sb == NULL)
	return;
    if (sb->wp != NULL)		/* Left or right scrollbar */
    {
	/*
	 * Careful: need to get scrollbar info out of first (left) scrollbar
	 * for window, but keep real scrollbar too because we must pass it to
	 * gui_drag_scrollbar().
	 */
	sb_info = &sb->wp->w_scrollbars[0];

	if (sb_info->size > 5)
	    page = sb_info->size - 2;	    /* use two lines of context */
	else
	    page = sb_info->size;
#ifdef FEAT_GUI_NEXTAW
	if (data < 0)
	{
	    data = (data - gui.char_height + 1) / gui.char_height;
	    if (data > -sb_info->size)
		data = -1;
	    else
		data = -page;
	}
	else if (data > 0)
	{
	    data = (data + gui.char_height - 1) / gui.char_height;
	    if (data < sb_info->size)
		data = 1;
	    else
		data = page;
	}
#else
	switch (data)
	{
	    case  ONE_LINE_DATA: data = 1; break;
	    case -ONE_LINE_DATA: data = -1; break;
	    case  ONE_PAGE_DATA: data = page; break;
	    case -ONE_PAGE_DATA: data = -page; break;
	    case  END_PAGE_DATA: data = sb_info->max; break;
	    case -END_PAGE_DATA: data = -sb_info->max; break;
			default: data = 0; break;
	}
#endif
    }
    else			/* Bottom scrollbar */
    {
	sb_info = sb;
#ifdef FEAT_GUI_NEXTAW
	if (data < 0)
	{
	    data = (data - gui.char_width + 1) / gui.char_width;
	    if (data > -sb->size)
		data = -1;
	}
	else if (data > 0)
	{
	    data = (data + gui.char_width - 1) / gui.char_width;
	    if (data < sb->size)
		data = 1;
	}
#endif
	if (data < -1)		/* page-width left */
	{
	    if (sb->size > 8)
		data = -(sb->size - 5);
	    else
		data = -sb->size;
	}
	else if (data > 1)	/* page-width right */
	{
	    if (sb->size > 8)
		data = (sb->size - 5);
	    else
		data = sb->size;
	}
    }

    value = sb_info->value + data;
    if (value > sb_info->max)
	value = sb_info->max;
    else if (value < 0)
	value = 0;

    /* Update the bottom scrollbar an extra time (why is this needed?? */
    if (sb->wp == NULL)		/* Bottom scrollbar */
	gui_mch_set_scrollbar_thumb(sb, value, sb->size, sb->max);

    gui_drag_scrollbar(sb, value, FALSE);
}

/*
 * Create all the Athena widgets necessary.
 */
    void
gui_x11_create_widgets()
{
    /*
     * We don't have any borders handled internally by the textArea to worry
     * about so only skip over the configured border width.
     */
    gui.border_offset = gui.border_width;

    /* The form containing all the other widgets */
    vimForm = XtVaCreateManagedWidget("vimForm",
	formWidgetClass,	vimShell,
	XtNborderWidth,		0,
	NULL);
    gui_athena_scroll_colors(vimForm);

#ifdef FEAT_MENU
    /* The top menu bar */
    menuBar = XtVaCreateManagedWidget("menuBar",
	boxWidgetClass,		vimForm,
	XtNresizable,		True,
	XtNtop,			XtChainTop,
	XtNbottom,		XtChainTop,
	XtNleft,		XtChainLeft,
	XtNright,		XtChainRight,
	XtNinsertPosition,	athena_calculate_ins_pos,
	NULL);
    gui_athena_menu_colors(menuBar);
    if (gui.menu_fg_pixel != INVALCOLOR)
	XtVaSetValues(menuBar, XtNborderColor, gui.menu_fg_pixel, NULL);
#endif

#ifdef FEAT_TOOLBAR
    /* Don't create it Managed, it will be managed when creating the first
     * item.  Otherwise an empty toolbar shows up. */
    toolBar = XtVaCreateWidget("toolBar",
	boxWidgetClass,		vimForm,
	XtNresizable,		True,
	XtNtop,			XtChainTop,
	XtNbottom,		XtChainTop,
	XtNleft,		XtChainLeft,
	XtNright,		XtChainRight,
	XtNorientation,		XtorientHorizontal,
	XtNhSpace,		1,
	XtNvSpace,		3,
	XtNinsertPosition,	athena_calculate_ins_pos,
	NULL);
    gui_athena_menu_colors(toolBar);
#endif

    /* The text area. */
    textArea = XtVaCreateManagedWidget("textArea",
	coreWidgetClass,	vimForm,
	XtNresizable,		True,
	XtNtop,			XtChainTop,
	XtNbottom,		XtChainTop,
	XtNleft,		XtChainLeft,
	XtNright,		XtChainLeft,
	XtNbackground,		gui.back_pixel,
	XtNborderWidth,		0,
	NULL);

    /*
     * Install the callbacks.
     */
    gui_x11_callbacks(textArea, vimForm);

#ifdef FEAT_MENU
    popupTrans = XtParseTranslationTable(
	    "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n"
	    "<LeaveWindow>: unhighlight()\n"
	    "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n"
	    "<Motion>: highlight() menu-delayedpopup()");
    parentTrans = XtParseTranslationTable("<LeaveWindow>: unhighlight()");
    menuTrans = XtParseTranslationTable(
	    "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n"
	    "<LeaveWindow>: menu-popdownsubmenus() XtMenuPopdown() unhighlight()\n"
	    "<BtnUp>: notify() unhighlight()\n"
	    "<BtnMotion>: highlight() menu-delayedpopup()");
    supermenuTrans = XtParseTranslationTable(
	    "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n"
	    "<LeaveWindow>: unhighlight()\n"
	    "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n"
	    "<BtnMotion>: highlight() menu-delayedpopup()");

    XtAppAddActions(XtWidgetToApplicationContext(vimForm), pullAction,
		    XtNumber(pullAction));
#endif

    /* Pretend we don't have input focus, we will get an event if we do. */
    gui.in_focus = FALSE;
}

#ifdef FEAT_MENU
/*
 * Calculates the Pixmap based on the size of the current menu font.
 */
    static Pixmap
gui_athena_create_pullright_pixmap(w)
    Widget  w;
{
    Pixmap  retval;
#ifdef FONTSET_ALWAYS
    XFontSet	font = None;
#else
    XFontStruct	*font = NULL;
#endif

#ifdef FONTSET_ALWAYS
    if (gui.menu_fontset == NOFONTSET)
#else
    if (gui.menu_font == NOFONT)
#endif
    {
	XrmValue from, to;
	WidgetList  children;
	Cardinal    num_children;

#ifdef FONTSET_ALWAYS
	from.size = strlen(from.addr = XtDefaultFontSet);
	to.addr = (XtPointer)&font;
	to.size = sizeof(XFontSet);
#else
	from.size = strlen(from.addr = XtDefaultFont);
	to.addr = (XtPointer)&font;
	to.size = sizeof(XFontStruct *);
#endif
	/* Assumption: The menuBar children will use the same font as the
	 *	       pulldown menu items AND they will all be of type
	 *	       XtNfont.
	 */
	XtVaGetValues(menuBar, XtNchildren, &children,
			       XtNnumChildren, &num_children,
			       NULL);
	if (XtConvertAndStore(w ? w :
				(num_children > 0) ? children[0] : menuBar,
			      XtRString, &from,
#ifdef FONTSET_ALWAYS
			      XtRFontSet, &to
#else
			      XtRFontStruct, &to
#endif
		    ) == False)
	    return None;
	/* "font" should now contain data */
    }
    else
#ifdef FONTSET_ALWAYS
	font = (XFontSet)gui.menu_fontset;
#else
	font = (XFontStruct *)gui.menu_font;
#endif

    {
	int	    width, height;
	GC	    draw_gc, undraw_gc;
	XGCValues   gc_values;
	XPoint	    points[3];

#ifdef FONTSET_ALWAYS
	height = fontset_height2(font);
#else
	height = font->max_bounds.ascent + font->max_bounds.descent;
#endif
	width = height - 2;
	puller_width = width + 4;
	retval = XCreatePixmap(gui.dpy,DefaultRootWindow(gui.dpy),width,
			       height, 1);
	gc_values.foreground = 1;
	gc_values.background = 0;
	draw_gc = XCreateGC(gui.dpy, retval,
		    GCForeground | GCBackground,
		    &gc_values);
	gc_values.foreground = 0;
	gc_values.background = 1;
	undraw_gc = XCreateGC(gui.dpy, retval,
			      GCForeground | GCBackground,
			      &gc_values);
	points[0].x = 0;
	points[0].y = 0;
	points[1].x = width - 1;
	points[1].y = (height - 1) / 2;
	points[2].x = 0;
	points[2].y = height - 1;
	XFillRectangle(gui.dpy, retval, undraw_gc, 0, 0, height, height);
	XFillPolygon(gui.dpy, retval, draw_gc, points, XtNumber(points),
		     Convex, CoordModeOrigin);
	XFreeGC(gui.dpy, draw_gc);
	XFreeGC(gui.dpy, undraw_gc);
    }
    return retval;
}
#endif

/*
 * Called when the GUI is not going to start after all.
 */
    void
gui_x11_destroy_widgets()
{
    textArea = NULL;
#ifdef FEAT_MENU
    menuBar = NULL;
#endif
#ifdef FEAT_TOOLBAR
    toolBar = NULL;
#endif
}

#if defined(FEAT_TOOLBAR) || defined(PROTO)
# include "gui_x11_pm.h"
# ifdef HAVE_X11_XPM_H
#  include <X11/xpm.h>
# endif

static void createXpmImages __ARGS((char_u *path, char **xpm, Pixmap *sen));
static void get_toolbar_pixmap __ARGS((vimmenu_T *menu, Pixmap *sen));

/*
 * Allocated a pixmap for toolbar menu "menu".
 * Return in "sen".
 */
    static void
get_toolbar_pixmap(menu, sen)
    vimmenu_T	*menu;
    Pixmap	*sen;
{
    char_u	buf[MAXPATHL];		/* buffer storing expanded pathname */
    char	**xpm = NULL;		/* xpm array */

    buf[0] = NUL;			/* start with NULL path */

    if (menu->iconfile != NULL)
    {
	/* Use the "icon="  argument. */
	gui_find_iconfile(menu->iconfile, buf, "xpm");
	createXpmImages(buf, NULL, sen);

	/* If it failed, try using the menu name. */
	if (*sen == (Pixmap)0 && gui_find_bitmap(menu->name, buf, "xpm") == OK)
	    createXpmImages(buf, NULL, sen);
	if (*sen != (Pixmap)0)
	    return;
    }

    if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL)
    {
	if (menu->iconidx >= 0 && menu->iconidx
	      < (int)(sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0])))
	    xpm = built_in_pixmaps[menu->iconidx];
	else
	    xpm = tb_blank_xpm;
    }

    if (xpm != NULL || buf[0] != NUL)
	createXpmImages(buf, xpm, sen);
}

/*
 * Read an Xpm file, doing color substitutions for the foreground and
 * background colors. If there is an error reading a color xpm file,
 * drop back and read the monochrome file. If successful, create the
 * insensitive Pixmap too.
 */
    static void
createXpmImages(path, xpm, sen)
    char_u	*path;
    char	**xpm;
    Pixmap	*sen;
{
    Window	rootWindow;
    XpmAttributes attrs;
    XpmColorSymbol color[5] =
    {
	{"none", "none", 0},
	{"iconColor1", NULL, 0},
	{"bottomShadowColor", NULL, 0},
	{"topShadowColor", NULL, 0},
	{"selectColor", NULL, 0}
    };
    int		screenNum;
    int		status;
    Pixmap	mask;
    Pixmap	map;

    gui_mch_get_toolbar_colors(
	    &color[BACKGROUND].pixel,
	    &color[FOREGROUND].pixel,
	    &color[BOTTOM_SHADOW].pixel,
	    &color[TOP_SHADOW].pixel,
	    &color[HIGHLIGHT].pixel);

    /* Setup the color substitution table */
    attrs.valuemask = XpmColorSymbols;
    attrs.colorsymbols = color;
    attrs.numsymbols = 5;

    screenNum = DefaultScreen(gui.dpy);
    rootWindow = RootWindow(gui.dpy, screenNum);

    /* Create the "sensitive" pixmap */
    if (xpm != NULL)
	status = XpmCreatePixmapFromData(gui.dpy, rootWindow, xpm,
							 &map, &mask, &attrs);
    else
	status = XpmReadFileToPixmap(gui.dpy, rootWindow, (char *)path,
							 &map, &mask, &attrs);
    if (status == XpmSuccess && map != 0)
    {
	XGCValues   gcvalues;
	GC	    back_gc;
	GC	    mask_gc;

	/* Need to create new Pixmaps with the mask applied. */
	gcvalues.foreground = color[BACKGROUND].pixel;
	back_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues);
	mask_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues);
	XSetClipMask(gui.dpy, mask_gc, mask);

	/* Create the "sensitive" pixmap. */
	*sen = XCreatePixmap(gui.dpy, rootWindow,
		 attrs.width, attrs.height,
		 DefaultDepth(gui.dpy, screenNum));
	XFillRectangle(gui.dpy, *sen, back_gc, 0, 0,
		attrs.width, attrs.height);
	XCopyArea(gui.dpy, map, *sen, mask_gc, 0, 0,
		attrs.width, attrs.height, 0, 0);

	XFreeGC(gui.dpy, back_gc);
	XFreeGC(gui.dpy, mask_gc);
	XFreePixmap(gui.dpy, map);
    }
    else
	*sen = 0;

    XpmFreeAttributes(&attrs);
}

    void
gui_mch_set_toolbar_pos(x, y, w, h)
    int	    x;
    int	    y;
    int	    w;
    int	    h;
{
    Dimension	border;
    int		height;

    if (!XtIsManaged(toolBar))	/* nothing to do */
	return;
    XtUnmanageChild(toolBar);
    XtVaGetValues(toolBar,
		XtNborderWidth, &border,
		NULL);
    height = h - 2 * border;
    if (height < 0)
	height = 1;
    XtVaSetValues(toolBar,
		  XtNhorizDistance, x,
		  XtNvertDistance, y,
		  XtNwidth, w - 2 * border,
		  XtNheight,	height,
		  NULL);
    XtManageChild(toolBar);
}
#endif

    void
gui_mch_set_text_area_pos(x, y, w, h)
    int	    x;
    int	    y;
    int	    w;
    int	    h;
{
    XtUnmanageChild(textArea);
    XtVaSetValues(textArea,
		  XtNhorizDistance, x,
		  XtNvertDistance, y,
		  XtNwidth, w,
		  XtNheight, h,
		  NULL);
    XtManageChild(textArea);
#ifdef FEAT_TOOLBAR
    /* Give keyboard focus to the textArea instead of the toolbar. */
    gui_mch_reset_focus();
#endif
}

#ifdef FEAT_TOOLBAR
/*
 * A toolbar button has been pushed; now reset the input focus
 * such that the user can type page up/down etc. and have the
 * input go to the editor window, not the button
 */
    static void
gui_mch_reset_focus()
{
    XtSetKeyboardFocus(vimForm, textArea);
}
#endif


    void
gui_x11_set_back_color()
{
    if (textArea != NULL)
	XtVaSetValues(textArea,
		  XtNbackground, gui.back_pixel,
		  NULL);
}

#if defined(FEAT_MENU) || defined(PROTO)
/*
 * Menu stuff.
 */

static char_u	*make_pull_name __ARGS((char_u * name));
static Widget	get_popup_entry __ARGS((Widget w));
static Widget	submenu_widget __ARGS((Widget));
static Boolean	has_submenu __ARGS((Widget));
static void gui_mch_submenu_change __ARGS((vimmenu_T *mp, int colors));
static void gui_athena_menu_font __ARGS((Widget id));
static Boolean	gui_athena_menu_has_submenus __ARGS((Widget, Widget));

    void
gui_mch_enable_menu(flag)
    int	    flag;
{
    if (flag)
    {
	XtManageChild(menuBar);
# ifdef FEAT_TOOLBAR
	if (XtIsManaged(toolBar))
	{
	    XtVaSetValues(toolBar,
		XtNvertDistance,    gui.menu_height,
		NULL);
	    XtVaSetValues(textArea,
		XtNvertDistance,    gui.menu_height + gui.toolbar_height,
		NULL);
	}
# endif
    }
    else
    {
	XtUnmanageChild(menuBar);
# ifdef FEAT_TOOLBAR
	if (XtIsManaged(toolBar))
	{
	    XtVaSetValues(toolBar,
		XtNvertDistance,    0,
		NULL);
	}
# endif
    }
}

    void
gui_mch_set_menu_pos(x, y, w, h)
    int	    x;
    int	    y;
    int	    w;
    int	    h;
{
    Dimension	border;
    int		height;

    XtUnmanageChild(menuBar);
    XtVaGetValues(menuBar, XtNborderWidth, &border, NULL);
    /* avoid trouble when there are no menu items, and h is 1 */
    height = h - 2 * border;
    if (height < 0)
	height = 1;
    XtVaSetValues(menuBar,
		XtNhorizDistance, x,
		XtNvertDistance, y,
		XtNwidth, w - 2 * border,
		XtNheight, height,
		NULL);
    XtManageChild(menuBar);
}

/*
 * Used to calculate the insertion position of a widget with respect to its
 * neighbors.
 *
 * Valid range of return values is: 0 (beginning of children) to
 *				    numChildren (end of children).
 */
    static Cardinal
athena_calculate_ins_pos(widget)
    Widget	widget;
{
    /* Assume that if the parent of the vimmenu_T is NULL, then we can get
     * to this menu by traversing "next", starting at "root_menu".
     *
     * This holds true for popup menus, toolbar, and toplevel menu items.
     */

    /* Popup menus:  "id" is NULL. Only submenu_id is valid */

    /* Menus that are not toplevel: "parent" will be non-NULL, "id" &
     * "submenu_id" will be non-NULL.
     */

    /* Toplevel menus: "parent" is NULL, id is the widget of the menu item */

    WidgetList	children;
    Cardinal	num_children = 0;
    int		retval;
    Arg		args[2];
    int		n = 0;
    int		i;

    XtSetArg(args[n], XtNchildren, &children); n++;
    XtSetArg(args[n], XtNnumChildren, &num_children); n++;
    XtGetValues(XtParent(widget), args, n);

    retval = num_children;
    for (i = 0; i < (int)num_children; ++i)
    {
	Widget	current = children[i];
	vimmenu_T	*menu = NULL;

	for (menu = (a_cur_menu->parent == NULL)
			       ? root_menu : a_cur_menu->parent->children;
			       menu != NULL;
			       menu = menu->next)
	    if (current == menu->id
		    && a_cur_menu->priority < menu->priority
		    && i < retval)
		retval = i;
    }
    return retval;
}

    void
gui_mch_add_menu(menu, idx)
    vimmenu_T	*menu;
    int		idx UNUSED;
{
    char_u	*pullright_name;
    Dimension	height, space, border;
    vimmenu_T	*parent = menu->parent;

    a_cur_menu = menu;
    if (parent == NULL)
    {
	if (menu_is_popup(menu->dname))
	{
	    menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname,
		simpleMenuWidgetClass,	vimShell,
		XtNinsertPosition,	athena_calculate_ins_pos,
		XtNtranslations,	popupTrans,
		NULL);
	    gui_athena_menu_colors(menu->submenu_id);
	}
	else if (menu_is_menubar(menu->dname))
	{
	    menu->id = XtVaCreateManagedWidget((char *)menu->dname,
		menuButtonWidgetClass, menuBar,
		XtNmenuName,	    menu->dname,
#ifdef FONTSET_ALWAYS
		XtNinternational,   True,
#endif
		NULL);
	    if (menu->id == (Widget)0)
		return;
	    gui_athena_menu_colors(menu->id);
	    gui_athena_menu_font(menu->id);

	    menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname,
		simpleMenuWidgetClass, menu->id,
		XtNinsertPosition,	athena_calculate_ins_pos,
		XtNtranslations,	supermenuTrans,
		NULL);
	    gui_athena_menu_colors(menu->submenu_id);
	    gui_athena_menu_font(menu->submenu_id);

	    /* Don't update the menu height when it was set at a fixed value */
	    if (!gui.menu_height_fixed)
	    {
		/*
		 * When we add a top-level item to the menu bar, we can figure
		 * out how high the menu bar should be.
		 */
		XtVaGetValues(menuBar,
			XtNvSpace,	&space,
			XtNborderWidth, &border,
			NULL);
		XtVaGetValues(menu->id,
			XtNheight,	&height,
			NULL);
		gui.menu_height = height + 2 * (space + border);
	    }
	}
    }
    else if (parent->submenu_id != (Widget)0)
    {
	menu->id = XtVaCreateManagedWidget((char *)menu->dname,
	    smeBSBObjectClass, parent->submenu_id,
	    XtNlabel, menu->dname,
#ifdef FONTSET_ALWAYS
	    XtNinternational,	True,
#endif
	    NULL);
	if (menu->id == (Widget)0)
	    return;
	if (pullerBitmap == None)
	    pullerBitmap = gui_athena_create_pullright_pixmap(menu->id);

	XtVaSetValues(menu->id, XtNrightBitmap, pullerBitmap,
				NULL);
	/* If there are other menu items that are not pulldown menus,
	 * we need to adjust the right margins of those, too.
	 */
	{
	    WidgetList	children;
	    Cardinal	num_children;
	    int		i;

	    XtVaGetValues(parent->submenu_id, XtNchildren, &children,
					      XtNnumChildren, &num_children,
					      NULL);
	    for (i = 0; i < (int)num_children; ++i)
	    {
		XtVaSetValues(children[i],
			      XtNrightMargin, puller_width,
			      NULL);
	    }
	}
	gui_athena_menu_colors(menu->id);
	gui_athena_menu_font(menu->id);

	pullright_name = make_pull_name(menu->dname);
	menu->submenu_id = XtVaCreatePopupShell((char *)pullright_name,
	    simpleMenuWidgetClass, parent->submenu_id,
	    XtNtranslations, menuTrans,
	    NULL);
	gui_athena_menu_colors(menu->submenu_id);
	gui_athena_menu_font(menu->submenu_id);
	vim_free(pullright_name);
	XtAddCallback(menu->submenu_id, XtNpopupCallback,
		      gui_athena_popup_callback, (XtPointer)menu);

	if (parent->parent != NULL)
	    XtOverrideTranslations(parent->submenu_id, parentTrans);
    }
    a_cur_menu = NULL;
}

/* Used to determine whether a SimpleMenu has pulldown entries.
 *
 * "id" is the parent of the menu items.
 * Ignore widget "ignore" in the pane.
 */
    static Boolean
gui_athena_menu_has_submenus(id, ignore)
    Widget	id;
    Widget	ignore;
{
    WidgetList	children;
    Cardinal	num_children;
    int		i;

    XtVaGetValues(id, XtNchildren, &children,
		      XtNnumChildren, &num_children,
		      NULL);
    for (i = 0; i < (int)num_children; ++i)
    {
	if (children[i] == ignore)
	    continue;
	if (has_submenu(children[i]))
	    return True;
    }
    return False;
}

    static void
gui_athena_menu_font(id)
    Widget	id;
{
#ifdef FONTSET_ALWAYS
    if (gui.menu_fontset != NOFONTSET)
    {
	if (XtIsManaged(id))
	{
	    XtUnmanageChild(id);
	    XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL);
	    /* We should force the widget to recalculate it's
	     * geometry now. */
	    XtManageChild(id);
	}
	else
	    XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL);
	if (has_submenu(id))
	    XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL);
    }
#else
    int		managed = FALSE;

    if (gui.menu_font != NOFONT)
    {
	if (XtIsManaged(id))
	{
	    XtUnmanageChild(id);
	    managed = TRUE;
	}

# ifdef FEAT_XFONTSET
	if (gui.fontset != NOFONTSET)
	    XtVaSetValues(id, XtNfontSet, gui.menu_font, NULL);
	else
# endif
	    XtVaSetValues(id, XtNfont, gui.menu_font, NULL);
	if (has_submenu(id))
	    XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL);

	/* Force the widget to recalculate it's geometry now. */
	if (managed)
	    XtManageChild(id);
    }
#endif
}


    void
gui_mch_new_menu_font()
{
    Pixmap oldpuller = None;

    if (menuBar == (Widget)0)
	return;

    if (pullerBitmap != None)
    {
	oldpuller = pullerBitmap;
	pullerBitmap = gui_athena_create_pullright_pixmap(NULL);
    }
    gui_mch_submenu_change(root_menu, FALSE);

    {
	/* Iterate through the menubar menu items and get the height of
	 * each one.  The menu bar height is set to the maximum of all
	 * the heights.
	 */
	vimmenu_T *mp;
	int max_height = 9999;

	for (mp = root_menu; mp != NULL; mp = mp->next)
	{
	    if (menu_is_menubar(mp->dname))
	    {
		Dimension height;

		XtVaGetValues(mp->id,
			XtNheight, &height,
			NULL);
		if (height < max_height)
		    max_height = height;
	    }
	}
	if (max_height != 9999)
	{
	    /* Don't update the menu height when it was set at a fixed value */
	    if (!gui.menu_height_fixed)
	    {
		Dimension   space, border;

		XtVaGetValues(menuBar,
			XtNvSpace,	&space,
			XtNborderWidth, &border,
			NULL);
		gui.menu_height = max_height + 2 * (space + border);
	    }
	}
    }
    /* Now, to simulate the window being resized.  Only, this
     * will resize the window to it's current state.
     *
     * There has to be a better way, but I do not see one at this time.
     * (David Harrison)
     */
    {
	Position w, h;

	XtVaGetValues(vimShell,
		XtNwidth, &w,
		XtNheight, &h,
		NULL);
	gui_resize_shell(w, h
#ifdef FEAT_XIM
						- xim_get_status_area_height()
#endif
		     );
    }
    gui_set_shellsize(FALSE, TRUE, RESIZE_VERT);
    ui_new_shellsize();
    if (oldpuller != None)
	XFreePixmap(gui.dpy, oldpuller);
}

#if defined(FEAT_BEVAL) || defined(PROTO)
    void
gui_mch_new_tooltip_font()
{
#  ifdef FEAT_TOOLBAR
    vimmenu_T   *menu;

    if (toolBar == (Widget)0)
	return;

    menu = gui_find_menu((char_u *)"ToolBar");
    if (menu != NULL)
	gui_mch_submenu_change(menu, FALSE);
#  endif
}

    void
gui_mch_new_tooltip_colors()
{
# ifdef FEAT_TOOLBAR
    vimmenu_T   *menu;

    if (toolBar == (Widget)0)
	return;

    menu = gui_find_menu((char_u *)"ToolBar");
    if (menu != NULL)
	gui_mch_submenu_change(menu, TRUE);
# endif
}
#endif

    static void
gui_mch_submenu_change(menu, colors)
    vimmenu_T	*menu;
    int		colors;		/* TRUE for colors, FALSE for font */
{
    vimmenu_T	*mp;

    for (mp = menu; mp != NULL; mp = mp->next)
    {
	if (mp->id != (Widget)0)
	{
	    if (colors)
	    {
		gui_athena_menu_colors(mp->id);
#ifdef FEAT_TOOLBAR
		/* For a toolbar item: Free the pixmap and allocate a new one,
		 * so that the background color is right. */
		if (mp->image != (Pixmap)0)
		{
		    XFreePixmap(gui.dpy, mp->image);
		    get_toolbar_pixmap(mp, &mp->image);
		    if (mp->image != (Pixmap)0)
			XtVaSetValues(mp->id, XtNbitmap, mp->image, NULL);
		}

# ifdef FEAT_BEVAL
		/* If we have a tooltip, then we need to change it's colors */
		if (mp->tip != NULL)
		{
		    Arg args[2];

		    args[0].name = XtNbackground;
		    args[0].value = gui.tooltip_bg_pixel;
		    args[1].name = XtNforeground;
		    args[1].value = gui.tooltip_fg_pixel;
		    XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
		}
# endif
#endif
	    }
	    else
	    {
		gui_athena_menu_font(mp->id);
#ifdef FEAT_BEVAL
		/* If we have a tooltip, then we need to change it's font */
		/* Assume XtNinternational == True (in createBalloonEvalWindow)
		 */
		if (mp->tip != NULL)
		{
		    Arg args[1];

		    args[0].name = XtNfontSet;
		    args[0].value = (XtArgVal)gui.tooltip_fontset;
		    XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
		}
#endif
	    }
	}

	if (mp->children != NULL)
	{
	    /* Set the colors/font for the tear off widget */
	    if (mp->submenu_id != (Widget)0)
	    {
		if (colors)
		    gui_athena_menu_colors(mp->submenu_id);
		else
		    gui_athena_menu_font(mp->submenu_id);
	    }
	    /* Set the colors for the children */
	    gui_mch_submenu_change(mp->children, colors);
	}
    }
}

/*
 * Make a submenu name into a pullright name.
 * Replace '.' by '_', can't include '.' in the submenu name.
 */
    static char_u *
make_pull_name(name)
    char_u * name;
{
    char_u  *pname;
    char_u  *p;

    pname = vim_strnsave(name, STRLEN(name) + strlen("-pullright"));
    if (pname != NULL)
    {
	strcat((char *)pname, "-pullright");
	while ((p = vim_strchr(pname, '.')) != NULL)
	    *p = '_';
    }
    return pname;
}

    void
gui_mch_add_menu_item(menu, idx)
    vimmenu_T	*menu;
    int		idx UNUSED;
{
    vimmenu_T	*parent = menu->parent;

    a_cur_menu = menu;
# ifdef FEAT_TOOLBAR
    if (menu_is_toolbar(parent->name))
    {
	WidgetClass	type;
	int		n;
	Arg		args[21];

	n = 0;
	if (menu_is_separator(menu->name))
	{
	    XtSetArg(args[n], XtNlabel, ""); n++;
	    XtSetArg(args[n], XtNborderWidth, 0); n++;
	}
	else
	{
	    get_toolbar_pixmap(menu, &menu->image);
	    XtSetArg(args[n], XtNlabel, menu->dname); n++;
	    XtSetArg(args[n], XtNinternalHeight, 1); n++;
	    XtSetArg(args[n], XtNinternalWidth, 1); n++;
	    XtSetArg(args[n], XtNborderWidth, 1); n++;
	    if (menu->image != 0)
		XtSetArg(args[n], XtNbitmap, menu->image); n++;
	}
	XtSetArg(args[n], XtNhighlightThickness, 0); n++;
	type = commandWidgetClass;
	/* TODO: figure out the position in the toolbar?
	 *       This currently works fine for the default toolbar, but
	 *       what if we add/remove items during later runtime?
	 */

	/* NOTE: "idx" isn't used here.  The position is calculated by
	 *       athena_calculate_ins_pos().  The position it calculates
	 *       should be equal to "idx".
	 */
	/* TODO: Could we just store "idx" and use that as the child
	 * placement?
	 */

	if (menu->id == NULL)
	{
	    menu->id = XtCreateManagedWidget((char *)menu->dname,
			type, toolBar, args, n);
	    XtAddCallback(menu->id,
		    XtNcallback, gui_x11_menu_cb, menu);
	}
	else
	    XtSetValues(menu->id, args, n);
	gui_athena_menu_colors(menu->id);

#ifdef FEAT_BEVAL
	gui_mch_menu_set_tip(menu);
#endif

	menu->parent = parent;
	menu->submenu_id = NULL;
	if (!XtIsManaged(toolBar)
		    && vim_strchr(p_go, GO_TOOLBAR) != NULL)
	    gui_mch_show_toolbar(TRUE);
	gui.toolbar_height = gui_mch_compute_toolbar_height();
	return;
    } /* toolbar menu item */
# endif

    /* Add menu separator */
    if (menu_is_separator(menu->name))
    {
	menu->submenu_id = (Widget)0;
	menu->id = XtVaCreateManagedWidget((char *)menu->dname,
		smeLineObjectClass, parent->submenu_id,
		NULL);
	if (menu->id == (Widget)0)
	    return;
	gui_athena_menu_colors(menu->id);
    }
    else
    {
	if (parent != NULL && parent->submenu_id != (Widget)0)
	{
	    menu->submenu_id = (Widget)0;
	    menu->id = XtVaCreateManagedWidget((char *)menu->dname,
		    smeBSBObjectClass, parent->submenu_id,
		    XtNlabel, menu->dname,
#ifdef FONTSET_ALWAYS
		    XtNinternational,	True,
#endif
		    NULL);
	    if (menu->id == (Widget)0)
		return;

	    /* If there are other "pulldown" items in this pane, then adjust
	     * the right margin to accommodate the arrow pixmap, otherwise
	     * the right margin will be the same as the left margin.
	     */
	    {
		Dimension   left_margin;

		XtVaGetValues(menu->id, XtNleftMargin, &left_margin, NULL);
		XtVaSetValues(menu->id, XtNrightMargin,
			gui_athena_menu_has_submenus(parent->submenu_id, NULL) ?
			    puller_width :
			    left_margin,
			NULL);
	    }

	    gui_athena_menu_colors(menu->id);
	    gui_athena_menu_font(menu->id);
	    XtAddCallback(menu->id, XtNcallback, gui_x11_menu_cb,
		    (XtPointer)menu);
	}
    }
    a_cur_menu = NULL;
}

#if defined(FEAT_TOOLBAR) || defined(PROTO)
    void
gui_mch_show_toolbar(int showit)
{
    Cardinal	numChildren;	    /* how many children toolBar has */

    if (toolBar == (Widget)0)
	return;
    XtVaGetValues(toolBar, XtNnumChildren, &numChildren, NULL);
    if (showit && numChildren > 0)
    {
	/* Assume that we want to show the toolbar if p_toolbar contains valid
	 * option settings, therefore p_toolbar must not be NULL.
	 */
	WidgetList  children;

	XtVaGetValues(toolBar, XtNchildren, &children, NULL);
	{
	    void    (*action)(BalloonEval *);
	    int	    text = 0;

	    if (strstr((const char *)p_toolbar, "tooltips"))
		action = &gui_mch_enable_beval_area;
	    else
		action = &gui_mch_disable_beval_area;
	    if (strstr((const char *)p_toolbar, "text"))
		text = 1;
	    else if (strstr((const char *)p_toolbar, "icons"))
		text = -1;
	    if (text != 0)
	    {
		vimmenu_T   *toolbar;
		vimmenu_T   *cur;

		for (toolbar = root_menu; toolbar; toolbar = toolbar->next)
		    if (menu_is_toolbar(toolbar->dname))
			break;
		/* Assumption: toolbar is NULL if there is no toolbar,
		 *	       otherwise it contains the toolbar menu structure.
		 *
		 * Assumption: "numChildren" == the number of items in the list
		 *	       of items beginning with toolbar->children.
		 */
		if (toolbar)
		{
		    for (cur = toolbar->children; cur; cur = cur->next)
		    {
			Arg	    args[2];
			int	    n = 0;

			/* Enable/Disable tooltip (OK to enable while currently
			 * enabled)
			 */
			if (cur->tip != NULL)
			    (*action)(cur->tip);
			if (text == 1)
			{
			    XtSetArg(args[n], XtNbitmap, None);
			    n++;
			    XtSetArg(args[n], XtNlabel,
				    menu_is_separator(cur->name) ? "" :
					(char *)cur->dname);
			    n++;
			}
			else
			{
			    XtSetArg(args[n], XtNbitmap, cur->image);
			    n++;
			    XtSetArg(args[n], XtNlabel, (cur->image == None) ?
				    menu_is_separator(cur->name) ?
					"" :
					(char *)cur->dname
				    :
				    (char *)None);
			    n++;
			}
			if (cur->id != NULL)
			{
			    XtUnmanageChild(cur->id);
			    XtSetValues(cur->id, args, n);
			    XtManageChild(cur->id);
			}
		    }
		}
	    }
	}
	gui.toolbar_height = gui_mch_compute_toolbar_height();
	XtManageChild(toolBar);
	if (XtIsManaged(menuBar))
	{
	    XtVaSetValues(textArea,
		    XtNvertDistance,    gui.toolbar_height + gui.menu_height,
		    NULL);
	    XtVaSetValues(toolBar,
		    XtNvertDistance,    gui.menu_height,
		    NULL);
	}
	else
	{
	    XtVaSetValues(textArea,
		    XtNvertDistance,    gui.toolbar_height,
		    NULL);
	    XtVaSetValues(toolBar,
		    XtNvertDistance,    0,
		    NULL);
	}
    }
    else
    {
	gui.toolbar_height = 0;
	if (XtIsManaged(menuBar))
	    XtVaSetValues(textArea,
		XtNvertDistance,    gui.menu_height,
		NULL);
	else
	    XtVaSetValues(textArea,
		XtNvertDistance,    0,
		NULL);

	XtUnmanageChild(toolBar);
    }
    gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
}


    int
gui_mch_compute_toolbar_height()
{
    Dimension	height;		    /* total Toolbar height */
    Dimension	whgt;		    /* height of each widget */
    Dimension	marginHeight;	    /* XmNmarginHeight of toolBar */
    Dimension	shadowThickness;    /* thickness of Xtparent(toolBar) */
    WidgetList	children;	    /* list of toolBar's children */
    Cardinal	numChildren;	    /* how many children toolBar has */
    int		i;

    height = 0;
    shadowThickness = 0;
    marginHeight = 0;
    if (toolBar != (Widget)0)
    {
	XtVaGetValues(toolBar,
		XtNborderWidth,	    &shadowThickness,
		XtNvSpace,	    &marginHeight,
		XtNchildren,	    &children,
		XtNnumChildren,	    &numChildren,
		NULL);
	for (i = 0; i < (int)numChildren; i++)
	{
	    whgt = 0;

	    XtVaGetValues(children[i], XtNheight, &whgt, NULL);
	    if (height < whgt)
		height = whgt;
	}
    }

    return (int)(height + (marginHeight << 1) + (shadowThickness << 1));
}

    void
gui_mch_get_toolbar_colors(bgp, fgp, bsp, tsp, hsp)
    Pixel	*bgp;
    Pixel	*fgp;
    Pixel       *bsp;
    Pixel	*tsp;
    Pixel	*hsp;
{
    XtVaGetValues(toolBar, XtNbackground, bgp, XtNborderColor, fgp, NULL);
    *bsp = *bgp;
    *tsp = *fgp;
    *hsp = *tsp;
}
#endif


    void
gui_mch_toggle_tearoffs(enable)
    int		enable UNUSED;
{
    /* no tearoff menus */
}

    void
gui_mch_new_menu_colors()
{
    if (menuBar == (Widget)0)
	return;
    if (gui.menu_fg_pixel != INVALCOLOR)
	XtVaSetValues(menuBar, XtNborderColor,	gui.menu_fg_pixel, NULL);
    gui_athena_menu_colors(menuBar);
#ifdef FEAT_TOOLBAR
    gui_athena_menu_colors(toolBar);
#endif

    gui_mch_submenu_change(root_menu, TRUE);
}

/*
 * Destroy the machine specific menu widget.
 */
    void
gui_mch_destroy_menu(menu)
    vimmenu_T *menu;
{
    Widget	parent;

    /* There is no item for the toolbar. */
    if (menu->id == (Widget)0)
	return;

    parent = XtParent(menu->id);

    /* When removing the last "pulldown" menu item from a pane, adjust the
     * right margins of the remaining widgets.
     */
    if (menu->submenu_id != (Widget)0)
    {
	/* Go through the menu items in the parent of this item and
	 * adjust their margins, if necessary.
	 * This takes care of the case when we delete the last menu item in a
	 * pane that has a submenu.  In this case, there will be no arrow
	 * pixmaps shown anymore.
	 */
	{
	    WidgetList  children;
	    Cardinal    num_children;
	    int		i;
	    Dimension	right_margin = 0;
	    Boolean	get_left_margin = False;

	    XtVaGetValues(parent, XtNchildren, &children,
				  XtNnumChildren, &num_children,
				  NULL);
	    if (gui_athena_menu_has_submenus(parent, menu->id))
		right_margin = puller_width;
	    else
		get_left_margin = True;

	    for (i = 0; i < (int)num_children; ++i)
	    {
		if (children[i] == menu->id)
		    continue;
		if (get_left_margin == True)
		{
		    Dimension left_margin;

		    XtVaGetValues(children[i], XtNleftMargin, &left_margin,
				  NULL);
		    XtVaSetValues(children[i], XtNrightMargin, left_margin,
				  NULL);
		}
		else
		    XtVaSetValues(children[i], XtNrightMargin, right_margin,
				  NULL);
	    }
	}
    }
    /* Please be sure to destroy the parent widget first (i.e. menu->id).
     *
     * This code should be basically identical to that in the file gui_motif.c
     * because they are both Xt based.
     */
    if (menu->id != (Widget)0)
    {
	Cardinal    num_children;
	Dimension   height, space, border;

	XtVaGetValues(menuBar,
		XtNvSpace,	&space,
		XtNborderWidth, &border,
		NULL);
	XtVaGetValues(menu->id,
		XtNheight,	&height,
		NULL);
#if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL)
	if (parent == toolBar && menu->tip != NULL)
	{
	    /* We try to destroy this before the actual menu, because there are
	     * callbacks, etc. that will be unregistered during the tooltip
	     * destruction.
	     *
	     * If you call "gui_mch_destroy_beval_area()" after destroying
	     * menu->id, then the tooltip's window will have already been
	     * deallocated by Xt, and unknown behaviour will ensue (probably
	     * a core dump).
	     */
	    gui_mch_destroy_beval_area(menu->tip);
	    menu->tip = NULL;
	}
#endif
	/*
	 * This is a hack to stop the Athena simpleMenuWidget from getting a
	 * BadValue error when a menu's last child is destroyed. We check to
	 * see if this is the last child and if so, don't delete it. The parent
	 * will be deleted soon anyway, and it will delete it's children like
	 * all good widgets do.
	 */
	/* NOTE: The cause of the BadValue X Protocol Error is because when the
	 * last child is destroyed, it is first unmanaged, thus causing a
	 * geometry resize request from the parent Shell widget.
	 * Since the Shell widget has no more children, it is resized to have
	 * width/height of 0.  XConfigureWindow() is then called with the
	 * width/height of 0, which generates the BadValue.
	 *
	 * This happens in phase two of the widget destruction process.
	 */
	{
	    if (parent != menuBar
#ifdef FEAT_TOOLBAR
		    && parent != toolBar
#endif
		    )
	    {
		XtVaGetValues(parent, XtNnumChildren, &num_children, NULL);
		if (num_children > 1)
		    XtDestroyWidget(menu->id);
	    }
	    else
		XtDestroyWidget(menu->id);
	    menu->id = (Widget)0;
	}

	if (parent == menuBar)
	{
	    if (!gui.menu_height_fixed)
		gui.menu_height = height + 2 * (space + border);
	}
#ifdef FEAT_TOOLBAR
	else if (parent == toolBar)
	{
	    /* When removing last toolbar item, don't display the toolbar. */
	    XtVaGetValues(toolBar, XtNnumChildren, &num_children, NULL);
	    if (num_children == 0)
		gui_mch_show_toolbar(FALSE);
	    else
		gui.toolbar_height = gui_mch_compute_toolbar_height();
	}
#endif
    }
    if (menu->submenu_id != (Widget)0)
    {
	XtDestroyWidget(menu->submenu_id);
	menu->submenu_id = (Widget)0;
    }
}

    static void
gui_athena_menu_timeout(client_data, id)
    XtPointer	    client_data;
    XtIntervalId    *id UNUSED;
{
    Widget  w = (Widget)client_data;
    Widget  popup;

    timer = 0;
    if (XtIsSubclass(w,smeBSBObjectClass))
    {
	Pixmap p;

	XtVaGetValues(w, XtNrightBitmap, &p, NULL);
	if ((p != None) && (p != XtUnspecifiedPixmap))
	{
	    /* We are dealing with an item that has a submenu */
	    popup = get_popup_entry(XtParent(w));
	    if (popup == (Widget)0)
		return;
	    XtPopup(popup, XtGrabNonexclusive);
	}
    }
}

/* This routine is used to calculate the position (in screen coordinates)
 * where a submenu should appear relative to the menu entry that popped it
 * up.  It should appear even with and just slightly to the left of the
 * rightmost end of the menu entry that caused the popup.
 *
 * This is called when XtPopup() is called.
 */
    static void
gui_athena_popup_callback(w, client_data, call_data)
    Widget	w;
    XtPointer	client_data;
    XtPointer	call_data UNUSED;
{
    /* Assumption: XtIsSubclass(XtParent(w),simpleMenuWidgetClass) */
    vimmenu_T	*menu = (vimmenu_T *)client_data;
    Dimension	width;
    Position	root_x, root_y;

    /* First, popdown any siblings that may have menus popped up */
    {
	vimmenu_T *i;

	for (i = menu->parent->children; i != NULL; i = i->next)
	{
	    if (i->submenu_id != NULL && XtIsManaged(i->submenu_id))
		XtPopdown(i->submenu_id);
	}
    }
    XtVaGetValues(XtParent(w),
		  XtNwidth,   &width,
		  NULL);
    /* Assumption: XawSimpleMenuGetActiveEntry(XtParent(w)) == menu->id */
    /* i.e. This IS the active entry */
    XtTranslateCoords(menu->id,width - 5, 0, &root_x, &root_y);
    XtVaSetValues(w, XtNx, root_x,
		     XtNy, root_y,
		     NULL);
}

    static void
gui_athena_popdown_submenus_action(w, event, args, nargs)
    Widget	w;
    XEvent	*event;
    String	*args;
    Cardinal	*nargs;
{
    WidgetList	children;
    Cardinal	num_children;

    XtVaGetValues(w, XtNchildren, &children,
		     XtNnumChildren, &num_children,
		     NULL);
    for (; num_children > 0; --num_children)
    {
	Widget child = children[num_children - 1];

	if (has_submenu(child))
	{
	    Widget temp_w;

	    temp_w = submenu_widget(child);
	    gui_athena_popdown_submenus_action(temp_w,event,args,nargs);
	    XtPopdown(temp_w);
	}
    }
}

/* Used to determine if the given widget has a submenu that can be popped up. */
    static Boolean
has_submenu(widget)
    Widget  widget;
{
    if ((widget != NULL) && XtIsSubclass(widget,smeBSBObjectClass))
    {
	Pixmap p;

	XtVaGetValues(widget, XtNrightBitmap, &p, NULL);
	if ((p != None) && (p != XtUnspecifiedPixmap))
	    return True;
    }
    return False;
}

    static void
gui_athena_delayed_arm_action(w, event, args, nargs)
    Widget	w;
    XEvent	*event;
    String	*args;
    Cardinal	*nargs;
{
    Dimension	width, height;

    if (event->type != MotionNotify)
	return;

    XtVaGetValues(w,
	XtNwidth,   &width,
	XtNheight,  &height,
	NULL);

    if (event->xmotion.x >= (int)width || event->xmotion.y >= (int)height)
	return;

    {
	static Widget	    previous_active_widget = NULL;
	Widget		    current;

	current = XawSimpleMenuGetActiveEntry(w);
	if (current != previous_active_widget)
	{
	    if (timer)
	    {
		/* If the timeout hasn't been triggered, remove it */
		XtRemoveTimeOut(timer);
	    }
	    gui_athena_popdown_submenus_action(w,event,args,nargs);
	    if (has_submenu(current))
	    {
		XtAppAddTimeOut(XtWidgetToApplicationContext(w), 600L,
				gui_athena_menu_timeout,
				(XtPointer)current);
	    }
	    previous_active_widget = current;
	}
    }
}

    static Widget
get_popup_entry(w)
    Widget  w;
{
    Widget	menuw;

    /* Get the active entry for the current menu */
    if ((menuw = XawSimpleMenuGetActiveEntry(w)) == (Widget)0)
	return NULL;

    return submenu_widget(menuw);
}

/* Given the widget that has been determined to have a submenu, return the submenu widget
 * that is to be popped up.
 */
    static Widget
submenu_widget(widget)
    Widget  widget;
{
    /* Precondition: has_submenu(widget) == True
     *	    XtIsSubclass(XtParent(widget),simpleMenuWidgetClass) == True
     */

    char_u	*pullright_name;
    Widget	popup;

    pullright_name = make_pull_name((char_u *)XtName(widget));
    popup = XtNameToWidget(XtParent(widget), (char *)pullright_name);
    vim_free(pullright_name);

    return popup;
    /* Postcondition: (popup != NULL) implies
     * (XtIsSubclass(popup,simpleMenuWidgetClass) == True) */
}

    void
gui_mch_show_popupmenu(menu)
    vimmenu_T *menu;
{
    int		rootx, rooty, winx, winy;
    Window	root, child;
    unsigned int mask;

    if (menu->submenu_id == (Widget)0)
	return;

    /* Position the popup menu at the pointer */
    if (XQueryPointer(gui.dpy, XtWindow(vimShell), &root, &child,
		&rootx, &rooty, &winx, &winy, &mask))
    {
	rootx -= 30;
	if (rootx < 0)
	    rootx = 0;
	rooty -= 5;
	if (rooty < 0)
	    rooty = 0;
	XtVaSetValues(menu->submenu_id,
		XtNx, rootx,
		XtNy, rooty,
		NULL);
    }

    XtOverrideTranslations(menu->submenu_id, popupTrans);
    XtPopupSpringLoaded(menu->submenu_id);
}

#endif /* FEAT_MENU */

/*
 * Set the menu and scrollbar colors to their default values.
 */
    void
gui_mch_def_colors()
{
    /*
     * Get the colors ourselves.  Using the automatic conversion doesn't
     * handle looking for approximate colors.
     */
    if (gui.in_use)
    {
	gui.menu_fg_pixel = gui_get_color((char_u *)gui.rsrc_menu_fg_name);
	gui.menu_bg_pixel = gui_get_color((char_u *)gui.rsrc_menu_bg_name);
	gui.scroll_fg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_fg_name);
	gui.scroll_bg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_bg_name);
#ifdef FEAT_BEVAL
	gui.tooltip_fg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_fg_name);
	gui.tooltip_bg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_bg_name);
#endif
    }
}


/*
 * Scrollbar stuff.
 */

    void
gui_mch_set_scrollbar_thumb(sb, val, size, max)
    scrollbar_T	*sb;
    long	val;
    long	size;
    long	max;
{
    double	v, s;

    if (sb->id == (Widget)0)
	return;

    /*
     * Athena scrollbar must go from 0.0 to 1.0.
     */
    if (max == 0)
    {
	/* So you can't scroll it at all (normally it scrolls past end) */
#ifdef FEAT_GUI_NEXTAW
	XawScrollbarSetThumb(sb->id, 0.0, 1.0);
#else
	vim_XawScrollbarSetThumb(sb->id, 0.0, 1.0, 0.0);
#endif
    }
    else
    {
	v = (double)val / (double)(max + 1);
	s = (double)size / (double)(max + 1);
#ifdef FEAT_GUI_NEXTAW
	XawScrollbarSetThumb(sb->id, v, s);
#else
	vim_XawScrollbarSetThumb(sb->id, v, s, 1.0);
#endif
    }
}

    void
gui_mch_set_scrollbar_pos(sb, x, y, w, h)
    scrollbar_T *sb;
    int		x;
    int		y;
    int		w;
    int		h;
{
    if (sb->id == (Widget)0)
	return;

    XtUnmanageChild(sb->id);
    XtVaSetValues(sb->id,
		  XtNhorizDistance, x,
		  XtNvertDistance, y,
		  XtNwidth, w,
		  XtNheight, h,
		  NULL);
    XtManageChild(sb->id);
}

    void
gui_mch_enable_scrollbar(sb, flag)
    scrollbar_T	*sb;
    int		flag;
{
    if (sb->id != (Widget)0)
    {
	if (flag)
	    XtManageChild(sb->id);
	else
	    XtUnmanageChild(sb->id);
    }
}

    void
gui_mch_create_scrollbar(sb, orient)
    scrollbar_T *sb;
    int		orient;	/* SBAR_VERT or SBAR_HORIZ */
{
    sb->id = XtVaCreateWidget("scrollBar",
#ifdef FEAT_GUI_NEXTAW
	    scrollbarWidgetClass, vimForm,
#else
	    vim_scrollbarWidgetClass, vimForm,
#endif
	    XtNresizable,   True,
	    XtNtop,	    XtChainTop,
	    XtNbottom,	    XtChainTop,
	    XtNleft,	    XtChainLeft,
	    XtNright,	    XtChainLeft,
	    XtNborderWidth, 0,
	    XtNorientation, (orient == SBAR_VERT) ? XtorientVertical
						  : XtorientHorizontal,
	    XtNforeground, gui.scroll_fg_pixel,
	    XtNbackground, gui.scroll_bg_pixel,
	    NULL);
    if (sb->id == (Widget)0)
	return;

    XtAddCallback(sb->id, XtNjumpProc,
		  gui_athena_scroll_cb_jump, (XtPointer)sb->ident);
    XtAddCallback(sb->id, XtNscrollProc,
		  gui_athena_scroll_cb_scroll, (XtPointer)sb->ident);

#ifdef FEAT_GUI_NEXTAW
    XawScrollbarSetThumb(sb->id, 0.0, 1.0);
#else
    vim_XawScrollbarSetThumb(sb->id, 0.0, 1.0, 0.0);
#endif
}

#if defined(FEAT_WINDOWS) || defined(PROTO)
    void
gui_mch_destroy_scrollbar(sb)
    scrollbar_T *sb;
{
    if (sb->id != (Widget)0)
	XtDestroyWidget(sb->id);
}
#endif

    void
gui_mch_set_scrollbar_colors(sb)
    scrollbar_T *sb;
{
    if (sb->id != (Widget)0)
	XtVaSetValues(sb->id,
	    XtNforeground, gui.scroll_fg_pixel,
	    XtNbackground, gui.scroll_bg_pixel,
	    NULL);

    /* This is needed for the rectangle below the vertical scrollbars. */
    if (sb == &gui.bottom_sbar && vimForm != (Widget)0)
	gui_athena_scroll_colors(vimForm);
}

/*
 * Miscellaneous stuff:
 */
    Window
gui_x11_get_wid()
{
    return XtWindow(textArea);
}

#if defined(FEAT_BROWSE) || defined(PROTO)
/*
 * Put up a file requester.
 * Returns the selected name in allocated memory, or NULL for Cancel.
 */
    char_u *
gui_mch_browse(saving, title, dflt, ext, initdir, filter)
    int		saving UNUSED;	/* select file to write */
    char_u	*title;		/* title for the window */
    char_u	*dflt;		/* default name */
    char_u	*ext UNUSED;	/* extension added */
    char_u	*initdir;	/* initial directory, NULL for current dir */
    char_u	*filter UNUSED;	/* file name filter */
{
    Position x, y;
    char_u	dirbuf[MAXPATHL];

    /* Concatenate "initdir" and "dflt". */
    if (initdir == NULL || *initdir == NUL)
	mch_dirname(dirbuf, MAXPATHL);
    else if (STRLEN(initdir) + 2 < MAXPATHL)
	STRCPY(dirbuf, initdir);
    else
	dirbuf[0] = NUL;
    if (dflt != NULL && *dflt != NUL
			      && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL)
    {
	add_pathsep(dirbuf);
	STRCAT(dirbuf, dflt);
    }

    /* Position the file selector just below the menubar */
    XtTranslateCoords(vimShell, (Position)0, (Position)
#ifdef FEAT_MENU
	    gui.menu_height
#else
	    0
#endif
	    , &x, &y);
    return (char_u *)vim_SelFile(vimShell, (char *)title, (char *)dirbuf,
		  NULL, (int)x, (int)y, gui.menu_fg_pixel, gui.menu_bg_pixel,
		  gui.scroll_fg_pixel, gui.scroll_bg_pixel);
}
#endif

#if defined(FEAT_GUI_DIALOG) || defined(PROTO)

static int	dialogStatus;
static Atom	dialogatom;

static void keyhit_callback __ARGS((Widget w, XtPointer client_data, XEvent *event, Boolean *cont));
static void butproc __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
static void dialog_wm_handler __ARGS((Widget w, XtPointer client_data, XEvent *event, Boolean *dum));

/*
 * Callback function for the textfield.  When CR is hit this works like
 * hitting the "OK" button, ESC like "Cancel".
 */
    static void
keyhit_callback(w, client_data, event, cont)
    Widget		w UNUSED;
    XtPointer		client_data UNUSED;
    XEvent		*event;
    Boolean		*cont UNUSED;
{
    char	buf[2];

    if (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1)
    {
	if (*buf == CAR)
	    dialogStatus = 1;
	else if (*buf == ESC)
	    dialogStatus = 0;
    }
}

    static void
butproc(w, client_data, call_data)
    Widget	w UNUSED;
    XtPointer	client_data;
    XtPointer	call_data UNUSED;
{
    dialogStatus = (int)(long)client_data + 1;
}

/*
 * Function called when dialog window closed.
 */
    static void
dialog_wm_handler(w, client_data, event, dum)
    Widget	w UNUSED;
    XtPointer	client_data UNUSED;
    XEvent	*event;
    Boolean	*dum UNUSED;
{
    if (event->type == ClientMessage
	    && (Atom)((XClientMessageEvent *)event)->data.l[0] == dialogatom)
	dialogStatus = 0;
}

    int
gui_mch_dialog(type, title, message, buttons, dfltbutton, textfield, ex_cmd)
    int		type UNUSED;
    char_u	*title;
    char_u	*message;
    char_u	*buttons;
    int		dfltbutton UNUSED;
    char_u	*textfield;
    int		ex_cmd UNUSED;
{
    char_u		*buts;
    char_u		*p, *next;
    XtAppContext	app;
    XEvent		event;
    Position		wd, hd;
    Position		wv, hv;
    Position		x, y;
    Widget		dialog;
    Widget		dialogshell;
    Widget		dialogmessage;
    Widget		dialogtextfield = 0;
    Widget		dialogButton;
    Widget		prev_dialogButton = NULL;
    int			butcount;
    int			vertical;

    if (title == NULL)
	title = (char_u *)_("Vim dialog");
    dialogStatus = -1;

    /* if our pointer is currently hidden, then we should show it. */
    gui_mch_mousehide(FALSE);

    /* Check 'v' flag in 'guioptions': vertical button placement. */
    vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);

    /* The shell is created each time, to make sure it is resized properly */
    dialogshell = XtVaCreatePopupShell("dialogShell",
	    transientShellWidgetClass, vimShell,
	    XtNtitle, title,
	    NULL);
    if (dialogshell == (Widget)0)
	goto error;

    dialog = XtVaCreateManagedWidget("dialog",
	    formWidgetClass, dialogshell,
	    XtNdefaultDistance, 20,
	    NULL);
    if (dialog == (Widget)0)
	goto error;
    gui_athena_menu_colors(dialog);
    dialogmessage = XtVaCreateManagedWidget("dialogMessage",
	    labelWidgetClass, dialog,
	    XtNlabel, message,
	    XtNtop, XtChainTop,
	    XtNbottom, XtChainTop,
	    XtNleft, XtChainLeft,
	    XtNright, XtChainLeft,
	    XtNresizable, True,
	    XtNborderWidth, 0,
	    NULL);
    gui_athena_menu_colors(dialogmessage);

    if (textfield != NULL)
    {
	dialogtextfield = XtVaCreateManagedWidget("textfield",
		asciiTextWidgetClass, dialog,
		XtNwidth, 400,
		XtNtop, XtChainTop,
		XtNbottom, XtChainTop,
		XtNleft, XtChainLeft,
		XtNright, XtChainRight,
		XtNfromVert, dialogmessage,
		XtNresizable, True,
		XtNstring, textfield,
		XtNlength, IOSIZE,
		XtNuseStringInPlace, True,
		XtNeditType, XawtextEdit,
		XtNwrap, XawtextWrapNever,
		XtNresize, XawtextResizeHeight,
		NULL);
	XtManageChild(dialogtextfield);
	XtAddEventHandler(dialogtextfield, KeyPressMask, False,
			    (XtEventHandler)keyhit_callback, (XtPointer)NULL);
	XawTextSetInsertionPoint(dialogtextfield,
					  (XawTextPosition)STRLEN(textfield));
	XtSetKeyboardFocus(dialog, dialogtextfield);
    }

    /* make a copy, so that we can insert NULs */
    buts = vim_strsave(buttons);
    if (buts == NULL)
	return -1;

    p = buts;
    for (butcount = 0; *p; ++butcount)
    {
	for (next = p; *next; ++next)
	{
	    if (*next == DLG_HOTKEY_CHAR)
		STRMOVE(next, next + 1);
	    if (*next == DLG_BUTTON_SEP)
	    {
		*next++ = NUL;
		break;
	    }
	}
	dialogButton = XtVaCreateManagedWidget("button",
		commandWidgetClass, dialog,
		XtNlabel, p,
		XtNtop, XtChainBottom,
		XtNbottom, XtChainBottom,
		XtNleft, XtChainLeft,
		XtNright, XtChainLeft,
		XtNfromVert, textfield == NULL ? dialogmessage : dialogtextfield,
		XtNvertDistance, vertical ? 4 : 20,
		XtNresizable, False,
		NULL);
	gui_athena_menu_colors(dialogButton);
	if (butcount > 0)
	    XtVaSetValues(dialogButton,
		    vertical ? XtNfromVert : XtNfromHoriz, prev_dialogButton,
		    NULL);

	XtAddCallback(dialogButton, XtNcallback, butproc, (XtPointer)(long_u)butcount);
	p = next;
	prev_dialogButton = dialogButton;
    }
    vim_free(buts);

    XtRealizeWidget(dialogshell);

    /* Setup for catching the close-window event, don't let it close Vim! */
    dialogatom = XInternAtom(gui.dpy, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(gui.dpy, XtWindow(dialogshell), &dialogatom, 1);
    XtAddEventHandler(dialogshell, NoEventMask, True, dialog_wm_handler, NULL);

    XtVaGetValues(dialogshell,
	    XtNwidth, &wd,
	    XtNheight, &hd,
	    NULL);
    XtVaGetValues(vimShell,
	    XtNwidth, &wv,
	    XtNheight, &hv,
	    NULL);
    XtTranslateCoords(vimShell,
	    (Position)((wv - wd) / 2),
	    (Position)((hv - hd) / 2),
	    &x, &y);
    if (x < 0)
	x = 0;
    if (y < 0)
	y = 0;
    XtVaSetValues(dialogshell, XtNx, x, XtNy, y, NULL);

    /* Position the mouse pointer in the dialog, required for when focus
     * follows mouse. */
    XWarpPointer(gui.dpy, (Window)0, XtWindow(dialogshell), 0, 0, 0, 0, 20, 40);


    app = XtWidgetToApplicationContext(dialogshell);

    XtPopup(dialogshell, XtGrabNonexclusive);

    for (;;)
    {
	XtAppNextEvent(app, &event);
	XtDispatchEvent(&event);
	if (dialogStatus >= 0)
	    break;
    }

    XtPopdown(dialogshell);

    if (textfield != NULL && dialogStatus < 0)
	*textfield = NUL;

error:
    XtDestroyWidget(dialogshell);

    return dialogStatus;
}
#endif

#if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU)
/*
 * Set the colors of Widget "id" to the menu colors.
 */
    static void
gui_athena_menu_colors(id)
    Widget  id;
{
    if (gui.menu_bg_pixel != INVALCOLOR)
	XtVaSetValues(id, XtNbackground, gui.menu_bg_pixel, NULL);
    if (gui.menu_fg_pixel != INVALCOLOR)
	XtVaSetValues(id, XtNforeground, gui.menu_fg_pixel, NULL);
}
#endif

/*
 * Set the colors of Widget "id" to the scroll colors.
 */
    static void
gui_athena_scroll_colors(id)
    Widget  id;
{
    if (gui.scroll_bg_pixel != INVALCOLOR)
	XtVaSetValues(id, XtNbackground, gui.scroll_bg_pixel, NULL);
    if (gui.scroll_fg_pixel != INVALCOLOR)
	XtVaSetValues(id, XtNforeground, gui.scroll_fg_pixel, NULL);
}
