/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved		by Bram Moolenaar
 *				GUI/Motif support by Robert Webb
 *
 * 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 "vim.h"

#include <Xm/Form.h>
#include <Xm/RowColumn.h>
#include <Xm/PushB.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/Separator.h>
#include <Xm/Label.h>
#include <Xm/CascadeB.h>
#include <Xm/ScrollBar.h>
#include <Xm/MenuShell.h>
#include <Xm/DrawingA.h>
#if (XmVersion >= 1002)
# include <Xm/RepType.h>
#endif
#include <Xm/Frame.h>
#include <Xm/LabelG.h>
#include <Xm/ToggleBG.h>
#include <Xm/SeparatoG.h>
#include <Xm/XmP.h>

#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#ifdef HAVE_X11_XPM_H
# if defined(VMS)
#  include <xpm.h>
# else
#  include <X11/xpm.h>
# endif
#else
# ifdef HAVE_XM_XPMP_H
#  include <Xm/XpmP.h>
# endif
#endif
#ifdef HAVE_XM_NOTEBOOK_H
# include <Xm/Notebook.h>
#endif

#include "gui_xmebw.h"	// for our Enhanced Button Widget

#if defined(FEAT_GUI_DIALOG) && defined(HAVE_XPM)
# include "../pixmaps/alert.xpm"
# include "../pixmaps/error.xpm"
# include "../pixmaps/generic.xpm"
# include "../pixmaps/info.xpm"
# include "../pixmaps/quest.xpm"
#endif

#define MOTIF_POPUP

extern Widget vimShell;

static Widget vimForm;
static Widget textAreaForm;
Widget textArea;
#ifdef FEAT_TOOLBAR
static Widget toolBarFrame;
static Widget toolBar;
#endif
#ifdef FEAT_GUI_TABLINE
static Widget	tabLine;
static Widget	tabLine_menu = 0;
static int	showing_tabline = 0;
#endif
#ifdef FEAT_FOOTER
static Widget footer;
#endif
#ifdef FEAT_MENU
# if (XmVersion >= 1002)
// remember the last set value for the tearoff item
static int tearoff_val = (int)XmTEAR_OFF_ENABLED;
# endif
static Widget menuBar;
#endif

#ifdef FEAT_TOOLBAR
# ifdef FEAT_FOOTER
static void toolbarbutton_enter_cb(Widget, XtPointer, XEvent *, Boolean *);
static void toolbarbutton_leave_cb(Widget, XtPointer, XEvent *, Boolean *);
# endif
static void reset_focus(void);
#endif

static void gui_motif_menu_colors(Widget id);
static void gui_motif_scroll_colors(Widget id);

#if (XmVersion >= 1002)
# define STRING_TAG  XmFONTLIST_DEFAULT_TAG
#else
# define STRING_TAG  XmSTRING_DEFAULT_CHARSET
#endif

/*
 * Call-back routines.
 */

    static void
scroll_cb(Widget w UNUSED, XtPointer client_data, XtPointer call_data)
{
    scrollbar_T *sb;
    long	value;
    int		dragging;

    sb = gui_find_scrollbar((long)client_data);

    value = ((XmScrollBarCallbackStruct *)call_data)->value;
    dragging = (((XmScrollBarCallbackStruct *)call_data)->reason ==
							      (int)XmCR_DRAG);
    gui_drag_scrollbar(sb, value, dragging);
}

#ifdef FEAT_GUI_TABLINE
    static void
tabline_cb(
    Widget	w UNUSED,
    XtPointer	client_data UNUSED,
    XtPointer	call_data)
{
    XmNotebookCallbackStruct *nptr;

    nptr = (XmNotebookCallbackStruct *)call_data;
    if (nptr->reason != (int)XmCR_NONE)
	send_tabline_event(nptr->page_number);
}

    static void
tabline_button_cb(
    Widget	w,
    XtPointer	client_data UNUSED,
    XtPointer	call_data UNUSED)
{
    int		cmd, tab_idx;

    XtVaGetValues(w, XmNuserData, &cmd, NULL);
    XtVaGetValues(tabLine_menu, XmNuserData, &tab_idx, NULL);

    send_tabline_menu_event(tab_idx, cmd);
}

/*
 * Tabline single mouse click timeout handler
 */
    static void
motif_tabline_timer_cb (
    XtPointer		timed_out,
    XtIntervalId	*interval_id UNUSED)
{
    *((int *)timed_out) = TRUE;
}

/*
 * check if the tabline tab scroller is clicked
 */
    static int
tabline_scroller_clicked(
    char		*scroller_name,
    XButtonPressedEvent *event)
{
    Widget	tab_scroll_w;
    Position	pos_x, pos_y;
    Dimension	width, height;

    tab_scroll_w = XtNameToWidget(tabLine, scroller_name);
    if (tab_scroll_w != (Widget)0) {
	XtVaGetValues(tab_scroll_w, XmNx, &pos_x, XmNy, &pos_y, XmNwidth,
		      &width, XmNheight, &height, NULL);
	if (pos_x >= 0) {
	    // Tab scroller (next) is visible
	    if ((event->x >= pos_x) && (event->x <= pos_x + width) &&
		(event->y >= pos_y) && (event->y <= pos_y + height)) {
		// Clicked on the scroller
		return TRUE;
	    }
	}
    }
    return FALSE;
}

    static void
tabline_menu_cb(
    Widget	w,
    XtPointer	closure UNUSED,
    XEvent	*e,
    Boolean	*continue_dispatch UNUSED)
{
    Widget			tab_w;
    XButtonPressedEvent		*event;
    int				tab_idx = 0;
    WidgetList			children;
    Cardinal			numChildren;
    static XtIntervalId		timer = (XtIntervalId)0;
    static int			timed_out = TRUE;

    event = (XButtonPressedEvent *)e;

    if (event->button == Button1)
    {
	if (tabline_scroller_clicked("MajorTabScrollerNext", event)
	    || tabline_scroller_clicked("MajorTabScrollerPrevious", event))
	    return;

	if (!timed_out)
	{
	    XtRemoveTimeOut(timer);
	    timed_out = TRUE;

	    /*
	     * Double click on the tabline gutter, add a new tab
	     */
	    send_tabline_menu_event(0, TABLINE_MENU_NEW);
	}
	else
	{
	    /*
	     * Single click on the tabline gutter, start a timer to check
	     * for double clicks
	     */
	    timer = XtAppAddTimeOut(app_context, (long_u)p_mouset,
				    motif_tabline_timer_cb, &timed_out);
	    timed_out = FALSE;
	}
	return;
    }

    if (event->button != Button3)
	return;

    // When ignoring events don't show the menu.
    if (hold_gui_events
# ifdef FEAT_CMDWIN
	    || cmdwin_type != 0
# endif
       )
	return;

    if (event->subwindow != None)
    {
	tab_w = XtWindowToWidget(XtDisplay(w), event->subwindow);
	// LINTED: avoid warning: dubious operation on enum
	if (tab_w != (Widget)0 && XmIsPushButton(tab_w))
	    XtVaGetValues(tab_w, XmNpageNumber, &tab_idx, NULL);
    }

    XtVaSetValues(tabLine_menu, XmNuserData, tab_idx, NULL);
    XtVaGetValues(tabLine_menu, XmNchildren, &children, XmNnumChildren,
		  &numChildren, NULL);
    XtManageChildren(children, numChildren);
    XmMenuPosition(tabLine_menu, (XButtonPressedEvent *)e) ;
    XtManageChild(tabLine_menu);
}

    static void
tabline_balloon_cb(BalloonEval *beval, int state UNUSED)
{
    int		nr;
    tabpage_T	*tp;

    if (beval->target == (Widget)0)
	return;

    XtVaGetValues(beval->target, XmNpageNumber, &nr, NULL);
    tp = find_tabpage(nr);
    if (tp == NULL)
	return;

    get_tabline_label(tp, TRUE);
    gui_mch_post_balloon(beval, NameBuff);
}

#endif

/*
 * End of call-back routines
 */

/*
 * Implement three dimensional shading of insensitive labels.
 * By Marcin Dalecki.
 */

#include <Xm/XmP.h>
#include <Xm/LabelP.h>

static XtExposeProc old_label_expose = NULL;

    static void
label_expose(Widget _w, XEvent *_event, Region _region)
{
    GC		    insensitiveGC;
    XmLabelWidget   lw = (XmLabelWidget)_w;
    unsigned char   label_type = (int)XmSTRING;

    XtVaGetValues(_w, XmNlabelType, &label_type, (XtPointer)0);

    if (XtIsSensitive(_w) || label_type != (int)XmSTRING)
	(*old_label_expose)(_w, _event, _region);
    else
    {
	XGCValues   values;
	XtGCMask    mask;
	XtGCMask    dynamic;
	XFontStruct *fs;

	_XmFontListGetDefaultFont(lw->label.font, &fs);

	// FIXME: we should be doing the whole drawing ourself here.
	insensitiveGC = lw->label.insensitive_GC;

	mask = GCForeground | GCBackground | GCGraphicsExposures;
	dynamic = GCClipMask | GCClipXOrigin | GCClipYOrigin;
	values.graphics_exposures = False;

	if (fs != 0)
	{
	    mask |= GCFont;
	    values.font = fs->fid;
	}

	if (lw->primitive.top_shadow_pixmap != None
		&& lw->primitive.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
	{
	    mask |= GCFillStyle | GCTile;
	    values.fill_style = FillTiled;
	    values.tile = lw->primitive.top_shadow_pixmap;
	}

	lw->label.TextRect.x += 1;
	lw->label.TextRect.y += 1;
	if (lw->label._acc_text != 0)
	{
	    lw->label.acc_TextRect.x += 1;
	    lw->label.acc_TextRect.y += 1;
	}

	values.foreground = lw->primitive.top_shadow_color;
	values.background = lw->core.background_pixel;

	lw->label.insensitive_GC = XtAllocateGC((Widget)lw, 0, mask,
					       &values, dynamic, (XtGCMask)0);
	(*old_label_expose)(_w, _event, _region);
	XtReleaseGC(_w, lw->label.insensitive_GC);

	lw->label.TextRect.x -= 1;
	lw->label.TextRect.y -= 1;
	if (lw->label._acc_text != 0)
	{
	    lw->label.acc_TextRect.x -= 1;
	    lw->label.acc_TextRect.y -= 1;
	}

	values.foreground = lw->primitive.bottom_shadow_color;
	values.background = lw->core.background_pixel;

	lw->label.insensitive_GC = XtAllocateGC((Widget) lw, 0, mask,
					       &values, dynamic, (XtGCMask)0);
	(*old_label_expose)(_w, _event, _region);
	XtReleaseGC(_w, lw->label.insensitive_GC);

	lw->label.insensitive_GC = insensitiveGC;
    }
}

/*
 * Create all the motif widgets necessary.
 */
    void
gui_x11_create_widgets(void)
{
#ifdef FEAT_GUI_TABLINE
    Widget	button, scroller;
    Arg		args[10];
    int		n;
    XmString	xms;
#endif

    /*
     * Install the 3D shade effect drawing routines.
     */
    if (old_label_expose == NULL)
    {
	old_label_expose = xmLabelWidgetClass->core_class.expose;
	xmLabelWidgetClass->core_class.expose = label_expose;
    }

    /*
     * Start out by adding the configured border width into the border offset
     */
    gui.border_offset = gui.border_width;

    /*
     * Install the tearOffModel resource converter.
     */
#if (XmVersion >= 1002)
    XmRepTypeInstallTearOffModelConverter();
#endif

    // Make sure the "Quit" menu entry of the window manager is ignored
    XtVaSetValues(vimShell, XmNdeleteResponse, XmDO_NOTHING, NULL);

    vimForm = XtVaCreateManagedWidget("vimForm",
	xmFormWidgetClass, vimShell,
	XmNborderWidth, 0,
	XmNhighlightThickness, 0,
	XmNshadowThickness, 0,
	XmNmarginWidth, 0,
	XmNmarginHeight, 0,
	XmNresizePolicy, XmRESIZE_ANY,
	NULL);
    gui_motif_menu_colors(vimForm);

#ifdef FEAT_MENU
    {
	Arg al[7]; // Make sure there is enough room for arguments!
	int ac = 0;

# if (XmVersion >= 1002)
	XtSetArg(al[ac], XmNtearOffModel, tearoff_val); ac++;
# endif
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
# ifndef FEAT_TOOLBAR
	// Always stick to right hand side.
	XtSetArg(al[ac], XmNrightOffset, 0); ac++;
# endif
	XtSetArg(al[ac], XmNmarginHeight, 0); ac++;
	menuBar = XmCreateMenuBar(vimForm, "menuBar", al, ac);
	XtManageChild(menuBar);

	// Remember the default colors, needed for ":hi clear".
	XtVaGetValues(menuBar,
	    XmNbackground, &gui.menu_def_bg_pixel,
	    XmNforeground, &gui.menu_def_fg_pixel,
	    NULL);
	gui_motif_menu_colors(menuBar);
    }
#endif

#ifdef FEAT_TOOLBAR
    /*
     * Create an empty ToolBar. We should get buttons defined from menu.vim.
     */
    toolBarFrame = XtVaCreateWidget("toolBarFrame",
	xmFrameWidgetClass, vimForm,
	XmNshadowThickness, 0,
	XmNmarginHeight, 0,
	XmNmarginWidth, 0,
	XmNleftAttachment, XmATTACH_FORM,
	XmNrightAttachment, XmATTACH_FORM,
	NULL);
    gui_motif_menu_colors(toolBarFrame);

    toolBar = XtVaCreateManagedWidget("toolBar",
	xmRowColumnWidgetClass, toolBarFrame,
	XmNchildType, XmFRAME_WORKAREA_CHILD,
	XmNrowColumnType, XmWORK_AREA,
	XmNorientation, XmHORIZONTAL,
	XmNtraversalOn, False,
	XmNisHomogeneous, False,
	XmNpacking, XmPACK_TIGHT,
	XmNspacing, 0,
	XmNshadowThickness, 0,
	XmNhighlightThickness, 0,
	XmNmarginHeight, 0,
	XmNmarginWidth, 0,
	XmNadjustLast, True,
	NULL);
    gui_motif_menu_colors(toolBar);

#endif

#ifdef FEAT_GUI_TABLINE
    // Create the Vim GUI tabline
    n = 0;
    XtSetArg(args[n], XmNbindingType, XmNONE); n++;
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    XtSetArg(args[n], XmNbackPageSize, XmNONE); n++;
    XtSetArg(args[n], XmNbackPageNumber, 0); n++;
    XtSetArg(args[n], XmNbackPagePlacement, XmTOP_RIGHT); n++;
    XtSetArg(args[n], XmNmajorTabSpacing, 0); n++;
    XtSetArg(args[n], XmNshadowThickness, 0); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    tabLine = XmCreateNotebook(vimForm, "Vim tabline", args, n);

    XtAddCallback(tabLine, XmNpageChangedCallback, (XtCallbackProc)tabline_cb,
			NULL);
    XtAddEventHandler(tabLine, ButtonPressMask, False,
			(XtEventHandler)tabline_menu_cb, NULL);

    gui.tabline_height = TABLINE_HEIGHT;

    /*
     * Set the size of the minor next/prev scrollers to zero, so
     * that they are not displayed. Due to a bug in OpenMotif 2.3,
     * even if these children widget are unmanaged, they are again
     * managed by the Notebook widget and the notebook widget geometry
     * is adjusted to account for the minor scroller widgets.
     */
    scroller = XtNameToWidget(tabLine, "MinorTabScrollerNext");
    XtVaSetValues(scroller, XmNwidth, 0, XmNresizable, False,
		  XmNtraversalOn, False, NULL);
    scroller = XtNameToWidget(tabLine, "MinorTabScrollerPrevious");
    XtVaSetValues(scroller, XmNwidth, 0, XmNresizable, False,
		  XmNtraversalOn, False, NULL);

    // Create the tabline popup menu
    tabLine_menu = XmCreatePopupMenu(tabLine, "tabline popup", NULL, 0);

    // Add the buttons to the tabline popup menu
    n = 0;
    XtSetArg(args[n], XmNuserData, TABLINE_MENU_CLOSE); n++;
    xms = XmStringCreate((char *)"Close tab", STRING_TAG);
    XtSetArg(args[n], XmNlabelString, xms); n++;
    button = XmCreatePushButton(tabLine_menu, "Close", args, n);
    XtAddCallback(button, XmNactivateCallback,
		  (XtCallbackProc)tabline_button_cb, NULL);
    XmStringFree(xms);

    n = 0;
    XtSetArg(args[n], XmNuserData, TABLINE_MENU_NEW); n++;
    xms = XmStringCreate((char *)"New Tab", STRING_TAG);
    XtSetArg(args[n], XmNlabelString, xms); n++;
    button = XmCreatePushButton(tabLine_menu, "New Tab", args, n);
    XtAddCallback(button, XmNactivateCallback,
		  (XtCallbackProc)tabline_button_cb, NULL);
    XmStringFree(xms);

    n = 0;
    XtSetArg(args[n], XmNuserData, TABLINE_MENU_OPEN); n++;
    xms = XmStringCreate((char *)"Open tab...", STRING_TAG);
    XtSetArg(args[n], XmNlabelString, xms); n++;
    button = XmCreatePushButton(tabLine_menu, "Open tab...", args, n);
    XtAddCallback(button, XmNactivateCallback,
		  (XtCallbackProc)tabline_button_cb, NULL);
    XmStringFree(xms);
#endif

    textAreaForm = XtVaCreateManagedWidget("textAreaForm",
	xmFormWidgetClass, vimForm,
	XmNleftAttachment, XmATTACH_FORM,
	XmNrightAttachment, XmATTACH_FORM,
	XmNbottomAttachment, XmATTACH_FORM,
	XmNtopAttachment, XmATTACH_FORM,
	XmNmarginWidth, 0,
	XmNmarginHeight, 0,
	XmNresizePolicy, XmRESIZE_ANY,
	NULL);
    gui_motif_scroll_colors(textAreaForm);

    textArea = XtVaCreateManagedWidget("textArea",
	xmDrawingAreaWidgetClass, textAreaForm,
	XmNforeground, gui.norm_pixel,
	XmNbackground, gui.back_pixel,
	XmNleftAttachment, XmATTACH_FORM,
	XmNtopAttachment, XmATTACH_FORM,
	XmNrightAttachment, XmATTACH_FORM,
	XmNbottomAttachment, XmATTACH_FORM,

	/*
	 * These take some control away from the user, but avoids making them
	 * add resources to get a decent looking setup.
	 */
	XmNborderWidth, 0,
	XmNhighlightThickness, 0,
	XmNshadowThickness, 0,
	NULL);

#ifdef FEAT_FOOTER
    /*
     * Create the Footer.
     */
    footer = XtVaCreateWidget("footer",
	xmLabelGadgetClass, vimForm,
	XmNalignment, XmALIGNMENT_BEGINNING,
	XmNmarginHeight, 0,
	XmNmarginWidth, 0,
	XmNtraversalOn, False,
	XmNrecomputeSize, False,
	XmNleftAttachment, XmATTACH_FORM,
	XmNleftOffset, 5,
	XmNrightAttachment, XmATTACH_FORM,
	XmNbottomAttachment, XmATTACH_FORM,
	NULL);
    gui_mch_set_footer((char_u *) "");
#endif

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

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

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

    void
gui_mch_set_text_area_pos(
    int	    x UNUSED,
    int	    y UNUSED,
    int	    w UNUSED,
    int	    h UNUSED)
{
#ifdef FEAT_TOOLBAR
    // Give keyboard focus to the textArea instead of the toolbar.
    reset_focus();
#endif
}

    void
gui_x11_set_back_color(void)
{
    if (textArea != NULL)
#if (XmVersion >= 1002)
	XmChangeColor(textArea, gui.back_pixel);
#else
	XtVaSetValues(textArea,
		  XmNbackground, gui.back_pixel,
		  NULL);
#endif
}

/*
 * Manage dialog centered on pointer. This could be used by the Athena code as
 * well.
 */
    void
manage_centered(Widget dialog_child)
{
    Widget shell = XtParent(dialog_child);
    Window root, child;
    unsigned int mask;
    unsigned int width, height, border_width, depth;
    int x, y, win_x, win_y, maxX, maxY;
    Boolean mappedWhenManaged;

    // Temporarily set value of XmNmappedWhenManaged
    // to stop the dialog from popping up right away
    XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, NULL);
    XtVaSetValues(shell, XmNmappedWhenManaged, False, NULL);

    XtManageChild(dialog_child);

    // Get the pointer position (x, y)
    XQueryPointer(XtDisplay(shell), XtWindow(shell), &root, &child,
		  &x, &y, &win_x, &win_y, &mask);

    // Translate the pointer position (x, y) into a position for the new
    // window that will place the pointer at its center
    XGetGeometry(XtDisplay(shell), XtWindow(shell), &root, &win_x, &win_y,
		 &width, &height, &border_width, &depth);
    width += 2 * border_width;
    height += 2 * border_width;
    x -= width / 2;
    y -= height / 2;

    // Ensure that the dialog remains on screen
    maxX = XtScreen(shell)->width - width;
    maxY = XtScreen(shell)->height - height;
    if (x < 0)
	x = 0;
    if (x > maxX)
	x = maxX;
    if (y < 0)
	y = 0;
    if (y > maxY)
	y = maxY;

    // Set desired window position in the DialogShell
    XtVaSetValues(shell, XmNx, x, XmNy, y, NULL);

    // Map the widget
    XtMapWidget(shell);

    // Restore the value of XmNmappedWhenManaged
    XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, NULL);
}

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

/*
 * Encapsulate the way an XmFontList is created.
 */
    XmFontList
gui_motif_create_fontlist(XFontStruct *font)
{
    XmFontList font_list;

# if (XmVersion <= 1001)
    // Motif 1.1 method
    font_list = XmFontListCreate(font, STRING_TAG);
# else
    // Motif 1.2 method
    XmFontListEntry font_list_entry;

    font_list_entry = XmFontListEntryCreate(STRING_TAG, XmFONT_IS_FONT,
					    (XtPointer)font);
    font_list = XmFontListAppendEntry(NULL, font_list_entry);
    XmFontListEntryFree(&font_list_entry);
# endif
    return font_list;
}

# if ((XmVersion > 1001) && defined(FEAT_XFONTSET)) || defined(PROTO)
    XmFontList
gui_motif_fontset2fontlist(XFontSet *fontset)
{
    XmFontList font_list;

    // Motif 1.2 method
    XmFontListEntry font_list_entry;

    font_list_entry = XmFontListEntryCreate(STRING_TAG,
					    XmFONT_IS_FONTSET,
					    (XtPointer)*fontset);
    font_list = XmFontListAppendEntry(NULL, font_list_entry);
    XmFontListEntryFree(&font_list_entry);
    return font_list;
}
# endif

#endif

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

static void gui_motif_add_actext(vimmenu_T *menu);
#if (XmVersion >= 1002)
static void toggle_tearoff(Widget wid);
static void gui_mch_recurse_tearoffs(vimmenu_T *menu);
#endif
static void submenu_change(vimmenu_T *mp, int colors);

static void do_set_mnemonics(int enable);
static int menu_enabled = TRUE;

    void
gui_mch_enable_menu(int flag)
{
    if (flag)
    {
	XtManageChild(menuBar);
#ifdef FEAT_TOOLBAR
	if (XtIsManaged(XtParent(toolBar)))
	{
	    // toolBar is attached to top form
	    XtVaSetValues(XtParent(toolBar),
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, menuBar,
		NULL);
#ifdef FEAT_GUI_TABLINE
	    if (showing_tabline)
	    {
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, XtParent(toolBar),
			      NULL);
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, tabLine,
			      NULL);
	    }
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, XtParent(toolBar),
			      NULL);
	}
	else
#endif
	{
#ifdef FEAT_GUI_TABLINE
	    if (showing_tabline)
	    {
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, menuBar,
			      NULL);
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, tabLine,
			      NULL);
	    }
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, menuBar,
			      NULL);
	}
    }
    else
    {
	XtUnmanageChild(menuBar);
#ifdef FEAT_TOOLBAR
	if (XtIsManaged(XtParent(toolBar)))
	{
	    XtVaSetValues(XtParent(toolBar),
		XmNtopAttachment, XmATTACH_FORM,
		NULL);
#ifdef FEAT_GUI_TABLINE
	    if (showing_tabline)
	    {
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, XtParent(toolBar),
			      NULL);
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, tabLine,
			      NULL);
	    }
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, XtParent(toolBar),
			      NULL);
	}
	else
#endif
	{
#ifdef FEAT_GUI_TABLINE
	    if (showing_tabline)
	    {
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_FORM,
			      NULL);
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, tabLine,
			      NULL);
	    }
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_FORM,
			      NULL);
	}
    }

}

/*
 * Enable or disable mnemonics for the toplevel menus.
 */
    void
gui_motif_set_mnemonics(int enable)
{
    /*
     * Don't enable menu mnemonics when the menu bar is disabled, LessTif
     * crashes when using a mnemonic then.
     */
    if (!menu_enabled)
	enable = FALSE;
    do_set_mnemonics(enable);
}

    static void
do_set_mnemonics(int enable)
{
    vimmenu_T	*menu;

    FOR_ALL_MENUS(menu)
	if (menu->id != (Widget)0)
	    XtVaSetValues(menu->id,
		    XmNmnemonic, enable ? menu->mnemonic : NUL,
		    NULL);
}

    void
gui_mch_add_menu(vimmenu_T *menu, int idx)
{
    XmString	label;
    Widget	shell;
    vimmenu_T	*parent = menu->parent;

#ifdef MOTIF_POPUP
    if (menu_is_popup(menu->name))
    {
	Arg arg[2];
	int n = 0;

	// Only create the popup menu when it's actually used, otherwise there
	// is a delay when using the right mouse button.
# if (XmVersion <= 1002)
	if (mouse_model_popup())
# endif
	{
	    if (gui.menu_bg_pixel != INVALCOLOR)
	    {
		XtSetArg(arg[0], XmNbackground, gui.menu_bg_pixel); n++;
	    }
	    if (gui.menu_fg_pixel != INVALCOLOR)
	    {
		XtSetArg(arg[1], XmNforeground, gui.menu_fg_pixel); n++;
	    }
	    menu->submenu_id = XmCreatePopupMenu(textArea, "contextMenu",
								      arg, n);
	    menu->id = (Widget)0;
	}
	return;
    }
#endif

    if (!menu_is_menubar(menu->name)
	    || (parent != NULL && parent->submenu_id == (Widget)0))
	return;

    label = XmStringCreate((char *)menu->dname, STRING_TAG);
    if (label == NULL)
	return;
    menu->id = XtVaCreateWidget("subMenu",
	    xmCascadeButtonWidgetClass,
	    (parent == NULL) ? menuBar : parent->submenu_id,
	    XmNlabelString, label,
	    XmNmnemonic, p_wak[0] == 'n' ? NUL : menu->mnemonic,
#if (XmVersion >= 1002)
	    // submenu: count the tearoff item (needed for LessTif)
	    XmNpositionIndex, idx + (parent != NULL
			   && tearoff_val == (int)XmTEAR_OFF_ENABLED ? 1 : 0),
#endif
	    NULL);
    gui_motif_menu_colors(menu->id);
    gui_motif_menu_fontlist(menu->id);
    XmStringFree(label);

    if (menu->id == (Widget)0)		// failed
	return;

    // add accelerator text
    gui_motif_add_actext(menu);

    shell = XtVaCreateWidget("subMenuShell",
	xmMenuShellWidgetClass, menu->id,
	XmNwidth, 1,
	XmNheight, 1,
	NULL);
    gui_motif_menu_colors(shell);
    menu->submenu_id = XtVaCreateWidget("rowColumnMenu",
	xmRowColumnWidgetClass, shell,
	XmNrowColumnType, XmMENU_PULLDOWN,
	NULL);
    gui_motif_menu_colors(menu->submenu_id);

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

#if (XmVersion >= 1002)
    // Set the colors for the tear off widget
    toggle_tearoff(menu->submenu_id);
#endif

    XtVaSetValues(menu->id,
	XmNsubMenuId, menu->submenu_id,
	NULL);

    /*
     * The "Help" menu is a special case, and should be placed at the far
     * right hand side of the menu-bar.  It's recognized by its high priority.
     */
    if (parent == NULL && menu->priority >= 9999)
	XtVaSetValues(menuBar,
		XmNmenuHelpWidget, menu->id,
		NULL);

    /*
     * When we add a top-level item to the menu bar, we can figure out how
     * high the menu bar should be.
     */
    if (parent == NULL)
	gui_mch_compute_menu_height(menu->id);
}


/*
 * Add mnemonic and accelerator text to a menu button.
 */
    static void
gui_motif_add_actext(vimmenu_T *menu)
{
    XmString	label;

    // Add accelerator text, if there is one
    if (menu->actext != NULL && menu->id != (Widget)0)
    {
	label = XmStringCreate((char *)menu->actext, STRING_TAG);
	if (label == NULL)
	    return;
	XtVaSetValues(menu->id, XmNacceleratorText, label, NULL);
	XmStringFree(label);
    }
}

    void
gui_mch_toggle_tearoffs(int enable)
{
#if (XmVersion >= 1002)
    if (enable)
	tearoff_val = (int)XmTEAR_OFF_ENABLED;
    else
	tearoff_val = (int)XmTEAR_OFF_DISABLED;
    toggle_tearoff(menuBar);
    gui_mch_recurse_tearoffs(root_menu);
#endif
}

#if (XmVersion >= 1002)
/*
 * Set the tearoff for one menu widget on or off, and set the color of the
 * tearoff widget.
 */
    static void
toggle_tearoff(Widget wid)
{
    Widget	w;

    XtVaSetValues(wid, XmNtearOffModel, tearoff_val, NULL);
    if (tearoff_val == (int)XmTEAR_OFF_ENABLED
	    && (w = XmGetTearOffControl(wid)) != (Widget)0)
	gui_motif_menu_colors(w);
}

    static void
gui_mch_recurse_tearoffs(vimmenu_T *menu)
{
    while (menu != NULL)
    {
	if (!menu_is_popup(menu->name))
	{
	    if (menu->submenu_id != (Widget)0)
		toggle_tearoff(menu->submenu_id);
	    gui_mch_recurse_tearoffs(menu->children);
	}
	menu = menu->next;
    }
}
#endif

    int
gui_mch_text_area_extra_height(void)
{
    Dimension	shadowHeight;

    XtVaGetValues(textAreaForm, XmNshadowThickness, &shadowHeight, NULL);
    return shadowHeight;
}

/*
 * Compute the height of the menu bar.
 * We need to check all the items for their position and height, for the case
 * there are several rows, and/or some characters extend higher or lower.
 */
    void
gui_mch_compute_menu_height(
    Widget	id)		    // can be NULL when deleting menu
{
    Dimension	y, maxy;
    Dimension	margin, shadow;
    vimmenu_T	*mp;
    static Dimension	height = 21;	// normal height of a menu item

    /*
     * Get the height of the new item, before managing it, because it will
     * still reflect the font size.  After managing it depends on the menu
     * height, which is what we just wanted to get!.
     */
    if (id != (Widget)0)
	XtVaGetValues(id, XmNheight, &height, NULL);

    // Find any menu Widget, to be able to call XtManageChild()
    else
	FOR_ALL_MENUS(mp)
	    if (mp->id != (Widget)0 && menu_is_menubar(mp->name))
	    {
		id = mp->id;
		break;
	    }

    /*
     * Now manage the menu item, to make them all be positioned (makes an
     * extra row when needed, removes it when not needed).
     */
    if (id != (Widget)0)
	XtManageChild(id);

    /*
     * Now find the menu item that is the furthest down, and get its position.
     */
    maxy = 0;
    FOR_ALL_MENUS(mp)
    {
	if (mp->id != (Widget)0 && menu_is_menubar(mp->name))
	{
	    XtVaGetValues(mp->id, XmNy, &y, NULL);
	    if (y > maxy)
		maxy = y;
	}
    }

    XtVaGetValues(menuBar,
	XmNmarginHeight, &margin,
	XmNshadowThickness, &shadow,
	NULL);

    /*
     * This computation is the result of trial-and-error:
     * maxy =	The maximum position of an item; required for when there are
     *		two or more rows
     * height = height of an item, before managing it;	Hopefully this will
     *		change with the font height.  Includes shadow-border.
     * shadow =	shadow-border; must be subtracted from the height.
     * margin = margin around the menu buttons;  Must be added.
     * Add 4 for the underlining of shortcut keys.
     */
    gui.menu_height = maxy + height - 2 * shadow + 2 * margin + 4;

    // Somehow the menu bar doesn't resize automatically.  Set it here,
    // even though this is a catch 22.  Don't do this when starting up,
    // somehow the menu gets very high then.
    if (gui.shell_created)
	XtVaSetValues(menuBar, XmNheight, gui.menu_height, NULL);
}

#ifdef FEAT_TOOLBAR

/*
 * Icons used by the toolbar code.
 */
#include "gui_x11_pm.h"

static char **get_toolbar_pixmap(vimmenu_T *menu, char **fname);

/*
 * Read an Xpm file.  Return OK or FAIL.
 */
    static int
check_xpm(char_u *path)
{
    XpmAttributes attrs;
    int		status;
    Pixmap	mask;
    Pixmap	map;

    attrs.valuemask = 0;

    // Create the "sensitive" pixmap
    status = XpmReadFileToPixmap(gui.dpy,
	    RootWindow(gui.dpy, DefaultScreen(gui.dpy)),
	    (char *)path, &map, &mask, &attrs);
    XpmFreeAttributes(&attrs);

    if (status == XpmSuccess)
	return OK;
    return FAIL;
}


/*
 * Allocated a pixmap for toolbar menu "menu".
 * When it's to be read from a file, "fname" is set to the file name
 * (in allocated memory).
 * Return a blank pixmap if it fails.
 */
    static char **
get_toolbar_pixmap(vimmenu_T *menu, char **fname)
{
    char_u	buf[MAXPATHL];		// buffer storing expanded pathname
    char	**xpm = NULL;		// xpm array
    int		res;

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

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

	// If it failed, try using the menu name.
	if (res == FAIL && gui_find_bitmap(menu->name, buf, "xpm") == OK)
	    res = check_xpm(buf);
	if (res == OK)
	{
	    *fname = (char *)vim_strsave(buf);
	    return tb_blank_xpm;
	}
    }

    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;
    }

    return xpm;
}

/*
 * Add arguments for the toolbar pixmap to a menu item.
 */
    static int
add_pixmap_args(vimmenu_T *menu, Arg *args, int n)
{
    vim_free(menu->xpm_fname);
    menu->xpm = get_toolbar_pixmap(menu, &menu->xpm_fname);
    if (menu->xpm == NULL)
    {
	XtSetArg(args[n], XmNlabelType, XmSTRING); n++;
    }
    else
    {
	if (menu->xpm_fname != NULL)
	{
	    XtSetArg(args[n], XmNpixmapFile, menu->xpm_fname); n++;
	}
	XtSetArg(args[n], XmNpixmapData, menu->xpm); n++;
	XtSetArg(args[n], XmNlabelLocation, XmBOTTOM); n++;
    }
    return n;
}
#endif // FEAT_TOOLBAR

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

# ifdef EBCDIC
    menu->mnemonic = 0;
# endif

# if (XmVersion <= 1002)
    // Don't add Popup menu items when the popup menu isn't used.
    if (menu_is_child_of_popup(menu) && !mouse_model_popup())
	return;
# endif

# ifdef FEAT_TOOLBAR
    if (menu_is_toolbar(parent->name))
    {
	WidgetClass	type;
	XmString	xms = NULL;    // fallback label if pixmap not found
	int		n;
	Arg		args[18];

	n = 0;
	if (menu_is_separator(menu->name))
	{
	    char	*cp;
	    Dimension	wid;

	    /*
	     * A separator has the format "-sep%d[:%d]-". The optional :%d is
	     * a width specifier. If no width is specified then we choose one.
	     */
	    cp = (char *)vim_strchr(menu->name, ':');
	    if (cp != NULL)
		wid = (Dimension)atoi(++cp);
	    else
		wid = 4;

	    type = xmSeparatorWidgetClass;
	    XtSetArg(args[n], XmNwidth, wid); n++;
	    XtSetArg(args[n], XmNminWidth, wid); n++;
	    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
	    XtSetArg(args[n], XmNseparatorType, XmSHADOW_ETCHED_IN); n++;
	}
	else
	{
	    // Without shadows one can't sense whatever the button has been
	    // pressed or not! However we want to save a bit of space...
	    // Need the highlightThickness to see the focus.
	    XtSetArg(args[n], XmNhighlightThickness, 1); n++;
	    XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
	    XtSetArg(args[n], XmNmarginWidth, 0); n++;
	    XtSetArg(args[n], XmNmarginHeight, 0); n++;
	    XtSetArg(args[n], XmNtraversalOn, False); n++;
	    // Set the label here, so that we can switch between icons/text
	    // by changing the XmNlabelType resource.
	    xms = XmStringCreate((char *)menu->dname, STRING_TAG);
	    XtSetArg(args[n], XmNlabelString, xms); n++;

	    n = add_pixmap_args(menu, args, n);

	    type = xmEnhancedButtonWidgetClass;
	}

	XtSetArg(args[n], XmNpositionIndex, idx); n++;
	if (menu->id == NULL)
	{
	    menu->id = XtCreateManagedWidget((char *)menu->dname,
			type, toolBar, args, n);
	    if (menu->id != NULL && type == xmEnhancedButtonWidgetClass)
	    {
		XtAddCallback(menu->id,
			XmNactivateCallback, gui_x11_menu_cb, menu);
# ifdef FEAT_FOOTER
		XtAddEventHandler(menu->id, EnterWindowMask, False,
			toolbarbutton_enter_cb, menu);
		XtAddEventHandler(menu->id, LeaveWindowMask, False,
			toolbarbutton_leave_cb, menu);
# endif
	    }
	}
	else
	    XtSetValues(menu->id, args, n);
	if (xms != NULL)
	    XmStringFree(xms);

# ifdef FEAT_BEVAL_GUI
	gui_mch_menu_set_tip(menu);
# endif

	menu->parent = parent;
	menu->submenu_id = NULL;
	// When adding first item to toolbar it might have to be enabled .
	if (!XtIsManaged(XtParent(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

    // No parent, must be a non-menubar menu
    if (parent->submenu_id == (Widget)0)
	return;

    menu->submenu_id = (Widget)0;

    // Add menu separator
    if (menu_is_separator(menu->name))
    {
	menu->id = XtVaCreateWidget("subMenu",
		xmSeparatorGadgetClass, parent->submenu_id,
#if (XmVersion >= 1002)
		// count the tearoff item (needed for LessTif)
		XmNpositionIndex, idx + (tearoff_val == (int)XmTEAR_OFF_ENABLED
								     ? 1 : 0),
#endif
		NULL);
	gui_motif_menu_colors(menu->id);
	return;
    }

    label = XmStringCreate((char *)menu->dname, STRING_TAG);
    if (label == NULL)
	return;
    menu->id = XtVaCreateWidget("subMenu",
	xmPushButtonWidgetClass, parent->submenu_id,
	XmNlabelString, label,
	XmNmnemonic, menu->mnemonic,
#if (XmVersion >= 1002)
	// count the tearoff item (needed for LessTif)
	XmNpositionIndex, idx + (tearoff_val == (int)XmTEAR_OFF_ENABLED
								     ? 1 : 0),
#endif
	NULL);
    gui_motif_menu_colors(menu->id);
    gui_motif_menu_fontlist(menu->id);
    XmStringFree(label);

    if (menu->id != (Widget)0)
    {
	XtAddCallback(menu->id, XmNactivateCallback, gui_x11_menu_cb,
		(XtPointer)menu);
	// add accelerator text
	gui_motif_add_actext(menu);
    }
}

#if (XmVersion <= 1002) || defined(PROTO)
/*
 * This function will destroy/create the popup menus dynamically,
 * according to the value of 'mousemodel'.
 * This will fix the "right mouse button freeze" that occurs when
 * there exists a popup menu but it isn't managed.
 */
    void
gui_motif_update_mousemodel(vimmenu_T *menu)
{
    int		idx = 0;

    // When GUI hasn't started the menus have not been created.
    if (!gui.in_use)
      return;

    while (menu)
    {
      if (menu->children != NULL)
      {
	  if (menu_is_popup(menu->name))
	  {
	      if (mouse_model_popup())
	      {
		  // Popup menu will be used.  Create the popup menus.
		  gui_mch_add_menu(menu, idx);
		  gui_motif_update_mousemodel(menu->children);
	      }
	      else
	      {
		  // Popup menu will not be used.  Destroy the popup menus.
		  gui_motif_update_mousemodel(menu->children);
		  gui_mch_destroy_menu(menu);
	      }
	  }
      }
      else if (menu_is_child_of_popup(menu))
      {
	  if (mouse_model_popup())
	      gui_mch_add_menu_item(menu, idx);
	  else
	      gui_mch_destroy_menu(menu);
      }
      menu = menu->next;
      ++idx;
    }
}
#endif

    void
gui_mch_new_menu_colors(void)
{
    if (menuBar == (Widget)0)
	return;
    gui_motif_menu_colors(menuBar);
#ifdef FEAT_TOOLBAR
    gui_motif_menu_colors(toolBarFrame);
    gui_motif_menu_colors(toolBar);
#endif

    submenu_change(root_menu, TRUE);
}

    void
gui_mch_new_menu_font(void)
{
    if (menuBar == (Widget)0)
	return;
    submenu_change(root_menu, FALSE);
    {
	Dimension   height;
	Position w, h;

	XtVaGetValues(menuBar, XmNheight, &height, NULL);
	gui.menu_height = height;

	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 defined(FEAT_BEVAL_GUI) || defined(PROTO)
    void
gui_mch_new_tooltip_font(void)
{
# ifdef FEAT_TOOLBAR
    vimmenu_T   *menu;

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

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

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

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

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

    static void
submenu_change(
    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_motif_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->xpm != NULL)
		{
		    int		n = 0;
		    Arg		args[18];

		    n = add_pixmap_args(mp, args, n);
		    XtSetValues(mp->id, args, n);
		}
# ifdef FEAT_BEVAL_GUI
		// If we have a tooltip, then we need to change its font
		if (mp->tip != NULL)
		{
		    Arg args[2];

		    args[0].name = XmNbackground;
		    args[0].value = gui.tooltip_bg_pixel;
		    args[1].name = XmNforeground;
		    args[1].value = gui.tooltip_fg_pixel;
		    XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
		}
# endif
#endif
	    }
	    else
	    {
		gui_motif_menu_fontlist(mp->id);
#ifdef FEAT_BEVAL_GUI
		// If we have a tooltip, then we need to change its font
		if (mp->tip != NULL)
		{
		    Arg args[1];

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

	if (mp->children != NULL)
	{
#if (XmVersion >= 1002)
	    // Set the colors/font for the tear off widget
	    if (mp->submenu_id != (Widget)0)
	    {
		if (colors)
		    gui_motif_menu_colors(mp->submenu_id);
		else
		    gui_motif_menu_fontlist(mp->submenu_id);
		toggle_tearoff(mp->submenu_id);
	    }
#endif
	    // Set the colors for the children
	    submenu_change(mp->children, colors);
	}
    }
}

/*
 * Destroy the machine specific menu widget.
 */
    void
gui_mch_destroy_menu(vimmenu_T *menu)
{
    // Please be sure to destroy the parent widget first (i.e. menu->id).
    // On the other hand, problems have been reported that the submenu must be
    // deleted first...
    //
    // This code should be basically identical to that in the file gui_athena.c
    // because they are both Xt based.
    if (menu->submenu_id != (Widget)0)
    {
	XtDestroyWidget(menu->submenu_id);
	menu->submenu_id = (Widget)0;
    }

    if (menu->id != (Widget)0)
    {
	Widget	    parent;

	parent = XtParent(menu->id);
#if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL_GUI)
	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
	XtDestroyWidget(menu->id);
	menu->id = (Widget)0;
	if (parent == menuBar)
	    gui_mch_compute_menu_height((Widget)0);
#ifdef FEAT_TOOLBAR
	else if (parent == toolBar)
	{
	    Cardinal    num_children;

	    // When removing last toolbar item, don't display the toolbar.
	    XtVaGetValues(toolBar, XmNnumChildren, &num_children, NULL);
	    if (num_children == 0)
		gui_mch_show_toolbar(FALSE);
	    else
		gui.toolbar_height = gui_mch_compute_toolbar_height();
	}
#endif
    }
}

    void
gui_mch_show_popupmenu(vimmenu_T *menu UNUSED)
{
#ifdef MOTIF_POPUP
    XmMenuPosition(menu->submenu_id, gui_x11_get_last_mouse_event());
    XtManageChild(menu->submenu_id);
#endif
}

#endif // FEAT_MENU

/*
 * Set the menu and scrollbar colors to their default values.
 */
    void
gui_mch_def_colors(void)
{
    if (gui.in_use)
    {
	// Use the values saved when starting up.  These should come from the
	// window manager or a resources file.
	gui.menu_fg_pixel = gui.menu_def_fg_pixel;
	gui.menu_bg_pixel = gui.menu_def_bg_pixel;
	gui.scroll_fg_pixel = gui.scroll_def_fg_pixel;
	gui.scroll_bg_pixel = gui.scroll_def_bg_pixel;
#ifdef FEAT_BEVAL_GUI
	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(
    scrollbar_T *sb,
    long	val,
    long	size,
    long	max)
{
    if (sb->id != (Widget)0)
	XtVaSetValues(sb->id,
		  XmNvalue, val,
		  XmNsliderSize, size,
		  XmNpageIncrement, (size > 2 ? size - 2 : 1),
		  XmNmaximum, max + 1,	    // Motif has max one past the end
		  NULL);
}

    void
gui_mch_set_scrollbar_pos(
    scrollbar_T *sb,
    int		x,
    int		y,
    int		w,
    int		h)
{
    if (sb->id != (Widget)0)
    {
	if (sb->type == SBAR_LEFT || sb->type == SBAR_RIGHT)
	{
	    if (y == 0)
		h -= gui.border_offset;
	    else
		y -= gui.border_offset;
	    XtVaSetValues(sb->id,
			  XmNtopOffset, y,
			  XmNbottomOffset, -y - h,
			  XmNwidth, w,
			  NULL);
	}
	else
	    XtVaSetValues(sb->id,
			  XmNtopOffset, y,
			  XmNleftOffset, x,
			  XmNrightOffset, gui.which_scrollbars[SBAR_RIGHT]
						    ? gui.scrollbar_width : 0,
			  XmNheight, h,
			  NULL);
	XtManageChild(sb->id);
    }
}

    int
gui_mch_get_scrollbar_xpadding(void)
{
    // TODO: Calculate the padding for adjust scrollbar position when the
    // Window is maximized.
    return 0;
}

    int
gui_mch_get_scrollbar_ypadding(void)
{
    // TODO: Calculate the padding for adjust scrollbar position when the
    // Window is maximized.
    return 0;
}

    void
gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
{
    Arg		args[16];
    int		n;

    if (sb->id != (Widget)0)
    {
	n = 0;
	if (flag)
	{
	    switch (sb->type)
	    {
		case SBAR_LEFT:
		    XtSetArg(args[n], XmNleftOffset, gui.scrollbar_width); n++;
		    break;

		case SBAR_RIGHT:
		    XtSetArg(args[n], XmNrightOffset, gui.scrollbar_width); n++;
		    break;

		case SBAR_BOTTOM:
		    XtSetArg(args[n], XmNbottomOffset, gui.scrollbar_height);n++;
		    break;
	    }
	    XtSetValues(textArea, args, n);
	    XtManageChild(sb->id);
	}
	else
	{
	    if (!gui.which_scrollbars[sb->type])
	    {
		// The scrollbars of this type are all disabled, adjust the
		// textArea attachment offset.
		switch (sb->type)
		{
		    case SBAR_LEFT:
			XtSetArg(args[n], XmNleftOffset, 0); n++;
			break;

		    case SBAR_RIGHT:
			XtSetArg(args[n], XmNrightOffset, 0); n++;
			break;

		    case SBAR_BOTTOM:
			XtSetArg(args[n], XmNbottomOffset, 0);n++;
			break;
		}
		XtSetValues(textArea, args, n);
	    }
	    XtUnmanageChild(sb->id);
	}
    }
}

    void
gui_mch_create_scrollbar(
    scrollbar_T *sb,
    int		orient)	// SBAR_VERT or SBAR_HORIZ
{
    Arg		args[16];
    int		n;

    n = 0;
    XtSetArg(args[n], XmNminimum, 0); n++;
    XtSetArg(args[n], XmNorientation,
	    (orient == SBAR_VERT) ? XmVERTICAL : XmHORIZONTAL); n++;

    switch (sb->type)
    {
	case SBAR_LEFT:
	    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
	    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_FORM); n++;
	    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
	    break;

	case SBAR_RIGHT:
	    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
	    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_FORM); n++;
	    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
	    break;

	case SBAR_BOTTOM:
	    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
	    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
	    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
	    break;
    }

    sb->id = XtCreateWidget("scrollBar",
	    xmScrollBarWidgetClass, textAreaForm, args, n);

    // Remember the default colors, needed for ":hi clear".
    if (gui.scroll_def_bg_pixel == (guicolor_T)0
	    && gui.scroll_def_fg_pixel == (guicolor_T)0)
	XtVaGetValues(sb->id,
		XmNbackground, &gui.scroll_def_bg_pixel,
		XmNforeground, &gui.scroll_def_fg_pixel,
		NULL);

    if (sb->id != (Widget)0)
    {
	gui_mch_set_scrollbar_colors(sb);
	XtAddCallback(sb->id, XmNvalueChangedCallback,
		      scroll_cb, (XtPointer)sb->ident);
	XtAddCallback(sb->id, XmNdragCallback,
		      scroll_cb, (XtPointer)sb->ident);
	XtAddEventHandler(sb->id, KeyPressMask, FALSE, gui_x11_key_hit_cb,
	    (XtPointer)0);
    }
}

    void
gui_mch_destroy_scrollbar(scrollbar_T *sb)
{
    if (sb->id != (Widget)0)
	XtDestroyWidget(sb->id);
}

    void
gui_mch_set_scrollbar_colors(scrollbar_T *sb)
{
    if (sb->id != (Widget)0)
    {
	if (gui.scroll_bg_pixel != INVALCOLOR)
	{
#if (XmVersion>=1002)
	    XmChangeColor(sb->id, gui.scroll_bg_pixel);
#else
	    XtVaSetValues(sb->id,
		    XmNtroughColor, gui.scroll_bg_pixel,
		    NULL);
#endif
	}

	if (gui.scroll_fg_pixel != INVALCOLOR)
	    XtVaSetValues(sb->id,
		    XmNforeground, gui.scroll_fg_pixel,
#if (XmVersion<1002)
		    XmNbackground, gui.scroll_fg_pixel,
#endif
		    NULL);
    }

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

/*
 * Miscellaneous stuff:
 */

    Window
gui_x11_get_wid(void)
{
    return(XtWindow(textArea));
}

/*
 * Look for a widget in the widget tree w, with a mnemonic matching keycode.
 * When one is found, simulate a button press on that widget and give it the
 * keyboard focus.  If the mnemonic is on a label, look in the userData field
 * of the label to see if it points to another widget, and give that the focus.
 */
    static void
do_mnemonic(Widget w, unsigned int keycode)
{
    WidgetList	    children;
    int		    numChildren, i;
    Boolean	    isMenu;
    KeySym	    mnemonic = '\0';
    char	    mneString[2];
    Widget	    userData;
    unsigned char   rowColType;

    if (XtIsComposite(w))
    {
	if (XtClass(w) == xmRowColumnWidgetClass)
	{
	    XtVaGetValues(w, XmNrowColumnType, &rowColType, NULL);
	    isMenu = (rowColType != (unsigned char)XmWORK_AREA);
	}
	else
	    isMenu = False;
	if (!isMenu)
	{
	    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
			  &numChildren, NULL);
	    for (i = 0; i < numChildren; i++)
		do_mnemonic(children[i], keycode);
	}
    }
    else
    {
	XtVaGetValues(w, XmNmnemonic, &mnemonic, NULL);
	if (mnemonic != '\0')
	{
	    mneString[0] = mnemonic;
	    mneString[1] = '\0';
	    if (XKeysymToKeycode(XtDisplay(XtParent(w)),
				       XStringToKeysym(mneString)) == keycode)
	    {
		if (XtClass(w) == xmLabelWidgetClass
			|| XtClass(w) == xmLabelGadgetClass)
		{
		    XtVaGetValues(w, XmNuserData, &userData, NULL);
		    if (userData != NULL && XtIsWidget(userData))
			XmProcessTraversal(userData, XmTRAVERSE_CURRENT);
		}
		else
		{
		    XKeyPressedEvent keyEvent;

		    XmProcessTraversal(w, XmTRAVERSE_CURRENT);

		    CLEAR_FIELD(keyEvent);
		    keyEvent.type = KeyPress;
		    keyEvent.serial = 1;
		    keyEvent.send_event = True;
		    keyEvent.display = XtDisplay(w);
		    keyEvent.window = XtWindow(w);
		    XtCallActionProc(w, "Activate", (XEvent *) & keyEvent,
								     NULL, 0);
		}
	    }
	}
    }
}

/*
 * Callback routine for dialog mnemonic processing.
 */
    static void
mnemonic_event(
	Widget	    w,
	XtPointer   call_data UNUSED,
	XKeyEvent   *event,
	Boolean	    *b UNUSED)
{
    do_mnemonic(w, event->keycode);
}


/*
 * Search the widget tree under w for widgets with mnemonics.  When found, add
 * a passive grab to the dialog widget for the mnemonic character, thus
 * directing mnemonic events to the dialog widget.
 */
    static void
add_mnemonic_grabs(Widget dialog, Widget w)
{
    char	    mneString[2];
    WidgetList	    children;
    int		    numChildren, i;
    Boolean	    isMenu;
    KeySym	    mnemonic = '\0';
    unsigned char   rowColType;

    if (XtIsComposite(w))
    {
	if (XtClass(w) == xmRowColumnWidgetClass)
	{
	    XtVaGetValues(w, XmNrowColumnType, &rowColType, NULL);
	    isMenu = (rowColType != (unsigned char)XmWORK_AREA);
	}
	else
	    isMenu = False;
	if (!isMenu)
	{
	    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
							  &numChildren, NULL);
	    for (i = 0; i < numChildren; i++)
		add_mnemonic_grabs(dialog, children[i]);
	}
    }
    else
    {
	XtVaGetValues(w, XmNmnemonic, &mnemonic, NULL);
	if (mnemonic != '\0')
	{
	    mneString[0] = mnemonic;
	    mneString[1] = '\0';
	    XtGrabKey(dialog, XKeysymToKeycode(XtDisplay(dialog),
						  XStringToKeysym(mneString)),
		    Mod1Mask, True, GrabModeAsync, GrabModeAsync);
	}
    }
}

/*
 * Add a handler for mnemonics in a dialog.  Motif itself only handles
 * mnemonics in menus. Mnemonics added or changed after this call will be
 * ignored.
 *
 * To add a mnemonic to a text field or list, set the XmNmnemonic resource on
 * the appropriate label and set the XmNuserData resource of the label to the
 * widget to get the focus when the mnemonic is typed.
 */
    static void
activate_dialog_mnemonics(Widget dialog)
{
    if (!dialog)
	return;

    XtAddEventHandler(dialog, KeyPressMask, False,
			   (XtEventHandler) mnemonic_event, (XtPointer) NULL);
    add_mnemonic_grabs(dialog, dialog);
}

/*
 * Removes the event handler and key-grabs for dialog mnemonic handling.
 */
    static void
suppress_dialog_mnemonics(Widget dialog)
{
    if (!dialog)
	return;

    XtUngrabKey(dialog, AnyKey, Mod1Mask);
    XtRemoveEventHandler(dialog, KeyPressMask, False,
			   (XtEventHandler) mnemonic_event, (XtPointer) NULL);
}

#if defined(FEAT_BROWSE) || defined(FEAT_GUI_DIALOG)
/*
 * Use the 'guifont' or 'guifontset' as a fontlist for a dialog widget.
 */
    static void
set_fontlist(Widget id)
{
    XmFontList fl;

#ifdef FONTSET_ALWAYS
    if (gui.fontset != NOFONTSET)
    {
	fl = gui_motif_fontset2fontlist((XFontSet *)&gui.fontset);
	if (fl != NULL)
	{
	    if (XtIsManaged(id))
	    {
		XtUnmanageChild(id);
		XtVaSetValues(id, XmNfontList, fl, NULL);
		// We should force the widget to recalculate its
		// geometry now.
		XtManageChild(id);
	    }
	    else
		XtVaSetValues(id, XmNfontList, fl, NULL);
	    XmFontListFree(fl);
	}
    }
#else
    if (gui.norm_font != NOFONT)
    {
	fl = gui_motif_create_fontlist((XFontStruct *)gui.norm_font);
	if (fl != NULL)
	{
	    if (XtIsManaged(id))
	    {
		XtUnmanageChild(id);
		XtVaSetValues(id, XmNfontList, fl, NULL);
		// We should force the widget to recalculate its
		// geometry now.
		XtManageChild(id);
	    }
	    else
		XtVaSetValues(id, XmNfontList, fl, NULL);
	    XmFontListFree(fl);
	}
    }
#endif
}
#endif

#if defined(FEAT_BROWSE) || defined(PROTO)

/*
 * file selector related stuff
 */

#include <Xm/FileSB.h>
#include <Xm/XmStrDefs.h>

typedef struct dialog_callback_arg
{
    char *  args;   // not used right now
    int	    id;
} dcbarg_T;

static Widget dialog_wgt;
static char *browse_fname = NULL;
static XmStringCharSet charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;
				// used to set up XmStrings

static void DialogCancelCB(Widget, XtPointer, XtPointer);
static void DialogAcceptCB(Widget, XtPointer, XtPointer);

/*
 * This function is used to translate the predefined label text of the
 * precomposed dialogs. We do this explicitly to allow:
 *
 * - usage of gettext for translation, as in all the other places.
 *
 * - equalize the messages between different GUI implementations as far as
 * possible.
 */
    static void
set_predefined_label(Widget parent, String name, char *new_label)
{
    XmString	str;
    Widget	w;
    char_u	*p, *next;
    KeySym	mnemonic = NUL;

    w = XtNameToWidget(parent, name);

    if (!w)
	return;

    p = vim_strsave((char_u *)new_label);
    if (p == NULL)
	return;
    for (next = p; *next; ++next)
    {
	if (*next == DLG_HOTKEY_CHAR)
	{
	    int len = STRLEN(next);

	    if (len > 0)
	    {
		mch_memmove(next, next + 1, len);
		mnemonic = next[0];
	    }
	}
    }

    str = XmStringCreate((char *)p, STRING_TAG);
    vim_free(p);

    if (str != NULL)
    {
	XtVaSetValues(w,
		XmNlabelString, str,
		XmNmnemonic, mnemonic,
		NULL);
	XmStringFree(str);
    }
    gui_motif_menu_fontlist(w);
}

    static void
set_predefined_fontlist(Widget parent, String name)
{
    Widget w;
    w = XtNameToWidget(parent, name);

    if (!w)
	return;

    set_fontlist(w);
}

/*
 * Put up a file requester.
 * Returns the selected name in allocated memory, or NULL for Cancel.
 */
    char_u *
gui_mch_browse(
    int		saving UNUSED,	// select file to write
    char_u	*title,		// title for the window
    char_u	*dflt,		// default name
    char_u	*ext UNUSED,	// not used (extension added)
    char_u	*initdir,	// initial directory, NULL for current dir
    char_u	*filter)	// file name filter
{
    char_u	dirbuf[MAXPATHL];
    char_u	dfltbuf[MAXPATHL];
    char_u	*pattern;
    char_u	*tofree = NULL;

    // There a difference between the resource name and value, Therefore, we
    // avoid to (ab-)use the (maybe internationalized!) dialog title as a
    // dialog name.

    dialog_wgt = XmCreateFileSelectionDialog(vimShell, "browseDialog", NULL, 0);

    if (initdir == NULL || *initdir == NUL)
    {
	mch_dirname(dirbuf, MAXPATHL);
	initdir = dirbuf;
    }

    if (dflt == NULL)
	dflt = (char_u *)"";
    else if (STRLEN(initdir) + STRLEN(dflt) + 2 < MAXPATHL)
    {
	// The default selection should be the full path, "dflt" is only the
	// file name.
	STRCPY(dfltbuf, initdir);
	add_pathsep(dfltbuf);
	STRCAT(dfltbuf, dflt);
	dflt = dfltbuf;
    }

    // Can only use one pattern for a file name.  Get the first pattern out of
    // the filter.  An empty pattern means everything matches.
    if (filter == NULL)
	pattern = (char_u *)"";
    else
    {
	char_u	*s, *p;

	s = filter;
	for (p = filter; *p != NUL; ++p)
	{
	    if (*p == '\t')	// end of description, start of pattern
		s = p + 1;
	    if (*p == ';' || *p == '\n')	// end of (first) pattern
		break;
	}
	pattern = vim_strnsave(s, p - s);
	tofree = pattern;
	if (pattern == NULL)
	    pattern = (char_u *)"";
    }

    XtVaSetValues(dialog_wgt,
	XtVaTypedArg,
	    XmNdirectory, XmRString, (char *)initdir, STRLEN(initdir) + 1,
	XtVaTypedArg,
	    XmNdirSpec,	XmRString, (char *)dflt, STRLEN(dflt) + 1,
	XtVaTypedArg,
	    XmNpattern,	XmRString, (char *)pattern, STRLEN(pattern) + 1,
	XtVaTypedArg,
	    XmNdialogTitle, XmRString, (char *)title, STRLEN(title) + 1,
	NULL);

    set_predefined_label(dialog_wgt, "Apply", _("&Filter"));
    set_predefined_label(dialog_wgt, "Cancel", _("&Cancel"));
    set_predefined_label(dialog_wgt, "Dir", _("Directories"));
    set_predefined_label(dialog_wgt, "FilterLabel", _("Filter"));
    set_predefined_label(dialog_wgt, "Help", _("&Help"));
    set_predefined_label(dialog_wgt, "Items", _("Files"));
    set_predefined_label(dialog_wgt, "OK", _("&OK"));
    set_predefined_label(dialog_wgt, "Selection", _("Selection"));

    // This is to save us from silly external settings using not fixed with
    // fonts for file selection.
    set_predefined_fontlist(dialog_wgt, "DirListSW.DirList");
    set_predefined_fontlist(dialog_wgt, "ItemsListSW.ItemsList");

    gui_motif_menu_colors(dialog_wgt);
    if (gui.scroll_bg_pixel != INVALCOLOR)
	XtVaSetValues(dialog_wgt, XmNtroughColor, gui.scroll_bg_pixel, NULL);

    XtAddCallback(dialog_wgt, XmNokCallback, DialogAcceptCB, (XtPointer)0);
    XtAddCallback(dialog_wgt, XmNcancelCallback, DialogCancelCB, (XtPointer)0);
    // We have no help in this window, so hide help button
    XtUnmanageChild(XmFileSelectionBoxGetChild(dialog_wgt,
					(unsigned char)XmDIALOG_HELP_BUTTON));

    manage_centered(dialog_wgt);
    activate_dialog_mnemonics(dialog_wgt);

    // sit in a loop until the dialog box has gone away
    do
    {
	XtAppProcessEvent(XtWidgetToApplicationContext(dialog_wgt),
	    (XtInputMask)XtIMAll);
    } while (XtIsManaged(dialog_wgt));

    suppress_dialog_mnemonics(dialog_wgt);
    XtDestroyWidget(dialog_wgt);
    vim_free(tofree);

    if (browse_fname == NULL)
	return NULL;
    return vim_strsave((char_u *)browse_fname);
}

/*
 * The code below was originally taken from
 *	/usr/examples/motif/xmsamplers/xmeditor.c
 * on Digital Unix 4.0d, but heavily modified.
 */

/*
 * Process callback from Dialog cancel actions.
 */
    static void
DialogCancelCB(
    Widget	w UNUSED,		//  widget id
    XtPointer	client_data UNUSED,	//  data from application
    XtPointer	call_data UNUSED)	//  data from widget class
{
    if (browse_fname != NULL)
    {
	XtFree(browse_fname);
	browse_fname = NULL;
    }
    XtUnmanageChild(dialog_wgt);
}

/*
 * Process callback from Dialog actions.
 */
    static void
DialogAcceptCB(
    Widget	w UNUSED,		//  widget id
    XtPointer	client_data UNUSED,	//  data from application
    XtPointer	call_data)		//  data from widget class
{
    XmFileSelectionBoxCallbackStruct *fcb;

    if (browse_fname != NULL)
    {
	XtFree(browse_fname);
	browse_fname = NULL;
    }
    fcb = (XmFileSelectionBoxCallbackStruct *)call_data;

    // get the filename from the file selection box
    XmStringGetLtoR(fcb->value, charset, &browse_fname);

    // popdown the file selection box
    XtUnmanageChild(dialog_wgt);
}

#endif // FEAT_BROWSE

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

static int	dialogStatus;

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

    if (XLookupString(&(event->xkey), buf, 2, &key_sym, NULL) == 1)
    {
	if (*buf == CAR)
	    dialogStatus = 1;
	else if (*buf == ESC)
	    dialogStatus = 2;
    }
    if ((key_sym == XK_Left || key_sym == XK_Right)
	    && !(event->xkey.state & ShiftMask))
	XmTextFieldClearSelection(w, XtLastTimestampProcessed(gui.dpy));
}

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

#ifdef HAVE_XPM

    static Widget
create_pixmap_label(
    Widget	parent,
    String	name,
    char	**data,
    ArgList	args,
    Cardinal	arg)
{
    Widget		label;
    Display		*dsp;
    Screen		*scr;
    int			depth;
    Pixmap		pixmap = 0;
    XpmAttributes	attr;
    Boolean		rs;
    XpmColorSymbol	color[5] =
    {
	{"none", NULL, 0},
	{"iconColor1", NULL, 0},
	{"bottomShadowColor", NULL, 0},
	{"topShadowColor", NULL, 0},
	{"selectColor", NULL, 0}
    };

    label = XmCreateLabelGadget(parent, name, args, arg);

    /*
     * We need to be careful here, since in case of gadgets, there is
     * no way to get the background color directly from the widget itself.
     * In such cases we get it from The Core part of his parent instead.
     */
    dsp = XtDisplayOfObject(label);
    scr = XtScreenOfObject(label);
    XtVaGetValues(XtIsSubclass(label, coreWidgetClass)
	    ?  label : XtParent(label),
		  XmNdepth, &depth,
		  XmNbackground, &color[0].pixel,
		  XmNforeground, &color[1].pixel,
		  XmNbottomShadowColor, &color[2].pixel,
		  XmNtopShadowColor, &color[3].pixel,
		  XmNhighlight, &color[4].pixel,
		  NULL);

    attr.valuemask = XpmColorSymbols | XpmCloseness | XpmDepth;
    attr.colorsymbols = color;
    attr.numsymbols = 5;
    attr.closeness = 65535;
    attr.depth = depth;
    XpmCreatePixmapFromData(dsp, RootWindowOfScreen(scr),
		    data, &pixmap, NULL, &attr);

    XtVaGetValues(label, XmNrecomputeSize, &rs, NULL);
    XtVaSetValues(label, XmNrecomputeSize, True, NULL);
    XtVaSetValues(label,
	    XmNlabelType, XmPIXMAP,
	    XmNlabelPixmap, pixmap,
	    NULL);
    XtVaSetValues(label, XmNrecomputeSize, rs, NULL);

    return label;
}
#endif

    int
gui_mch_dialog(
    int		type UNUSED,
    char_u	*title,
    char_u	*message,
    char_u	*button_names,
    int		dfltbutton,
    char_u	*textfield,		// buffer of size IOSIZE
    int		ex_cmd UNUSED)
{
    char_u		*buts;
    char_u		*p, *next;
    XtAppContext	app;
    XmString		label;
    int			butcount;
    Widget		w;
    Widget		dialogform = NULL;
    Widget		form = NULL;
    Widget		dialogtextfield = NULL;
    Widget		*buttons;
    Widget		sep_form = NULL;
    Boolean		vertical;
    Widget		separator = NULL;
    int			n;
    Arg			args[6];
#ifdef HAVE_XPM
    char		**icon_data = NULL;
    Widget		dialogpixmap = NULL;
#endif

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

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

    dialogform = XmCreateFormDialog(vimShell, (char *)"dialog", NULL, 0);

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

    // Set the title of the Dialog window
    label = XmStringCreateSimple((char *)title);
    if (label == NULL)
	return -1;
    XtVaSetValues(dialogform,
	    XmNdialogTitle, label,
	    XmNhorizontalSpacing, 4,
	    XmNverticalSpacing, vertical ? 0 : 4,
	    NULL);
    XmStringFree(label);

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

    // Count the number of buttons and allocate buttons[].
    butcount = 1;
    for (p = buts; *p; ++p)
	if (*p == DLG_BUTTON_SEP)
	    ++butcount;
    buttons = ALLOC_MULT(Widget, butcount);
    if (buttons == NULL)
    {
	vim_free(buts);
	return -1;
    }

    /*
     * Create the buttons.
     */
    sep_form = (Widget) 0;
    p = buts;
    for (butcount = 0; *p; ++butcount)
    {
	KeySym mnemonic = NUL;

	for (next = p; *next; ++next)
	{
	    if (*next == DLG_HOTKEY_CHAR)
	    {
		int len = STRLEN(next);

		if (len > 0)
		{
		    mch_memmove(next, next + 1, len);
		    mnemonic = next[0];
		}
	    }
	    if (*next == DLG_BUTTON_SEP)
	    {
		*next++ = NUL;
		break;
	    }
	}
	label = XmStringCreate(_((char *)p), STRING_TAG);
	if (label == NULL)
	    break;

	buttons[butcount] = XtVaCreateManagedWidget("button",
		xmPushButtonWidgetClass, dialogform,
		XmNlabelString, label,
		XmNmnemonic, mnemonic,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNbottomOffset, 4,
		XmNshowAsDefault, butcount == dfltbutton - 1,
		XmNdefaultButtonShadowThickness, 1,
		NULL);
	XmStringFree(label);
	gui_motif_menu_fontlist(buttons[butcount]);

	// Layout properly.

	if (butcount > 0)
	{
	    if (vertical)
		XtVaSetValues(buttons[butcount],
			XmNtopWidget, buttons[butcount - 1],
			NULL);
	    else
	    {
		if (*next == NUL)
		{
		    XtVaSetValues(buttons[butcount],
			    XmNrightAttachment, XmATTACH_FORM,
			    XmNrightOffset, 4,
			    NULL);

		    // fill in a form as invisible separator
		    sep_form = XtVaCreateWidget("separatorForm",
			    xmFormWidgetClass,	dialogform,
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, buttons[butcount - 1],
			    XmNrightAttachment, XmATTACH_WIDGET,
			    XmNrightWidget, buttons[butcount],
			    XmNbottomAttachment, XmATTACH_FORM,
			    XmNbottomOffset, 4,
			    NULL);
		    XtManageChild(sep_form);
		}
		else
		{
		    XtVaSetValues(buttons[butcount],
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, buttons[butcount - 1],
			    NULL);
		}
	    }
	}
	else if (!vertical)
	{
	    if (*next == NUL)
	    {
		XtVaSetValues(buttons[0],
			XmNrightAttachment, XmATTACH_FORM,
			XmNrightOffset, 4,
			NULL);

		// fill in a form as invisible separator
		sep_form = XtVaCreateWidget("separatorForm",
			xmFormWidgetClass, dialogform,
			XmNleftAttachment, XmATTACH_FORM,
			XmNleftOffset, 4,
			XmNrightAttachment, XmATTACH_WIDGET,
			XmNrightWidget, buttons[0],
			XmNbottomAttachment, XmATTACH_FORM,
			XmNbottomOffset, 4,
			NULL);
		XtManageChild(sep_form);
	    }
	    else
		XtVaSetValues(buttons[0],
			XmNleftAttachment, XmATTACH_FORM,
			XmNleftOffset, 4,
			NULL);
	}

	XtAddCallback(buttons[butcount], XmNactivateCallback,
			  (XtCallbackProc)butproc, (XtPointer)(long)butcount);
	p = next;
    }
    vim_free(buts);

    separator = (Widget) 0;
    if (butcount > 0)
    {
	// Create the separator for beauty.
	n = 0;
	XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
	XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
	XtSetArg(args[n], XmNbottomWidget, buttons[0]); n++;
	XtSetArg(args[n], XmNbottomOffset, 4); n++;
	XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
	XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
	separator = XmCreateSeparatorGadget(dialogform, "separator", args, n);
	XtManageChild(separator);
    }

    if (textfield != NULL)
    {
	dialogtextfield = XtVaCreateWidget("textField",
		xmTextFieldWidgetClass, dialogform,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	if (butcount > 0)
	    XtVaSetValues(dialogtextfield,
		    XmNbottomAttachment, XmATTACH_WIDGET,
		    XmNbottomWidget, separator,
		    NULL);
	else
	    XtVaSetValues(dialogtextfield,
		    XmNbottomAttachment, XmATTACH_FORM,
		    NULL);

	set_fontlist(dialogtextfield);
	XmTextFieldSetString(dialogtextfield, (char *)textfield);
	XtManageChild(dialogtextfield);
	XtAddEventHandler(dialogtextfield, KeyPressMask, False,
			    (XtEventHandler)keyhit_callback, (XtPointer)NULL);
    }

    // Form holding both message and pixmap labels
    form = XtVaCreateWidget("separatorForm",
	    xmFormWidgetClass, dialogform,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNtopAttachment, XmATTACH_FORM,
	    NULL);
    XtManageChild(form);

#ifdef HAVE_XPM
    // Add a pixmap, left of the message.
    switch (type)
    {
	case VIM_GENERIC:
	    icon_data = generic_xpm;
	    break;
	case VIM_ERROR:
	    icon_data = error_xpm;
	    break;
	case VIM_WARNING:
	    icon_data = alert_xpm;
	    break;
	case VIM_INFO:
	    icon_data = info_xpm;
	    break;
	case VIM_QUESTION:
	    icon_data = quest_xpm;
	    break;
	default:
	    icon_data = generic_xpm;
    }

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNtopOffset, 8); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNbottomOffset, 8); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftOffset, 8); n++;

    dialogpixmap = create_pixmap_label(form, "dialogPixmap",
	    icon_data, args, n);
    XtManageChild(dialogpixmap);
#endif

    // Create the dialog message.
    // Since LessTif is apparently having problems with the creation of
    // properly localized string, we use LtoR here. The symptom is that the
    // string sill not show properly in multiple lines as it does in native
    // Motif.
    label = XmStringCreateLtoR((char *)message, STRING_TAG);
    if (label == NULL)
	return -1;
    w = XtVaCreateManagedWidget("dialogMessage",
				xmLabelGadgetClass, form,
				XmNlabelString, label,
				XmNalignment, XmALIGNMENT_BEGINNING,
				XmNtopAttachment, XmATTACH_FORM,
				XmNtopOffset, 8,
#ifdef HAVE_XPM
				XmNleftAttachment, XmATTACH_WIDGET,
				XmNleftWidget, dialogpixmap,
#else
				XmNleftAttachment, XmATTACH_FORM,
#endif
				XmNleftOffset, 8,
				XmNrightAttachment, XmATTACH_FORM,
				XmNrightOffset, 8,
				XmNbottomAttachment, XmATTACH_FORM,
				XmNbottomOffset, 8,
				NULL);
    XmStringFree(label);
    set_fontlist(w);

    if (textfield != NULL)
    {
	XtVaSetValues(form,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, dialogtextfield,
		NULL);
    }
    else
    {
	if (butcount > 0)
	    XtVaSetValues(form,
		    XmNbottomAttachment, XmATTACH_WIDGET,
		    XmNbottomWidget, separator,
		    NULL);
	else
	    XtVaSetValues(form,
		    XmNbottomAttachment, XmATTACH_FORM,
		    NULL);
    }

    if (dfltbutton < 1)
	dfltbutton = 1;
    if (dfltbutton > butcount)
	dfltbutton = butcount;
    XtVaSetValues(dialogform,
	    XmNdefaultButton, buttons[dfltbutton - 1], NULL);
    if (textfield != NULL)
	XtVaSetValues(dialogform, XmNinitialFocus, dialogtextfield, NULL);
    else
	XtVaSetValues(dialogform, XmNinitialFocus, buttons[dfltbutton - 1],
									NULL);

    manage_centered(dialogform);
    activate_dialog_mnemonics(dialogform);

    if (textfield != NULL && *textfield != NUL)
    {
	// This only works after the textfield has been realised.
	XmTextFieldSetSelection(dialogtextfield,
			 (XmTextPosition)0, (XmTextPosition)STRLEN(textfield),
					   XtLastTimestampProcessed(gui.dpy));
	XmTextFieldSetCursorPosition(dialogtextfield,
					   (XmTextPosition)STRLEN(textfield));
    }

    app = XtWidgetToApplicationContext(dialogform);

    // Loop until a button is pressed or the dialog is killed somehow.
    dialogStatus = -1;
    for (;;)
    {
	XtAppProcessEvent(app, (XtInputMask)XtIMAll);
	if (dialogStatus >= 0 || !XtIsManaged(dialogform))
	    break;
    }

    vim_free(buttons);

    if (textfield != NULL)
    {
	p = (char_u *)XmTextGetString(dialogtextfield);
	if (p == NULL || dialogStatus < 0)
	    *textfield = NUL;
	else
	    vim_strncpy(textfield, p, IOSIZE - 1);
	XtFree((char *)p);
    }

    suppress_dialog_mnemonics(dialogform);
    XtDestroyWidget(dialogform);

    return dialogStatus;
}
#endif // FEAT_GUI_DIALOG

#if defined(FEAT_FOOTER) || defined(PROTO)

    static int
gui_mch_compute_footer_height(void)
{
    Dimension	height;		    // total Toolbar height
    Dimension	top;		    // XmNmarginTop
    Dimension	bottom;		    // XmNmarginBottom
    Dimension	shadow;		    // XmNshadowThickness

    XtVaGetValues(footer,
	    XmNheight, &height,
	    XmNmarginTop, &top,
	    XmNmarginBottom, &bottom,
	    XmNshadowThickness, &shadow,
	    NULL);

    return (int) height + top + bottom + (shadow << 1);
}

    void
gui_mch_enable_footer(int showit)
{
    if (showit)
    {
	gui.footer_height = gui_mch_compute_footer_height();
	XtManageChild(footer);
    }
    else
    {
	gui.footer_height = 0;
	XtUnmanageChild(footer);
    }
    XtVaSetValues(textAreaForm, XmNbottomOffset, gui.footer_height, NULL);
}

    void
gui_mch_set_footer(char_u *s)
{
    XmString	xms;

    xms = XmStringCreate((char *)s, STRING_TAG);
    if (xms != NULL)
    {
	XtVaSetValues(footer, XmNlabelString, xms, NULL);
	XmStringFree(xms);
    }
}

#endif


#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, XmNnumChildren, &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, XmNchildren, &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_ALL_MENUS(toolbar)
		    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[1];
			int	    n = 0;

			// Enable/Disable tooltip (OK to enable while
			// currently enabled).
			if (cur->tip != NULL)
			    (*action)(cur->tip);
			if (!menu_is_separator(cur->name))
			{
			    if (text == 1 || cur->xpm == NULL)
			    {
				XtSetArg(args[n], XmNlabelType, XmSTRING);
				++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(XtParent(toolBar));
#ifdef FEAT_GUI_TABLINE
	if (showing_tabline)
	{
	    XtVaSetValues(tabLine,
			  XmNtopAttachment, XmATTACH_WIDGET,
			  XmNtopWidget, XtParent(toolBar),
			  NULL);
	    XtVaSetValues(textAreaForm,
			  XmNtopAttachment, XmATTACH_WIDGET,
			  XmNtopWidget, tabLine,
			  NULL);
	}
	else
#endif
	    XtVaSetValues(textAreaForm,
			  XmNtopAttachment, XmATTACH_WIDGET,
			  XmNtopWidget, XtParent(toolBar),
			  NULL);
	if (XtIsManaged(menuBar))
	    XtVaSetValues(XtParent(toolBar),
		    XmNtopAttachment, XmATTACH_WIDGET,
		    XmNtopWidget, menuBar,
		    NULL);
	else
	    XtVaSetValues(XtParent(toolBar),
		    XmNtopAttachment, XmATTACH_FORM,
		    NULL);
    }
    else
    {
	gui.toolbar_height = 0;
	if (XtIsManaged(menuBar))
	{
#ifdef FEAT_GUI_TABLINE
	    if (showing_tabline)
	    {
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, menuBar,
			      NULL);
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, tabLine,
			      NULL);
	    }
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, menuBar,
			      NULL);
	}
	else
	{
#ifdef FEAT_GUI_TABLINE
	    if (showing_tabline)
	    {
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_FORM,
			      NULL);
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, tabLine,
			      NULL);
	    }
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_FORM,
			      NULL);
	}

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

/*
 * 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
reset_focus(void)
{
    if (textArea != NULL)
	XmProcessTraversal(textArea, XmTRAVERSE_CURRENT);
}

    int
gui_mch_compute_toolbar_height(void)
{
    Dimension	borders;
    Dimension	height;		    // total Toolbar height
    Dimension	whgt;		    // height of each widget
    WidgetList	children;	    // list of toolBar's children
    Cardinal	numChildren;	    // how many children toolBar has
    int		i;

    borders = 0;
    height = 0;
    if (toolBar != (Widget)0 && toolBarFrame != (Widget)0)
    {				    // get height of XmFrame parent
	Dimension	fst;
	Dimension	fmh;
	Dimension	tst;
	Dimension	tmh;

	XtVaGetValues(toolBarFrame,
		XmNshadowThickness, &fst,
		XmNmarginHeight, &fmh,
		NULL);
	borders += fst + fmh;
	XtVaGetValues(toolBar,
		XmNshadowThickness, &tst,
		XmNmarginHeight, &tmh,
		XmNchildren, &children,
		XmNnumChildren, &numChildren, NULL);
	borders += tst + tmh;
	for (i = 0; i < (int)numChildren; i++)
	{
	    whgt = 0;
	    XtVaGetValues(children[i], XmNheight, &whgt, NULL);
	    if (height < whgt)
		height = whgt;
	}
    }
#ifdef LESSTIF_VERSION
    // Hack: When starting up we get wrong dimensions.
    if (height < 10)
	height = 24;
#endif

    return (int)(height + (borders << 1));
}

    void
motif_get_toolbar_colors(
    Pixel       *bgp,
    Pixel       *fgp,
    Pixel       *bsp,
    Pixel       *tsp,
    Pixel       *hsp)
{
    XtVaGetValues(toolBar,
	    XmNbackground, bgp,
	    XmNforeground, fgp,
	    XmNbottomShadowColor, bsp,
	    XmNtopShadowColor, tsp,
	    XmNhighlightColor, hsp,
	    NULL);
}

# ifdef FEAT_FOOTER
/*
 * The next toolbar enter/leave callbacks should really do balloon help.  But
 * I have to use footer help for backwards compatibility.  Hopefully both will
 * get implemented and the user will have a choice.
 */
    static void
toolbarbutton_enter_cb(
    Widget	w UNUSED,
    XtPointer	client_data,
    XEvent	*event UNUSED,
    Boolean	*cont UNUSED)
{
    vimmenu_T	*menu = (vimmenu_T *) client_data;

    if (menu->strings[MENU_INDEX_TIP] != NULL)
    {
	if (vim_strchr(p_go, GO_FOOTER) != NULL)
	    gui_mch_set_footer(menu->strings[MENU_INDEX_TIP]);
    }
}

    static void
toolbarbutton_leave_cb(
    Widget	w UNUSED,
    XtPointer	client_data UNUSED,
    XEvent	*event UNUSED,
    Boolean	*cont UNUSED)
{
    gui_mch_set_footer((char_u *) "");
}
# endif
#endif

#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
/*
 * Show or hide the tabline.
 */
    void
gui_mch_show_tabline(int showit)
{
    if (tabLine == (Widget)0)
	return;

    if (!showit != !showing_tabline)
    {
	if (showit)
	{
	    XtManageChild(tabLine);
	    XtUnmanageChild(XtNameToWidget(tabLine, "PageScroller"));
	    XtUnmanageChild(XtNameToWidget(tabLine, "MinorTabScrollerNext"));
	    XtUnmanageChild(XtNameToWidget(tabLine,
					   "MinorTabScrollerPrevious"));
#ifdef FEAT_MENU
# ifdef FEAT_TOOLBAR
	    if (XtIsManaged(XtParent(toolBar)))
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, XtParent(toolBar), NULL);
	    else
# endif
		if (XtIsManaged(menuBar))
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, menuBar, NULL);
	    else
#endif
		XtVaSetValues(tabLine,
			      XmNtopAttachment, XmATTACH_FORM, NULL);
	    XtVaSetValues(textAreaForm,
			  XmNtopAttachment, XmATTACH_WIDGET,
			  XmNtopWidget, tabLine,
			  NULL);
	}
	else
	{
	    XtUnmanageChild(tabLine);
#ifdef FEAT_MENU
# ifdef FEAT_TOOLBAR
	    if (XtIsManaged(XtParent(toolBar)))
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, XtParent(toolBar), NULL);
	    else
# endif
		if (XtIsManaged(menuBar))
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_WIDGET,
			      XmNtopWidget, menuBar, NULL);
	    else
#endif
		XtVaSetValues(textAreaForm,
			      XmNtopAttachment, XmATTACH_FORM, NULL);
	}
	showing_tabline = showit;
    }
}

/*
 * Return TRUE when tabline is displayed.
 */
    int
gui_mch_showing_tabline(void)
{
    return tabLine != (Widget)0 && showing_tabline;
}

/*
 * Update the labels of the tabline.
 */
    void
gui_mch_update_tabline(void)
{
    tabpage_T		*tp;
    int			nr = 1, n;
    Arg			args[10];
    int			curtabidx = 0, currentpage;
    Widget		tab;
    XmNotebookPageInfo	page_info;
    XmNotebookPageStatus page_status;
    int			last_page, tab_count;
    XmString		label_str;
    char		*label_cstr;
    BalloonEval		*beval;

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

    // Add a label for each tab page.  They all contain the same text area.
    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
    {
	if (tp == curtab)
	    curtabidx = nr;

	page_status = XmNotebookGetPageInfo(tabLine, nr, &page_info);
	if (page_status == XmPAGE_INVALID
		|| page_info.major_tab_widget == (Widget)0)
	{
	    // Add the tab
	    n = 0;
	    XtSetArg(args[n], XmNnotebookChildType, XmMAJOR_TAB); n++;
	    XtSetArg(args[n], XmNtraversalOn, False); n++;
	    XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
	    XtSetArg(args[n], XmNhighlightThickness, 1); n++;
	    XtSetArg(args[n], XmNshadowThickness , 1); n++;
	    tab = XmCreatePushButton(tabLine, "-Empty-", args, n);
	    XtManageChild(tab);
	    beval = gui_mch_create_beval_area(tab, NULL, tabline_balloon_cb,
									NULL);
	    XtVaSetValues(tab, XmNuserData, beval, NULL);
	}
	else
	    tab = page_info.major_tab_widget;

	XtVaSetValues(tab, XmNpageNumber, nr, NULL);

	/*
	 * Change the label text only if it is different
	 */
	XtVaGetValues(tab, XmNlabelString, &label_str, NULL);
	if (XmStringGetLtoR(label_str, XmSTRING_DEFAULT_CHARSET, &label_cstr))
	{
	    get_tabline_label(tp, FALSE);
	    if (STRCMP(label_cstr, NameBuff) != 0)
	    {
		XtVaSetValues(tab, XtVaTypedArg, XmNlabelString, XmRString,
			      NameBuff, STRLEN(NameBuff) + 1, NULL);
		/*
		 * Force a resize of the tab label button
		 */
		XtUnmanageChild(tab);
		XtManageChild(tab);
	    }
	    XtFree(label_cstr);
	}
    }

    tab_count = nr - 1;

    XtVaGetValues(tabLine, XmNlastPageNumber, &last_page, NULL);

    // Remove any old labels.
    while (nr <= last_page)
    {
	if (XmNotebookGetPageInfo(tabLine, nr, &page_info) != XmPAGE_INVALID
	    && page_info.page_number == nr
	    && page_info.major_tab_widget != (Widget)0)
	{
	    XtVaGetValues(page_info.major_tab_widget, XmNuserData, &beval, NULL);
	    if (beval != NULL)
		gui_mch_destroy_beval_area(beval);
	    XtUnmanageChild(page_info.major_tab_widget);
	    XtDestroyWidget(page_info.major_tab_widget);
	}
	nr++;
    }

    XtVaSetValues(tabLine, XmNlastPageNumber, tab_count, NULL);

    XtVaGetValues(tabLine, XmNcurrentPageNumber, &currentpage, NULL);
    if (currentpage != curtabidx)
	XtVaSetValues(tabLine, XmNcurrentPageNumber, curtabidx, NULL);
}

/*
 * Set the current tab to "nr".  First tab is 1.
 */
    void
gui_mch_set_curtab(int nr)
{
    int		currentpage;

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

    XtVaGetValues(tabLine, XmNcurrentPageNumber, &currentpage, NULL);
    if (currentpage != nr)
	XtVaSetValues(tabLine, XmNcurrentPageNumber, nr, NULL);
}
#endif

/*
 * Set the colors of Widget "id" to the menu colors.
 */
    static void
gui_motif_menu_colors(Widget id)
{
    if (gui.menu_bg_pixel != INVALCOLOR)
#if (XmVersion >= 1002)
	XmChangeColor(id, gui.menu_bg_pixel);
#else
	XtVaSetValues(id, XmNbackground, gui.menu_bg_pixel, NULL);
#endif
    if (gui.menu_fg_pixel != INVALCOLOR)
	XtVaSetValues(id, XmNforeground, gui.menu_fg_pixel, NULL);
}

/*
 * Set the colors of Widget "id" to the scrollbar colors.
 */
    static void
gui_motif_scroll_colors(Widget id)
{
    if (gui.scroll_bg_pixel != INVALCOLOR)
#if (XmVersion >= 1002)
	XmChangeColor(id, gui.scroll_bg_pixel);
#else
	XtVaSetValues(id, XmNbackground, gui.scroll_bg_pixel, NULL);
#endif
    if (gui.scroll_fg_pixel != INVALCOLOR)
	XtVaSetValues(id, XmNforeground, gui.scroll_fg_pixel, NULL);
}

/*
 * Set the fontlist for Widget "id" to use gui.menu_fontset or gui.menu_font.
 */
    void
gui_motif_menu_fontlist(Widget id UNUSED)
{
#ifdef FEAT_MENU
#ifdef FONTSET_ALWAYS
    if (gui.menu_fontset != NOFONTSET)
    {
	XmFontList fl;

	fl = gui_motif_fontset2fontlist((XFontSet *)&gui.menu_fontset);
	if (fl != NULL)
	{
	    if (XtIsManaged(id))
	    {
		XtUnmanageChild(id);
		XtVaSetValues(id, XmNfontList, fl, NULL);
		// We should force the widget to recalculate its
		// geometry now.
		XtManageChild(id);
	    }
	    else
		XtVaSetValues(id, XmNfontList, fl, NULL);
	    XmFontListFree(fl);
	}
    }
#else
    if (gui.menu_font != NOFONT)
    {
	XmFontList fl;

	fl = gui_motif_create_fontlist((XFontStruct *)gui.menu_font);
	if (fl != NULL)
	{
	    if (XtIsManaged(id))
	    {
		XtUnmanageChild(id);
		XtVaSetValues(id, XmNfontList, fl, NULL);
		// We should force the widget to recalculate its
		// geometry now.
		XtManageChild(id);
	    }
	    else
		XtVaSetValues(id, XmNfontList, fl, NULL);
	    XmFontListFree(fl);
	}
    }
#endif
#endif
}


/*
 * We don't create it twice for the sake of speed.
 */

typedef struct _SharedFindReplace
{
    Widget dialog;	// the main dialog widget
    Widget wword;	// 'Exact match' check button
    Widget mcase;	// 'match case' check button
    Widget up;		// search direction 'Up' radio button
    Widget down;	// search direction 'Down' radio button
    Widget what;	// 'Find what' entry text widget
    Widget with;	// 'Replace with' entry text widget
    Widget find;	// 'Find Next' action button
    Widget replace;	// 'Replace With' action button
    Widget all;		// 'Replace All' action button
    Widget undo;	// 'Undo' action button

    Widget cancel;
} SharedFindReplace;

static SharedFindReplace find_widgets = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static SharedFindReplace repl_widgets = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

    static void
find_replace_destroy_callback(
    Widget	w UNUSED,
    XtPointer	client_data,
    XtPointer	call_data UNUSED)
{
    SharedFindReplace *cd = (SharedFindReplace *)client_data;

    if (cd != NULL)
       // suppress_dialog_mnemonics(cd->dialog);
	cd->dialog = (Widget)0;
}

    static void
find_replace_dismiss_callback(
    Widget	w UNUSED,
    XtPointer	client_data,
    XtPointer	call_data UNUSED)
{
    SharedFindReplace *cd = (SharedFindReplace *)client_data;

    if (cd != NULL)
	XtUnmanageChild(cd->dialog);
}

    static void
entry_activate_callback(
    Widget	w UNUSED,
    XtPointer	client_data,
    XtPointer	call_data UNUSED)
{
    XmProcessTraversal((Widget)client_data, XmTRAVERSE_CURRENT);
}

    static void
find_replace_callback(
    Widget	w UNUSED,
    XtPointer	client_data,
    XtPointer	call_data UNUSED)
{
    long_u	flags = (long_u)client_data;
    char	*find_text, *repl_text;
    Boolean	direction_down = TRUE;
    Boolean	wword;
    Boolean	mcase;
    SharedFindReplace *sfr;

    if (flags == FRD_UNDO)
    {
	char_u	*save_cpo = p_cpo;

	// No need to be Vi compatible here.
	p_cpo = empty_option;
	u_undo(1);
	p_cpo = save_cpo;
	gui_update_screen();
	return;
    }

    // Get the search/replace strings from the dialog
    if (flags == FRD_FINDNEXT)
    {
	repl_text = NULL;
	sfr = &find_widgets;
    }
    else
    {
	repl_text = XmTextFieldGetString(repl_widgets.with);
	sfr = &repl_widgets;
    }
    find_text = XmTextFieldGetString(sfr->what);
    XtVaGetValues(sfr->down, XmNset, &direction_down, NULL);
    XtVaGetValues(sfr->wword, XmNset, &wword, NULL);
    XtVaGetValues(sfr->mcase, XmNset, &mcase, NULL);
    if (wword)
	flags |= FRD_WHOLE_WORD;
    if (mcase)
	flags |= FRD_MATCH_CASE;

    (void)gui_do_findrepl((int)flags, (char_u *)find_text, (char_u *)repl_text,
							      direction_down);

    if (find_text != NULL)
	XtFree(find_text);
    if (repl_text != NULL)
	XtFree(repl_text);
}

    static void
find_replace_keypress(
    Widget		w UNUSED,
    SharedFindReplace	*frdp,
    XKeyEvent		*event,
    Boolean		*b UNUSED)
{
    KeySym keysym;

    if (frdp == NULL)
	return;

    keysym = XLookupKeysym(event, 0);

    // the scape key pops the whole dialog down
    if (keysym == XK_Escape)
	XtUnmanageChild(frdp->dialog);
}

    static void
set_label(Widget w, char *label)
{
    XmString	str;
    char_u	*p, *next;
    KeySym	mnemonic = NUL;

    if (!w)
	return;

    p = vim_strsave((char_u *)label);
    if (p == NULL)
	return;
    for (next = p; *next; ++next)
    {
	if (*next == DLG_HOTKEY_CHAR)
	{
	    int len = STRLEN(next);

	    if (len > 0)
	    {
		mch_memmove(next, next + 1, len);
		mnemonic = next[0];
	    }
	}
    }

    str = XmStringCreateSimple((char *)p);
    vim_free(p);
    if (str)
    {
	XtVaSetValues(w,
		XmNlabelString, str,
		XmNmnemonic, mnemonic,
		NULL);
	XmStringFree(str);
    }
    gui_motif_menu_fontlist(w);
}

    static void
find_replace_dialog_create(char_u *arg, int do_replace)
{
    SharedFindReplace	*frdp;
    Widget		separator;
    Widget		input_form;
    Widget		button_form;
    Widget		toggle_form;
    Widget		frame;
    XmString		str;
    int			n;
    Arg			args[6];
    int			wword = FALSE;
    int			mcase = !p_ic;
    Dimension		width;
    Dimension		widest;
    char_u		*entry_text;

    frdp = do_replace ? &repl_widgets : &find_widgets;

    // Get the search string to use.
    entry_text = get_find_dialog_text(arg, &wword, &mcase);

    // If the dialog already exists, just raise it.
    if (frdp->dialog)
    {
	gui_motif_synch_fonts();

	// If the window is already up, just pop it to the top
	if (XtIsManaged(frdp->dialog))
	    XMapRaised(XtDisplay(frdp->dialog),
					    XtWindow(XtParent(frdp->dialog)));
	else
	    XtManageChild(frdp->dialog);
	XtPopup(XtParent(frdp->dialog), XtGrabNone);
	XmProcessTraversal(frdp->what, XmTRAVERSE_CURRENT);

	if (entry_text != NULL)
	    XmTextFieldSetString(frdp->what, (char *)entry_text);
	vim_free(entry_text);

	XtVaSetValues(frdp->wword, XmNset, wword, NULL);
	return;
    }

    // Create a fresh new dialog window
    if (do_replace)
	 str = XmStringCreateSimple(_("VIM - Search and Replace..."));
    else
	 str = XmStringCreateSimple(_("VIM - Search..."));

    n = 0;
    XtSetArg(args[n], XmNautoUnmanage, False); n++;
    XtSetArg(args[n], XmNnoResize, True); n++;
    XtSetArg(args[n], XmNdialogTitle, str); n++;

    frdp->dialog = XmCreateFormDialog(vimShell, "findReplaceDialog", args, n);
    XmStringFree(str);
    XtAddCallback(frdp->dialog, XmNdestroyCallback,
	    find_replace_destroy_callback, frdp);

    button_form = XtVaCreateWidget("buttonForm",
	    xmFormWidgetClass,	frdp->dialog,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNrightOffset, 4,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNtopOffset, 4,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNbottomOffset, 4,
	    NULL);

    frdp->find = XtVaCreateManagedWidget("findButton",
	    xmPushButtonWidgetClass, button_form,
	    XmNsensitive, True,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNrightAttachment, XmATTACH_FORM,
	    NULL);
    set_label(frdp->find, _("Find &Next"));

    XtAddCallback(frdp->find, XmNactivateCallback,
	    find_replace_callback,
	    (do_replace ? (XtPointer)FRD_R_FINDNEXT : (XtPointer)FRD_FINDNEXT));

    if (do_replace)
    {
	frdp->replace = XtVaCreateManagedWidget("replaceButton",
		xmPushButtonWidgetClass, button_form,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, frdp->find,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	set_label(frdp->replace, _("&Replace"));
	XtAddCallback(frdp->replace, XmNactivateCallback,
		find_replace_callback, (XtPointer)FRD_REPLACE);

	frdp->all = XtVaCreateManagedWidget("replaceAllButton",
		xmPushButtonWidgetClass, button_form,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, frdp->replace,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	set_label(frdp->all, _("Replace &All"));
	XtAddCallback(frdp->all, XmNactivateCallback,
		find_replace_callback, (XtPointer)FRD_REPLACEALL);

	frdp->undo = XtVaCreateManagedWidget("undoButton",
		xmPushButtonWidgetClass, button_form,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, frdp->all,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	set_label(frdp->undo, _("&Undo"));
	XtAddCallback(frdp->undo, XmNactivateCallback,
		find_replace_callback, (XtPointer)FRD_UNDO);
    }

    frdp->cancel = XtVaCreateManagedWidget("closeButton",
	    xmPushButtonWidgetClass, button_form,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNrightAttachment, XmATTACH_FORM,
	    XmNbottomAttachment, XmATTACH_FORM,
	    NULL);
    set_label(frdp->cancel, _("&Cancel"));
    XtAddCallback(frdp->cancel, XmNactivateCallback,
	    find_replace_dismiss_callback, frdp);
    gui_motif_menu_fontlist(frdp->cancel);

    XtManageChild(button_form);

    n = 0;
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
    XtSetArg(args[n], XmNrightWidget, button_form); n++;
    XtSetArg(args[n], XmNrightOffset, 4); n++;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    separator = XmCreateSeparatorGadget(frdp->dialog, "separator", args, n);
    XtManageChild(separator);

    input_form = XtVaCreateWidget("inputForm",
	    xmFormWidgetClass,	frdp->dialog,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNrightAttachment, XmATTACH_WIDGET,
	    XmNrightWidget, separator,
	    XmNrightOffset, 4,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNtopOffset, 4,
	    NULL);

    {
	Widget label_what;
	Widget label_with = (Widget)0;

	str = XmStringCreateSimple(_("Find what:"));
	label_what = XtVaCreateManagedWidget("whatLabel",
		xmLabelGadgetClass, input_form,
		XmNlabelString, str,
		XmNleftAttachment,	XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNtopOffset, 4,
		NULL);
	XmStringFree(str);
	gui_motif_menu_fontlist(label_what);

	frdp->what = XtVaCreateManagedWidget("whatText",
		xmTextFieldWidgetClass, input_form,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		NULL);

	if (do_replace)
	{
	    frdp->with = XtVaCreateManagedWidget("withText",
		    xmTextFieldWidgetClass,	input_form,
		    XmNtopAttachment, XmATTACH_WIDGET,
		    XmNtopWidget, frdp->what,
		    XmNtopOffset, 4,
		    XmNleftAttachment, XmATTACH_FORM,
		    XmNrightAttachment, XmATTACH_FORM,
		    XmNbottomAttachment, XmATTACH_FORM,
		    NULL);

	    XtAddCallback(frdp->with, XmNactivateCallback,
		    find_replace_callback, (XtPointer) FRD_R_FINDNEXT);

	    str = XmStringCreateSimple(_("Replace with:"));
	    label_with = XtVaCreateManagedWidget("withLabel",
		    xmLabelGadgetClass, input_form,
		    XmNlabelString, str,
		    XmNleftAttachment, XmATTACH_FORM,
		    XmNtopAttachment, XmATTACH_WIDGET,
		    XmNtopWidget, frdp->what,
		    XmNtopOffset, 4,
		    XmNbottomAttachment, XmATTACH_FORM,
		    NULL);
	    XmStringFree(str);
	    gui_motif_menu_fontlist(label_with);

	    /*
	     * Make the entry activation only change the input focus onto the
	     * with item.
	     */
	    XtAddCallback(frdp->what, XmNactivateCallback,
		    entry_activate_callback, frdp->with);
	    XtAddEventHandler(frdp->with, KeyPressMask, False,
			    (XtEventHandler)find_replace_keypress,
			    (XtPointer) frdp);

	}
	else
	{
	    /*
	     * Make the entry activation do the search.
	     */
	    XtAddCallback(frdp->what, XmNactivateCallback,
		    find_replace_callback, (XtPointer)FRD_FINDNEXT);
	}
	XtAddEventHandler(frdp->what, KeyPressMask, False,
			    (XtEventHandler)find_replace_keypress,
			    (XtPointer)frdp);

	// Get the maximum width between the label widgets and line them up.
	n = 0;
	XtSetArg(args[n], XmNwidth, &width); n++;
	XtGetValues(label_what, args, n);
	widest = width;
	if (do_replace)
	{
	    XtGetValues(label_with, args, n);
	    if (width > widest)
		widest = width;
	}

	XtVaSetValues(frdp->what, XmNleftOffset, widest, NULL);
	if (do_replace)
	    XtVaSetValues(frdp->with, XmNleftOffset, widest, NULL);

    }

    XtManageChild(input_form);

    {
	Widget radio_box;
	Widget w;

	frame = XtVaCreateWidget("directionFrame",
		xmFrameWidgetClass, frdp->dialog,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, input_form,
		XmNtopOffset, 4,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNbottomOffset, 4,
		XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNrightWidget, input_form,
		NULL);

	str = XmStringCreateSimple(_("Direction"));
	w = XtVaCreateManagedWidget("directionFrameLabel",
		xmLabelGadgetClass, frame,
		XmNlabelString, str,
		XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING,
		XmNchildType, XmFRAME_TITLE_CHILD,
		NULL);
	XmStringFree(str);
	gui_motif_menu_fontlist(w);

	radio_box = XmCreateRadioBox(frame, "radioBox",
		(ArgList)NULL, 0);

	str = XmStringCreateSimple( _("Up"));
	frdp->up = XtVaCreateManagedWidget("upRadioButton",
		xmToggleButtonGadgetClass, radio_box,
		XmNlabelString, str,
		XmNset, False,
		NULL);
	XmStringFree(str);
	gui_motif_menu_fontlist(frdp->up);

	str = XmStringCreateSimple(_("Down"));
	frdp->down = XtVaCreateManagedWidget("downRadioButton",
		xmToggleButtonGadgetClass, radio_box,
		XmNlabelString, str,
		XmNset, True,
		NULL);
	XmStringFree(str);
	gui_motif_menu_fontlist(frdp->down);

	XtManageChild(radio_box);
	XtManageChild(frame);
    }

    toggle_form = XtVaCreateWidget("toggleForm",
	    xmFormWidgetClass,	frdp->dialog,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNrightAttachment, XmATTACH_WIDGET,
	    XmNrightWidget, frame,
	    XmNrightOffset, 4,
	    XmNtopAttachment, XmATTACH_WIDGET,
	    XmNtopWidget, input_form,
	    XmNtopOffset, 4,
	    XmNbottomAttachment, XmATTACH_FORM,
	    XmNbottomOffset, 4,
	    NULL);

    str = XmStringCreateSimple(_("Match whole word only"));
    frdp->wword = XtVaCreateManagedWidget("wordToggle",
	    xmToggleButtonGadgetClass, toggle_form,
	    XmNlabelString, str,
	    XmNtopAttachment, XmATTACH_FORM,
	    XmNtopOffset, 4,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNset, wword,
	    NULL);
    XmStringFree(str);

    str = XmStringCreateSimple(_("Match case"));
    frdp->mcase = XtVaCreateManagedWidget("caseToggle",
	    xmToggleButtonGadgetClass, toggle_form,
	    XmNlabelString, str,
	    XmNleftAttachment, XmATTACH_FORM,
	    XmNleftOffset, 4,
	    XmNtopAttachment, XmATTACH_WIDGET,
	    XmNtopWidget, frdp->wword,
	    XmNtopOffset, 4,
	    XmNset, mcase,
	    NULL);
    XmStringFree(str);
    gui_motif_menu_fontlist(frdp->wword);
    gui_motif_menu_fontlist(frdp->mcase);

    XtManageChild(toggle_form);

    if (entry_text != NULL)
	XmTextFieldSetString(frdp->what, (char *)entry_text);
    vim_free(entry_text);

    gui_motif_synch_fonts();

    manage_centered(frdp->dialog);
    activate_dialog_mnemonics(frdp->dialog);
    XmProcessTraversal(frdp->what, XmTRAVERSE_CURRENT);
}

   void
gui_mch_find_dialog(exarg_T *eap)
{
    if (!gui.in_use)
	return;

    find_replace_dialog_create(eap->arg, FALSE);
}


    void
gui_mch_replace_dialog(exarg_T *eap)
{
    if (!gui.in_use)
	return;

    find_replace_dialog_create(eap->arg, TRUE);
}

/*
 * Synchronize all gui elements, which are dependant upon the
 * main text font used. Those are in esp. the find/replace dialogs.
 * If you don't understand why this should be needed, please try to
 * search for "pi\xea\xb6\xe6" in iso8859-2.
 */
    void
gui_motif_synch_fonts(void)
{
    SharedFindReplace *frdp;
    int		    do_replace;
    XFontStruct	    *font;
    XmFontList	    font_list;

    // FIXME: Unless we find out how to create a XmFontList from a XFontSet,
    // we just give up here on font synchronization.
    font = (XFontStruct *)gui.norm_font;
    if (font == NULL)
	return;

    font_list = gui_motif_create_fontlist(font);

    // OK this loop is a bit tricky...
    for (do_replace = 0; do_replace <= 1; ++do_replace)
    {
	frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
	if (frdp->dialog)
	{
	    XtVaSetValues(frdp->what, XmNfontList, font_list, NULL);
	    if (do_replace)
		XtVaSetValues(frdp->with, XmNfontList, font_list, NULL);
	}
    }

    XmFontListFree(font_list);
}
