diff --git a/src/gui_x11.c b/src/gui_x11.c
new file mode 100644
index 0000000..7087e02
--- /dev/null
+++ b/src/gui_x11.c
@@ -0,0 +1,3748 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+/*
+ * Common code for the Motif and Athena GUI.
+ * Not used for GTK.
+ */
+
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <X11/StringDefs.h>
+#include <X11/Intrinsic.h>
+#include <X11/Shell.h>
+#include <X11/cursorfont.h>
+
+#include "vim.h"
+
+/*
+ * For Workshop XpmP.h is preferred, because it makes the signs drawn with a
+ * transparent background instead of black.
+ */
+#if defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF) \
+	&& (!defined(HAVE_X11_XPM_H) || defined(FEAT_SUN_WORKSHOP))
+# include <Xm/XpmP.h>
+#else
+# ifdef HAVE_X11_XPM_H
+#  include <X11/xpm.h>
+# endif
+#endif
+
+#ifdef FEAT_XFONTSET
+# ifdef X_LOCALE
+#  include <X11/Xlocale.h>
+# else
+#  include <locale.h>
+# endif
+#endif
+
+#ifdef HAVE_X11_SUNKEYSYM_H
+# include <X11/Sunkeysym.h>
+#endif
+
+#ifdef HAVE_X11_XMU_EDITRES_H
+# include <X11/Xmu/Editres.h>
+#endif
+
+#ifdef FEAT_BEVAL_TIP
+# include "gui_beval.h"
+#endif
+
+#define VIM_NAME	"vim"
+#define VIM_CLASS	"Vim"
+
+/* Default resource values */
+#define DFLT_FONT		"7x13"
+#ifdef FONTSET_ALWAYS
+# define DFLT_MENU_FONT		XtDefaultFontSet
+#else
+# define DFLT_MENU_FONT		XtDefaultFont
+#endif
+#define DFLT_TOOLTIP_FONT	XtDefaultFontSet
+
+#ifdef FEAT_GUI_ATHENA
+# define DFLT_MENU_BG_COLOR	"gray77"
+# define DFLT_MENU_FG_COLOR	"black"
+# define DFLT_SCROLL_BG_COLOR	"gray60"
+# define DFLT_SCROLL_FG_COLOR	"gray77"
+# define DFLT_TOOLTIP_BG_COLOR	"#ffffffff9191"
+# define DFLT_TOOLTIP_FG_COLOR	"#000000000000"
+#else
+/* use the default (CDE) colors */
+# define DFLT_MENU_BG_COLOR	""
+# define DFLT_MENU_FG_COLOR	""
+# define DFLT_SCROLL_BG_COLOR	""
+# define DFLT_SCROLL_FG_COLOR	""
+# define DFLT_TOOLTIP_BG_COLOR	"#ffffffff9191"
+# define DFLT_TOOLTIP_FG_COLOR	"#000000000000"
+#endif
+
+Widget vimShell = (Widget)0;
+
+static Atom   wm_atoms[2];	/* Window Manager Atoms */
+#define DELETE_WINDOW_IDX 0	/* index in wm_atoms[] for WM_DELETE_WINDOW */
+#define SAVE_YOURSELF_IDX 1	/* index in wm_atoms[] for WM_SAVE_YOURSELF */
+
+#ifdef FEAT_XFONTSET
+/*
+ * We either draw with a fontset (when current_fontset != NULL) or with a
+ * normal font (current_fontset == NULL, use gui.text_gc and gui.back_gc).
+ */
+static XFontSet current_fontset = NULL;
+
+#define XDrawString(dpy, win, gc, x, y, str, n) \
+	do \
+	{ \
+	    if (current_fontset != NULL) \
+		XmbDrawString(dpy, win, current_fontset, gc, x, y, str, n); \
+	    else \
+		XDrawString(dpy, win, gc, x, y, str, n); \
+	} while (0)
+
+#define XDrawString16(dpy, win, gc, x, y, str, n) \
+	do \
+	{ \
+	    if (current_fontset != NULL) \
+		XwcDrawString(dpy, win, current_fontset, gc, x, y, (wchar_t *)str, n); \
+	    else \
+		XDrawString16(dpy, win, gc, x, y, str, n); \
+	} while (0)
+
+static int check_fontset_sanity __ARGS((XFontSet fs));
+static int fontset_width __ARGS((XFontSet fs));
+static int fontset_ascent __ARGS((XFontSet fs));
+#endif
+
+static guicolor_T	prev_fg_color = INVALCOLOR;
+static guicolor_T	prev_bg_color = INVALCOLOR;
+
+#if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU)
+static XButtonPressedEvent last_mouse_event;
+#endif
+
+static int find_closest_color __ARGS((Colormap colormap, XColor *colorPtr));
+static void gui_x11_timer_cb __ARGS((XtPointer timed_out, XtIntervalId *interval_id));
+static void gui_x11_visibility_cb __ARGS((Widget w, XtPointer dud, XEvent *event, Boolean *dum));
+static void gui_x11_expose_cb __ARGS((Widget w, XtPointer dud, XEvent *event, Boolean *dum));
+static void gui_x11_resize_window_cb __ARGS((Widget w, XtPointer dud, XEvent *event, Boolean *dum));
+static void gui_x11_focus_change_cb __ARGS((Widget w, XtPointer data, XEvent *event, Boolean *dum));
+static void gui_x11_enter_cb __ARGS((Widget w, XtPointer data, XEvent *event, Boolean *dum));
+static void gui_x11_leave_cb __ARGS((Widget w, XtPointer data, XEvent *event, Boolean *dum));
+static void gui_x11_mouse_cb __ARGS((Widget w, XtPointer data, XEvent *event, Boolean *dum));
+#ifdef FEAT_SNIFF
+static void gui_x11_sniff_request_cb __ARGS((XtPointer closure, int *source, XtInputId *id));
+#endif
+static void gui_x11_check_copy_area __ARGS((void));
+#ifdef FEAT_CLIENTSERVER
+static void gui_x11_send_event_handler __ARGS((Widget, XtPointer, XEvent *, Boolean *));
+#endif
+static void gui_x11_wm_protocol_handler __ARGS((Widget, XtPointer, XEvent *, Boolean *));
+static void gui_x11_blink_cb __ARGS((XtPointer timed_out, XtIntervalId *interval_id));
+static Cursor gui_x11_create_blank_mouse __ARGS((void));
+
+
+/*
+ * Keycodes recognized by vim.
+ * NOTE: when changing this, the table in gui_gtk_x11.c probably needs the
+ * same change!
+ */
+static struct specialkey
+{
+    KeySym  key_sym;
+    char_u  vim_code0;
+    char_u  vim_code1;
+} special_keys[] =
+{
+    {XK_Up,		'k', 'u'},
+    {XK_Down,		'k', 'd'},
+    {XK_Left,		'k', 'l'},
+    {XK_Right,		'k', 'r'},
+
+    {XK_F1,		'k', '1'},
+    {XK_F2,		'k', '2'},
+    {XK_F3,		'k', '3'},
+    {XK_F4,		'k', '4'},
+    {XK_F5,		'k', '5'},
+    {XK_F6,		'k', '6'},
+    {XK_F7,		'k', '7'},
+    {XK_F8,		'k', '8'},
+    {XK_F9,		'k', '9'},
+    {XK_F10,		'k', ';'},
+
+    {XK_F11,		'F', '1'},
+    {XK_F12,		'F', '2'},
+    {XK_F13,		'F', '3'},
+    {XK_F14,		'F', '4'},
+    {XK_F15,		'F', '5'},
+    {XK_F16,		'F', '6'},
+    {XK_F17,		'F', '7'},
+    {XK_F18,		'F', '8'},
+    {XK_F19,		'F', '9'},
+    {XK_F20,		'F', 'A'},
+
+    {XK_F21,		'F', 'B'},
+    {XK_F22,		'F', 'C'},
+    {XK_F23,		'F', 'D'},
+    {XK_F24,		'F', 'E'},
+    {XK_F25,		'F', 'F'},
+    {XK_F26,		'F', 'G'},
+    {XK_F27,		'F', 'H'},
+    {XK_F28,		'F', 'I'},
+    {XK_F29,		'F', 'J'},
+    {XK_F30,		'F', 'K'},
+
+    {XK_F31,		'F', 'L'},
+    {XK_F32,		'F', 'M'},
+    {XK_F33,		'F', 'N'},
+    {XK_F34,		'F', 'O'},
+    {XK_F35,		'F', 'P'},	/* keysymdef.h defines up to F35 */
+#ifdef SunXK_F36
+    {SunXK_F36,		'F', 'Q'},
+    {SunXK_F37,		'F', 'R'},
+#endif
+
+    {XK_Help,		'%', '1'},
+    {XK_Undo,		'&', '8'},
+    {XK_BackSpace,	'k', 'b'},
+    {XK_Insert,		'k', 'I'},
+    {XK_Delete,		'k', 'D'},
+    {XK_Home,		'k', 'h'},
+    {XK_End,		'@', '7'},
+    {XK_Prior,		'k', 'P'},
+    {XK_Next,		'k', 'N'},
+    {XK_Print,		'%', '9'},
+
+    /* Keypad keys: */
+#ifdef XK_KP_Left
+    {XK_KP_Left,	'k', 'l'},
+    {XK_KP_Right,	'k', 'r'},
+    {XK_KP_Up,		'k', 'u'},
+    {XK_KP_Down,	'k', 'd'},
+    {XK_KP_Insert,	KS_EXTRA, (char_u)KE_KINS},
+    {XK_KP_Delete,	KS_EXTRA, (char_u)KE_KDEL},
+    {XK_KP_Home,	'K', '1'},
+    {XK_KP_End,		'K', '4'},
+    {XK_KP_Prior,	'K', '3'},
+    {XK_KP_Next,	'K', '5'},
+
+    {XK_KP_Add,		'K', '6'},
+    {XK_KP_Subtract,	'K', '7'},
+    {XK_KP_Divide,	'K', '8'},
+    {XK_KP_Multiply,	'K', '9'},
+    {XK_KP_Enter,	'K', 'A'},
+    {XK_KP_Decimal,	'K', 'B'},
+
+    {XK_KP_0,		'K', 'C'},
+    {XK_KP_1,		'K', 'D'},
+    {XK_KP_2,		'K', 'E'},
+    {XK_KP_3,		'K', 'F'},
+    {XK_KP_4,		'K', 'G'},
+    {XK_KP_5,		'K', 'H'},
+    {XK_KP_6,		'K', 'I'},
+    {XK_KP_7,		'K', 'J'},
+    {XK_KP_8,		'K', 'K'},
+    {XK_KP_9,		'K', 'L'},
+#endif
+
+    /* End of list marker: */
+    {(KeySym)0,	    0, 0}
+};
+
+#define XtNboldFont		"boldFont"
+#define XtCBoldFont		"BoldFont"
+#define XtNitalicFont		"italicFont"
+#define XtCItalicFont		"ItalicFont"
+#define XtNboldItalicFont	"boldItalicFont"
+#define XtCBoldItalicFont	"BoldItalicFont"
+#define XtNscrollbarWidth	"scrollbarWidth"
+#define XtCScrollbarWidth	"ScrollbarWidth"
+#define XtNmenuHeight		"menuHeight"
+#define XtCMenuHeight		"MenuHeight"
+#define XtNmenuFont		"menuFont"
+#define XtCMenuFont		"MenuFont"
+#define XtNmenuFontSet		"menuFontSet"
+#define XtCMenuFontSet		"MenuFontSet"
+
+
+/* Resources for setting the foreground and background colors of menus */
+#define XtNmenuBackground	"menuBackground"
+#define XtCMenuBackground	"MenuBackground"
+#define XtNmenuForeground	"menuForeground"
+#define XtCMenuForeground	"MenuForeground"
+
+/* Resources for setting the foreground and background colors of scrollbars */
+#define XtNscrollBackground	"scrollBackground"
+#define XtCScrollBackground	"ScrollBackground"
+#define XtNscrollForeground	"scrollForeground"
+#define XtCScrollForeground	"ScrollForeground"
+
+/* Resources for setting the foreground and background colors of tooltip */
+#define XtNtooltipBackground	"tooltipBackground"
+#define XtCTooltipBackground	"TooltipBackground"
+#define XtNtooltipForeground	"tooltipForeground"
+#define XtCTooltipForeground	"TooltipForeground"
+#define XtNtooltipFont		"tooltipFont"
+#define XtCTooltipFont		"TooltipFont"
+
+/*
+ * X Resources:
+ */
+static XtResource vim_resources[] =
+{
+    {
+	XtNforeground,
+	XtCForeground,
+	XtRPixel,
+	sizeof(Pixel),
+	XtOffsetOf(gui_T, def_norm_pixel),
+	XtRString,
+	XtDefaultForeground
+    },
+    {
+	XtNbackground,
+	XtCBackground,
+	XtRPixel,
+	sizeof(Pixel),
+	XtOffsetOf(gui_T, def_back_pixel),
+	XtRString,
+	XtDefaultBackground
+    },
+    {
+	XtNfont,
+	XtCFont,
+	XtRString,
+	sizeof(String *),
+	XtOffsetOf(gui_T, rsrc_font_name),
+	XtRImmediate,
+	XtDefaultFont
+    },
+    {
+	XtNboldFont,
+	XtCBoldFont,
+	XtRString,
+	sizeof(String *),
+	XtOffsetOf(gui_T, rsrc_bold_font_name),
+	XtRImmediate,
+	""
+    },
+    {
+	XtNitalicFont,
+	XtCItalicFont,
+	XtRString,
+	sizeof(String *),
+	XtOffsetOf(gui_T, rsrc_ital_font_name),
+	XtRImmediate,
+	""
+    },
+    {
+	XtNboldItalicFont,
+	XtCBoldItalicFont,
+	XtRString,
+	sizeof(String *),
+	XtOffsetOf(gui_T, rsrc_boldital_font_name),
+	XtRImmediate,
+	""
+    },
+    {
+	XtNgeometry,
+	XtCGeometry,
+	XtRString,
+	sizeof(String *),
+	XtOffsetOf(gui_T, geom),
+	XtRImmediate,
+	""
+    },
+    {
+	XtNreverseVideo,
+	XtCReverseVideo,
+	XtRBool,
+	sizeof(Bool),
+	XtOffsetOf(gui_T, rsrc_rev_video),
+	XtRImmediate,
+	(XtPointer)False
+    },
+    {
+	XtNborderWidth,
+	XtCBorderWidth,
+	XtRInt,
+	sizeof(int),
+	XtOffsetOf(gui_T, border_width),
+	XtRImmediate,
+	(XtPointer)2
+    },
+    {
+	XtNscrollbarWidth,
+	XtCScrollbarWidth,
+	XtRInt,
+	sizeof(int),
+	XtOffsetOf(gui_T, scrollbar_width),
+	XtRImmediate,
+	(XtPointer)SB_DEFAULT_WIDTH
+    },
+#ifdef FEAT_MENU
+# ifdef FEAT_GUI_ATHENA		/* with Motif the height is always computed */
+    {
+	XtNmenuHeight,
+	XtCMenuHeight,
+	XtRInt,
+	sizeof(int),
+	XtOffsetOf(gui_T, menu_height),
+	XtRImmediate,
+	(XtPointer)MENU_DEFAULT_HEIGHT	    /* Should figure out at run time */
+    },
+# endif
+    {
+# ifdef FONTSET_ALWAYS
+	XtNmenuFontSet,
+	XtCMenuFontSet,
+#else
+	XtNmenuFont,
+	XtCMenuFont,
+#endif
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_menu_font_name),
+	XtRString,
+	DFLT_MENU_FONT
+    },
+#endif
+    {
+	XtNmenuForeground,
+	XtCMenuForeground,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_menu_fg_name),
+	XtRString,
+	DFLT_MENU_FG_COLOR
+    },
+    {
+	XtNmenuBackground,
+	XtCMenuBackground,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_menu_bg_name),
+	XtRString,
+	DFLT_MENU_BG_COLOR
+    },
+    {
+	XtNscrollForeground,
+	XtCScrollForeground,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_scroll_fg_name),
+	XtRString,
+	DFLT_SCROLL_FG_COLOR
+    },
+    {
+	XtNscrollBackground,
+	XtCScrollBackground,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_scroll_bg_name),
+	XtRString,
+	DFLT_SCROLL_BG_COLOR
+    },
+#ifdef FEAT_BEVAL
+    {
+	XtNtooltipForeground,
+	XtCTooltipForeground,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_tooltip_fg_name),
+	XtRString,
+	DFLT_TOOLTIP_FG_COLOR
+    },
+    {
+	XtNtooltipBackground,
+	XtCTooltipBackground,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_tooltip_bg_name),
+	XtRString,
+	DFLT_TOOLTIP_BG_COLOR
+    },
+    {
+	XtNtooltipFont,
+	XtCTooltipFont,
+	XtRString,
+	sizeof(char *),
+	XtOffsetOf(gui_T, rsrc_tooltip_font_name),
+	XtRString,
+	DFLT_TOOLTIP_FONT
+    },
+    /* This one isn't really needed, keep for Sun Workshop? */
+    {
+	"balloonEvalFontSet",
+	XtCFontSet,
+	XtRFontSet,
+	sizeof(XFontSet),
+	XtOffsetOf(gui_T, tooltip_fontset),
+	XtRImmediate,
+	(XtPointer)NOFONTSET
+    },
+#endif /* FEAT_BEVAL */
+#ifdef FEAT_XIM
+    {
+	"preeditType",
+	"PreeditType",
+	XtRString,
+	sizeof(char*),
+	XtOffsetOf(gui_T, rsrc_preedit_type_name),
+	XtRString,
+	(XtPointer)"OverTheSpot,OffTheSpot,Root"
+    },
+    {
+	"inputMethod",
+	"InputMethod",
+	XtRString,
+	sizeof(char*),
+	XtOffsetOf(gui_T, rsrc_input_method),
+	XtRString,
+	NULL
+    },
+#endif /* FEAT_XIM */
+};
+
+/*
+ * This table holds all the X GUI command line options allowed.  This includes
+ * the standard ones so that we can skip them when vim is started without the
+ * GUI (but the GUI might start up later).
+ * When changing this, also update doc/vim_gui.txt and the usage message!!!
+ */
+static XrmOptionDescRec cmdline_options[] =
+{
+    /* We handle these options ourselves */
+    {"-bg",		".background",	    XrmoptionSepArg,	NULL},
+    {"-background",	".background",	    XrmoptionSepArg,	NULL},
+    {"-fg",		".foreground",	    XrmoptionSepArg,	NULL},
+    {"-foreground",	".foreground",	    XrmoptionSepArg,	NULL},
+    {"-fn",		".font",	    XrmoptionSepArg,	NULL},
+    {"-font",		".font",	    XrmoptionSepArg,	NULL},
+    {"-boldfont",	".boldFont",	    XrmoptionSepArg,	NULL},
+    {"-italicfont",	".italicFont",	    XrmoptionSepArg,	NULL},
+    {"-geom",		".geometry",	    XrmoptionSepArg,	NULL},
+    {"-geometry",	".geometry",	    XrmoptionSepArg,	NULL},
+    {"-reverse",	"*reverseVideo",    XrmoptionNoArg,	"True"},
+    {"-rv",		"*reverseVideo",    XrmoptionNoArg,	"True"},
+    {"+reverse",	"*reverseVideo",    XrmoptionNoArg,	"False"},
+    {"+rv",		"*reverseVideo",    XrmoptionNoArg,	"False"},
+    {"-display",	".display",	    XrmoptionSepArg,	NULL},
+    {"-iconic",		"*iconic",	    XrmoptionNoArg,	"True"},
+    {"-name",		".name",	    XrmoptionSepArg,	NULL},
+    {"-bw",		".borderWidth",	    XrmoptionSepArg,	NULL},
+    {"-borderwidth",	".borderWidth",	    XrmoptionSepArg,	NULL},
+    {"-sw",		".scrollbarWidth",  XrmoptionSepArg,	NULL},
+    {"-scrollbarwidth",	".scrollbarWidth",  XrmoptionSepArg,	NULL},
+    {"-mh",		".menuHeight",	    XrmoptionSepArg,	NULL},
+    {"-menuheight",	".menuHeight",	    XrmoptionSepArg,	NULL},
+#ifdef FONTSET_ALWAYS
+    {"-mf",		".menuFontSet",	    XrmoptionSepArg,	NULL},
+    {"-menufont",	".menuFontSet",	    XrmoptionSepArg,	NULL},
+    {"-menufontset",	".menuFontSet",	    XrmoptionSepArg,	NULL},
+#else
+    {"-mf",		".menuFont",	    XrmoptionSepArg,	NULL},
+    {"-menufont",	".menuFont",	    XrmoptionSepArg,	NULL},
+#endif
+    {"-xrm",		NULL,		    XrmoptionResArg,	NULL}
+};
+
+static int gui_argc = 0;
+static char **gui_argv = NULL;
+
+/*
+ * Call-back routines.
+ */
+
+/* ARGSUSED */
+    static void
+gui_x11_timer_cb(timed_out, interval_id)
+    XtPointer	    timed_out;
+    XtIntervalId    *interval_id;
+{
+    *((int *)timed_out) = TRUE;
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_visibility_cb(w, dud, event, dum)
+    Widget	w;
+    XtPointer	dud;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    if (event->type != VisibilityNotify)
+	return;
+
+    gui.visibility = event->xvisibility.state;
+
+    /*
+     * When we do an XCopyArea(), and the window is partially obscured, we want
+     * to receive an event to tell us whether it worked or not.
+     */
+    XSetGraphicsExposures(gui.dpy, gui.text_gc,
+	    gui.visibility != VisibilityUnobscured);
+
+    /* This is needed for when redrawing is slow. */
+    gui_mch_update();
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_expose_cb(w, dud, event, dum)
+    Widget	w;
+    XtPointer	dud;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    XExposeEvent	*gevent;
+    int			new_x;
+
+    if (event->type != Expose)
+	return;
+
+    out_flush();	    /* make sure all output has been processed */
+
+    gevent = (XExposeEvent *)event;
+    gui_redraw(gevent->x, gevent->y, gevent->width, gevent->height);
+
+    new_x = FILL_X(0);
+
+    /* Clear the border areas if needed */
+    if (gevent->x < new_x)
+	XClearArea(gui.dpy, gui.wid, 0, 0, new_x, 0, False);
+    if (gevent->y < FILL_Y(0))
+	XClearArea(gui.dpy, gui.wid, 0, 0, 0, FILL_Y(0), False);
+    if (gevent->x > FILL_X(Columns))
+	XClearArea(gui.dpy, gui.wid, FILL_X((int)Columns), 0, 0, 0, False);
+    if (gevent->y > FILL_Y(Rows))
+	XClearArea(gui.dpy, gui.wid, 0, FILL_Y((int)Rows), 0, 0, False);
+
+    /* This is needed for when redrawing is slow. */
+    gui_mch_update();
+}
+
+#if (defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP)) \
+	|| defined(PROTO)
+/*
+ *	This function fills in the XRectangle object with the current
+ *	x,y coordinates and height, width so that an XtVaSetValues to
+ *	the same shell of those resources will restore the window to its
+ *	formar position and dimensions.
+ *
+ *	Note: This function may fail, in which case the XRectangle will
+ *	be unchanged.  Be sure to have the XRectangle set with the
+ *	proper values for a failed condition prior to calling this
+ *	function.
+ */
+    static void
+shellRectangle(Widget shell, XRectangle *r)
+{
+    Window		rootw, shellw, child, parentw;
+    int			absx, absy;
+    XWindowAttributes	a;
+    Window		*children;
+    unsigned int	childrenCount;
+
+    shellw = XtWindow(shell);
+    if (shellw == 0)
+	return;
+    for (;;)
+    {
+	XQueryTree(XtDisplay(shell), shellw, &rootw, &parentw,
+						   &children, &childrenCount);
+	XFree(children);
+	if (parentw == rootw)
+	    break;
+	shellw = parentw;
+    }
+    XGetWindowAttributes(XtDisplay(shell), shellw, &a);
+    XTranslateCoordinates(XtDisplay(shell), shellw, a.root, 0, 0,
+							&absx, &absy, &child);
+    r->x = absx;
+    r->y = absy;
+    XtVaGetValues(shell, XmNheight, &r->height, XmNwidth, &r->width, NULL);
+}
+#endif
+
+/* ARGSUSED */
+    static void
+gui_x11_resize_window_cb(w, dud, event, dum)
+    Widget	w;
+    XtPointer	dud;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    static int lastWidth, lastHeight;
+
+    if (event->type != ConfigureNotify)
+	return;
+
+    if (event->xconfigure.width != lastWidth
+	    || event->xconfigure.height != lastHeight)
+    {
+	lastWidth = event->xconfigure.width;
+	lastHeight = event->xconfigure.height;
+	gui_resize_shell(event->xconfigure.width, event->xconfigure.height
+#ifdef FEAT_XIM
+						- xim_get_status_area_height()
+#endif
+		     );
+    }
+#ifdef FEAT_SUN_WORKSHOP
+    if (usingSunWorkShop)
+    {
+	XRectangle  rec;
+
+	shellRectangle(w, &rec);
+	workshop_frame_moved(rec.x, rec.y, rec.width, rec.height);
+    }
+#endif
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+    {
+	XRectangle  rec;
+
+	shellRectangle(w, &rec);
+	netbeans_frame_moved(rec.x, rec.y);
+    }
+#endif
+#ifdef FEAT_XIM
+    xim_set_preedit();
+#endif
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_focus_change_cb(w, data, event, dum)
+    Widget	w;
+    XtPointer	data;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    gui_focus_change(event->type == FocusIn);
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_enter_cb(w, data, event, dum)
+    Widget	w;
+    XtPointer	data;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    gui_focus_change(TRUE);
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_leave_cb(w, data, event, dum)
+    Widget	w;
+    XtPointer	data;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    gui_focus_change(FALSE);
+}
+
+#if defined(X_HAVE_UTF8_STRING) && defined(FEAT_MBYTE)
+# if X_HAVE_UTF8_STRING
+#  define USE_UTF8LOOKUP
+# endif
+#endif
+
+/* ARGSUSED */
+    void
+gui_x11_key_hit_cb(w, dud, event, dum)
+    Widget	w;
+    XtPointer	dud;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    XKeyPressedEvent	*ev_press;
+#ifdef FEAT_XIM
+    char_u		string2[256];
+    char_u		string_shortbuf[256];
+    char_u		*string = string_shortbuf;
+    Boolean		string_alloced = False;
+    Status		status;
+#else
+    char_u		string[4], string2[3];
+#endif
+    KeySym		key_sym, key_sym2;
+    int			len, len2;
+    int			i;
+    int			modifiers;
+    int			key;
+
+    ev_press = (XKeyPressedEvent *)event;
+
+#ifdef FEAT_XIM
+    if (xic)
+    {
+# ifdef USE_UTF8LOOKUP
+	/* XFree86 4.0.2 or newer: Be able to get UTF-8 characters even when
+	 * the locale isn't utf-8. */
+	if (enc_utf8)
+	    len = Xutf8LookupString(xic, ev_press, (char *)string,
+				  sizeof(string_shortbuf), &key_sym, &status);
+	else
+# endif
+	    len = XmbLookupString(xic, ev_press, (char *)string,
+				  sizeof(string_shortbuf), &key_sym, &status);
+	if (status == XBufferOverflow)
+	{
+	    string = (char_u *)XtMalloc(len + 1);
+	    string_alloced = True;
+# ifdef USE_UTF8LOOKUP
+	    /* XFree86 4.0.2 or newer: Be able to get UTF-8 characters even
+	     * when the locale isn't utf-8.  */
+	    if (enc_utf8)
+		len = Xutf8LookupString(xic, ev_press, (char *)string,
+						      len, &key_sym, &status);
+	    else
+# endif
+		len = XmbLookupString(xic, ev_press, (char *)string,
+						      len, &key_sym, &status);
+	}
+	if (status == XLookupNone || status == XLookupChars)
+	    key_sym = XK_VoidSymbol;
+
+# ifdef FEAT_MBYTE
+	/* Do conversion from 'termencoding' to 'encoding'.  When using
+	 * Xutf8LookupString() it has already been done. */
+	if (len > 0 && input_conv.vc_type != CONV_NONE
+#  ifdef USE_UTF8LOOKUP
+		&& !enc_utf8
+#  endif
+		)
+	{
+	    int		maxlen = len * 4 + 40;  /* guessed */
+	    char_u	*p = (char_u *)XtMalloc(maxlen);
+
+	    mch_memmove(p, string, len);
+	    if (string_alloced)
+		XtFree((char *)string);
+	    string = p;
+	    string_alloced = True;
+	    len = convert_input(p, len, maxlen);
+	}
+# endif
+
+	/* Translate CSI to K_CSI, otherwise it could be recognized as the
+	 * start of a special key. */
+	for (i = 0; i < len; ++i)
+	    if (string[i] == CSI)
+	    {
+		char_u	*p = (char_u *)XtMalloc(len + 3);
+
+		mch_memmove(p, string, i + 1);
+		p[i + 1] = KS_EXTRA;
+		p[i + 2] = (int)KE_CSI;
+		mch_memmove(p + i + 3, string + i + 1, len - i);
+		if (string_alloced)
+		    XtFree((char *)string);
+		string = p;
+		string_alloced = True;
+		i += 2;
+		len += 2;
+	    }
+    }
+    else
+#endif
+	len = XLookupString(ev_press, (char *)string, sizeof(string),
+		&key_sym, NULL);
+
+#ifdef SunXK_F36
+    /*
+    * These keys have bogus lookup strings, and trapping them here is
+    * easier than trying to XRebindKeysym() on them with every possible
+    * combination of modifiers.
+    */
+    if (key_sym == SunXK_F36 || key_sym == SunXK_F37)
+	len = 0;
+#endif
+
+#ifdef FEAT_HANGULIN
+    if ((key_sym == XK_space) && (ev_press->state & ShiftMask))
+    {
+	hangul_input_state_toggle();
+	goto theend;
+    }
+#endif
+
+    if (key_sym == XK_space)
+	string[0] = ' ';	/* Otherwise Ctrl-Space doesn't work */
+
+    /*
+     * Only on some machines ^_ requires Ctrl+Shift+minus.  For consistency,
+     * allow just Ctrl+minus too.
+     */
+    if (key_sym == XK_minus && (ev_press->state & ControlMask))
+	string[0] = Ctrl__;
+
+#ifdef XK_ISO_Left_Tab
+    /* why do we get XK_ISO_Left_Tab instead of XK_Tab for shift-tab? */
+    if (key_sym == XK_ISO_Left_Tab)
+    {
+	key_sym = XK_Tab;
+	string[0] = TAB;
+	len = 1;
+    }
+#endif
+
+    /* Check for Alt/Meta key (Mod1Mask), but not for a BS, DEL or character
+     * that already has the 8th bit set.  And not when using a double-byte
+     * encoding, setting the 8th bit may make it the lead byte of a
+     * double-byte character. */
+    if (len == 1
+	    && (ev_press->state & Mod1Mask)
+	    && !(key_sym == XK_BackSpace || key_sym == XK_Delete)
+	    && (string[0] & 0x80) == 0
+#ifdef FEAT_MBYTE
+	    && !enc_dbcs
+#endif
+	    )
+    {
+#if defined(FEAT_MENU) && defined(FEAT_GUI_MOTIF)
+	/* Ignore ALT keys when they are used for the menu only */
+	if (gui.menu_is_active
+		&& (p_wak[0] == 'y'
+		    || (p_wak[0] == 'm' && gui_is_menu_shortcut(string[0]))))
+	    goto theend;
+#endif
+	/*
+	 * Before we set the 8th bit, check to make sure the user doesn't
+	 * already have a mapping defined for this sequence. We determine this
+	 * by checking to see if the input would be the same without the
+	 * Alt/Meta key.
+	 * Don't do this for <S-M-Tab>, that should become K_S_TAB with ALT.
+	 */
+	ev_press->state &= ~Mod1Mask;
+	len2 = XLookupString(ev_press, (char *)string2, sizeof(string2),
+							     &key_sym2, NULL);
+	if (key_sym2 == XK_space)
+	    string2[0] = ' ';	    /* Otherwise Meta-Ctrl-Space doesn't work */
+	if (	   len2 == 1
+		&& string[0] == string2[0]
+		&& !(key_sym == XK_Tab && (ev_press->state & ShiftMask)))
+	{
+	    string[0] |= 0x80;
+#ifdef FEAT_MBYTE
+	    if (enc_utf8) /* convert to utf-8 */
+	    {
+		string[1] = string[0] & 0xbf;
+		string[0] = ((unsigned)string[0] >> 6) + 0xc0;
+		if (string[1] == CSI)
+		{
+		    string[2] = KS_EXTRA;
+		    string[3] = (int)KE_CSI;
+		    len = 4;
+		}
+		else
+		    len = 2;
+	    }
+#endif
+	}
+	else
+	    ev_press->state |= Mod1Mask;
+    }
+
+    if (len == 1 && string[0] == CSI)
+    {
+	string[1] = KS_EXTRA;
+	string[2] = (int)KE_CSI;
+	len = -3;
+    }
+
+    /* Check for special keys.  Also do this when len == 1 (key has an ASCII
+     * value) to detect backspace, delete and keypad keys. */
+    if (len == 0 || len == 1)
+    {
+	for (i = 0; special_keys[i].key_sym != (KeySym)0; i++)
+	{
+	    if (special_keys[i].key_sym == key_sym)
+	    {
+		string[0] = CSI;
+		string[1] = special_keys[i].vim_code0;
+		string[2] = special_keys[i].vim_code1;
+		len = -3;
+		break;
+	    }
+	}
+    }
+
+    /* Unrecognised key is ignored. */
+    if (len == 0)
+	goto theend;
+
+    /* Special keys (and a few others) may have modifiers.  Also when using a
+     * double-byte encoding (can't set the 8th bit). */
+    if (len == -3 || key_sym == XK_space || key_sym == XK_Tab
+	    || key_sym == XK_Return || key_sym == XK_Linefeed
+	    || key_sym == XK_Escape
+#ifdef FEAT_MBYTE
+	    || (enc_dbcs && len == 1 && (ev_press->state & Mod1Mask))
+#endif
+       )
+    {
+	modifiers = 0;
+	if (ev_press->state & ShiftMask)
+	    modifiers |= MOD_MASK_SHIFT;
+	if (ev_press->state & ControlMask)
+	    modifiers |= MOD_MASK_CTRL;
+	if (ev_press->state & Mod1Mask)
+	    modifiers |= MOD_MASK_ALT;
+
+	/*
+	 * For some keys a shift modifier is translated into another key
+	 * code.
+	 */
+	if (len == -3)
+	    key = TO_SPECIAL(string[1], string[2]);
+	else
+	    key = string[0];
+	key = simplify_key(key, &modifiers);
+	if (key == CSI)
+	    key = K_CSI;
+	if (IS_SPECIAL(key))
+	{
+	    string[0] = CSI;
+	    string[1] = K_SECOND(key);
+	    string[2] = K_THIRD(key);
+	    len = 3;
+	}
+	else
+	{
+	    string[0] = key;
+	    len = 1;
+	}
+
+	if (modifiers != 0)
+	{
+	    string2[0] = CSI;
+	    string2[1] = KS_MODIFIER;
+	    string2[2] = modifiers;
+	    add_to_input_buf(string2, 3);
+	}
+    }
+
+    if (len == 1 && ((string[0] == Ctrl_C && ctrl_c_interrupts)
+#ifdef UNIX
+	    || (intr_char != 0 && string[0] == intr_char)
+#endif
+	    ))
+    {
+	trash_input_buf();
+	got_int = TRUE;
+    }
+
+    add_to_input_buf(string, len);
+
+    /*
+     * blank out the pointer if necessary
+     */
+    if (p_mh)
+	gui_mch_mousehide(TRUE);
+
+#if defined(FEAT_BEVAL_TIP)
+    {
+	BalloonEval *be;
+
+	if ((be = gui_mch_currently_showing_beval()) != NULL)
+	    gui_mch_unpost_balloon(be);
+    }
+#endif
+theend:
+    {}	    /* some compilers need a statement here */
+#ifdef FEAT_XIM
+    if (string_alloced)
+	XtFree((char *)string);
+#endif
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_mouse_cb(w, dud, event, dum)
+    Widget	w;
+    XtPointer	dud;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    static XtIntervalId timer = (XtIntervalId)0;
+    static int	timed_out = TRUE;
+
+    int		button;
+    int		repeated_click = FALSE;
+    int		x, y;
+    int_u	x_modifiers;
+    int_u	vim_modifiers;
+
+    if (event->type == MotionNotify)
+    {
+	/* Get the latest position, avoids lagging behind on a drag. */
+	x = event->xmotion.x;
+	y = event->xmotion.y;
+	x_modifiers = event->xmotion.state;
+	button = (x_modifiers & (Button1Mask | Button2Mask | Button3Mask))
+		? MOUSE_DRAG : ' ';
+
+	/*
+	 * if our pointer is currently hidden, then we should show it.
+	 */
+	gui_mch_mousehide(FALSE);
+
+	if (button != MOUSE_DRAG)	/* just moving the rodent */
+	{
+#ifdef FEAT_MENU
+	    if (dud)			/* moved in vimForm */
+		y -= gui.menu_height;
+#endif
+	    gui_mouse_moved(x, y);
+	    return;
+	}
+    }
+    else
+    {
+	x = event->xbutton.x;
+	y = event->xbutton.y;
+	if (event->type == ButtonPress)
+	{
+	    /* Handle multiple clicks */
+	    if (!timed_out)
+	    {
+		XtRemoveTimeOut(timer);
+		repeated_click = TRUE;
+	    }
+	    timed_out = FALSE;
+	    timer = XtAppAddTimeOut(app_context, (long_u)p_mouset,
+			gui_x11_timer_cb, &timed_out);
+	    switch (event->xbutton.button)
+	    {
+		case Button1:	button = MOUSE_LEFT;	break;
+		case Button2:	button = MOUSE_MIDDLE;	break;
+		case Button3:	button = MOUSE_RIGHT;	break;
+		case Button4:	button = MOUSE_4;	break;
+		case Button5:	button = MOUSE_5;	break;
+		default:
+		    return;	/* Unknown button */
+	    }
+	}
+	else if (event->type == ButtonRelease)
+	    button = MOUSE_RELEASE;
+	else
+	    return;	/* Unknown mouse event type */
+
+	x_modifiers = event->xbutton.state;
+#if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU)
+	last_mouse_event = event->xbutton;
+#endif
+    }
+
+    vim_modifiers = 0x0;
+    if (x_modifiers & ShiftMask)
+	vim_modifiers |= MOUSE_SHIFT;
+    if (x_modifiers & ControlMask)
+	vim_modifiers |= MOUSE_CTRL;
+    if (x_modifiers & Mod1Mask)	    /* Alt or Meta key */
+	vim_modifiers |= MOUSE_ALT;
+
+    gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers);
+}
+
+#ifdef FEAT_SNIFF
+/* ARGSUSED */
+    static void
+gui_x11_sniff_request_cb(closure, source, id)
+    XtPointer	closure;
+    int		*source;
+    XtInputId	*id;
+{
+    static char_u bytes[3] = {CSI, (int)KS_EXTRA, (int)KE_SNIFF};
+
+    add_to_input_buf(bytes, 3);
+}
+#endif
+
+/*
+ * End of call-back routines
+ */
+
+/*
+ * Parse the GUI related command-line arguments.  Any arguments used are
+ * deleted from argv, and *argc is decremented accordingly.  This is called
+ * when vim is started, whether or not the GUI has been started.
+ */
+    void
+gui_mch_prepare(argc, argv)
+    int	    *argc;
+    char    **argv;
+{
+    int	    arg;
+    int	    i;
+
+    /*
+     * Move all the entries in argv which are relevant to X into gui_argv.
+     */
+    gui_argc = 0;
+    gui_argv = (char **)lalloc((long_u)(*argc * sizeof(char *)), FALSE);
+    if (gui_argv == NULL)
+	return;
+    gui_argv[gui_argc++] = argv[0];
+    arg = 1;
+    while (arg < *argc)
+    {
+	/* Look for argv[arg] in cmdline_options[] table */
+	for (i = 0; i < XtNumber(cmdline_options); i++)
+	    if (strcmp(argv[arg], cmdline_options[i].option) == 0)
+		break;
+
+	if (i < XtNumber(cmdline_options))
+	{
+	    /* Remember finding "-rv" or "-reverse" */
+	    if (strcmp("-rv", argv[arg]) == 0
+		    || strcmp("-reverse", argv[arg]) == 0)
+		found_reverse_arg = TRUE;
+	    else if ((strcmp("-fn", argv[arg]) == 0
+			|| strcmp("-font", argv[arg]) == 0)
+		    && arg + 1 < *argc)
+		font_argument = argv[arg + 1];
+
+	    /* Found match in table, so move it into gui_argv */
+	    gui_argv[gui_argc++] = argv[arg];
+	    if (--*argc > arg)
+	    {
+		mch_memmove(&argv[arg], &argv[arg + 1], (*argc - arg)
+						    * sizeof(char *));
+		if (cmdline_options[i].argKind != XrmoptionNoArg)
+		{
+		    /* Move the options argument as well */
+		    gui_argv[gui_argc++] = argv[arg];
+		    if (--*argc > arg)
+			mch_memmove(&argv[arg], &argv[arg + 1], (*argc - arg)
+							    * sizeof(char *));
+		}
+	    }
+	    argv[*argc] = NULL;
+	}
+	else
+#ifdef FEAT_SUN_WORKSHOP
+	    if (strcmp("-ws", argv[arg]) == 0)
+	{
+	    usingSunWorkShop++;
+	    p_acd = TRUE;
+	    gui.dofork = FALSE;	/* don't fork() when starting GUI */
+	    mch_memmove(&argv[arg], &argv[arg + 1],
+					    (--*argc - arg) * sizeof(char *));
+	    argv[*argc] = NULL;
+# ifdef WSDEBUG
+	    wsdebug_wait(WT_ENV | WT_WAIT | WT_STOP, "SPRO_GVIM_WAIT", 20);
+	    wsdebug_log_init("SPRO_GVIM_DEBUG", "SPRO_GVIM_DLEVEL");
+# endif
+	}
+	else
+#endif
+#ifdef FEAT_NETBEANS_INTG
+	    if (strncmp("-nb", argv[arg], 3) == 0)
+	{
+	    usingNetbeans++;
+	    gui.dofork = FALSE;	/* don't fork() when starting GUI */
+	    netbeansArg = argv[arg];
+	    mch_memmove(&argv[arg], &argv[arg + 1],
+					    (--*argc - arg) * sizeof(char *));
+	    argv[*argc] = NULL;
+	}
+	else
+#endif
+	    arg++;
+    }
+}
+
+#ifndef XtSpecificationRelease
+# define CARDINAL (Cardinal *)
+#else
+# if XtSpecificationRelease == 4
+# define CARDINAL (Cardinal *)
+# else
+# define CARDINAL (int *)
+# endif
+#endif
+
+/*
+ * Check if the GUI can be started.  Called before gvimrc is sourced.
+ * Return OK or FAIL.
+ */
+    int
+gui_mch_init_check()
+{
+#ifdef FEAT_XIM
+    XtSetLanguageProc(NULL, NULL, NULL);
+#endif
+    open_app_context();
+    if (app_context != NULL)
+	gui.dpy = XtOpenDisplay(app_context, 0, VIM_NAME, VIM_CLASS,
+	    cmdline_options, XtNumber(cmdline_options),
+	    CARDINAL &gui_argc, gui_argv);
+
+    if (app_context == NULL || gui.dpy == NULL)
+    {
+	gui.dying = TRUE;
+	EMSG(_(e_opendisp));
+	return FAIL;
+    }
+    return OK;
+}
+
+
+#ifdef USE_XSMP
+/*
+ * Handle XSMP processing, de-registering the attachment upon error
+ */
+static XtInputId _xsmp_xtinputid;
+
+static void local_xsmp_handle_requests __ARGS((XtPointer c, int *s, XtInputId *i));
+
+/*ARGSUSED*/
+    static void
+local_xsmp_handle_requests(c, s, i)
+    XtPointer	c;
+    int		*s;
+    XtInputId	*i;
+{
+    if (xsmp_handle_requests() == FAIL)
+	XtRemoveInput(_xsmp_xtinputid);
+}
+#endif
+
+
+/*
+ * Initialise the X GUI.  Create all the windows, set up all the call-backs etc.
+ * Returns OK for success, FAIL when the GUI can't be started.
+ */
+    int
+gui_mch_init()
+{
+    XtGCMask	gc_mask;
+    XGCValues	gc_vals;
+    int		x, y, mask;
+    unsigned	w, h;
+
+#if 0
+    /* Uncomment this to enable synchronous mode for debugging */
+    XSynchronize(gui.dpy, True);
+#endif
+
+    vimShell = XtVaAppCreateShell(VIM_NAME, VIM_CLASS,
+	    applicationShellWidgetClass, gui.dpy, NULL);
+
+    /*
+     * Get the application resources
+     */
+    XtVaGetApplicationResources(vimShell, (XtPointer)&gui,
+	vim_resources, XtNumber(vim_resources), NULL);
+
+    gui.scrollbar_height = gui.scrollbar_width;
+
+    /*
+     * Get the colors ourselves.  Using the automatic conversion doesn't
+     * handle looking for approximate colors.
+     */
+    /* NOTE: These next few lines are an exact duplicate of gui_athena.c's
+     * gui_mch_def_colors().  Why?
+     */
+    gui.menu_fg_pixel = gui_get_color((char_u *)gui.rsrc_menu_fg_name);
+    gui.menu_bg_pixel = gui_get_color((char_u *)gui.rsrc_menu_bg_name);
+    gui.scroll_fg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_fg_name);
+    gui.scroll_bg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_bg_name);
+#ifdef FEAT_BEVAL
+    gui.tooltip_fg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_fg_name);
+    gui.tooltip_bg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_bg_name);
+#endif
+
+#if defined(FEAT_MENU) && defined(FEAT_GUI_ATHENA)
+    /* If the menu height was set, don't change it at runtime */
+    if (gui.menu_height != MENU_DEFAULT_HEIGHT)
+	gui.menu_height_fixed = TRUE;
+#endif
+
+    /* Set default foreground and background colours */
+    gui.norm_pixel = gui.def_norm_pixel;
+    gui.back_pixel = gui.def_back_pixel;
+
+    /* Check if reverse video needs to be applied (on Sun it's done by X) */
+    if (gui.rsrc_rev_video && gui_get_lightness(gui.back_pixel)
+					  > gui_get_lightness(gui.norm_pixel))
+    {
+	gui.norm_pixel = gui.def_back_pixel;
+	gui.back_pixel = gui.def_norm_pixel;
+	gui.def_norm_pixel = gui.norm_pixel;
+	gui.def_back_pixel = gui.back_pixel;
+    }
+
+    /* Get the colors from the "Normal", "Tooltip", "Scrollbar" and "Menu"
+     * group (set in syntax.c or in a vimrc file) */
+    set_normal_colors();
+
+    /*
+     * Check that none of the colors are the same as the background color
+     */
+    gui_check_colors();
+
+    /*
+     * Set up the GCs.	The font attributes will be set in gui_init_font().
+     */
+    gc_mask = GCForeground | GCBackground;
+    gc_vals.foreground = gui.norm_pixel;
+    gc_vals.background = gui.back_pixel;
+    gui.text_gc = XtGetGC(vimShell, gc_mask, &gc_vals);
+
+    gc_vals.foreground = gui.back_pixel;
+    gc_vals.background = gui.norm_pixel;
+    gui.back_gc = XtGetGC(vimShell, gc_mask, &gc_vals);
+
+    gc_mask |= GCFunction;
+    gc_vals.foreground = gui.norm_pixel ^ gui.back_pixel;
+    gc_vals.background = gui.norm_pixel ^ gui.back_pixel;
+    gc_vals.function   = GXxor;
+    gui.invert_gc = XtGetGC(vimShell, gc_mask, &gc_vals);
+
+    gui.visibility = VisibilityUnobscured;
+    x11_setup_atoms(gui.dpy);
+
+    if (gui_win_x != -1 && gui_win_y != -1)
+	gui_mch_set_winpos(gui_win_x, gui_win_y);
+
+    /* Now adapt the supplied(?) geometry-settings */
+    /* Added by Kjetil Jacobsen <kjetilja@stud.cs.uit.no> */
+    if (gui.geom != NULL && *gui.geom != NUL)
+    {
+	mask = XParseGeometry((char *)gui.geom, &x, &y, &w, &h);
+	if (mask & WidthValue)
+	    Columns = w;
+	if (mask & HeightValue)
+	    Rows = h;
+	/*
+	 * Set the (x,y) position of the main window only if specified in the
+	 * users geometry, so we get good defaults when they don't. This needs
+	 * to be done before the shell is popped up.
+	 */
+	if (mask & (XValue|YValue))
+	    XtVaSetValues(vimShell, XtNgeometry, gui.geom, NULL);
+    }
+
+    gui_x11_create_widgets();
+
+   /*
+    * Add an icon to Vim (Marcel Douben: 11 May 1998).
+    */
+    if (vim_strchr(p_go, GO_ICON) != NULL)
+    {
+#ifndef HAVE_XPM
+# include "vim_icon.xbm"
+# include "vim_mask.xbm"
+
+	Arg	arg[2];
+
+	XtSetArg(arg[0], XtNiconPixmap,
+		XCreateBitmapFromData(gui.dpy,
+		    DefaultRootWindow(gui.dpy),
+		    (char *)vim_icon_bits,
+		    vim_icon_width,
+		    vim_icon_height));
+	XtSetArg(arg[1], XtNiconMask,
+		XCreateBitmapFromData(gui.dpy,
+		    DefaultRootWindow(gui.dpy),
+		    (char *)vim_mask_icon_bits,
+		    vim_mask_icon_width,
+		    vim_mask_icon_height));
+	XtSetValues(vimShell, arg, (Cardinal)2);
+#else
+/* Use Pixmaps, looking much nicer. */
+
+/* If you get an error message here, you still need to unpack the runtime
+ * archive! */
+# ifdef magick
+#  undef magick
+# endif
+# define magick vim32x32
+# include "../runtime/vim32x32.xpm"
+# undef magick
+# define magick vim16x16
+# include "../runtime/vim16x16.xpm"
+# undef magick
+# define magick vim48x48
+# include "../runtime/vim48x48.xpm"
+# undef magick
+
+    static Pixmap	icon = 0;
+    static Pixmap	icon_mask = 0;
+    static char		**magick = vim32x32;
+    Window		root_window;
+    XIconSize		*size;
+    int			number_sizes;
+    Display		*dsp;
+    Screen		*scr;
+    XpmAttributes	attr;
+    Colormap		cmap;
+
+    /*
+     * Adjust the icon to the preferences of the actual window manager.
+     */
+    root_window = XRootWindowOfScreen(XtScreen(vimShell));
+    if (XGetIconSizes(XtDisplay(vimShell), root_window,
+						   &size, &number_sizes) != 0)
+    {
+
+	if (number_sizes > 0)
+	{
+	    if (size->max_height >= 48 && size->max_height >= 48)
+		magick = vim48x48;
+	    else if (size->max_height >= 32 && size->max_height >= 32)
+		magick = vim32x32;
+	    else if (size->max_height >= 16 && size->max_height >= 16)
+		magick = vim16x16;
+	}
+    }
+
+    dsp = XtDisplay(vimShell);
+    scr = XtScreen(vimShell);
+
+    cmap = DefaultColormap(dsp, DefaultScreen(dsp));
+    XtVaSetValues(vimShell, XtNcolormap, cmap, NULL);
+
+    attr.valuemask = 0L;
+    attr.valuemask = XpmCloseness | XpmReturnPixels | XpmColormap | XpmDepth;
+    attr.closeness = 65535;	/* accuracy isn't crucial */
+    attr.colormap = cmap;
+    attr.depth = DefaultDepthOfScreen(scr);
+
+    if (!icon)
+	XpmCreatePixmapFromData(dsp, root_window, magick, &icon,
+							   &icon_mask, &attr);
+
+# ifdef FEAT_GUI_ATHENA
+    XtVaSetValues(vimShell, XtNiconPixmap, icon, XtNiconMask, icon_mask, NULL);
+# else
+    XtVaSetValues(vimShell, XmNiconPixmap, icon, XmNiconMask, icon_mask, NULL);
+# endif
+#endif
+    }
+
+    if (gui.color_approx)
+	EMSG(_("Vim E458: Cannot allocate colormap entry, some colors may be incorrect"));
+
+#ifdef FEAT_SUN_WORKSHOP
+    if (usingSunWorkShop)
+	workshop_connect(app_context);
+#endif
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+	netbeans_Xt_connect(app_context);
+#endif
+
+#ifdef FEAT_BEVAL
+    gui_init_tooltip_font();
+#endif
+#ifdef FEAT_MENU
+    gui_init_menu_font();
+#endif
+
+#ifdef USE_XSMP
+    /* Attach listener on ICE connection */
+    if (-1 != xsmp_icefd)
+	_xsmp_xtinputid = XtAppAddInput(app_context, xsmp_icefd,
+		(XtPointer)XtInputReadMask, local_xsmp_handle_requests, NULL);
+#endif
+
+    return OK;
+}
+
+/*
+ * Called when starting the GUI fails after calling gui_mch_init().
+ */
+    void
+gui_mch_uninit()
+{
+    gui_x11_destroy_widgets();
+#ifndef LESSTIF_VERSION
+    XtCloseDisplay(gui.dpy);
+#endif
+    gui.dpy = NULL;
+    vimShell = (Widget)0;
+}
+
+/*
+ * Called when the foreground or background color has been changed.
+ */
+    void
+gui_mch_new_colors()
+{
+    long_u	gc_mask;
+    XGCValues	gc_vals;
+
+    gc_mask = GCForeground | GCBackground;
+    gc_vals.foreground = gui.norm_pixel;
+    gc_vals.background = gui.back_pixel;
+    if (gui.text_gc != NULL)
+	XChangeGC(gui.dpy, gui.text_gc, gc_mask, &gc_vals);
+
+    gc_vals.foreground = gui.back_pixel;
+    gc_vals.background = gui.norm_pixel;
+    if (gui.back_gc != NULL)
+	XChangeGC(gui.dpy, gui.back_gc, gc_mask, &gc_vals);
+
+    gc_mask |= GCFunction;
+    gc_vals.foreground = gui.norm_pixel ^ gui.back_pixel;
+    gc_vals.background = gui.norm_pixel ^ gui.back_pixel;
+    gc_vals.function   = GXxor;
+    if (gui.invert_gc != NULL)
+	XChangeGC(gui.dpy, gui.invert_gc, gc_mask, &gc_vals);
+
+    gui_x11_set_back_color();
+}
+
+/*
+ * Open the GUI window which was created by a call to gui_mch_init().
+ */
+    int
+gui_mch_open()
+{
+    /* Actually open the window */
+    XtPopup(vimShell, XtGrabNone);
+
+    gui.wid = gui_x11_get_wid();
+    gui.blank_pointer = gui_x11_create_blank_mouse();
+
+    /*
+     * Add a callback for the Close item on the window managers menu, and the
+     * save-yourself event.
+     */
+    wm_atoms[SAVE_YOURSELF_IDX] =
+			      XInternAtom(gui.dpy, "WM_SAVE_YOURSELF", False);
+    wm_atoms[DELETE_WINDOW_IDX] =
+			      XInternAtom(gui.dpy, "WM_DELETE_WINDOW", False);
+    XSetWMProtocols(gui.dpy, XtWindow(vimShell), wm_atoms, 2);
+    XtAddEventHandler(vimShell, NoEventMask, True, gui_x11_wm_protocol_handler,
+							     NULL);
+#ifdef HAVE_X11_XMU_EDITRES_H
+    /*
+     * Enable editres protocol (see "man editres").
+     * Usually will need to add -lXmu to the linker line as well.
+     */
+    XtAddEventHandler(vimShell, (EventMask)0, True, _XEditResCheckMessages,
+	    (XtPointer)NULL);
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+    if (serverName == NULL && serverDelayedStartName != NULL)
+    {
+	/* This is a :gui command in a plain vim with no previous server */
+	commWindow = XtWindow(vimShell);
+	(void)serverRegisterName(gui.dpy, serverDelayedStartName);
+    }
+    else
+    {
+	/*
+	 * Cannot handle "widget-less" windows with XtProcessEvent() we'll
+	 * have to change the "server" registration to that of the main window
+	 * If we have not registered a name yet, remember the window
+	 */
+	serverChangeRegisteredWindow(gui.dpy, XtWindow(vimShell));
+    }
+    XtAddEventHandler(vimShell, PropertyChangeMask, False,
+		      gui_x11_send_event_handler, NULL);
+#endif
+
+
+#if defined(FEAT_MENU) && defined(FEAT_GUI_ATHENA)
+    /* The Athena GUI needs this again after opening the window */
+    gui_position_menu();
+# ifdef FEAT_TOOLBAR
+    gui_mch_set_toolbar_pos(0, gui.menu_height, gui.menu_width,
+			    gui.toolbar_height);
+# endif
+#endif
+
+    /* Get the colors for the highlight groups (gui_check_colors() might have
+     * changed them) */
+    highlight_gui_started();		/* re-init colors and fonts */
+
+#ifdef FEAT_HANGULIN
+    hangul_keyboard_set();
+#endif
+#ifdef FEAT_XIM
+    xim_init();
+#endif
+#ifdef FEAT_SUN_WORKSHOP
+    workshop_postinit();
+#endif
+
+    return OK;
+}
+
+#if defined(FEAT_BEVAL) || defined(PROTO)
+/*
+ * Convert the tooltip fontset name to an XFontSet.
+ */
+    void
+gui_init_tooltip_font()
+{
+    XrmValue from, to;
+
+    from.addr = (char *)gui.rsrc_tooltip_font_name;
+    from.size = strlen(from.addr);
+    to.addr = (XtPointer)&gui.tooltip_fontset;
+    to.size = sizeof(XFontSet);
+
+    if (XtConvertAndStore(vimShell, XtRString, &from, XtRFontSet, &to) == False)
+    {
+	/* Failed. What to do? */
+    }
+}
+#endif
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/* Convert the menu font/fontset name to an XFontStruct/XFontset */
+    void
+gui_init_menu_font()
+{
+    XrmValue from, to;
+
+#ifdef FONTSET_ALWAYS
+    from.addr = (char *)gui.rsrc_menu_font_name;
+    from.size = strlen(from.addr);
+    to.addr = (XtPointer)&gui.menu_fontset;
+    to.size = sizeof(GuiFontset);
+
+    if (XtConvertAndStore(vimShell, XtRString, &from, XtRFontSet, &to) == False)
+    {
+	/* Failed. What to do? */
+    }
+#else
+    from.addr = (char *)gui.rsrc_menu_font_name;
+    from.size = strlen(from.addr);
+    to.addr = (XtPointer)&gui.menu_font;
+    to.size = sizeof(GuiFont);
+
+    if (XtConvertAndStore(vimShell, XtRString, &from, XtRFontStruct, &to) == False)
+    {
+	/* Failed. What to do? */
+    }
+#endif
+}
+#endif
+
+/*ARGSUSED*/
+    void
+gui_mch_exit(rc)
+    int		rc;
+{
+#if 0
+    /* Lesstif gives an error message here, and so does Solaris.  The man page
+     * says that this isn't needed when exiting, so just skip it. */
+    XtCloseDisplay(gui.dpy);
+#endif
+}
+
+/*
+ * Get the position of the top left corner of the window.
+ */
+    int
+gui_mch_get_winpos(x, y)
+    int		*x, *y;
+{
+    Dimension	xpos, ypos;
+
+    XtVaGetValues(vimShell,
+	XtNx,	&xpos,
+	XtNy,	&ypos,
+	NULL);
+    *x = xpos;
+    *y = ypos;
+    return OK;
+}
+
+/*
+ * Set the position of the top left corner of the window to the given
+ * coordinates.
+ */
+    void
+gui_mch_set_winpos(x, y)
+    int		x, y;
+{
+    XtVaSetValues(vimShell,
+	XtNx,	x,
+	XtNy,	y,
+	NULL);
+}
+
+    void
+gui_mch_set_shellsize(width, height, min_width, min_height,
+		    base_width, base_height)
+    int		width;
+    int		height;
+    int		min_width;
+    int		min_height;
+    int		base_width;
+    int		base_height;
+{
+    XtVaSetValues(vimShell,
+	XtNwidthInc,	gui.char_width,
+	XtNheightInc,	gui.char_height,
+#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 4
+	XtNbaseWidth,	base_width,
+	XtNbaseHeight,	base_height,
+#endif
+	XtNminWidth,	min_width,
+	XtNminHeight,	min_height,
+	XtNwidth,	width,
+#ifdef FEAT_XIM
+	XtNheight,	height + xim_get_status_area_height(),
+#else
+	XtNheight,	height,
+#endif
+	NULL);
+}
+
+/*
+ * Allow 10 pixels for horizontal borders, 30 for vertical borders.
+ * Is there no way in X to find out how wide the borders really are?
+ */
+    void
+gui_mch_get_screen_dimensions(screen_w, screen_h)
+    int	    *screen_w;
+    int	    *screen_h;
+{
+    *screen_w = DisplayWidth(gui.dpy, DefaultScreen(gui.dpy)) - 10;
+    *screen_h = DisplayHeight(gui.dpy, DefaultScreen(gui.dpy)) - p_ghr;
+}
+
+/*
+ * Initialise vim to use the font "font_name".  If it's NULL, pick a default
+ * font.
+ * If "fontset" is TRUE, load the "font_name" as a fontset.
+ * Return FAIL if the font could not be loaded, OK otherwise.
+ */
+/*ARGSUSED*/
+    int
+gui_mch_init_font(font_name, do_fontset)
+    char_u	*font_name;
+    int		do_fontset;
+{
+    XFontStruct	*font = NULL;
+
+#ifdef FEAT_XFONTSET
+    XFontSet	fontset = NULL;
+
+    if (do_fontset)
+    {
+	/* If 'guifontset' is set, VIM treats all font specifications as if
+	 * they were fontsets, and 'guifontset' becomes the default. */
+	if (font_name != NULL)
+	{
+	    fontset = (XFontSet)gui_mch_get_fontset(font_name, FALSE, TRUE);
+	    if (fontset == NULL)
+		return FAIL;
+	}
+    }
+    else
+#endif
+    {
+	if (font_name == NULL)
+	{
+	    /*
+	     * If none of the fonts in 'font' could be loaded, try the one set
+	     * in the X resource, and finally just try using DFLT_FONT, which
+	     * will hopefully always be there.
+	     */
+	    font_name = gui.rsrc_font_name;
+	    font = (XFontStruct *)gui_mch_get_font(font_name, FALSE);
+	    if (font == NULL)
+		font_name = (char_u *)DFLT_FONT;
+	}
+	if (font == NULL)
+	    font = (XFontStruct *)gui_mch_get_font(font_name, FALSE);
+	if (font == NULL)
+	    return FAIL;
+    }
+
+    gui_mch_free_font(gui.norm_font);
+#ifdef FEAT_XFONTSET
+    gui_mch_free_fontset(gui.fontset);
+
+    if (fontset != NULL)
+    {
+	gui.norm_font = NOFONT;
+	gui.fontset = (GuiFontset)fontset;
+	gui.char_width = fontset_width(fontset);
+	gui.char_height = fontset_height(fontset) + p_linespace;
+	gui.char_ascent = fontset_ascent(fontset) + p_linespace / 2;
+    }
+    else
+#endif
+    {
+	gui.norm_font = (GuiFont)font;
+#ifdef FEAT_XFONTSET
+	gui.fontset = NOFONTSET;
+#endif
+	gui.char_width = font->max_bounds.width;
+	gui.char_height = font->ascent + font->descent + p_linespace;
+	gui.char_ascent = font->ascent + p_linespace / 2;
+    }
+
+    hl_set_font_name(font_name);
+
+    /*
+     * Try to load other fonts for bold, italic, and bold-italic.
+     * We should also try to work out what font to use for these when they are
+     * not specified by X resources, but we don't yet.
+     */
+    if (font_name == gui.rsrc_font_name)
+    {
+	if (gui.bold_font == NOFONT
+		&& gui.rsrc_bold_font_name != NULL
+		&& *gui.rsrc_bold_font_name != NUL)
+	    gui.bold_font = gui_mch_get_font(gui.rsrc_bold_font_name, FALSE);
+	if (gui.ital_font == NOFONT
+		&& gui.rsrc_ital_font_name != NULL
+		&& *gui.rsrc_ital_font_name != NUL)
+	    gui.ital_font = gui_mch_get_font(gui.rsrc_ital_font_name, FALSE);
+	if (gui.boldital_font == NOFONT
+		&& gui.rsrc_boldital_font_name != NULL
+		&& *gui.rsrc_boldital_font_name != NUL)
+	    gui.boldital_font = gui_mch_get_font(gui.rsrc_boldital_font_name,
+								       FALSE);
+    }
+    else
+    {
+	/* When not using the font specified by the resources, also don't use
+	 * the bold/italic fonts, otherwise setting 'guifont' will look very
+	 * strange. */
+	if (gui.bold_font != NOFONT)
+	{
+	    XFreeFont(gui.dpy, (XFontStruct *)gui.bold_font);
+	    gui.bold_font = NOFONT;
+	}
+	if (gui.ital_font != NOFONT)
+	{
+	    XFreeFont(gui.dpy, (XFontStruct *)gui.ital_font);
+	    gui.ital_font = NOFONT;
+	}
+	if (gui.boldital_font != NOFONT)
+	{
+	    XFreeFont(gui.dpy, (XFontStruct *)gui.boldital_font);
+	    gui.boldital_font = NOFONT;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Get a font structure for highlighting.
+ */
+    GuiFont
+gui_mch_get_font(name, giveErrorIfMissing)
+    char_u	*name;
+    int		giveErrorIfMissing;
+{
+    XFontStruct	*font;
+
+    if (!gui.in_use || name == NULL)    /* can't do this when GUI not running */
+	return NOFONT;
+
+    font = XLoadQueryFont(gui.dpy, (char *)name);
+
+    if (font == NULL)
+    {
+	if (giveErrorIfMissing)
+	    EMSG2(_(e_font), name);
+	return NOFONT;
+    }
+
+#ifdef DEBUG
+    printf("Font Information for '%s':\n", name);
+    printf("  w = %d, h = %d, ascent = %d, descent = %d\n",
+	   font->max_bounds.width, font->ascent + font->descent,
+	   font->ascent, font->descent);
+    printf("  max ascent = %d, max descent = %d, max h = %d\n",
+	   font->max_bounds.ascent, font->max_bounds.descent,
+	   font->max_bounds.ascent + font->max_bounds.descent);
+    printf("  min lbearing = %d, min rbearing = %d\n",
+	   font->min_bounds.lbearing, font->min_bounds.rbearing);
+    printf("  max lbearing = %d, max rbearing = %d\n",
+	   font->max_bounds.lbearing, font->max_bounds.rbearing);
+    printf("  leftink = %d, rightink = %d\n",
+	   (font->min_bounds.lbearing < 0),
+	   (font->max_bounds.rbearing > font->max_bounds.width));
+    printf("\n");
+#endif
+
+    if (font->max_bounds.width != font->min_bounds.width)
+    {
+	EMSG2(_(e_fontwidth), name);
+	XFreeFont(gui.dpy, font);
+	return NOFONT;
+    }
+    return (GuiFont)font;
+}
+
+    int
+gui_mch_adjust_charsize()
+{
+#ifdef FEAT_XFONTSET
+    if (gui.fontset != NOFONTSET)
+    {
+	gui.char_height = fontset_height((XFontSet)gui.fontset) + p_linespace;
+	gui.char_ascent = fontset_ascent((XFontSet)gui.fontset)
+							    + p_linespace / 2;
+    }
+    else
+#endif
+    {
+	XFontStruct *font = (XFontStruct *)gui.norm_font;
+
+	gui.char_height = font->ascent + font->descent + p_linespace;
+	gui.char_ascent = font->ascent + p_linespace / 2;
+    }
+    return OK;
+}
+
+/*
+ * Set the current text font.
+ */
+    void
+gui_mch_set_font(font)
+    GuiFont	font;
+{
+    static Font	prev_font = (Font)-1;
+    Font	fid = ((XFontStruct *)font)->fid;
+
+    if (fid != prev_font)
+    {
+	XSetFont(gui.dpy, gui.text_gc, fid);
+	XSetFont(gui.dpy, gui.back_gc, fid);
+	prev_font = fid;
+	gui.char_ascent = ((XFontStruct *)font)->ascent + p_linespace / 2;
+    }
+#ifdef FEAT_XFONTSET
+    current_fontset = (XFontSet)NULL;
+#endif
+}
+
+#if defined(FEAT_XFONTSET) || defined(PROTO)
+/*
+ * Set the current text fontset.
+ * Adjust the ascent, in case it's different.
+ */
+    void
+gui_mch_set_fontset(fontset)
+    GuiFontset	fontset;
+{
+    current_fontset = (XFontSet)fontset;
+    gui.char_ascent = fontset_ascent(current_fontset) + p_linespace / 2;
+}
+#endif
+
+#if 0 /* not used */
+/*
+ * Return TRUE if the two fonts given are equivalent.
+ */
+    int
+gui_mch_same_font(f1, f2)
+    GuiFont	f1;
+    GuiFont	f2;
+{
+#ifdef FEAT_XFONTSET
+    if (gui.fontset != NULL)
+	return f1 == f2;
+    else
+#endif
+    return ((XFontStruct *)f1)->fid == ((XFontStruct *)f2)->fid;
+}
+#endif
+
+/*
+ * If a font is not going to be used, free its structure.
+ */
+    void
+gui_mch_free_font(font)
+    GuiFont	font;
+{
+    if (font != NOFONT)
+	XFreeFont(gui.dpy, (XFontStruct *)font);
+}
+
+#if defined(FEAT_XFONTSET) || defined(PROTO)
+/*
+ * If a fontset is not going to be used, free its structure.
+ */
+    void
+gui_mch_free_fontset(fontset)
+    GuiFontset	fontset;
+{
+    if (fontset != NOFONTSET)
+	XFreeFontSet(gui.dpy, (XFontSet)fontset);
+}
+
+/*
+ * Load the fontset "name".
+ * Return a reference to the fontset, or NOFONTSET when failing.
+ */
+    GuiFontset
+gui_mch_get_fontset(name, giveErrorIfMissing, fixed_width)
+    char_u	*name;
+    int		giveErrorIfMissing;
+    int		fixed_width;
+{
+    XFontSet	fontset;
+    char	**missing, *def_str;
+    int		num_missing;
+
+    if (!gui.in_use || name == NULL)
+	return NOFONTSET;
+
+    fontset = XCreateFontSet(gui.dpy, (char *)name, &missing, &num_missing,
+			     &def_str);
+    if (num_missing > 0)
+    {
+	int i;
+
+	if (giveErrorIfMissing)
+	{
+	    EMSG2(_("E250: Fonts for the following charsets are missing in fontset %s:"), name);
+	    for (i = 0; i < num_missing; i++)
+		EMSG2("%s", missing[i]);
+	}
+	XFreeStringList(missing);
+    }
+
+    if (fontset == NULL)
+    {
+	if (giveErrorIfMissing)
+	    EMSG2(_(e_fontset), name);
+	return NOFONTSET;
+    }
+
+    if (fixed_width && check_fontset_sanity(fontset) == FAIL)
+    {
+	XFreeFontSet(gui.dpy, fontset);
+	return NOFONTSET;
+    }
+    return (GuiFontset)fontset;
+}
+
+/*
+ * Check if fontset "fs" is fixed width.
+ */
+    static int
+check_fontset_sanity(fs)
+    XFontSet fs;
+{
+    XFontStruct	**xfs;
+    char	**font_name;
+    int		fn;
+    char	*base_name;
+    int		i;
+    int		min_width;
+    int		min_font_idx = 0;
+
+    base_name = XBaseFontNameListOfFontSet(fs);
+    fn = XFontsOfFontSet(fs, &xfs, &font_name);
+    for (i = 0; i < fn; i++)
+    {
+	if (xfs[i]->max_bounds.width != xfs[i]->min_bounds.width)
+	{
+	    EMSG2(_("E252: Fontset name: %s"), base_name);
+	    EMSG2(_("Font '%s' is not fixed-width"), font_name[i]);
+	    return FAIL;
+	}
+    }
+    /* scan base font width */
+    min_width = 32767;
+    for (i = 0; i < fn; i++)
+    {
+	if (xfs[i]->max_bounds.width<min_width)
+	{
+	    min_width = xfs[i]->max_bounds.width;
+	    min_font_idx = i;
+	}
+    }
+    for (i = 0; i < fn; i++)
+    {
+	if (	   xfs[i]->max_bounds.width != 2 * min_width
+		&& xfs[i]->max_bounds.width != min_width)
+	{
+	    EMSG2(_("E253: Fontset name: %s\n"), base_name);
+	    EMSG2(_("Font0: %s\n"), font_name[min_font_idx]);
+	    EMSG2(_("Font1: %s\n"), font_name[i]);
+	    EMSGN(_("Font%ld width is not twice that of font0\n"), i);
+	    EMSGN(_("Font0 width: %ld\n"), xfs[min_font_idx]->max_bounds.width);
+	    EMSGN(_("Font1 width: %ld\n\n"), xfs[i]->max_bounds.width);
+	    return FAIL;
+	}
+    }
+    /* it seems ok. Good Luck!! */
+    return OK;
+}
+
+    static int
+fontset_width(fs)
+    XFontSet fs;
+{
+    return XmbTextEscapement(fs, "Vim", 3) / 3;
+}
+
+    int
+fontset_height(fs)
+    XFontSet fs;
+{
+    XFontSetExtents *extents;
+
+    extents = XExtentsOfFontSet(fs);
+    return extents->max_logical_extent.height;
+}
+
+#if (defined(FONTSET_ALWAYS) && defined(FEAT_GUI_ATHENA) \
+	    && defined(FEAT_MENU)) || defined(PROTO)
+/*
+ * Returns the bounding box height around the actual glyph image of all
+ * characters in all fonts of the fontset.
+ */
+    int
+fontset_height2(fs)
+    XFontSet fs;
+{
+    XFontSetExtents *extents;
+
+    extents = XExtentsOfFontSet(fs);
+    return extents->max_ink_extent.height;
+}
+#endif
+
+/* NOT USED YET
+    static int
+fontset_descent(fs)
+    XFontSet fs;
+{
+    XFontSetExtents *extents;
+
+    extents = XExtentsOfFontSet (fs);
+    return extents->max_logical_extent.height + extents->max_logical_extent.y;
+}
+*/
+
+    static int
+fontset_ascent(fs)
+    XFontSet fs;
+{
+    XFontSetExtents *extents;
+
+    extents = XExtentsOfFontSet(fs);
+    return -extents->max_logical_extent.y;
+}
+
+#endif /* FEAT_XFONTSET */
+
+/*
+ * Return the Pixel value (color) for the given color name.
+ * Return INVALCOLOR for error.
+ */
+    guicolor_T
+gui_mch_get_color(reqname)
+    char_u *reqname;
+{
+    int		i;
+    char_u	*name = reqname;
+    Colormap	colormap;
+    XColor      color;
+    static char *(vimnames[][2]) =
+    {
+	/* A number of colors that some X11 systems don't have */
+	{"LightRed",	"#FFBBBB"},
+	{"LightGreen",	"#88FF88"},
+	{"LightMagenta","#FFBBFF"},
+	{"DarkCyan",	"#008888"},
+	{"DarkBlue",	"#0000BB"},
+	{"DarkRed",	"#BB0000"},
+	{"DarkMagenta",	"#BB00BB"},
+	{"DarkGrey",	"#BBBBBB"},
+	{"DarkYellow",	"#BBBB00"},
+	{NULL, NULL}
+    };
+
+    /* can't do this when GUI not running */
+    if (!gui.in_use || *reqname == NUL)
+	return INVALCOLOR;
+
+    colormap = DefaultColormap(gui.dpy, XDefaultScreen(gui.dpy));
+
+    /* Do this twice if the name isn't recognized. */
+    while (name != NULL)
+    {
+	i = XParseColor(gui.dpy, colormap, (char *)name, &color);
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+	if (i == 0)
+	{
+	    char *old;
+
+	    /* The X11 system is trying to resolve named colors only by names
+	     * corresponding to the current locale language.  But Vim scripts
+	     * usually contain the English color names.  Therefore we have to
+	     * try a second time here with the native "C" locale set.
+	     * Hopefully, restoring the old locale this way works on all
+	     * systems...
+	     */
+	    old = setlocale(LC_ALL, NULL);
+	    if (old != NULL && STRCMP(old, "C") != 0)
+	    {
+		old = (char *)vim_strsave((char_u *)old);
+		setlocale(LC_ALL, "C");
+		i = XParseColor(gui.dpy, colormap, (char *)name, &color);
+		setlocale(LC_ALL, old);
+		vim_free(old);
+	    }
+	}
+#endif
+	if (i != 0 && (XAllocColor(gui.dpy, colormap, &color) != 0
+		    || find_closest_color(colormap, &color) == OK))
+	    return (guicolor_T)color.pixel;
+
+	/* check for a few builtin names */
+	for (i = 0; ; ++i)
+	{
+	    if (vimnames[i][0] == NULL)
+	    {
+		name = NULL;
+		break;
+	    }
+	    if (STRICMP(name, vimnames[i][0]) == 0)
+	    {
+		name = (char_u *)vimnames[i][1];
+		break;
+	    }
+	}
+    }
+
+    return INVALCOLOR;
+}
+
+/*
+ * Find closest color for "colorPtr" in "colormap".  set "colorPtr" to the
+ * resulting color.
+ * Based on a similar function in TCL.
+ * Return FAIL if not able to find or allocate a color.
+ */
+    static int
+find_closest_color(colormap, colorPtr)
+    Colormap	colormap;
+    XColor	*colorPtr;
+{
+    double	tmp, distance, closestDistance;
+    int		i, closest, numFound, cmap_size;
+    XColor	*colortable;
+    XVisualInfo	template, *visInfoPtr;
+
+    template.visualid = XVisualIDFromVisual(DefaultVisual(gui.dpy,
+						    XDefaultScreen(gui.dpy)));
+    visInfoPtr = XGetVisualInfo(gui.dpy, (long)VisualIDMask,
+							&template, &numFound);
+    if (numFound < 1)
+	/* FindClosestColor couldn't lookup visual */
+	return FAIL;
+
+    cmap_size = visInfoPtr->colormap_size;
+    XFree((char *)visInfoPtr);
+    colortable = (XColor *)alloc((unsigned)(cmap_size * sizeof(XColor)));
+    if (!colortable)
+	return FAIL;  /* out of memory */
+
+    for (i = 0; i  < cmap_size; i++)
+	colortable[i].pixel = (unsigned long)i;
+    XQueryColors (gui.dpy, colormap, colortable, cmap_size);
+
+    /*
+     * Find the color that best approximates the desired one, then
+     * try to allocate that color.  If that fails, it must mean that
+     * the color was read-write (so we can't use it, since it's owner
+     * might change it) or else it was already freed.  Try again,
+     * over and over again, until something succeeds.
+     */
+    closestDistance = 1e30;
+    closest = 0;
+    for (i = 0; i < cmap_size; i++)
+    {
+	/*
+	 * Use Euclidean distance in RGB space, weighted by Y (of YIQ)
+	 * as the objective function;  this accounts for differences
+	 * in the color sensitivity of the eye.
+	 */
+	tmp = .30 * (((int)colorPtr->red) - (int)colortable[i].red);
+	distance = tmp * tmp;
+	tmp = .61 * (((int)colorPtr->green) - (int)colortable[i].green);
+	distance += tmp * tmp;
+	tmp = .11 * (((int)colorPtr->blue) - (int)colortable[i].blue);
+	distance += tmp * tmp;
+	if (distance < closestDistance)
+	{
+	    closest = i;
+	    closestDistance = distance;
+	}
+    }
+
+    if (XAllocColor(gui.dpy, colormap, &colortable[closest]) != 0)
+    {
+	gui.color_approx = TRUE;
+	*colorPtr = colortable[closest];
+    }
+
+    free(colortable);
+    return OK;
+}
+
+    void
+gui_mch_set_fg_color(color)
+    guicolor_T	color;
+{
+    if (color != prev_fg_color)
+    {
+	XSetForeground(gui.dpy, gui.text_gc, (Pixel)color);
+	prev_fg_color = color;
+    }
+}
+
+/*
+ * Set the current text background color.
+ */
+    void
+gui_mch_set_bg_color(color)
+    guicolor_T	color;
+{
+    if (color != prev_bg_color)
+    {
+	XSetBackground(gui.dpy, gui.text_gc, (Pixel)color);
+	prev_bg_color = color;
+    }
+}
+
+/*
+ * create a mouse pointer that is blank
+ */
+    static Cursor
+gui_x11_create_blank_mouse()
+{
+    Pixmap blank_pixmap = XCreatePixmap(gui.dpy, gui.wid, 1, 1, 1);
+    GC gc = XCreateGC(gui.dpy, blank_pixmap, (unsigned long)0, (XGCValues*)0);
+    XDrawPoint(gui.dpy, blank_pixmap, gc, 0, 0);
+    XFreeGC(gui.dpy, gc);
+    return XCreatePixmapCursor(gui.dpy, blank_pixmap, blank_pixmap,
+	    (XColor*)&gui.norm_pixel, (XColor*)&gui.norm_pixel, 0, 0);
+}
+
+    void
+gui_mch_draw_string(row, col, s, len, flags)
+    int		row;
+    int		col;
+    char_u	*s;
+    int		len;
+    int		flags;
+{
+    int			cells = len;
+#ifdef FEAT_MBYTE
+    static XChar2b	*buf = NULL;
+    static int		buflen = 0;
+    char_u		*p;
+    int			wlen = 0;
+    int			c;
+
+    if (enc_utf8)
+    {
+	/* Convert UTF-8 byte sequence to 16 bit characters for the X
+	 * functions.  Need a buffer for the 16 bit characters.  Keep it
+	 * between calls, because allocating it each time is slow. */
+	if (buflen < len)
+	{
+	    XtFree((char *)buf);
+	    buf = (XChar2b *)XtMalloc(len * sizeof(XChar2b));
+	    buflen = len;
+	}
+	p = s;
+	cells = 0;
+	while (p < s + len)
+	{
+	    c = utf_ptr2char(p);
+	    if (c >= 0x10000)	/* show chars > 0xffff as ? */
+		c = 0xbf;
+	    buf[wlen].byte1 = (unsigned)c >> 8;
+	    buf[wlen].byte2 = c;
+	    ++wlen;
+	    cells += utf_char2cells(c);
+	    p += utf_ptr2len_check(p);
+	}
+    }
+    else if (has_mbyte)
+    {
+	cells = 0;
+	for (p = s; p < s + len; )
+	{
+	    cells += ptr2cells(p);
+	    p += (*mb_ptr2len_check)(p);
+	}
+    }
+
+#endif
+
+#ifdef FEAT_XFONTSET
+    if (current_fontset != NULL)
+    {
+	/* Setup a clip rectangle to avoid spilling over in the next or
+	 * previous line.  This is apparently needed for some fonts which are
+	 * used in a fontset. */
+	XRectangle	clip;
+
+	clip.x = 0;
+	clip.y = 0;
+	clip.height = gui.char_height;
+	clip.width = gui.char_width * cells + 1;
+	XSetClipRectangles(gui.dpy, gui.text_gc, FILL_X(col), FILL_Y(row),
+		&clip, 1, Unsorted);
+    }
+#endif
+
+    if (flags & DRAW_TRANSP)
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    XDrawString16(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col),
+		    TEXT_Y(row), buf, wlen);
+	else
+#endif
+	    XDrawString(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col),
+		    TEXT_Y(row), (char *)s, len);
+    }
+    else if (p_linespace != 0
+#ifdef FEAT_XFONTSET
+	    || current_fontset != NULL
+#endif
+	    )
+    {
+	XSetForeground(gui.dpy, gui.text_gc, prev_bg_color);
+	XFillRectangle(gui.dpy, gui.wid, gui.text_gc, FILL_X(col),
+		FILL_Y(row), gui.char_width * cells, gui.char_height);
+	XSetForeground(gui.dpy, gui.text_gc, prev_fg_color);
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    XDrawString16(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col),
+		    TEXT_Y(row), buf, wlen);
+	else
+#endif
+	    XDrawString(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col),
+		    TEXT_Y(row), (char *)s, len);
+    }
+    else
+    {
+	/* XmbDrawImageString has bug, don't use it for fontset. */
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    XDrawImageString16(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col),
+		    TEXT_Y(row), buf, wlen);
+	else
+#endif
+	    XDrawImageString(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col),
+		    TEXT_Y(row), (char *)s, len);
+    }
+
+    /* Bold trick: draw the text again with a one-pixel offset. */
+    if (flags & DRAW_BOLD)
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    XDrawString16(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col) + 1,
+		    TEXT_Y(row), buf, wlen);
+	else
+#endif
+	    XDrawString(gui.dpy, gui.wid, gui.text_gc, TEXT_X(col) + 1,
+		    TEXT_Y(row), (char *)s, len);
+    }
+
+    /* Underline: draw a line at the bottom of the character cell. */
+    if (flags & DRAW_UNDERL)
+	XDrawLine(gui.dpy, gui.wid, gui.text_gc, FILL_X(col),
+	     FILL_Y(row + 1) - 1, FILL_X(col + cells) - 1, FILL_Y(row + 1) - 1);
+
+#ifdef FEAT_XFONTSET
+    if (current_fontset != NULL)
+	XSetClipMask(gui.dpy, gui.text_gc, None);
+#endif
+}
+
+/*
+ * Return OK if the key with the termcap name "name" is supported.
+ */
+    int
+gui_mch_haskey(name)
+    char_u  *name;
+{
+    int i;
+
+    for (i = 0; special_keys[i].key_sym != (KeySym)0; i++)
+	if (name[0] == special_keys[i].vim_code0 &&
+					 name[1] == special_keys[i].vim_code1)
+	    return OK;
+    return FAIL;
+}
+
+/*
+ * Return the text window-id and display.  Only required for X-based GUI's
+ */
+    int
+gui_get_x11_windis(win, dis)
+    Window  *win;
+    Display **dis;
+{
+    *win = XtWindow(vimShell);
+    *dis = gui.dpy;
+    return OK;
+}
+
+    void
+gui_mch_beep()
+{
+    XBell(gui.dpy, 0);
+}
+
+    void
+gui_mch_flash(msec)
+    int		msec;
+{
+    /* Do a visual beep by reversing the foreground and background colors */
+    XFillRectangle(gui.dpy, gui.wid, gui.invert_gc, 0, 0,
+	    FILL_X((int)Columns) + gui.border_offset,
+	    FILL_Y((int)Rows) + gui.border_offset);
+    XSync(gui.dpy, False);
+    ui_delay((long)msec, TRUE);	/* wait for a few msec */
+    XFillRectangle(gui.dpy, gui.wid, gui.invert_gc, 0, 0,
+	    FILL_X((int)Columns) + gui.border_offset,
+	    FILL_Y((int)Rows) + gui.border_offset);
+}
+
+/*
+ * Invert a rectangle from row r, column c, for nr rows and nc columns.
+ */
+    void
+gui_mch_invert_rectangle(r, c, nr, nc)
+    int	    r;
+    int	    c;
+    int	    nr;
+    int	    nc;
+{
+    XFillRectangle(gui.dpy, gui.wid, gui.invert_gc,
+	FILL_X(c), FILL_Y(r), (nc) * gui.char_width, (nr) * gui.char_height);
+}
+
+/*
+ * Iconify the GUI window.
+ */
+    void
+gui_mch_iconify()
+{
+    XIconifyWindow(gui.dpy, XtWindow(vimShell), DefaultScreen(gui.dpy));
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Bring the Vim window to the foreground.
+ */
+    void
+gui_mch_set_foreground()
+{
+    XMapRaised(gui.dpy, XtWindow(vimShell));
+}
+#endif
+
+/*
+ * Draw a cursor without focus.
+ */
+    void
+gui_mch_draw_hollow_cursor(color)
+    guicolor_T color;
+{
+    int		w = 1;
+
+#ifdef FEAT_MBYTE
+    if (mb_lefthalve(gui.row, gui.col))
+	w = 2;
+#endif
+    gui_mch_set_fg_color(color);
+    XDrawRectangle(gui.dpy, gui.wid, gui.text_gc, FILL_X(gui.col),
+	    FILL_Y(gui.row), w * gui.char_width - 1, gui.char_height - 1);
+}
+
+/*
+ * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
+ * color "color".
+ */
+    void
+gui_mch_draw_part_cursor(w, h, color)
+    int		w;
+    int		h;
+    guicolor_T	color;
+{
+    gui_mch_set_fg_color(color);
+
+    XFillRectangle(gui.dpy, gui.wid, gui.text_gc,
+#ifdef FEAT_RIGHTLEFT
+	    /* vertical line should be on the right of current point */
+	    CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w :
+#endif
+		FILL_X(gui.col),
+	    FILL_Y(gui.row) + gui.char_height - h,
+	    w, h);
+}
+
+/*
+ * Catch up with any queued X events.  This may put keyboard input into the
+ * input buffer, call resize call-backs, trigger timers etc.  If there is
+ * nothing in the X event queue (& no timers pending), then we return
+ * immediately.
+ */
+    void
+gui_mch_update()
+{
+    XtInputMask mask, desired;
+
+#ifdef ALT_X_INPUT
+    if (suppress_alternate_input)
+	desired = (XtIMXEvent | XtIMTimer);
+    else
+#endif
+	desired = (XtIMAll);
+    while ((mask = XtAppPending(app_context)) && (mask & desired)
+	    && !vim_is_input_buf_full())
+	XtAppProcessEvent(app_context, desired);
+}
+
+/*
+ * GUI input routine called by gui_wait_for_chars().  Waits for a character
+ * from the keyboard.
+ *  wtime == -1	    Wait forever.
+ *  wtime == 0	    This should never happen.
+ *  wtime > 0	    Wait wtime milliseconds for a character.
+ * Returns OK if a character was found to be available within the given time,
+ * or FAIL otherwise.
+ */
+    int
+gui_mch_wait_for_chars(wtime)
+    long    wtime;
+{
+    int		    focus;
+
+    /*
+     * Make this static, in case gui_x11_timer_cb is called after leaving
+     * this function (otherwise a random value on the stack may be changed).
+     */
+    static int	    timed_out;
+    XtIntervalId    timer = (XtIntervalId)0;
+    XtInputMask	    desired;
+#ifdef FEAT_SNIFF
+    static int	    sniff_on = 0;
+    static XtInputId sniff_input_id = 0;
+#endif
+
+    timed_out = FALSE;
+
+#ifdef FEAT_SNIFF
+    if (sniff_on && !want_sniff_request)
+    {
+	if (sniff_input_id)
+	    XtRemoveInput(sniff_input_id);
+	sniff_on = 0;
+    }
+    else if (!sniff_on && want_sniff_request)
+    {
+	sniff_input_id = XtAppAddInput(app_context, fd_from_sniff,
+		     (XtPointer)XtInputReadMask, gui_x11_sniff_request_cb, 0);
+	sniff_on = 1;
+    }
+#endif
+
+    if (wtime > 0)
+	timer = XtAppAddTimeOut(app_context, (long_u)wtime, gui_x11_timer_cb,
+								  &timed_out);
+
+    focus = gui.in_focus;
+#ifdef ALT_X_INPUT
+    if (suppress_alternate_input)
+	desired = (XtIMXEvent | XtIMTimer);
+    else
+#endif
+	desired = (XtIMAll);
+    while (!timed_out)
+    {
+	/* Stop or start blinking when focus changes */
+	if (gui.in_focus != focus)
+	{
+	    if (gui.in_focus)
+		gui_mch_start_blink();
+	    else
+		gui_mch_stop_blink();
+	    focus = gui.in_focus;
+	}
+
+	/*
+	 * Don't use gui_mch_update() because then we will spin-lock until a
+	 * char arrives, instead we use XtAppProcessEvent() to hang until an
+	 * event arrives.  No need to check for input_buf_full because we are
+	 * returning as soon as it contains a single char.  Note that
+	 * XtAppNextEvent() may not be used because it will not return after a
+	 * timer event has arrived -- webb
+	 */
+	XtAppProcessEvent(app_context, desired);
+
+	if (input_available())
+	{
+	    if (timer != (XtIntervalId)0 && !timed_out)
+		XtRemoveTimeOut(timer);
+	    return OK;
+	}
+    }
+    return FAIL;
+}
+
+/*
+ * Output routines.
+ */
+
+/* Flush any output to the screen */
+    void
+gui_mch_flush()
+{
+    XFlush(gui.dpy);
+}
+
+/*
+ * Clear a rectangular region of the screen from text pos (row1, col1) to
+ * (row2, col2) inclusive.
+ */
+    void
+gui_mch_clear_block(row1, col1, row2, col2)
+    int		row1;
+    int		col1;
+    int		row2;
+    int		col2;
+{
+    int		x;
+
+    x = FILL_X(col1);
+
+    /* Clear one extra pixel at the far right, for when bold characters have
+     * spilled over to the next column. */
+    XFillRectangle(gui.dpy, gui.wid, gui.back_gc, x, FILL_Y(row1),
+	    (col2 - col1 + 1) * gui.char_width + (col2 == Columns - 1),
+	    (row2 - row1 + 1) * gui.char_height);
+}
+
+    void
+gui_mch_clear_all()
+{
+    XClearArea(gui.dpy, gui.wid, 0, 0, 0, 0, False);
+}
+
+/*
+ * Delete the given number of lines from the given row, scrolling up any
+ * text further down within the scroll region.
+ */
+    void
+gui_mch_delete_lines(row, num_lines)
+    int	    row;
+    int	    num_lines;
+{
+    if (gui.visibility == VisibilityFullyObscured)
+	return;	    /* Can't see the window */
+
+    /* copy one extra pixel at the far right, for when bold has spilled
+     * over */
+    XCopyArea(gui.dpy, gui.wid, gui.wid, gui.text_gc,
+	FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines),
+	gui.char_width * (gui.scroll_region_right - gui.scroll_region_left + 1)
+			       + (gui.scroll_region_right == Columns - 1),
+	gui.char_height * (gui.scroll_region_bot - row - num_lines + 1),
+	FILL_X(gui.scroll_region_left), FILL_Y(row));
+
+    gui_clear_block(gui.scroll_region_bot - num_lines + 1,
+						       gui.scroll_region_left,
+			  gui.scroll_region_bot, gui.scroll_region_right);
+    gui_x11_check_copy_area();
+}
+
+/*
+ * Insert the given number of lines before the given row, scrolling down any
+ * following text within the scroll region.
+ */
+    void
+gui_mch_insert_lines(row, num_lines)
+    int	    row;
+    int	    num_lines;
+{
+    if (gui.visibility == VisibilityFullyObscured)
+	return;	    /* Can't see the window */
+
+    /* copy one extra pixel at the far right, for when bold has spilled
+     * over */
+    XCopyArea(gui.dpy, gui.wid, gui.wid, gui.text_gc,
+	FILL_X(gui.scroll_region_left), FILL_Y(row),
+	gui.char_width * (gui.scroll_region_right - gui.scroll_region_left + 1)
+			       + (gui.scroll_region_right == Columns - 1),
+	gui.char_height * (gui.scroll_region_bot - row - num_lines + 1),
+	FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines));
+
+    gui_clear_block(row, gui.scroll_region_left,
+				row + num_lines - 1, gui.scroll_region_right);
+    gui_x11_check_copy_area();
+}
+
+/*
+ * Update the region revealed by scrolling up/down.
+ */
+    static void
+gui_x11_check_copy_area()
+{
+    XEvent		    event;
+    XGraphicsExposeEvent    *gevent;
+
+    if (gui.visibility != VisibilityPartiallyObscured)
+	return;
+
+    XFlush(gui.dpy);
+
+    /* Wait to check whether the scroll worked or not */
+    for (;;)
+    {
+	if (XCheckTypedEvent(gui.dpy, NoExpose, &event))
+	    return;	/* The scroll worked. */
+
+	if (XCheckTypedEvent(gui.dpy, GraphicsExpose, &event))
+	{
+	    gevent = (XGraphicsExposeEvent *)&event;
+	    gui_redraw(gevent->x, gevent->y, gevent->width, gevent->height);
+	    if (gevent->count == 0)
+		return;		/* This was the last expose event */
+	}
+	XSync(gui.dpy, False);
+    }
+}
+
+/*
+ * X Selection stuff, for cutting and pasting text to other windows.
+ */
+
+    void
+clip_mch_lose_selection(cbd)
+    VimClipboard	*cbd;
+{
+    clip_x11_lose_selection(vimShell, cbd);
+}
+
+    int
+clip_mch_own_selection(cbd)
+    VimClipboard	*cbd;
+{
+    return clip_x11_own_selection(vimShell, cbd);
+}
+
+    void
+clip_mch_request_selection(cbd)
+    VimClipboard	*cbd;
+{
+    clip_x11_request_selection(vimShell, gui.dpy, cbd);
+}
+
+    void
+clip_mch_set_selection(cbd)
+    VimClipboard	*cbd;
+{
+    clip_x11_set_selection(cbd);
+}
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Menu stuff.
+ */
+
+/*
+ * Make a menu either grey or not grey.
+ */
+    void
+gui_mch_menu_grey(menu, grey)
+    vimmenu_T	*menu;
+    int		grey;
+{
+    if (menu->id != (Widget)0)
+    {
+	gui_mch_menu_hidden(menu, False);
+	if (grey
+#ifdef FEAT_GUI_MOTIF
+		|| !menu->sensitive
+#endif
+		)
+	    XtSetSensitive(menu->id, False);
+	else
+	    XtSetSensitive(menu->id, True);
+    }
+}
+
+/*
+ * Make menu item hidden or not hidden
+ */
+    void
+gui_mch_menu_hidden(menu, hidden)
+    vimmenu_T	*menu;
+    int		hidden;
+{
+    if (menu->id != (Widget)0)
+    {
+	if (hidden)
+	    XtUnmanageChild(menu->id);
+	else
+	    XtManageChild(menu->id);
+    }
+}
+
+/*
+ * This is called after setting all the menus to grey/hidden or not.
+ */
+    void
+gui_mch_draw_menubar()
+{
+    /* Nothing to do in X */
+}
+
+/* ARGSUSED */
+    void
+gui_x11_menu_cb(w, client_data, call_data)
+    Widget	w;
+    XtPointer	client_data, call_data;
+{
+    gui_menu_cb((vimmenu_T *)client_data);
+}
+
+#endif /* FEAT_MENU */
+
+
+
+/*
+ * Function called when window closed.	Works like ":qa".
+ * Should put up a requester!
+ */
+/*ARGSUSED*/
+    static void
+gui_x11_wm_protocol_handler(w, client_data, event, dum)
+    Widget	w;
+    XtPointer	client_data;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    /*
+     * Only deal with Client messages.
+     */
+    if (event->type != ClientMessage)
+	return;
+
+    /*
+     * The WM_SAVE_YOURSELF event arrives when the window manager wants to
+     * exit.  That can be cancelled though, thus Vim shouldn't exit here.
+     * Just sync our swap files.
+     */
+    if (((XClientMessageEvent *)event)->data.l[0] ==
+						  wm_atoms[SAVE_YOURSELF_IDX])
+    {
+	out_flush();
+	ml_sync_all(FALSE, FALSE);	/* preserve all swap files */
+
+	/* Set the window's WM_COMMAND property, to let the window manager
+	 * know we are done saving ourselves.  We don't want to be restarted,
+	 * thus set argv to NULL. */
+	XSetCommand(gui.dpy, XtWindow(vimShell), NULL, 0);
+	return;
+    }
+
+    if (((XClientMessageEvent *)event)->data.l[0] !=
+						  wm_atoms[DELETE_WINDOW_IDX])
+	return;
+
+    gui_shell_closed();
+}
+
+#ifdef FEAT_CLIENTSERVER
+/*
+ * Function called when property changed. Check for incoming commands
+ */
+/*ARGSUSED*/
+    static void
+gui_x11_send_event_handler(w, client_data, event, dum)
+    Widget	w;
+    XtPointer	client_data;
+    XEvent	*event;
+    Boolean	*dum;
+{
+    XPropertyEvent *e = (XPropertyEvent *) event;
+
+    if (e->type == PropertyNotify && e->window == commWindow
+	    && e->atom == commProperty &&  e->state == PropertyNewValue)
+    {
+	serverEventProc(gui.dpy, event);
+    }
+}
+#endif
+
+/*
+ * Cursor blink functions.
+ *
+ * This is a simple state machine:
+ * BLINK_NONE	not blinking at all
+ * BLINK_OFF	blinking, cursor is not shown
+ * BLINK_ON	blinking, cursor is shown
+ */
+
+#define BLINK_NONE  0
+#define BLINK_OFF   1
+#define BLINK_ON    2
+
+static int		blink_state = BLINK_NONE;
+static long_u		blink_waittime = 700;
+static long_u		blink_ontime = 400;
+static long_u		blink_offtime = 250;
+static XtIntervalId	blink_timer = (XtIntervalId)0;
+
+    void
+gui_mch_set_blinking(waittime, on, off)
+    long    waittime, on, off;
+{
+    blink_waittime = waittime;
+    blink_ontime = on;
+    blink_offtime = off;
+}
+
+/*
+ * Stop the cursor blinking.  Show the cursor if it wasn't shown.
+ */
+    void
+gui_mch_stop_blink()
+{
+    if (blink_timer != (XtIntervalId)0)
+    {
+	XtRemoveTimeOut(blink_timer);
+	blink_timer = (XtIntervalId)0;
+    }
+    if (blink_state == BLINK_OFF)
+	gui_update_cursor(TRUE, FALSE);
+    blink_state = BLINK_NONE;
+}
+
+/*
+ * Start the cursor blinking.  If it was already blinking, this restarts the
+ * waiting time and shows the cursor.
+ */
+    void
+gui_mch_start_blink()
+{
+    if (blink_timer != (XtIntervalId)0)
+	XtRemoveTimeOut(blink_timer);
+    /* Only switch blinking on if none of the times is zero */
+    if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
+    {
+	blink_timer = XtAppAddTimeOut(app_context, blink_waittime,
+						      gui_x11_blink_cb, NULL);
+	blink_state = BLINK_ON;
+	gui_update_cursor(TRUE, FALSE);
+    }
+}
+
+/* ARGSUSED */
+    static void
+gui_x11_blink_cb(timed_out, interval_id)
+    XtPointer	    timed_out;
+    XtIntervalId    *interval_id;
+{
+    if (blink_state == BLINK_ON)
+    {
+	gui_undraw_cursor();
+	blink_state = BLINK_OFF;
+	blink_timer = XtAppAddTimeOut(app_context, blink_offtime,
+						      gui_x11_blink_cb, NULL);
+    }
+    else
+    {
+	gui_update_cursor(TRUE, FALSE);
+	blink_state = BLINK_ON;
+	blink_timer = XtAppAddTimeOut(app_context, blink_ontime,
+						      gui_x11_blink_cb, NULL);
+    }
+}
+
+/*
+ * Return the RGB value of a pixel as a long.
+ */
+    long_u
+gui_mch_get_rgb(pixel)
+    guicolor_T	pixel;
+{
+    XColor	xc;
+    Colormap	colormap;
+
+    colormap = DefaultColormap(gui.dpy, XDefaultScreen(gui.dpy));
+    xc.pixel = pixel;
+    XQueryColor(gui.dpy, colormap, &xc);
+
+    return ((xc.red & 0xff00) << 8) + (xc.green & 0xff00)
+						   + ((unsigned)xc.blue >> 8);
+}
+
+/*
+ * Add the callback functions.
+ */
+    void
+gui_x11_callbacks(textArea, vimForm)
+    Widget textArea;
+    Widget vimForm;
+{
+    XtAddEventHandler(textArea, VisibilityChangeMask, FALSE,
+	gui_x11_visibility_cb, (XtPointer)0);
+
+    XtAddEventHandler(textArea, ExposureMask, FALSE, gui_x11_expose_cb,
+	(XtPointer)0);
+
+    XtAddEventHandler(vimShell, StructureNotifyMask, FALSE,
+	gui_x11_resize_window_cb, (XtPointer)0);
+
+    XtAddEventHandler(vimShell, FocusChangeMask, FALSE, gui_x11_focus_change_cb,
+	(XtPointer)0);
+    /*
+     * Only install these enter/leave callbacks when 'p' in 'guioptions'.
+     * Only needed for some window managers.
+     */
+    if (vim_strchr(p_go, GO_POINTER) != NULL)
+    {
+	XtAddEventHandler(vimShell, LeaveWindowMask, FALSE, gui_x11_leave_cb,
+	    (XtPointer)0);
+	XtAddEventHandler(textArea, LeaveWindowMask, FALSE, gui_x11_leave_cb,
+	    (XtPointer)0);
+	XtAddEventHandler(textArea, EnterWindowMask, FALSE, gui_x11_enter_cb,
+	    (XtPointer)0);
+	XtAddEventHandler(vimShell, EnterWindowMask, FALSE, gui_x11_enter_cb,
+	    (XtPointer)0);
+    }
+
+    XtAddEventHandler(vimForm, KeyPressMask, FALSE, gui_x11_key_hit_cb,
+	(XtPointer)0);
+    XtAddEventHandler(textArea, KeyPressMask, FALSE, gui_x11_key_hit_cb,
+	(XtPointer)0);
+
+    /* get pointer moved events from scrollbar, needed for 'mousefocus' */
+    XtAddEventHandler(vimForm, PointerMotionMask,
+	FALSE, gui_x11_mouse_cb, (XtPointer)1);
+    XtAddEventHandler(textArea, ButtonPressMask | ButtonReleaseMask |
+					 ButtonMotionMask | PointerMotionMask,
+	FALSE, gui_x11_mouse_cb, (XtPointer)0);
+}
+
+/*
+ * Get current y mouse coordinate in text window.
+ * Return -1 when unknown.
+ */
+    int
+gui_mch_get_mouse_x()
+{
+    int		rootx, rooty, winx, winy;
+    Window	root, child;
+    unsigned int mask;
+
+    if (gui.wid && XQueryPointer(gui.dpy, gui.wid, &root, &child,
+					 &rootx, &rooty, &winx, &winy, &mask))
+	return winx;
+    return -1;
+}
+
+    int
+gui_mch_get_mouse_y()
+{
+    int		rootx, rooty, winx, winy;
+    Window	root, child;
+    unsigned int mask;
+
+    if (gui.wid && XQueryPointer(gui.dpy, gui.wid, &root, &child,
+					 &rootx, &rooty, &winx, &winy, &mask))
+	return winy;
+    return -1;
+}
+
+    void
+gui_mch_setmouse(x, y)
+    int		x;
+    int		y;
+{
+    if (gui.wid)
+	XWarpPointer(gui.dpy, (Window)0, gui.wid, 0, 0, 0, 0, x, y);
+}
+
+#if (defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU)) || defined(PROTO)
+    XButtonPressedEvent *
+gui_x11_get_last_mouse_event()
+{
+    return &last_mouse_event;
+}
+#endif
+
+#if defined(FEAT_SIGN_ICONS) || defined(PROTO)
+
+/* Signs are currently always 2 chars wide.  Hopefully the font is big enough
+ * to provide room for the bitmap! */
+# define SIGN_WIDTH (gui.char_width * 2)
+
+#if 0	/* not used */
+    void
+gui_mch_clearsign(row)
+    int		row;
+{
+    if (gui.in_use)
+	XClearArea(gui.dpy, gui.wid, 0, TEXT_Y(row) - gui.char_height,
+		SIGN_WIDTH, gui.char_height, FALSE);
+}
+#endif
+
+    void
+gui_mch_drawsign(row, col, typenr)
+    int		row;
+    int		col;
+    int		typenr;
+{
+    XImage	*sign;
+
+    if (gui.in_use && (sign = (XImage *)sign_get_image(typenr)) != NULL)
+    {
+	XClearArea(gui.dpy, gui.wid, TEXT_X(col), TEXT_Y(row) - sign->height,
+		SIGN_WIDTH, gui.char_height, FALSE);
+	XPutImage(gui.dpy, gui.wid, gui.text_gc, sign, 0, 0,
+		TEXT_X(col) + (SIGN_WIDTH - sign->width) / 2,
+		TEXT_Y(row) - sign->height,
+		sign->width, sign->height);
+    }
+}
+
+    void *
+gui_mch_register_sign(signfile)
+    char_u	    *signfile;
+{
+    XpmAttributes   attrs;
+    XImage	    *sign;
+    int		    status;
+
+    /*
+     * Setup the color substitution table.
+     */
+    sign = NULL;
+    if (signfile[0] != NUL && signfile[0] != '-')
+    {
+	sign = (XImage *)alloc(sizeof(XImage));
+	if (sign != NULL)
+	{
+	    XpmColorSymbol color[5] =
+	    {
+		{"none", NULL, 0},
+		{"iconColor1", NULL, 0},
+		{"bottomShadowColor", NULL, 0},
+		{"topShadowColor", NULL, 0},
+		{"selectColor", NULL, 0}
+	    };
+	    attrs.valuemask = XpmColorSymbols;
+	    attrs.numsymbols = 2;
+	    attrs.colorsymbols = color;
+	    attrs.colorsymbols[0].pixel = gui.back_pixel;
+	    attrs.colorsymbols[1].pixel = gui.norm_pixel;
+	    status = XpmReadFileToImage(gui.dpy, (char *)signfile,
+							 &sign, NULL, &attrs);
+
+	    if (status == 0)
+	    {
+		/* Sign width is fixed at two columns now.
+		if (sign->width > gui.sign_width)
+		    gui.sign_width = sign->width + 8; */
+	    }
+	    else
+	    {
+		vim_free(sign);
+		sign = NULL;
+		EMSG(_(e_signdata));
+	    }
+	}
+    }
+
+    return (void *)sign;
+}
+
+    void
+gui_mch_destroy_sign(sign)
+    void *sign;
+{
+    XFree(((XImage *)sign)->data);
+    vim_free(sign);
+}
+#endif
+
+
+#ifdef FEAT_MOUSESHAPE
+/* The last set mouse pointer shape is remembered, to be used when it goes
+ * from hidden to not hidden. */
+static int last_shape = 0;
+#endif
+
+/*
+ * Use the blank mouse pointer or not.
+ */
+    void
+gui_mch_mousehide(hide)
+    int		hide;	/* TRUE = use blank ptr, FALSE = use parent ptr */
+{
+    if (gui.pointer_hidden != hide)
+    {
+	gui.pointer_hidden = hide;
+	if (hide)
+	    XDefineCursor(gui.dpy, gui.wid, gui.blank_pointer);
+	else
+#ifdef FEAT_MOUSESHAPE
+	    mch_set_mouse_shape(last_shape);
+#else
+	    XUndefineCursor(gui.dpy, gui.wid);
+#endif
+    }
+}
+
+#if defined(FEAT_MOUSESHAPE) || defined(PROTO)
+
+/* Table for shape IDs.  Keep in sync with the mshape_names[] table in
+ * misc2.c! */
+static int mshape_ids[] =
+{
+    XC_left_ptr,		/* arrow */
+    0,				/* blank */
+    XC_xterm,			/* beam */
+    XC_sb_v_double_arrow,	/* updown */
+    XC_sizing,			/* udsizing */
+    XC_sb_h_double_arrow,	/* leftright */
+    XC_sizing,			/* lrsizing */
+    XC_watch,			/* busy */
+    XC_X_cursor,		/* no */
+    XC_crosshair,		/* crosshair */
+    XC_hand1,			/* hand1 */
+    XC_hand2,			/* hand2 */
+    XC_pencil,			/* pencil */
+    XC_question_arrow,		/* question */
+    XC_right_ptr,		/* right-arrow */
+    XC_center_ptr,		/* up-arrow */
+    XC_left_ptr			/* last one */
+};
+
+    void
+mch_set_mouse_shape(shape)
+    int	shape;
+{
+    int	    id;
+
+    if (!gui.in_use)
+	return;
+
+    if (shape == MSHAPE_HIDE || gui.pointer_hidden)
+	XDefineCursor(gui.dpy, gui.wid, gui.blank_pointer);
+    else
+    {
+	if (shape >= MSHAPE_NUMBERED)
+	{
+	    id = shape - MSHAPE_NUMBERED;
+	    if (id >= XC_num_glyphs)
+		id = XC_left_ptr;
+	    else
+		id &= ~1;	/* they are always even (why?) */
+	}
+	else
+	    id = mshape_ids[shape];
+
+	XDefineCursor(gui.dpy, gui.wid, XCreateFontCursor(gui.dpy, id));
+    }
+    if (shape != MSHAPE_HIDE)
+	last_shape = shape;
+}
+#endif
+
+#if defined(FEAT_TOOLBAR) || defined(PROTO)
+/*
+ * Icons used by the toolbar code.
+ */
+#include "../pixmaps/tb_new.xpm"
+#include "../pixmaps/tb_open.xpm"
+#include "../pixmaps/tb_close.xpm"
+#include "../pixmaps/tb_save.xpm"
+#include "../pixmaps/tb_print.xpm"
+#include "../pixmaps/tb_cut.xpm"
+#include "../pixmaps/tb_copy.xpm"
+#include "../pixmaps/tb_paste.xpm"
+#include "../pixmaps/tb_find.xpm"
+#include "../pixmaps/tb_find_next.xpm"
+#include "../pixmaps/tb_find_prev.xpm"
+#include "../pixmaps/tb_find_help.xpm"
+#include "../pixmaps/tb_exit.xpm"
+#include "../pixmaps/tb_undo.xpm"
+#include "../pixmaps/tb_redo.xpm"
+#include "../pixmaps/tb_help.xpm"
+#include "../pixmaps/tb_macro.xpm"
+#include "../pixmaps/tb_make.xpm"
+#include "../pixmaps/tb_save_all.xpm"
+#include "../pixmaps/tb_jump.xpm"
+#include "../pixmaps/tb_ctags.xpm"
+#include "../pixmaps/tb_load_session.xpm"
+#include "../pixmaps/tb_save_session.xpm"
+#include "../pixmaps/tb_new_session.xpm"
+#include "../pixmaps/tb_blank.xpm"
+#include "../pixmaps/tb_maximize.xpm"
+#include "../pixmaps/tb_split.xpm"
+#include "../pixmaps/tb_minimize.xpm"
+#include "../pixmaps/tb_shell.xpm"
+#include "../pixmaps/tb_replace.xpm"
+#include "../pixmaps/tb_vsplit.xpm"
+#include "../pixmaps/tb_maxwidth.xpm"
+#include "../pixmaps/tb_minwidth.xpm"
+
+/*
+ * Those are the pixmaps used for the default buttons.
+ */
+static char **(built_in_pixmaps[]) =
+{
+    tb_new_xpm,
+    tb_open_xpm,
+    tb_save_xpm,
+    tb_undo_xpm,
+    tb_redo_xpm,
+    tb_cut_xpm,
+    tb_copy_xpm,
+    tb_paste_xpm,
+    tb_print_xpm,
+    tb_help_xpm,
+    tb_find_xpm,
+    tb_save_all_xpm,
+    tb_save_session_xpm,
+    tb_new_session_xpm,
+    tb_load_session_xpm,
+    tb_macro_xpm,
+    tb_replace_xpm,
+    tb_close_xpm,
+    tb_maximize_xpm,
+    tb_minimize_xpm,
+    tb_split_xpm,
+    tb_shell_xpm,
+    tb_find_prev_xpm,
+    tb_find_next_xpm,
+    tb_find_help_xpm,
+    tb_make_xpm,
+    tb_jump_xpm,
+    tb_ctags_xpm,
+    tb_vsplit_xpm,
+    tb_maxwidth_xpm,
+    tb_minwidth_xpm,
+    tb_exit_xpm
+};
+
+static void createXpmImages __ARGS((char_u *path, char **xpm, Pixmap *sen, Pixmap *insen));
+
+/*
+ * Allocated a pixmap for toolbar menu "menu".
+ * Return in "sen" and "insen".  "insen" can be NULL.
+ */
+    void
+get_toolbar_pixmap(menu, sen, insen)
+    vimmenu_T	*menu;
+    Pixmap	*sen;
+    Pixmap	*insen;
+{
+    char_u	buf[MAXPATHL];		/* buffer storing expanded pathname */
+    char	**xpm = NULL;		/* xpm array */
+
+    buf[0] = NUL;			/* start with NULL path */
+
+    if (menu->iconfile != NULL)
+    {
+	/* Use the "icon="  argument. */
+	gui_find_iconfile(menu->iconfile, buf, "xpm");
+	createXpmImages(buf, NULL, sen, insen);
+
+	/* If it failed, try using the menu name. */
+	if (*sen == (Pixmap)0 && gui_find_bitmap(menu->name, buf, "xpm") == OK)
+	    createXpmImages(buf, NULL, sen, insen);
+	if (*sen != (Pixmap)0)
+	    return;
+    }
+
+    if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL)
+    {
+	if (menu->iconidx >= 0 && menu->iconidx
+		   < (sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0])))
+	    xpm = built_in_pixmaps[menu->iconidx];
+	else
+	    xpm = tb_blank_xpm;
+    }
+
+    if (xpm != NULL || buf[0] != NUL)
+	createXpmImages(buf, xpm, sen, insen);
+}
+
+/* Indices for named colors */
+#define BACKGROUND	0
+#define FOREGROUND	1
+#define BOTTOM_SHADOW	2
+#define TOP_SHADOW	3
+#define HIGHLIGHT	4
+
+/*
+ * Read an Xpm file, doing color substitutions for the foreground and
+ * background colors. If there is an error reading a color xpm file,
+ * drop back and read the monochrome file. If successful, create the
+ * insensitive Pixmap too.
+ */
+    static void
+createXpmImages(path, xpm, sen, insen)
+    char_u	*path;
+    char	**xpm;
+    Pixmap	*sen;
+    Pixmap	*insen;	    /* can be NULL */
+{
+    Window	rootWindow;
+    XpmAttributes attrs;
+    XpmColorSymbol color[5] =
+    {
+	{"none", "none", 0},
+	{"iconColor1", NULL, 0},
+	{"bottomShadowColor", NULL, 0},
+	{"topShadowColor", NULL, 0},
+	{"selectColor", NULL, 0}
+    };
+    int		screenNum;
+    int		status;
+    Pixmap	mask;
+    Pixmap	map;
+
+    gui_mch_get_toolbar_colors(
+	    &color[BACKGROUND].pixel,
+	    &color[FOREGROUND].pixel,
+	    &color[BOTTOM_SHADOW].pixel,
+	    &color[TOP_SHADOW].pixel,
+	    &color[HIGHLIGHT].pixel);
+
+    /* Setup the color subsititution table */
+    attrs.valuemask = XpmColorSymbols;
+    attrs.colorsymbols = color;
+    attrs.numsymbols = 5;
+
+    screenNum = DefaultScreen(gui.dpy);
+    rootWindow = RootWindow(gui.dpy, screenNum);
+
+    /* Create the "sensitive" pixmap */
+    if (xpm != NULL)
+	status = XpmCreatePixmapFromData(gui.dpy, rootWindow, xpm,
+							 &map, &mask, &attrs);
+    else
+	status = XpmReadFileToPixmap(gui.dpy, rootWindow, (char *)path,
+							 &map, &mask, &attrs);
+    if (status == XpmSuccess && map != 0)
+    {
+	XGCValues   gcvalues;
+	GC	    back_gc;
+	GC	    mask_gc;
+
+	/* Need to create new Pixmaps with the mask applied. */
+	gcvalues.foreground = color[BACKGROUND].pixel;
+	back_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues);
+	mask_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues);
+	XSetClipMask(gui.dpy, mask_gc, mask);
+
+	/* Create the "sensitive" pixmap. */
+	*sen = XCreatePixmap(gui.dpy, rootWindow,
+		 attrs.width, attrs.height,
+		 DefaultDepth(gui.dpy, screenNum));
+	XFillRectangle(gui.dpy, *sen, back_gc, 0, 0,
+		attrs.width, attrs.height);
+	XCopyArea(gui.dpy, map, *sen, mask_gc, 0, 0,
+		attrs.width, attrs.height, 0, 0);
+
+#ifdef FEAT_GUI_MOTIF	/* not used for Athena */
+	if (insen != NULL)
+	{
+	    int		x, y;
+	    int		startX;
+
+	    /* Create the "insensitive" pixmap.  It's a copy of the "sensitive"
+	     * pixmap with half the pixels set to the background color. */
+	    *insen = XCreatePixmap(gui.dpy, rootWindow,
+		    attrs.width, attrs.height,
+		    DefaultDepth(gui.dpy, screenNum));
+	    XCopyArea(gui.dpy, *sen, *insen, back_gc, 0, 0,
+		    attrs.width, attrs.height, 0, 0);
+	    for (y = 0; y < attrs.height; y++)
+	    {
+		if (y % 2 == 0)
+		    startX = 0;
+		else
+		    startX = 1;
+		for (x = startX; x < attrs.width; x += 2)
+		    XDrawPoint(gui.dpy, *insen, back_gc, x, y);
+	    }
+
+	}
+#endif
+	XFreeGC(gui.dpy, back_gc);
+	XFreeGC(gui.dpy, mask_gc);
+	XFreePixmap(gui.dpy, map);
+    }
+    else
+    {
+	*sen = 0;
+	if (insen != NULL)
+	    *insen = 0;
+    }
+
+    XpmFreeAttributes(&attrs);
+}
+#endif
+
+#if (defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL)) || defined(PROTO)
+/*
+ * Set the balloon-eval used for the tooltip of a toolbar menu item.
+ * The check for a non-toolbar item was added, because there is a crash when
+ * passing a normal menu item here.  Can't explain that, but better avoid it.
+ */
+    void
+gui_mch_menu_set_tip(menu)
+    vimmenu_T	*menu;
+{
+    if (menu->id != NULL && menu->parent != NULL
+				       && menu_is_toolbar(menu->parent->name))
+    {
+	/* Always destroy and create the balloon, in case the string was
+	 * changed. */
+	if (menu->tip != NULL)
+	{
+	    gui_mch_destroy_beval_area(menu->tip);
+	    menu->tip = NULL;
+	}
+	if (menu->strings[MENU_INDEX_TIP] != NULL)
+	    menu->tip = gui_mch_create_beval_area(
+		    menu->id,
+		    menu->strings[MENU_INDEX_TIP],
+		    NULL,
+		    NULL);
+    }
+}
+#endif
