diff --git a/src/gui_gtk.c b/src/gui_gtk.c
new file mode 100644
index 0000000..0d552c0
--- /dev/null
+++ b/src/gui_gtk.c
@@ -0,0 +1,3035 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *
+ * 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.
+ */
+
+/*
+ * Porting to GTK+ was done by:
+ *
+ * (C) 1998,1999,2000 by Marcin Dalecki <dalecki@evision.ag>
+ *
+ * With GREAT support and continuous encouragements by Andy Kahn and of
+ * course Bram Moolenaar!
+ *
+ * Support for GTK+ 2 was added by:
+ *
+ * (C) 2002,2003  Jason Hildebrand  <jason@peaceworks.ca>
+ *		  Daniel Elstner  <daniel.elstner@gmx.net>
+ *
+ * Best supporting actor (He helped somewhat, aesthetically speaking):
+ * Maxime Romano <verbophobe@hotmail.com>
+ */
+
+#ifdef FEAT_GUI_GTK
+# include "gui_gtk_f.h"
+#endif
+
+/* GTK defines MAX and MIN, but some system header files as well.  Undefine
+ * them and don't use them. */
+#ifdef MIN
+# undef MIN
+#endif
+#ifdef MAX
+# undef MAX
+#endif
+
+#include "vim.h"
+
+#ifdef FEAT_GUI_GNOME
+/* Gnome redefines _() and N_().  Grrr... */
+# ifdef _
+#  undef _
+# endif
+# ifdef N_
+#  undef N_
+# endif
+# ifdef textdomain
+#  undef textdomain
+# endif
+# ifdef bindtextdomain
+#  undef bindtextdomain
+# endif
+# if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
+#  define ENABLE_NLS	/* so the texts in the dialog boxes are translated */
+# endif
+# include <gnome.h>
+#endif
+
+#if defined(FEAT_GUI_DIALOG) && !defined(HAVE_GTK2)
+# include "../pixmaps/alert.xpm"
+# include "../pixmaps/error.xpm"
+# include "../pixmaps/generic.xpm"
+# include "../pixmaps/info.xpm"
+# include "../pixmaps/quest.xpm"
+#endif
+
+#if defined(FEAT_TOOLBAR) && !defined(HAVE_GTK2)
+/*
+ * 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"
+#endif /* FEAT_TOOLBAR && !HAVE_GTK2 */
+
+#ifdef FEAT_GUI_GTK
+# include <gdk/gdkkeysyms.h>
+# include <gdk/gdk.h>
+# ifdef WIN3264
+#  include <gdk/gdkwin32.h>
+# else
+#  include <gdk/gdkx.h>
+# endif
+
+# include <gtk/gtk.h>
+#else
+/* define these items to be able to generate prototypes without GTK */
+typedef int GtkWidget;
+# define gpointer int
+# define guint8 int
+# define GdkPixmap int
+# define GdkBitmap int
+# define GtkIconFactory int
+# define GtkToolbar int
+# define GtkAdjustment int
+# define gboolean int
+# define GdkEventKey int
+# define CancelData int
+#endif
+
+#ifdef HAVE_GTK2
+/*
+ * Convenience macros to convert from 'encoding' to 'termencoding' and
+ * vice versa.	If no conversion is necessary the passed-in pointer is
+ * returned as is, without allocating any memory.  Thus additional _FREE()
+ * macros are provided.  The _FREE() macros also set the pointer to NULL,
+ * in order to avoid bugs due to illegal memory access only happening if
+ * 'encoding' != utf-8...
+ *
+ * Defining these macros as pure expressions looks a bit tricky but
+ * avoids depending on the context of the macro expansion.  One of the
+ * rare occasions where the comma operator comes in handy :)
+ *
+ * Note: Do NOT keep the result around when handling control back to
+ * the main Vim!  The user could change 'encoding' at any time.
+ */
+# define CONVERT_TO_UTF8(String)				\
+    ((output_conv.vc_type == CONV_NONE || (String) == NULL)	\
+	    ? (String)						\
+	    : string_convert(&output_conv, (String), NULL))
+
+# define CONVERT_TO_UTF8_FREE(String)				\
+    ((String) = ((output_conv.vc_type == CONV_NONE)		\
+			? (char_u *)NULL			\
+			: (vim_free(String), (char_u *)NULL)))
+
+# define CONVERT_FROM_UTF8(String)				\
+    ((input_conv.vc_type == CONV_NONE || (String) == NULL)	\
+	    ? (String)						\
+	    : string_convert(&input_conv, (String), NULL))
+
+# define CONVERT_FROM_UTF8_FREE(String)				\
+    ((String) = ((input_conv.vc_type == CONV_NONE)		\
+			? (char_u *)NULL			\
+			: (vim_free(String), (char_u *)NULL)))
+
+#endif /* HAVE_GTK2 */
+
+static void entry_activate_cb(GtkWidget *widget, gpointer data);
+static void entry_changed_cb(GtkWidget *entry, GtkWidget *dialog);
+static void find_replace_cb(GtkWidget *widget, gpointer data);
+
+#if defined(FEAT_TOOLBAR) && defined(HAVE_GTK2)
+/*
+ * Table from BuiltIn## icon indices to GTK+ stock IDs.  Order must exactly
+ * match toolbar_names[] in menu.c!  All stock icons including the "vim-*"
+ * ones can be overridden in your gtkrc file.
+ */
+static const char * const menu_stock_ids[] =
+{
+    /* 00 */ GTK_STOCK_NEW,
+    /* 01 */ GTK_STOCK_OPEN,
+    /* 02 */ GTK_STOCK_SAVE,
+    /* 03 */ GTK_STOCK_UNDO,
+    /* 04 */ GTK_STOCK_REDO,
+    /* 05 */ GTK_STOCK_CUT,
+    /* 06 */ GTK_STOCK_COPY,
+    /* 07 */ GTK_STOCK_PASTE,
+    /* 08 */ GTK_STOCK_PRINT,
+    /* 09 */ GTK_STOCK_HELP,
+    /* 10 */ GTK_STOCK_FIND,
+    /* 11 */ "vim-save-all",
+    /* 12 */ "vim-session-save",
+    /* 13 */ "vim-session-new",
+    /* 14 */ "vim-session-load",
+    /* 15 */ GTK_STOCK_EXECUTE,
+    /* 16 */ GTK_STOCK_FIND_AND_REPLACE,
+    /* 17 */ GTK_STOCK_CLOSE,		/* FIXME: fuzzy */
+    /* 18 */ "vim-window-maximize",
+    /* 19 */ "vim-window-minimize",
+    /* 20 */ "vim-window-split",
+    /* 21 */ "vim-shell",
+    /* 22 */ GTK_STOCK_GO_BACK,
+    /* 23 */ GTK_STOCK_GO_FORWARD,
+    /* 24 */ "vim-find-help",
+    /* 25 */ GTK_STOCK_CONVERT,
+    /* 26 */ GTK_STOCK_JUMP_TO,
+    /* 27 */ "vim-build-tags",
+    /* 28 */ "vim-window-split-vertical",
+    /* 29 */ "vim-window-maximize-width",
+    /* 30 */ "vim-window-minimize-width",
+    /* 31 */ GTK_STOCK_QUIT
+};
+
+    static void
+add_stock_icon(GtkIconFactory	*factory,
+	       const char	*stock_id,
+	       const guint8	*inline_data,
+	       int		data_length)
+{
+    GdkPixbuf	*pixbuf;
+    GtkIconSet	*icon_set;
+
+    pixbuf = gdk_pixbuf_new_from_inline(data_length, inline_data, FALSE, NULL);
+    icon_set = gtk_icon_set_new_from_pixbuf(pixbuf);
+
+    gtk_icon_factory_add(factory, stock_id, icon_set);
+
+    gtk_icon_set_unref(icon_set);
+    g_object_unref(pixbuf);
+}
+
+    static int
+lookup_menu_iconfile(char_u *iconfile, char_u *dest)
+{
+    expand_env(iconfile, dest, MAXPATHL);
+
+    if (mch_isFullName(dest))
+    {
+	return vim_fexists(dest);
+    }
+    else
+    {
+	static const char   suffixes[][4] = {"png", "xpm", "bmp"};
+	char_u		    buf[MAXPATHL];
+	unsigned int	    i;
+
+	for (i = 0; i < G_N_ELEMENTS(suffixes); ++i)
+	    if (gui_find_bitmap(dest, buf, (char *)suffixes[i]) == OK)
+	    {
+		STRCPY(dest, buf);
+		return TRUE;
+	    }
+
+	return FALSE;
+    }
+}
+
+    static GtkWidget *
+load_menu_iconfile(char_u *name, GtkIconSize icon_size)
+{
+    GtkWidget	    *image = NULL;
+    GtkIconSet	    *icon_set;
+    GtkIconSource   *icon_source;
+
+    /*
+     * Rather than loading the icon directly into a GtkImage, create
+     * a new GtkIconSet and put it in there.  This way we can easily
+     * scale the toolbar icons on the fly when needed.
+     */
+    icon_set = gtk_icon_set_new();
+    icon_source = gtk_icon_source_new();
+
+    gtk_icon_source_set_filename(icon_source, (const char *)name);
+    gtk_icon_set_add_source(icon_set, icon_source);
+
+    image = gtk_image_new_from_icon_set(icon_set, icon_size);
+
+    gtk_icon_source_free(icon_source);
+    gtk_icon_set_unref(icon_set);
+
+    return image;
+}
+
+    static GtkWidget *
+create_menu_icon(vimmenu_T *menu, GtkIconSize icon_size)
+{
+    GtkWidget	*image = NULL;
+    char_u	buf[MAXPATHL];
+
+    /* First use a specified "icon=" argument. */
+    if (menu->iconfile != NULL && lookup_menu_iconfile(menu->iconfile, buf))
+	image = load_menu_iconfile(buf, icon_size);
+
+    /* If not found and not builtin specified try using the menu name. */
+    if (image == NULL && !menu->icon_builtin
+				     && lookup_menu_iconfile(menu->name, buf))
+	image = load_menu_iconfile(buf, icon_size);
+
+    /* Still not found?  Then use a builtin icon, a blank one as fallback. */
+    if (image == NULL)
+    {
+	const char  *stock_id;
+	const int   n_ids = G_N_ELEMENTS(menu_stock_ids);
+
+	if (menu->iconidx >= 0 && menu->iconidx < n_ids)
+	    stock_id = menu_stock_ids[menu->iconidx];
+	else
+	    stock_id = GTK_STOCK_MISSING_IMAGE;
+
+	image = gtk_image_new_from_stock(stock_id, icon_size);
+    }
+
+    return image;
+}
+
+#endif /* FEAT_TOOLBAR && HAVE_GTK2 */
+
+#if (defined(FEAT_TOOLBAR) && defined(HAVE_GTK2)) || defined(PROTO)
+
+    void
+gui_gtk_register_stock_icons(void)
+{
+#   include "../pixmaps/stock_icons.h"
+    GtkIconFactory *factory;
+
+    factory = gtk_icon_factory_new();
+#   define ADD_ICON(Name, Data) add_stock_icon(factory, Name, Data, (int)sizeof(Data))
+
+    ADD_ICON("vim-build-tags",		  stock_vim_build_tags);
+    ADD_ICON("vim-find-help",		  stock_vim_find_help);
+    ADD_ICON("vim-save-all",		  stock_vim_save_all);
+    ADD_ICON("vim-session-load",	  stock_vim_session_load);
+    ADD_ICON("vim-session-new",		  stock_vim_session_new);
+    ADD_ICON("vim-session-save",	  stock_vim_session_save);
+    ADD_ICON("vim-shell",		  stock_vim_shell);
+    ADD_ICON("vim-window-maximize",	  stock_vim_window_maximize);
+    ADD_ICON("vim-window-maximize-width", stock_vim_window_maximize_width);
+    ADD_ICON("vim-window-minimize",	  stock_vim_window_minimize);
+    ADD_ICON("vim-window-minimize-width", stock_vim_window_minimize_width);
+    ADD_ICON("vim-window-split",	  stock_vim_window_split);
+    ADD_ICON("vim-window-split-vertical", stock_vim_window_split_vertical);
+
+#   undef ADD_ICON
+    gtk_icon_factory_add_default(factory);
+    g_object_unref(factory);
+}
+
+#endif /* FEAT_TOOLBAR && HAVE_GTK2 */
+
+
+/*
+ * Only use accelerators when gtk_menu_ensure_uline_accel_group() is
+ * available, which is in version 1.2.1.  That was the first version where
+ * accelerators properly worked (according to the change log).
+ */
+#ifdef GTK_CHECK_VERSION
+# if GTK_CHECK_VERSION(1, 2, 1)
+#  define GTK_USE_ACCEL
+# endif
+#endif
+
+#if defined(FEAT_MENU) || defined(PROTO)
+
+/*
+ * Translate Vim's mnemonic tagging to GTK+ style and convert to UTF-8
+ * if necessary.  The caller must vim_free() the returned string.
+ *
+ *	Input	Output
+ *	_	__
+ *	&&	&
+ *	&	_	stripped if use_mnemonic == FALSE
+ *	<Tab>		end of menu label text
+ */
+    static char_u *
+translate_mnemonic_tag(char_u *name, int use_mnemonic)
+{
+    char_u  *buf;
+    char_u  *psrc;
+    char_u  *pdest;
+    int	    n_underscores = 0;
+
+# ifdef HAVE_GTK2
+    name = CONVERT_TO_UTF8(name);
+# endif
+    if (name == NULL)
+	return NULL;
+
+    for (psrc = name; *psrc != NUL && *psrc != TAB; ++psrc)
+	if (*psrc == '_')
+	    ++n_underscores;
+
+    buf = alloc((unsigned)(psrc - name + n_underscores + 1));
+    if (buf != NULL)
+    {
+	pdest = buf;
+	for (psrc = name; *psrc != NUL && *psrc != TAB; ++psrc)
+	{
+	    if (*psrc == '_')
+	    {
+		*pdest++ = '_';
+		*pdest++ = '_';
+	    }
+	    else if (*psrc != '&')
+	    {
+		*pdest++ = *psrc;
+	    }
+	    else if (*(psrc + 1) == '&')
+	    {
+		*pdest++ = *psrc++;
+	    }
+	    else if (use_mnemonic)
+	    {
+		*pdest++ = '_';
+	    }
+	}
+	*pdest = NUL;
+    }
+
+# ifdef HAVE_GTK2
+    CONVERT_TO_UTF8_FREE(name);
+# endif
+    return buf;
+}
+
+# ifdef HAVE_GTK2
+
+    static void
+menu_item_new(vimmenu_T *menu, GtkWidget *parent_widget)
+{
+    GtkWidget	*box;
+    char_u	*text;
+    int		use_mnemonic;
+
+    /* It would be neat to have image menu items, but that would require major
+     * changes to Vim's menu system.  Not to mention that all the translations
+     * had to be updated. */
+    menu->id = gtk_menu_item_new();
+    box = gtk_hbox_new(FALSE, 20);
+
+    use_mnemonic = (p_wak[0] != 'n' || !GTK_IS_MENU_BAR(parent_widget));
+    text = translate_mnemonic_tag(menu->name, use_mnemonic);
+
+    menu->label = gtk_label_new_with_mnemonic((const char *)text);
+    vim_free(text);
+
+    gtk_box_pack_start(GTK_BOX(box), menu->label, FALSE, FALSE, 0);
+
+    if (menu->actext != NULL && menu->actext[0] != NUL)
+    {
+	text = CONVERT_TO_UTF8(menu->actext);
+
+	gtk_box_pack_end(GTK_BOX(box),
+			 gtk_label_new((const char *)text),
+			 FALSE, FALSE, 0);
+
+	CONVERT_TO_UTF8_FREE(text);
+    }
+
+    gtk_container_add(GTK_CONTAINER(menu->id), box);
+    gtk_widget_show_all(menu->id);
+}
+
+# else /* !HAVE_GTK2 */
+
+/*
+ * Create a highly customized menu item by hand instead of by using:
+ *
+ * gtk_menu_item_new_with_label(menu->dname);
+ *
+ * This is neccessary, since there is no other way in GTK+ 1 to get the
+ * not automatically parsed accellerator stuff right.
+ */
+    static void
+menu_item_new(vimmenu_T *menu, GtkWidget *parent_widget)
+{
+    GtkWidget	*widget;
+    GtkWidget	*bin;
+    GtkWidget	*label;
+    char_u	*name;
+    guint	accel_key;
+
+    widget = gtk_widget_new(GTK_TYPE_MENU_ITEM,
+			    "GtkWidget::visible", TRUE,
+			    "GtkWidget::sensitive", TRUE,
+			    /* "GtkWidget::parent", parent->submenu_id, */
+			    NULL);
+    bin = gtk_widget_new(GTK_TYPE_HBOX,
+			 "GtkWidget::visible", TRUE,
+			 "GtkWidget::parent", widget,
+			 "GtkBox::spacing", 16,
+			 NULL);
+    label = gtk_widget_new(GTK_TYPE_ACCEL_LABEL,
+			   "GtkWidget::visible", TRUE,
+			   "GtkWidget::parent", bin,
+			   "GtkAccelLabel::accel_widget", widget,
+			   "GtkMisc::xalign", 0.0,
+			   NULL);
+    menu->label = label;
+
+    if (menu->actext)
+	gtk_widget_new(GTK_TYPE_LABEL,
+		       "GtkWidget::visible", TRUE,
+		       "GtkWidget::parent", bin,
+		       "GtkLabel::label", menu->actext,
+		       "GtkMisc::xalign", 1.0,
+			NULL);
+
+    /*
+     * Translate VIM accelerator tagging into GTK+'s.  Note that since GTK uses
+     * underscores as the accelerator key, we need to add an additional under-
+     * score for each understore that appears in the menu name.
+     */
+#  ifdef GTK_USE_ACCEL
+    name = translate_mnemonic_tag(menu->name,
+		(p_wak[0] != 'n' || !GTK_IS_MENU_BAR(parent_widget)));
+#  else
+    name = translate_mnemonic_tag(menu->name, FALSE);
+#  endif
+
+    /* let GTK do its thing */
+    accel_key = gtk_label_parse_uline(GTK_LABEL(label), (const char *)name);
+    vim_free(name);
+
+#  ifdef GTK_USE_ACCEL
+    /* Don't add accelator if 'winaltkeys' is "no". */
+    if (accel_key != GDK_VoidSymbol)
+    {
+	if (GTK_IS_MENU_BAR(parent_widget))
+	{
+	    if (*p_wak != 'n')
+		gtk_widget_add_accelerator(widget,
+			"activate_item",
+			gui.accel_group,
+			accel_key, GDK_MOD1_MASK,
+			(GtkAccelFlags)0);
+	}
+	else
+	{
+	    gtk_widget_add_accelerator(widget,
+		    "activate_item",
+		    gtk_menu_ensure_uline_accel_group(GTK_MENU(parent_widget)),
+		    accel_key, 0,
+		    (GtkAccelFlags)0);
+	}
+    }
+#  endif /* GTK_USE_ACCEL */
+
+    menu->id = widget;
+}
+
+# endif /* !HAVE_GTK2 */
+
+    void
+gui_mch_add_menu(vimmenu_T *menu, int idx)
+{
+    vimmenu_T	*parent;
+    GtkWidget	*parent_widget;
+
+    if (menu->name[0] == ']' || menu_is_popup(menu->name))
+    {
+	menu->submenu_id = gtk_menu_new();
+	return;
+    }
+
+    parent = menu->parent;
+
+    if ((parent != NULL && parent->submenu_id == NULL)
+	    || !menu_is_menubar(menu->name))
+	return;
+
+    parent_widget = (parent != NULL) ? parent->submenu_id : gui.menubar;
+    menu_item_new(menu, parent_widget);
+
+    /* since the tearoff should always appear first, increment idx */
+    if (parent != NULL && !menu_is_popup(parent->name))
+	++idx;
+
+    gtk_menu_shell_insert(GTK_MENU_SHELL(parent_widget), menu->id, idx);
+
+#ifndef HAVE_GTK2
+    /*
+     * The "Help" menu is a special case, and should be placed at the far
+     * right hand side of the menu-bar.  It's detected by its high priority.
+     *
+     * Right-aligning "Help" is considered bad UI design nowadays.
+     * Thus lets disable this for GTK+ 2 to match the environment.
+     */
+    if (parent == NULL && menu->priority >= 9999)
+	gtk_menu_item_right_justify(GTK_MENU_ITEM(menu->id));
+#endif
+
+    menu->submenu_id = gtk_menu_new();
+
+    gtk_menu_set_accel_group(GTK_MENU(menu->submenu_id), gui.accel_group);
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu->id), menu->submenu_id);
+
+    menu->tearoff_handle = gtk_tearoff_menu_item_new();
+    if (vim_strchr(p_go, GO_TEAROFF) != NULL)
+	gtk_widget_show(menu->tearoff_handle);
+    gtk_menu_prepend(GTK_MENU(menu->submenu_id), menu->tearoff_handle);
+}
+
+/*ARGSUSED*/
+    static void
+menu_item_activate(GtkWidget *widget, gpointer data)
+{
+    gui_menu_cb((vimmenu_T *)data);
+
+# ifndef HAVE_GTK2
+    /* Work around a bug in GTK+ 1: we don't seem to get a focus-in
+     * event after clicking a menu item shown via :popup. */
+    if (!gui.in_focus)
+	gui_focus_change(TRUE);
+# endif
+
+    /* make sure the menu action is taken immediately */
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+# if defined(FEAT_TOOLBAR) && !defined(HAVE_GTK2)
+/*
+ * These are the pixmaps used for the default buttons.
+ * Order must exactly match toolbar_names[] in menu.c!
+ */
+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
+};
+
+/*
+ * creates a blank pixmap using tb_blank
+ */
+    static void
+pixmap_create_from_xpm(char **xpm, GdkPixmap **pixmap, GdkBitmap **mask)
+{
+    *pixmap = gdk_pixmap_colormap_create_from_xpm_d(
+	    NULL,
+	    gtk_widget_get_colormap(gui.mainwin),
+	    mask,
+	    NULL,
+	    xpm);
+}
+
+/*
+ * creates a pixmap by using a built-in number
+ */
+    static void
+pixmap_create_by_num(int pixmap_num, GdkPixmap **pixmap, GdkBitmap **mask)
+{
+    if (pixmap_num >= 0 && pixmap_num < (sizeof(built_in_pixmaps)
+					    / sizeof(built_in_pixmaps[0])))
+	pixmap_create_from_xpm(built_in_pixmaps[pixmap_num], pixmap, mask);
+}
+
+/*
+ * Creates a pixmap by using the pixmap "name" found in 'runtimepath'/bitmaps/
+ */
+    static void
+pixmap_create_by_dir(char_u *name, GdkPixmap **pixmap, GdkBitmap **mask)
+{
+    char_u full_pathname[MAXPATHL + 1];
+
+    if (gui_find_bitmap(name, full_pathname, "xpm") == OK)
+	*pixmap = gdk_pixmap_colormap_create_from_xpm(
+		NULL,
+		gtk_widget_get_colormap(gui.mainwin),
+		mask,
+		&gui.mainwin->style->bg[GTK_STATE_NORMAL],
+		(const char *)full_pathname);
+}
+
+/*
+ * Creates a pixmap by using the pixmap "fname".
+ */
+    static void
+pixmap_create_from_file(char_u *fname, GdkPixmap **pixmap, GdkBitmap **mask)
+{
+    *pixmap = gdk_pixmap_colormap_create_from_xpm(
+		NULL,
+		gtk_widget_get_colormap(gui.mainwin),
+		mask,
+		&gui.mainwin->style->bg[GTK_STATE_NORMAL],
+		(const char *)fname);
+}
+
+# endif /* FEAT_TOOLBAR && !HAVE_GTK2 */
+
+    void
+gui_mch_add_menu_item(vimmenu_T *menu, int idx)
+{
+    vimmenu_T *parent;
+
+    parent = menu->parent;
+
+# ifdef FEAT_TOOLBAR
+    if (menu_is_toolbar(parent->name))
+    {
+	GtkToolbar *toolbar;
+
+	toolbar = GTK_TOOLBAR(gui.toolbar);
+	menu->submenu_id = NULL;
+
+	if (menu_is_separator(menu->name))
+	{
+	    gtk_toolbar_insert_space(toolbar, idx);
+	    menu->id = NULL;
+	}
+	else
+	{
+#  ifdef HAVE_GTK2
+	    char_u *text;
+	    char_u *tooltip;
+
+	    text    = CONVERT_TO_UTF8(menu->dname);
+	    tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
+
+	    menu->id = gtk_toolbar_insert_item(
+		    toolbar,
+		    (const char *)text,
+		    (const char *)tooltip,
+		    NULL,
+		    create_menu_icon(menu, gtk_toolbar_get_icon_size(toolbar)),
+		    G_CALLBACK(&menu_item_activate),
+		    menu,
+		    idx);
+
+	    CONVERT_TO_UTF8_FREE(text);
+	    CONVERT_TO_UTF8_FREE(tooltip);
+
+#  else /* !HAVE_GTK2 */
+
+	    GdkPixmap *pixmap = NULL;
+	    GdkBitmap *mask = NULL;
+
+	    /* First try user specified bitmap, then builtin, the a blank. */
+	    if (menu->iconfile != NULL)
+	    {
+		char_u buf[MAXPATHL + 1];
+
+		gui_find_iconfile(menu->iconfile, buf, "xpm");
+		pixmap_create_from_file(buf, &pixmap, &mask);
+	    }
+	    if (pixmap == NULL && !menu->icon_builtin)
+		pixmap_create_by_dir(menu->name, &pixmap, &mask);
+	    if (pixmap == NULL && menu->iconidx >= 0)
+		pixmap_create_by_num(menu->iconidx, &pixmap, &mask);
+	    if (pixmap == NULL)
+		pixmap_create_from_xpm(tb_blank_xpm, &pixmap, &mask);
+	    if (pixmap == NULL)
+		return; /* should at least have blank pixmap, but if not... */
+
+	    menu->id = gtk_toolbar_insert_item(
+				    toolbar,
+				    (char *)(menu->dname),
+				    (char *)(menu->strings[MENU_INDEX_TIP]),
+				    (char *)(menu->dname),
+				    gtk_pixmap_new(pixmap, mask),
+				    GTK_SIGNAL_FUNC(menu_item_activate),
+				    (gpointer)menu,
+				    idx);
+#  endif /* !HAVE_GTK2 */
+	}
+    }
+    else
+# endif /* FEAT_TOOLBAR */
+    {
+	/* No parent, must be a non-menubar menu */
+	if (parent->submenu_id == NULL)
+	    return;
+
+	/* Make place for the possible tearoff handle item.  Not in the popup
+	 * menu, it doesn't have a tearoff item. */
+	if (parent != NULL && !menu_is_popup(parent->name))
+	    ++idx;
+
+	if (menu_is_separator(menu->name))
+	{
+	    /* Separator: Just add it */
+	    menu->id = gtk_menu_item_new();
+	    gtk_widget_set_sensitive(menu->id, FALSE);
+	    gtk_widget_show(menu->id);
+	    gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx);
+
+	    return;
+	}
+
+	/* Add textual menu item. */
+	menu_item_new(menu, parent->submenu_id);
+	gtk_widget_show(menu->id);
+	gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx);
+
+	if (menu->id != NULL)
+	    gtk_signal_connect(GTK_OBJECT(menu->id), "activate",
+			       GTK_SIGNAL_FUNC(menu_item_activate), menu);
+    }
+}
+#endif /* FEAT_MENU */
+
+
+    void
+gui_mch_set_text_area_pos(int x, int y, int w, int h)
+{
+    gtk_form_move_resize(GTK_FORM(gui.formwin), gui.drawarea, x, y, w, h);
+}
+
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Enable or disable accelators for the toplevel menus.
+ */
+    void
+gui_gtk_set_mnemonics(int enable)
+{
+    vimmenu_T	*menu;
+    char_u	*name;
+# if !defined(HAVE_GTK2) && defined(GTK_USE_ACCEL)
+    guint	accel_key;
+# endif
+
+    for (menu = root_menu; menu != NULL; menu = menu->next)
+    {
+	if (menu->id == NULL)
+	    continue;
+
+# if defined(HAVE_GTK2)
+	name = translate_mnemonic_tag(menu->name, enable);
+	gtk_label_set_text_with_mnemonic(GTK_LABEL(menu->label),
+					 (const char *)name);
+	vim_free(name);
+# elif defined(GTK_USE_ACCEL)
+	name = translate_mnemonic_tag(menu->name, TRUE);
+	if (name != NULL)
+	{
+	    accel_key = gtk_label_parse_uline(GTK_LABEL(menu->label),
+					      (const char *)name);
+	    if (accel_key != GDK_VoidSymbol)
+		gtk_widget_remove_accelerator(menu->id, gui.accel_group,
+					      accel_key, GDK_MOD1_MASK);
+	    if (enable && accel_key != GDK_VoidSymbol)
+		gtk_widget_add_accelerator(menu->id, "activate_item",
+					   gui.accel_group,
+					   accel_key, GDK_MOD1_MASK,
+					   (GtkAccelFlags)0);
+	    vim_free(name);
+	}
+	if (!enable)
+	{
+	    name = translate_mnemonic_tag(menu->name, FALSE);
+	    gtk_label_parse_uline(GTK_LABEL(menu->label), (const char *)name);
+	    vim_free(name);
+	}
+# endif
+    }
+}
+
+    static void
+recurse_tearoffs(vimmenu_T *menu, int val)
+{
+    for (; menu != NULL; menu = menu->next)
+    {
+	if (menu->submenu_id != NULL && menu->tearoff_handle != NULL
+		&& menu->name[0] != ']' && !menu_is_popup(menu->name))
+	{
+	    if (val)
+		gtk_widget_show(menu->tearoff_handle);
+	    else
+		gtk_widget_hide(menu->tearoff_handle);
+	}
+	recurse_tearoffs(menu->children, val);
+    }
+}
+
+    void
+gui_mch_toggle_tearoffs(int enable)
+{
+    recurse_tearoffs(root_menu, enable);
+}
+#endif /* FEAT_MENU */
+
+
+#if defined(FEAT_TOOLBAR) && !defined(HAVE_GTK2)
+/*
+ * Seems like there's a hole in the GTK Toolbar API: there's no provision for
+ * removing an item from the toolbar.  Therefore I need to resort to going
+ * really deeply into the internal widget structures.
+ *
+ * <danielk> I'm not sure the statement above is true -- at least with
+ * GTK+ 2 one can just call gtk_widget_destroy() and be done with it.
+ * It is true though that you couldn't remove space items before GTK+ 2
+ * (without digging into the internals that is).  But the code below
+ * doesn't seem to handle those either.  Well, it's obsolete anyway.
+ */
+    static void
+toolbar_remove_item_by_text(GtkToolbar *tb, const char *text)
+{
+    GtkContainer *container;
+    GList *childl;
+    GtkToolbarChild *gtbc;
+
+    g_return_if_fail(tb != NULL);
+    g_return_if_fail(GTK_IS_TOOLBAR(tb));
+    container = GTK_CONTAINER(&tb->container);
+
+    for (childl = tb->children; childl; childl = childl->next)
+    {
+	gtbc = (GtkToolbarChild *)childl->data;
+
+	if (gtbc->type != GTK_TOOLBAR_CHILD_SPACE
+		&& strcmp(GTK_LABEL(gtbc->label)->label, text) == 0)
+	{
+	    gboolean was_visible;
+
+	    was_visible = GTK_WIDGET_VISIBLE(gtbc->widget);
+	    gtk_widget_unparent(gtbc->widget);
+
+	    tb->children = g_list_remove_link(tb->children, childl);
+	    g_free(gtbc);
+	    g_list_free(childl);
+	    tb->num_children--;
+
+	    if (was_visible && GTK_WIDGET_VISIBLE(container))
+		gtk_widget_queue_resize(GTK_WIDGET(container));
+
+	    break;
+	}
+    }
+}
+#endif /* FEAT_TOOLBAR && !HAVE_GTK2 */
+
+
+#if defined(FEAT_TOOLBAR) && defined(HAVE_GTK2)
+    static int
+get_menu_position(vimmenu_T *menu)
+{
+    vimmenu_T	*node;
+    int		index = 0;
+
+    for (node = menu->parent->children; node != menu; node = node->next)
+    {
+	g_return_val_if_fail(node != NULL, -1);
+	++index;
+    }
+
+    return index;
+}
+#endif /* FEAT_TOOLBAR && HAVE_GTK2 */
+
+
+#if defined(FEAT_TOOLBAR) || defined(PROTO)
+    void
+gui_mch_menu_set_tip(vimmenu_T *menu)
+{
+    if (menu->id != NULL && menu->parent != NULL
+	    && gui.toolbar != NULL && menu_is_toolbar(menu->parent->name))
+    {
+	char_u *tooltip;
+
+# ifdef HAVE_GTK2
+	tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
+# else
+	tooltip = menu->strings[MENU_INDEX_TIP];
+# endif
+	gtk_tooltips_set_tip(GTK_TOOLBAR(gui.toolbar)->tooltips,
+			     menu->id, (const char *)tooltip, NULL);
+# ifdef HAVE_GTK2
+	CONVERT_TO_UTF8_FREE(tooltip);
+# endif
+    }
+}
+#endif /* FEAT_TOOLBAR */
+
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Destroy the machine specific menu widget.
+ */
+    void
+gui_mch_destroy_menu(vimmenu_T *menu)
+{
+# ifdef FEAT_TOOLBAR
+    if (menu->parent != NULL && menu_is_toolbar(menu->parent->name))
+    {
+#  ifdef HAVE_GTK2
+	if (menu_is_separator(menu->name))
+	    gtk_toolbar_remove_space(GTK_TOOLBAR(gui.toolbar),
+				     get_menu_position(menu));
+	else if (menu->id != NULL)
+	    gtk_widget_destroy(menu->id);
+#  else
+	toolbar_remove_item_by_text(GTK_TOOLBAR(gui.toolbar),
+				    (const char *)menu->dname);
+#  endif
+    }
+    else
+# endif /* FEAT_TOOLBAR */
+    {
+	if (menu->submenu_id != NULL)
+	    gtk_widget_destroy(menu->submenu_id);
+
+	if (menu->id != NULL)
+	    gtk_widget_destroy(menu->id);
+    }
+
+    menu->submenu_id = NULL;
+    menu->id = NULL;
+}
+#endif /* FEAT_MENU */
+
+
+/*
+ * Scrollbar stuff.
+ */
+    void
+gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
+{
+    if (sb->id != NULL)
+    {
+	GtkAdjustment *adjustment;
+
+	adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
+
+	adjustment->lower = 0.0;
+	adjustment->value = val;
+	adjustment->upper = max + 1;
+	adjustment->page_size = size;
+	adjustment->page_increment = size < 3L ? 1L : size - 2L;
+	adjustment->step_increment = 1.0;
+
+#ifdef HAVE_GTK2
+	g_signal_handler_block(GTK_OBJECT(adjustment),
+						      (gulong)sb->handler_id);
+#else
+	gtk_signal_handler_block(GTK_OBJECT(adjustment),
+						       (guint)sb->handler_id);
+#endif
+	gtk_adjustment_changed(adjustment);
+#ifdef HAVE_GTK2
+	g_signal_handler_unblock(GTK_OBJECT(adjustment),
+						      (gulong)sb->handler_id);
+#else
+	gtk_signal_handler_unblock(GTK_OBJECT(adjustment),
+						       (guint)sb->handler_id);
+#endif
+    }
+}
+
+    void
+gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)
+{
+    if (sb->id != NULL)
+	gtk_form_move_resize(GTK_FORM(gui.formwin), sb->id, x, y, w, h);
+}
+
+/*
+ * Take action upon scrollbar dragging.
+ */
+    static void
+adjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
+{
+    scrollbar_T	*sb;
+    long	value;
+    int		dragging = FALSE;
+
+#ifdef FEAT_XIM
+    /* cancel any preediting */
+    if (im_is_preediting())
+	xim_reset();
+#endif
+
+    sb = gui_find_scrollbar((long)data);
+    value = (long)adjustment->value;
+    /*
+     * The dragging argument must be right for the scrollbar to work with
+     * closed folds.  This isn't documented, hopefully this will keep on
+     * working in later GTK versions.
+     *
+     * FIXME: Well, it doesn't work in GTK2. :)
+     * HACK: Get the mouse pointer position, if it appears to be on an arrow
+     * button set "dragging" to FALSE.  This assumes square buttons!
+     */
+    if (sb != NULL)
+    {
+#ifdef HAVE_GTK2
+	dragging = TRUE;
+
+	if (sb->wp != NULL)
+	{
+	    int			x;
+	    int			y;
+	    GdkModifierType	state;
+	    int			width;
+	    int			height;
+
+	    /* vertical scrollbar: need to set "dragging" properly in case
+	     * there are closed folds. */
+	    gdk_window_get_pointer(sb->id->window, &x, &y, &state);
+	    gdk_window_get_size(sb->id->window, &width, &height);
+	    if (x >= 0 && x < width && y >= 0 && y < height)
+	    {
+		if (y < width)
+		{
+		    /* up arrow: move one (closed fold) line up */
+		    dragging = FALSE;
+		    value = sb->wp->w_topline - 2;
+		}
+		else if (y > height - width)
+		{
+		    /* down arrow: move one (closed fold) line down */
+		    dragging = FALSE;
+		    value = sb->wp->w_topline;
+		}
+	    }
+	}
+#else
+	dragging = (GTK_RANGE(sb->id)->scroll_type == GTK_SCROLL_NONE);
+#endif
+    }
+
+    gui_drag_scrollbar(sb, value, dragging);
+
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/* SBAR_VERT or SBAR_HORIZ */
+    void
+gui_mch_create_scrollbar(scrollbar_T *sb, int orient)
+{
+    if (orient == SBAR_HORIZ)
+	sb->id = gtk_hscrollbar_new(NULL);
+    else if (orient == SBAR_VERT)
+	sb->id = gtk_vscrollbar_new(NULL);
+
+    if (sb->id != NULL)
+    {
+	GtkAdjustment *adjustment;
+
+	GTK_WIDGET_UNSET_FLAGS(sb->id, GTK_CAN_FOCUS);
+	gtk_form_put(GTK_FORM(gui.formwin), sb->id, 0, 0);
+
+	adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
+
+	sb->handler_id = gtk_signal_connect(
+			     GTK_OBJECT(adjustment), "value_changed",
+			     GTK_SIGNAL_FUNC(adjustment_value_changed),
+			     GINT_TO_POINTER(sb->ident));
+	gui_mch_update();
+    }
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+    void
+gui_mch_destroy_scrollbar(scrollbar_T *sb)
+{
+    if (sb->id != NULL)
+    {
+	gtk_widget_destroy(sb->id);
+	sb->id = NULL;
+    }
+    gui_mch_update();
+}
+#endif
+
+#if defined(FEAT_BROWSE) || defined(PROTO)
+/*
+ * Implementation of the file selector related stuff
+ */
+
+/*ARGSUSED*/
+    static void
+browse_ok_cb(GtkWidget *widget, gpointer cbdata)
+{
+    gui_T *vw = (gui_T *)cbdata;
+
+    if (vw->browse_fname != NULL)
+	g_free(vw->browse_fname);
+
+    vw->browse_fname = (char_u *)g_strdup(gtk_file_selection_get_filename(
+					GTK_FILE_SELECTION(vw->filedlg)));
+    gtk_widget_hide(vw->filedlg);
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*ARGSUSED*/
+    static void
+browse_cancel_cb(GtkWidget *widget, gpointer cbdata)
+{
+    gui_T *vw = (gui_T *)cbdata;
+
+    if (vw->browse_fname != NULL)
+    {
+	g_free(vw->browse_fname);
+	vw->browse_fname = NULL;
+    }
+    gtk_widget_hide(vw->filedlg);
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*ARGSUSED*/
+    static gboolean
+browse_destroy_cb(GtkWidget * widget)
+{
+    if (gui.browse_fname != NULL)
+    {
+	g_free(gui.browse_fname);
+	gui.browse_fname = NULL;
+    }
+    gui.filedlg = NULL;
+
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+
+    return FALSE;
+}
+
+/*
+ * Put up a file requester.
+ * Returns the selected name in allocated memory, or NULL for Cancel.
+ * saving,			select file to write
+ * title			title for the window
+ * dflt				default name
+ * ext				not used (extension added)
+ * initdir			initial directory, NULL for current dir
+ * filter			not used (file name filter)
+ */
+/*ARGSUSED*/
+    char_u *
+gui_mch_browse(int saving,
+	       char_u *title,
+	       char_u *dflt,
+	       char_u *ext,
+	       char_u *initdir,
+	       char_u *filter)
+{
+    GtkFileSelection *fs;	/* shortcut */
+    char_u dirbuf[MAXPATHL];
+    char_u *p;
+
+# ifdef HAVE_GTK2
+    title = CONVERT_TO_UTF8(title);
+# endif
+
+    if (!gui.filedlg)
+    {
+	gui.filedlg = gtk_file_selection_new((const gchar *)title);
+	gtk_window_set_modal(GTK_WINDOW(gui.filedlg), TRUE);
+	gtk_window_set_transient_for(GTK_WINDOW(gui.filedlg),
+		GTK_WINDOW(gui.mainwin));
+	fs = GTK_FILE_SELECTION(gui.filedlg);
+
+	gtk_container_border_width(GTK_CONTAINER(fs), 4);
+
+	gtk_signal_connect(GTK_OBJECT(fs->ok_button),
+		"clicked", GTK_SIGNAL_FUNC(browse_ok_cb), &gui);
+	gtk_signal_connect(GTK_OBJECT(fs->cancel_button),
+		"clicked", GTK_SIGNAL_FUNC(browse_cancel_cb), &gui);
+	/* gtk_signal_connect() doesn't work for destroy, it causes a hang */
+	gtk_signal_connect_object(GTK_OBJECT(gui.filedlg),
+		"destroy", GTK_SIGNAL_FUNC(browse_destroy_cb),
+		GTK_OBJECT(gui.filedlg));
+    }
+    else
+	gtk_window_set_title(GTK_WINDOW(gui.filedlg), (const gchar *)title);
+
+# ifdef HAVE_GTK2
+    CONVERT_TO_UTF8_FREE(title);
+# endif
+
+    /* if our pointer is currently hidden, then we should show it. */
+    gui_mch_mousehide(FALSE);
+
+    /* Concatenate "initdir" and "dflt". */
+    if (initdir == NULL || *initdir == NUL)
+	mch_dirname(dirbuf, MAXPATHL);
+    else if (STRLEN(initdir) + 2 < MAXPATHL)
+	STRCPY(dirbuf, initdir);
+    else
+	dirbuf[0] = NUL;
+    /* Always need a trailing slash for a directory. */
+    add_pathsep(dirbuf);
+    if (dflt != NULL && *dflt != NUL
+			      && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL)
+	STRCAT(dirbuf, dflt);
+
+    gtk_file_selection_set_filename(GTK_FILE_SELECTION(gui.filedlg),
+						      (const gchar *)dirbuf);
+# ifndef HAVE_GTK2
+    gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin),
+				       GTK_WIDGET(gui.filedlg), VW_POS_MOUSE);
+# endif
+
+    gtk_widget_show(gui.filedlg);
+    while (gui.filedlg && GTK_WIDGET_DRAWABLE(gui.filedlg))
+	gtk_main_iteration_do(TRUE);
+
+    if (gui.browse_fname == NULL)
+	return NULL;
+
+    /* shorten the file name if possible */
+    mch_dirname(dirbuf, MAXPATHL);
+    p = shorten_fname(gui.browse_fname, dirbuf);
+    if (p == NULL)
+	p = gui.browse_fname;
+    return vim_strsave(p);
+}
+
+#endif	/* FEAT_BROWSE */
+
+#if (defined(FEAT_GUI_DIALOG) && !defined(HAVE_GTK2)) || defined(PROTO)
+
+static char_u *dialog_textfield = NULL;
+static GtkWidget *dialog_textentry;
+
+    static void
+dlg_destroy(GtkWidget *dlg)
+{
+    if (dialog_textfield != NULL)
+    {
+	const char *text;
+
+	text = gtk_entry_get_text(GTK_ENTRY(dialog_textentry));
+	STRNCPY(dialog_textfield, text, IOSIZE);
+	dialog_textfield[IOSIZE - 1] = NUL;
+    }
+
+    /* Destroy the dialog, will break the waiting loop. */
+    gtk_widget_destroy(dlg);
+}
+
+# ifdef FEAT_GUI_GNOME
+/* ARGSUSED */
+    static int
+gui_gnome_dialog( int	type,
+		char_u	*title,
+		char_u	*message,
+		char_u	*buttons,
+		int	dfltbutton,
+		char_u	*textfield)
+{
+    GtkWidget	*dlg;
+    char	*gdtype;
+    char_u	*buttons_copy, *p, *next;
+    char	**buttons_list;
+    int		butcount, cur;
+
+    /* make a copy, so that we can insert NULs */
+    if ((buttons_copy = vim_strsave(buttons)) == NULL)
+	return -1;
+
+    /* determine exact number of buttons and allocate array to hold them */
+    for (butcount = 0, p = buttons; *p; p++)
+    {
+	if (*p == '\n')
+	    butcount++;
+    }
+    butcount++;
+    buttons_list = g_new0(char *, butcount + 1);
+
+    /* Add pixmap */
+    switch (type)
+    {
+    case VIM_ERROR:
+	gdtype = GNOME_MESSAGE_BOX_ERROR;
+	break;
+    case VIM_WARNING:
+	gdtype = GNOME_MESSAGE_BOX_WARNING;
+	break;
+    case VIM_INFO:
+	gdtype = GNOME_MESSAGE_BOX_INFO;
+	break;
+    case VIM_QUESTION:
+	gdtype = GNOME_MESSAGE_BOX_QUESTION;
+	break;
+    default:
+	gdtype = GNOME_MESSAGE_BOX_GENERIC;
+    };
+
+    p = buttons_copy;
+    for (cur = 0; cur < butcount; ++cur)
+    {
+	for (next = p; *next; ++next)
+	{
+	    if (*next == DLG_HOTKEY_CHAR)
+		mch_memmove(next, next + 1, STRLEN(next));
+	    if (*next == DLG_BUTTON_SEP)
+	    {
+		*next++ = NUL;
+		break;
+	    }
+	}
+
+	/* this should probably go into a table, but oh well */
+	if (g_strcasecmp((char *)p, "Ok") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_OK);
+	else if (g_strcasecmp((char *)p, "Cancel") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_CANCEL);
+	else if (g_strcasecmp((char *)p, "Yes") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_YES);
+	else if (g_strcasecmp((char *)p, "No") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_NO);
+	else if (g_strcasecmp((char *)p, "Close") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_CLOSE);
+	else if (g_strcasecmp((char *)p, "Help") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_HELP);
+	else if (g_strcasecmp((char *)p, "Apply") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_APPLY);
+#if 0
+	/*
+	 * these aren't really used that often anyway, but are listed here as
+	 * placeholders in case we need them.
+	 */
+	else if (g_strcasecmp((char *)p, "Next") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_NEXT);
+	else if (g_strcasecmp((char *)p, "Prev") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_PREV);
+	else if (g_strcasecmp((char *)p, "Up") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_UP);
+	else if (g_strcasecmp((char *)p, "Down") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_DOWN);
+	else if (g_strcasecmp((char *)p, "Font") == 0)
+	    buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_FONT);
+#endif
+	else
+	    buttons_list[cur] = g_strdup((char *)p);
+
+	if (*next == NUL)
+	    break;
+
+	p = next;
+    }
+    vim_free(buttons_copy);
+
+    dlg = gnome_message_box_newv((const char *)message,
+				 (const char *)gdtype,
+				 (const char **)buttons_list);
+    for (cur = 0; cur < butcount; ++cur)
+	g_free(buttons_list[cur]);
+    g_free(buttons_list);
+
+    dialog_textfield = textfield;
+    if (textfield != NULL)
+    {
+	/* Add text entry field */
+	dialog_textentry = gtk_entry_new();
+	gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dlg)->vbox), dialog_textentry,
+			   TRUE, TRUE, 0);
+	gtk_entry_set_text(GTK_ENTRY(dialog_textentry),
+			   (const gchar *)textfield);
+	gtk_entry_select_region(GTK_ENTRY(dialog_textentry), 0,
+				STRLEN(textfield));
+	gtk_entry_set_max_length(GTK_ENTRY(dialog_textentry), IOSIZE - 1);
+	gtk_entry_set_position(GTK_ENTRY(dialog_textentry), STRLEN(textfield));
+	gtk_widget_show(dialog_textentry);
+	gtk_window_set_focus(GTK_WINDOW(dlg), dialog_textentry);
+    }
+
+    gtk_signal_connect_object(GTK_OBJECT(dlg), "destroy",
+			      GTK_SIGNAL_FUNC(dlg_destroy), GTK_OBJECT(dlg));
+    gnome_dialog_set_default(GNOME_DIALOG(dlg), dfltbutton + 1);
+    gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin),
+			       GTK_WIDGET(dlg), VW_POS_MOUSE);
+
+    return (1 + gnome_dialog_run_and_close(GNOME_DIALOG(dlg)));
+}
+
+# endif /* FEAT_GUI_GNOME */
+
+typedef struct _ButtonData
+{
+    int		*status;
+    int		index;
+    GtkWidget	*dialog;
+} ButtonData;
+
+typedef struct _CancelData
+{
+    int		*status;
+    int		ignore_enter;
+    GtkWidget	*dialog;
+} CancelData;
+
+/* ARGSUSED */
+    static void
+dlg_button_clicked(GtkWidget * widget, ButtonData *data)
+{
+    *(data->status) = data->index + 1;
+    dlg_destroy(data->dialog);
+}
+
+/*
+ * This makes the Escape key equivalent to the cancel button.
+ */
+/*ARGSUSED*/
+    static int
+dlg_key_press_event(GtkWidget * widget, GdkEventKey * event, CancelData *data)
+{
+    /* Ignore hitting Enter when there is no default button. */
+    if (data->ignore_enter && event->keyval == GDK_Return)
+	return TRUE;
+
+    if (event->keyval != GDK_Escape && event->keyval != GDK_Return)
+	return FALSE;
+
+    /* The result value of 0 from a dialog is signaling cancelation.
+     * 1 means OK. */
+    *(data->status) = (event->keyval == GDK_Return);
+    dlg_destroy(data->dialog);
+
+    return TRUE;
+}
+
+/*
+ * Callback function for when the dialog was destroyed by a window manager.
+ */
+    static void
+dlg_destroy_cb(int *p)
+{
+    *p = TRUE;		/* set dialog_destroyed to break out of the loop */
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/* ARGSUSED */
+    int
+gui_mch_dialog(	int	type,		/* type of dialog */
+		char_u	*title,		/* title of dialog */
+		char_u	*message,	/* message text */
+		char_u	*buttons,	/* names of buttons */
+		int	def_but,	/* default button */
+		char_u	*textfield)	/* text for textfield or NULL */
+{
+    char_u	*names;
+    char_u	*p;
+    int		i;
+    int		butcount;
+    int		dialog_status = -1;
+    int		dialog_destroyed = FALSE;
+    int		vertical;
+
+    GtkWidget		*dialog;
+    GtkWidget		*frame;
+    GtkWidget		*vbox;
+    GtkWidget		*table;
+    GtkWidget		*dialogmessage;
+    GtkWidget		*action_area;
+    GtkWidget		*sub_area;
+    GtkWidget		*separator;
+    GtkAccelGroup	*accel_group;
+    GtkWidget		*pixmap;
+    GdkPixmap		*icon = NULL;
+    GdkBitmap		*mask = NULL;
+    char		**icon_data = NULL;
+
+    GtkWidget		**button;
+    ButtonData		*data;
+    CancelData		cancel_data;
+
+    /* if our pointer is currently hidden, then we should show it. */
+    gui_mch_mousehide(FALSE);
+
+# ifdef FEAT_GUI_GNOME
+    /* If Gnome is available, use it for the dialog. */
+    if (gtk_socket_id == 0)
+	return gui_gnome_dialog(type, title, message, buttons, def_but,
+								   textfield);
+# endif
+
+    if (title == NULL)
+	title = (char_u *)_("Vim dialog...");
+
+    if ((type < 0) || (type > VIM_LAST_TYPE))
+	type = VIM_GENERIC;
+
+    /* Check 'v' flag in 'guioptions': vertical button placement. */
+    vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
+
+    dialog = gtk_window_new(GTK_WINDOW_DIALOG);
+    gtk_window_set_title(GTK_WINDOW(dialog), (const gchar *)title);
+    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui.mainwin));
+    gtk_widget_realize(dialog);
+    gdk_window_set_decorations(dialog->window, GDK_DECOR_BORDER);
+    gdk_window_set_functions(dialog->window, GDK_FUNC_MOVE);
+
+    cancel_data.status = &dialog_status;
+    cancel_data.dialog = dialog;
+    gtk_signal_connect_after(GTK_OBJECT(dialog), "key_press_event",
+		    GTK_SIGNAL_FUNC(dlg_key_press_event),
+		    (gpointer) &cancel_data);
+    /* Catch the destroy signal, otherwise we don't notice a window manager
+     * destroying the dialog window. */
+    gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
+		    GTK_SIGNAL_FUNC(dlg_destroy_cb),
+		    (gpointer)&dialog_destroyed);
+
+    gtk_grab_add(dialog);
+
+    /* this makes it look beter on Motif style window managers */
+    frame = gtk_frame_new(NULL);
+    gtk_container_add(GTK_CONTAINER(dialog), frame);
+    gtk_widget_show(frame);
+
+    vbox = gtk_vbox_new(FALSE, 0);
+    gtk_container_add(GTK_CONTAINER(frame), vbox);
+    gtk_widget_show(vbox);
+
+    table = gtk_table_new(1, 3, FALSE);
+    gtk_table_set_row_spacings(GTK_TABLE(table), 4);
+    gtk_table_set_col_spacings(GTK_TABLE(table), 8);
+    gtk_container_border_width(GTK_CONTAINER(table), 4);
+    gtk_box_pack_start(GTK_BOX(vbox), table, 4, 4, 0);
+    gtk_widget_show(table);
+
+    /* Add pixmap */
+    switch (type)
+    {
+    case VIM_GENERIC:
+	icon_data = generic_xpm;
+	break;
+    case VIM_ERROR:
+	icon_data = error_xpm;
+	break;
+    case VIM_WARNING:
+	icon_data = alert_xpm;
+	break;
+    case VIM_INFO:
+	icon_data = info_xpm;
+	break;
+    case VIM_QUESTION:
+	icon_data = quest_xpm;
+	break;
+    default:
+	icon_data = generic_xpm;
+    };
+    icon = gdk_pixmap_colormap_create_from_xpm_d(NULL,
+				     gtk_widget_get_colormap(dialog),
+				     &mask, NULL, icon_data);
+    if (icon)
+    {
+	pixmap = gtk_pixmap_new(icon, mask);
+	/* gtk_misc_set_alignment(GTK_MISC(pixmap), 0.5, 0.5); */
+	gtk_table_attach_defaults(GTK_TABLE(table), pixmap, 0, 1, 0, 1);
+	gtk_widget_show(pixmap);
+    }
+
+    /* Add label */
+    dialogmessage = gtk_label_new((const gchar *)message);
+    gtk_table_attach_defaults(GTK_TABLE(table), dialogmessage, 1, 2, 0, 1);
+    gtk_widget_show(dialogmessage);
+
+    dialog_textfield = textfield;
+    if (textfield != NULL)
+    {
+	/* Add text entry field */
+	dialog_textentry = gtk_entry_new();
+	gtk_widget_set_usize(dialog_textentry, 400, -2);
+	gtk_box_pack_start(GTK_BOX(vbox), dialog_textentry, TRUE, TRUE, 0);
+	gtk_entry_set_text(GTK_ENTRY(dialog_textentry),
+						    (const gchar *)textfield);
+	gtk_entry_select_region(GTK_ENTRY(dialog_textentry), 0,
+							   STRLEN(textfield));
+	gtk_entry_set_max_length(GTK_ENTRY(dialog_textentry), IOSIZE - 1);
+	gtk_entry_set_position(GTK_ENTRY(dialog_textentry), STRLEN(textfield));
+	gtk_widget_show(dialog_textentry);
+    }
+
+    /* Add box for buttons */
+    action_area = gtk_hbox_new(FALSE, 0);
+    gtk_container_border_width(GTK_CONTAINER(action_area), 4);
+    gtk_box_pack_end(GTK_BOX(vbox), action_area, FALSE, TRUE, 0);
+    gtk_widget_show(action_area);
+
+    /* Add a [vh]box in the hbox to center the buttons in the dialog. */
+    if (vertical)
+	sub_area = gtk_vbox_new(FALSE, 0);
+    else
+	sub_area = gtk_hbox_new(FALSE, 0);
+    gtk_container_set_border_width(GTK_CONTAINER(sub_area), 0);
+    gtk_box_pack_start(GTK_BOX(action_area), sub_area, TRUE, FALSE, 0);
+    gtk_widget_show(sub_area);
+
+    /*
+     * Create the buttons.
+     */
+
+    /*
+     * Translate the Vim accelerator character into an underscore for GTK+.
+     * Double underscores to keep them in the label.
+     */
+    /* count the number of underscores */
+    i = 1;
+    for (p = buttons; *p; ++p)
+	if (*p == '_')
+	    ++i;
+
+    /* make a copy of "buttons" with the translated characters */
+    names = alloc(STRLEN(buttons) + i);
+    if (names == NULL)
+	return -1;
+
+    p = names;
+    for (i = 0; buttons[i]; ++i)
+    {
+	if (buttons[i] == DLG_HOTKEY_CHAR)
+	    *p++ = '_';
+	else
+	{
+	    if (buttons[i] == '_')
+		*p++ = '_';
+	    *p++ = buttons[i];
+	}
+    }
+    *p = NUL;
+
+    /* Count the number of buttons and allocate button[] and data[]. */
+    butcount = 1;
+    for (p = names; *p; ++p)
+	if (*p == DLG_BUTTON_SEP)
+	    ++butcount;
+    button = (GtkWidget **)alloc((unsigned)(butcount * sizeof(GtkWidget *)));
+    data = (ButtonData *)alloc((unsigned)(butcount * sizeof(ButtonData)));
+    if (button == NULL || data == NULL)
+    {
+	vim_free(names);
+	vim_free(button);
+	vim_free(data);
+	return -1;
+    }
+
+    /* Attach the new accelerator group to the window. */
+    accel_group = gtk_accel_group_new();
+    gtk_accel_group_attach(accel_group, GTK_OBJECT(dialog));
+
+    p = names;
+    for (butcount = 0; *p; ++butcount)
+    {
+	char_u		*next;
+	GtkWidget	*label;
+# ifdef GTK_USE_ACCEL
+	guint		accel_key;
+# endif
+
+	/* Chunk out this single button. */
+	for (next = p; *next; ++next)
+	{
+	    if (*next == DLG_BUTTON_SEP)
+	    {
+		*next++ = NUL;
+		break;
+	    }
+	}
+
+	button[butcount] = gtk_button_new();
+	GTK_WIDGET_SET_FLAGS(button[butcount], GTK_CAN_DEFAULT);
+
+	label = gtk_accel_label_new("");
+	gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(label), dialog);
+
+# ifdef GTK_USE_ACCEL
+	accel_key = gtk_label_parse_uline(GTK_LABEL(label), (const gchar *)p);
+	/* Don't add accelator if 'winaltkeys' is "no". */
+	if (accel_key != GDK_VoidSymbol)
+	{
+	    gtk_widget_add_accelerator(button[butcount],
+		    "clicked",
+		    accel_group,
+		    accel_key, 0,
+		    0);
+	}
+# else
+	(void)gtk_label_parse_uline(GTK_LABEL(label), (const gchar *)p);
+# endif
+
+	gtk_container_add(GTK_CONTAINER(button[butcount]), label);
+	gtk_widget_show_all(button[butcount]);
+
+	data[butcount].status = &dialog_status;
+	data[butcount].index = butcount;
+	data[butcount].dialog = dialog;
+	gtk_signal_connect(GTK_OBJECT(button[butcount]),
+			   (const char *)"clicked",
+			   GTK_SIGNAL_FUNC(dlg_button_clicked),
+			   (gpointer) &data[butcount]);
+
+	gtk_box_pack_start(GTK_BOX(sub_area), button[butcount],
+			   TRUE, FALSE, 0);
+	p = next;
+    }
+
+    vim_free(names);
+
+    cancel_data.ignore_enter = FALSE;
+    if (butcount > 0)
+    {
+	--def_but;		/* 1 is first button */
+	if (def_but >= butcount)
+	    def_but = -1;
+	if (def_but >= 0)
+	{
+	    gtk_widget_grab_focus(button[def_but]);
+	    gtk_widget_grab_default(button[def_but]);
+	}
+	else
+	    /* No default, ignore hitting Enter. */
+	    cancel_data.ignore_enter = TRUE;
+    }
+
+    if (textfield != NULL)
+	gtk_window_set_focus(GTK_WINDOW(dialog), dialog_textentry);
+
+    separator = gtk_hseparator_new();
+    gtk_box_pack_end(GTK_BOX(vbox), separator, FALSE, TRUE, 0);
+    gtk_widget_show(separator);
+
+    dialog_status = -1;
+
+    gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin),
+					    GTK_WIDGET(dialog), VW_POS_MOUSE);
+
+    gtk_widget_show(dialog);
+
+    /* loop here until the dialog goes away */
+    while (dialog_status == -1 && !dialog_destroyed
+					       && GTK_WIDGET_DRAWABLE(dialog))
+	gtk_main_iteration_do(TRUE);
+
+    if (dialog_status < 0)
+	dialog_status = 0;
+    if (dialog_status != 1 && textfield != NULL)
+	*textfield = NUL;	/* dialog was cancelled */
+
+    /* let the garbage collector know that we don't need it any longer */
+    gtk_accel_group_unref(accel_group);
+
+    vim_free(button);
+    vim_free(data);
+
+    return dialog_status;
+}
+
+#endif /* FEAT_GUI_DIALOG && !HAVE_GTK2 */
+
+
+#if defined(FEAT_GUI_DIALOG) && defined(HAVE_GTK2)
+
+    static GtkWidget *
+create_message_dialog(int type, char_u *title, char_u *message)
+{
+    GtkWidget	    *dialog;
+    GtkMessageType  message_type;
+
+    switch (type)
+    {
+	case VIM_ERROR:	    message_type = GTK_MESSAGE_ERROR;	 break;
+	case VIM_WARNING:   message_type = GTK_MESSAGE_WARNING;	 break;
+	case VIM_QUESTION:  message_type = GTK_MESSAGE_QUESTION; break;
+	default:	    message_type = GTK_MESSAGE_INFO;	 break;
+    }
+
+    message = CONVERT_TO_UTF8(message);
+    dialog  = gtk_message_dialog_new(GTK_WINDOW(gui.mainwin),
+				     GTK_DIALOG_DESTROY_WITH_PARENT,
+				     message_type,
+				     GTK_BUTTONS_NONE,
+				     "%s", (const char *)message);
+    CONVERT_TO_UTF8_FREE(message);
+
+    if (title != NULL)
+    {
+	title = CONVERT_TO_UTF8(title);
+	gtk_window_set_title(GTK_WINDOW(dialog), (const char *)title);
+	CONVERT_TO_UTF8_FREE(title);
+    }
+    else if (type == VIM_GENERIC)
+    {
+	gtk_window_set_title(GTK_WINDOW(dialog), "VIM");
+    }
+
+    return dialog;
+}
+
+/*
+ * Split up button_string into individual button labels by inserting
+ * NUL bytes.  Also replace the Vim-style mnemonic accelerator prefix
+ * '&' with '_'.  button_string must point to allocated memory!
+ * Return an allocated array of pointers into button_string.
+ */
+    static char **
+split_button_string(char_u *button_string, int *n_buttons)
+{
+    char	    **array;
+    char_u	    *p;
+    unsigned int    count = 1;
+
+    for (p = button_string; *p != NUL; ++p)
+	if (*p == DLG_BUTTON_SEP)
+	    ++count;
+
+    array = (char **)alloc((count + 1) * sizeof(char *));
+    count = 0;
+
+    if (array != NULL)
+    {
+	array[count++] = (char *)button_string;
+	for (p = button_string; *p != NUL; ++p)
+	{
+	    if (*p == DLG_BUTTON_SEP)
+	    {
+		*p = NUL;
+		array[count++] = (char *)p + 1;
+	    }
+	    else if (*p == DLG_HOTKEY_CHAR)
+		*p = '_';
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte)
+		p += (*mb_ptr2len_check)(p) - 1;
+#endif
+	}
+	array[count] = NULL; /* currently not relied upon, but doesn't hurt */
+    }
+
+    *n_buttons = count;
+    return array;
+}
+
+    static char **
+split_button_translation(const char *message)
+{
+    char    **buttons = NULL;
+    char_u  *str;
+    int	    n_buttons = 0;
+    int	    n_expected = 1;
+
+    for (str = (char_u *)message; *str != NUL; ++str)
+	if (*str == DLG_BUTTON_SEP)
+	    ++n_expected;
+
+    str = (char_u *)_(message);
+    if (str != NULL)
+    {
+	if (output_conv.vc_type != CONV_NONE)
+	    str = string_convert(&output_conv, str, NULL);
+	else
+	    str = vim_strsave(str);
+
+	if (str != NULL)
+	    buttons = split_button_string(str, &n_buttons);
+    }
+    /*
+     * Uh-oh... this should never ever happen.	But we don't wanna crash
+     * if the translation is broken, thus fall back to the untranslated
+     * buttons string in case of emergency.
+     */
+    if (buttons == NULL || n_buttons != n_expected)
+    {
+	vim_free(buttons);
+	vim_free(str);
+	buttons = NULL;
+	str = vim_strsave((char_u *)message);
+
+	if (str != NULL)
+	    buttons = split_button_string(str, &n_buttons);
+	if (buttons == NULL)
+	    vim_free(str);
+    }
+
+    return buttons;
+}
+
+    static int
+button_equal(const char *a, const char *b)
+{
+    while (*a != '\0' && *b != '\0')
+    {
+	if (*a == '_' && *++a == '\0')
+	    break;
+	if (*b == '_' && *++b == '\0')
+	    break;
+
+	if (g_unichar_tolower(g_utf8_get_char(a))
+		!= g_unichar_tolower(g_utf8_get_char(b)))
+	    return FALSE;
+
+	a = g_utf8_next_char(a);
+	b = g_utf8_next_char(b);
+    }
+
+    return (*a == '\0' && *b == '\0');
+}
+
+    static void
+dialog_add_buttons(GtkDialog *dialog, char_u *button_string)
+{
+    char    **ok;
+    char    **ync;  /* "yes no cancel" */
+    char    **buttons;
+    int	    n_buttons = 0;
+    int	    index;
+
+    button_string = vim_strsave(button_string); /* must be writable */
+    if (button_string == NULL)
+	return;
+
+    /* Check 'v' flag in 'guioptions': vertical button placement. */
+    if (vim_strchr(p_go, GO_VERTICAL) != NULL)
+    {
+	GtkWidget	*vbutton_box;
+
+	vbutton_box = gtk_vbutton_box_new();
+	gtk_widget_show(vbutton_box);
+	gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+						 vbutton_box, TRUE, FALSE, 0);
+	/* Overrule the "action_area" value, hopefully this works... */
+	GTK_DIALOG(dialog)->action_area = vbutton_box;
+    }
+
+    /*
+     * Yes this is ugly, I don't particularly like it either.  But doing it
+     * this way has the compelling advantage that translations need not to
+     * be touched at all.  See below what 'ok' and 'ync' are used for.
+     */
+    ok	    = split_button_translation(N_("&Ok"));
+    ync     = split_button_translation(N_("&Yes\n&No\n&Cancel"));
+    buttons = split_button_string(button_string, &n_buttons);
+
+    /*
+     * Yes, the buttons are in reversed order to match the GNOME 2 desktop
+     * environment.  Don't hit me -- it's all about consistency.
+     * Well, apparently somebody changed his mind: with GTK 2.2.4 it works the
+     * other way around...
+     */
+    for (index = 1; index <= n_buttons; ++index)
+    {
+	char	*label;
+	char_u	*label8;
+
+	label = buttons[index - 1];
+	/*
+	 * Perform some guesswork to find appropriate stock items for the
+	 * buttons.  We have to compare with a sample of the translated
+	 * button string to get things right.  Yes, this is hackish :/
+	 *
+	 * But even the common button labels aren't necessarily translated,
+	 * since anyone can create their own dialogs using Vim functions.
+	 * Thus we have to check for those too.
+	 */
+	if (ok != NULL && ync != NULL) /* almost impossible to fail */
+	{
+	    if	    (button_equal(label, ok[0]))    label = GTK_STOCK_OK;
+	    else if (button_equal(label, ync[0]))   label = GTK_STOCK_YES;
+	    else if (button_equal(label, ync[1]))   label = GTK_STOCK_NO;
+	    else if (button_equal(label, ync[2]))   label = GTK_STOCK_CANCEL;
+	    else if (button_equal(label, "Ok"))     label = GTK_STOCK_OK;
+	    else if (button_equal(label, "Yes"))    label = GTK_STOCK_YES;
+	    else if (button_equal(label, "No"))     label = GTK_STOCK_NO;
+	    else if (button_equal(label, "Cancel")) label = GTK_STOCK_CANCEL;
+	}
+	label8 = CONVERT_TO_UTF8((char_u *)label);
+	gtk_dialog_add_button(dialog, (const gchar *)label8, index);
+	CONVERT_TO_UTF8_FREE(label8);
+    }
+
+    if (ok != NULL)
+	vim_free(*ok);
+    if (ync != NULL)
+	vim_free(*ync);
+    vim_free(ok);
+    vim_free(ync);
+    vim_free(buttons);
+    vim_free(button_string);
+}
+
+/*
+ * Allow mnemonic accelerators to be activated without pressing <Alt>.
+ * I'm not sure if it's a wise idea to do this.  However, the old GTK+ 1.2
+ * GUI used to work this way, and I consider the impact on UI consistency
+ * low enough to justify implementing this as a special Vim feature.
+ */
+typedef struct _DialogInfo
+{
+    int		ignore_enter;	    /* no default button, ignore "Enter" */
+    int		noalt;		    /* accept accelerators without Alt */
+    GtkDialog	*dialog;	    /* Widget of the dialog */
+} DialogInfo;
+
+/*ARGSUSED2*/
+    static gboolean
+dialog_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+    DialogInfo *di = (DialogInfo *)data;
+
+    /* Ignore hitting "Enter" if there is no default button. */
+    if (di->ignore_enter && event->keyval == GDK_Return)
+	return TRUE;
+
+    /* Close the dialog when hitting "Esc". */
+    if (event->keyval == GDK_Escape)
+    {
+	gtk_dialog_response(di->dialog, GTK_RESPONSE_REJECT);
+	return TRUE;
+    }
+
+    if (di->noalt
+	      && (event->state & gtk_accelerator_get_default_mod_mask()) == 0)
+    {
+	return gtk_window_mnemonic_activate(
+		   GTK_WINDOW(widget), event->keyval,
+		   gtk_window_get_mnemonic_modifier(GTK_WINDOW(widget)));
+    }
+
+    return FALSE; /* continue emission */
+}
+
+    int
+gui_mch_dialog(int	type,	    /* type of dialog */
+	       char_u	*title,	    /* title of dialog */
+	       char_u	*message,   /* message text */
+	       char_u	*buttons,   /* names of buttons */
+	       int	def_but,    /* default button */
+	       char_u	*textfield) /* text for textfield or NULL */
+{
+    GtkWidget	*dialog;
+    GtkWidget	*entry = NULL;
+    char_u	*text;
+    int		response;
+    DialogInfo  dialoginfo;
+
+    dialog = create_message_dialog(type, title, message);
+    dialoginfo.dialog = GTK_DIALOG(dialog);
+    dialog_add_buttons(GTK_DIALOG(dialog), buttons);
+
+    if (textfield != NULL)
+    {
+	GtkWidget *alignment;
+
+	entry = gtk_entry_new();
+	gtk_widget_show(entry);
+
+	text = CONVERT_TO_UTF8(textfield);
+	gtk_entry_set_text(GTK_ENTRY(entry), (const char *)text);
+	CONVERT_TO_UTF8_FREE(text);
+
+	alignment = gtk_alignment_new((float)0.5, (float)0.5,
+						      (float)1.0, (float)1.0);
+	gtk_container_add(GTK_CONTAINER(alignment), entry);
+	gtk_container_set_border_width(GTK_CONTAINER(alignment), 5);
+	gtk_widget_show(alignment);
+
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+			   alignment, TRUE, FALSE, 0);
+	dialoginfo.noalt = FALSE;
+    }
+    else
+	dialoginfo.noalt = TRUE;
+
+    /* Allow activation of mnemonic accelerators without pressing <Alt> when
+     * there is no textfield.  Handle pressing Enter and Esc. */
+    g_signal_connect(G_OBJECT(dialog), "key_press_event",
+			 G_CALLBACK(&dialog_key_press_event_cb), &dialoginfo);
+
+    if (def_but > 0)
+    {
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), def_but);
+	dialoginfo.ignore_enter = FALSE;
+    }
+    else
+	/* No default button, ignore pressing Enter. */
+	dialoginfo.ignore_enter = TRUE;
+
+    /* Show the mouse pointer if it's currently hidden. */
+    gui_mch_mousehide(FALSE);
+
+    response = gtk_dialog_run(GTK_DIALOG(dialog));
+
+    /* GTK_RESPONSE_NONE means the dialog was programmatically destroyed. */
+    if (response != GTK_RESPONSE_NONE)
+    {
+	if (textfield != NULL)
+	{
+	    text = (char_u *)gtk_entry_get_text(GTK_ENTRY(entry));
+	    text = CONVERT_FROM_UTF8(text);
+
+	    STRNCPY(textfield, text, IOSIZE);
+	    textfield[IOSIZE - 1] = NUL;
+
+	    CONVERT_FROM_UTF8_FREE(text);
+	}
+	gtk_widget_destroy(dialog);
+    }
+
+    /* Terrible hack: When the text area still has focus when we remove the
+     * dialog, somehow gvim loses window focus.  This is with "point to type"
+     * in the KDE 3.1 window manager.  Warp the mouse pointer to outside the
+     * window and back to avoid that. */
+    if (!gui.in_focus)
+    {
+	int x, y;
+
+	gdk_window_get_pointer(gui.drawarea->window, &x, &y, NULL);
+	gui_mch_setmouse(-100, -100);
+	gui_mch_setmouse(x, y);
+    }
+
+    return response > 0 ? response : 0;
+}
+
+#endif /* FEAT_GUI_DIALOG && HAVE_GTK2 */
+
+
+#if defined(FEAT_MENU) || defined(PROTO)
+
+    void
+gui_mch_show_popupmenu(vimmenu_T *menu)
+{
+# if defined(FEAT_XIM) && defined(HAVE_GTK2)
+    /*
+     * Append a submenu for selecting an input method.	This is
+     * currently the only way to switch input methods at runtime.
+     */
+    if (xic != NULL && g_object_get_data(G_OBJECT(menu->submenu_id),
+					 "vim-has-im-menu") == NULL)
+    {
+	GtkWidget   *menuitem;
+	GtkWidget   *submenu;
+	char_u	    *name;
+
+	menuitem = gtk_separator_menu_item_new();
+	gtk_widget_show(menuitem);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu->submenu_id), menuitem);
+
+	name = (char_u *)_("Input _Methods");
+	name = CONVERT_TO_UTF8(name);
+	menuitem = gtk_menu_item_new_with_mnemonic((const char *)name);
+	CONVERT_TO_UTF8_FREE(name);
+	gtk_widget_show(menuitem);
+
+	submenu = gtk_menu_new();
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu->submenu_id), menuitem);
+
+	gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(xic),
+					     GTK_MENU_SHELL(submenu));
+	g_object_set_data(G_OBJECT(menu->submenu_id),
+			  "vim-has-im-menu", GINT_TO_POINTER(TRUE));
+    }
+# endif /* FEAT_XIM && HAVE_GTK2 */
+
+    gtk_menu_popup(GTK_MENU(menu->submenu_id),
+		   NULL, NULL,
+		   (GtkMenuPositionFunc)NULL, NULL,
+		   3U, (guint32)GDK_CURRENT_TIME);
+}
+
+/*
+ * Menu position callback; used by gui_make_popup() to place the menu
+ * at the current text cursor position.
+ *
+ * Note: The push_in output argument seems to affect scrolling of huge
+ * menus that don't fit on the screen.	Leave it at the default for now.
+ */
+/*ARGSUSED0*/
+    static void
+popup_menu_position_func(GtkMenu *menu,
+			 gint *x, gint *y,
+# ifdef HAVE_GTK2
+			 gboolean *push_in,
+# endif
+			 gpointer user_data)
+{
+    if (curwin != NULL && gui.drawarea != NULL && gui.drawarea->window != NULL)
+    {
+	gdk_window_get_origin(gui.drawarea->window, x, y);
+
+	/* Find the cursor position in the current window */
+	*x += FILL_X(W_WINCOL(curwin) + curwin->w_wcol + 1) + 1;
+	*y += FILL_Y(W_WINROW(curwin) + curwin->w_wrow + 1) + 1;
+    }
+}
+
+    void
+gui_make_popup(char_u *path_name)
+{
+    vimmenu_T *menu;
+
+    menu = gui_find_menu(path_name);
+
+    if (menu != NULL && menu->submenu_id != NULL)
+    {
+	gtk_menu_popup(GTK_MENU(menu->submenu_id),
+		       NULL, NULL,
+		       &popup_menu_position_func, NULL,
+		       0U, (guint32)GDK_CURRENT_TIME);
+    }
+}
+
+#endif /* FEAT_MENU */
+
+
+/*
+ * We don't create it twice.
+ */
+
+typedef struct _SharedFindReplace
+{
+    GtkWidget *dialog;	/* the main dialog widget */
+    GtkWidget *wword;	/* 'Whole word only' check button */
+    GtkWidget *mcase;	/* 'Match case' check button */
+    GtkWidget *up;	/* search direction 'Up' radio button */
+    GtkWidget *down;	/* search direction 'Down' radio button */
+    GtkWidget *what;	/* 'Find what' entry text widget */
+    GtkWidget *with;	/* 'Replace with' entry text widget */
+    GtkWidget *find;	/* 'Find Next' action button */
+    GtkWidget *replace;	/* 'Replace With' action button */
+    GtkWidget *all;	/* 'Replace All' action button */
+} SharedFindReplace;
+
+static SharedFindReplace find_widgets = { NULL, };
+static SharedFindReplace repl_widgets = { NULL, };
+
+/* ARGSUSED */
+    static int
+find_key_press_event(
+		GtkWidget	*widget,
+		GdkEventKey	*event,
+		SharedFindReplace *frdp)
+{
+    /* If the user is holding one of the key modifiers we will just bail out,
+     * thus preserving the possibility of normal focus traversal.
+     */
+    if (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))
+	return FALSE;
+
+    /* the Escape key synthesizes a cancellation action */
+    if (event->keyval == GDK_Escape)
+    {
+	gtk_widget_hide(frdp->dialog);
+
+	return TRUE;
+    }
+    /*
+     * What the **** is this for?  Disabled for GTK+ 2 because due to
+     * gtk_signal_connect_after() it doesn't have any effect anyway.
+     * (Fortunately.)
+     */
+#ifndef HAVE_GTK2
+    /* block traversal resulting from those keys */
+    if (event->keyval == GDK_Left
+	    || event->keyval == GDK_Right
+	    || event->keyval == GDK_space)
+	return TRUE;
+#endif
+
+    /* It would be delightfull if it where possible to do search history
+     * operations on the K_UP and K_DOWN keys here.
+     */
+
+    return FALSE;
+}
+
+#ifdef HAVE_GTK2
+    static GtkWidget *
+create_image_button(const char *stock_id, const char *label)
+{
+    char_u	*text;
+    GtkWidget	*box;
+    GtkWidget	*alignment;
+    GtkWidget	*button;
+
+    text = CONVERT_TO_UTF8((char_u *)label);
+
+    box = gtk_hbox_new(FALSE, 3);
+    gtk_box_pack_start(GTK_BOX(box),
+		       gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON),
+		       FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(box),
+		       gtk_label_new((const char *)text),
+		       FALSE, FALSE, 0);
+
+    CONVERT_TO_UTF8_FREE(text);
+
+    alignment = gtk_alignment_new((float)0.5, (float)0.5,
+						      (float)0.0, (float)0.0);
+    gtk_container_add(GTK_CONTAINER(alignment), box);
+    gtk_widget_show_all(alignment);
+
+    button = gtk_button_new();
+    gtk_container_add(GTK_CONTAINER(button), alignment);
+
+    return button;
+}
+
+/*
+ * This is currently only used by find_replace_dialog_create(), and
+ * I'd really like to keep it at that.	In other words: don't spread
+ * this nasty hack all over the code.  Think twice.
+ */
+    static const char *
+convert_localized_message(char_u **buffer, const char *message)
+{
+    if (output_conv.vc_type == CONV_NONE)
+	return message;
+
+    vim_free(*buffer);
+    *buffer = string_convert(&output_conv, (char_u *)message, NULL);
+
+    return (const char *)*buffer;
+}
+#endif /* HAVE_GTK2 */
+
+    static void
+find_replace_dialog_create(char_u *arg, int do_replace)
+{
+#ifndef HAVE_GTK2
+    GtkWidget	*frame;
+#endif
+    GtkWidget	*hbox;		/* main top down box */
+    GtkWidget	*actionarea;
+    GtkWidget	*table;
+    GtkWidget	*tmp;
+    GtkWidget	*vbox;
+    gboolean	sensitive;
+    SharedFindReplace *frdp;
+    char_u	*entry_text;
+    int		wword = FALSE;
+    int		mcase = !p_ic;
+#ifdef HAVE_GTK2
+    char_u	*conv_buffer = NULL;
+#   define CONV(message) convert_localized_message(&conv_buffer, (message))
+#else
+#   define CONV(message) (message)
+#endif
+
+    frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
+
+    /* Get the search string to use. */
+    entry_text = get_find_dialog_text(arg, &wword, &mcase);
+
+#ifdef HAVE_GTK2
+    if (entry_text != NULL && output_conv.vc_type != CONV_NONE)
+    {
+	char_u *old_text = entry_text;
+	entry_text = string_convert(&output_conv, entry_text, NULL);
+	vim_free(old_text);
+    }
+#endif
+
+    /*
+     * If the dialog already exists, just raise it.
+     */
+    if (frdp->dialog)
+    {
+#ifndef HAVE_GTK2
+	/* always make the dialog appear where you want it even if the mainwin
+	 * has moved -- dbv */
+	gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin),
+				      GTK_WIDGET(frdp->dialog), VW_POS_MOUSE);
+	gui_gtk_synch_fonts();
+
+	if (!GTK_WIDGET_VISIBLE(frdp->dialog))
+	{
+	    gtk_widget_grab_focus(frdp->what);
+	    gtk_widget_show(frdp->dialog);
+	}
+#endif
+	if (entry_text != NULL)
+	{
+	    gtk_entry_set_text(GTK_ENTRY(frdp->what), (char *)entry_text);
+	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->wword),
+							     (gboolean)wword);
+	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->mcase),
+							     (gboolean)mcase);
+	}
+#ifdef HAVE_GTK2
+	gtk_window_present(GTK_WINDOW(frdp->dialog));
+#else
+	gdk_window_raise(frdp->dialog->window);
+#endif
+	vim_free(entry_text);
+	return;
+    }
+
+#ifdef HAVE_GTK2
+    frdp->dialog = gtk_dialog_new();
+    gtk_dialog_set_has_separator(GTK_DIALOG(frdp->dialog), FALSE);
+    gtk_window_set_transient_for(GTK_WINDOW(frdp->dialog), GTK_WINDOW(gui.mainwin));
+    gtk_window_set_destroy_with_parent(GTK_WINDOW(frdp->dialog), TRUE);
+#else
+    frdp->dialog = gtk_window_new(GTK_WINDOW_DIALOG);
+#endif
+
+    if (do_replace)
+    {
+#ifndef HAVE_GTK2
+	gtk_window_set_wmclass(GTK_WINDOW(frdp->dialog), "searchrepl", "gvim");
+#endif
+	gtk_window_set_title(GTK_WINDOW(frdp->dialog),
+			     CONV(_("VIM - Search and Replace...")));
+    }
+    else
+    {
+#ifndef HAVE_GTK2
+	gtk_window_set_wmclass(GTK_WINDOW(frdp->dialog), "search", "gvim");
+#endif
+	gtk_window_set_title(GTK_WINDOW(frdp->dialog),
+			     CONV(_("VIM - Search...")));
+    }
+
+#ifndef HAVE_GTK2 /* Utter crack.  Shudder. */
+    gtk_widget_realize(frdp->dialog);
+    gdk_window_set_decorations(frdp->dialog->window,
+	    GDK_DECOR_TITLE | GDK_DECOR_BORDER | GDK_DECOR_RESIZEH);
+    gdk_window_set_functions(frdp->dialog->window,
+	    GDK_FUNC_RESIZE | GDK_FUNC_MOVE);
+#endif
+
+#ifndef HAVE_GTK2
+    /* this makes it look better on Motif style window managers */
+    frame = gtk_frame_new(NULL);
+    gtk_container_add(GTK_CONTAINER(frdp->dialog), frame);
+#endif
+
+    hbox = gtk_hbox_new(FALSE, 0);
+#ifdef HAVE_GTK2
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(frdp->dialog)->vbox), hbox);
+#else
+    gtk_container_add(GTK_CONTAINER(frame), hbox);
+#endif
+
+    if (do_replace)
+	table = gtk_table_new(1024, 4, FALSE);
+    else
+	table = gtk_table_new(1024, 3, FALSE);
+    gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0);
+    gtk_container_border_width(GTK_CONTAINER(table), 4);
+
+    tmp = gtk_label_new(CONV(_("Find what:")));
+    gtk_misc_set_alignment(GTK_MISC(tmp), (gfloat)0.0, (gfloat)0.5);
+    gtk_table_attach(GTK_TABLE(table), tmp, 0, 1, 0, 1,
+		     GTK_FILL, GTK_EXPAND, 2, 2);
+    frdp->what = gtk_entry_new();
+    sensitive = (entry_text != NULL && entry_text[0] != NUL);
+    if (entry_text != NULL)
+	gtk_entry_set_text(GTK_ENTRY(frdp->what), (char *)entry_text);
+    gtk_signal_connect(GTK_OBJECT(frdp->what), "changed",
+		       GTK_SIGNAL_FUNC(entry_changed_cb), frdp->dialog);
+    gtk_signal_connect_after(GTK_OBJECT(frdp->what), "key_press_event",
+				 GTK_SIGNAL_FUNC(find_key_press_event),
+				 (gpointer) frdp);
+    gtk_table_attach(GTK_TABLE(table), frdp->what, 1, 1024, 0, 1,
+		     GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2);
+
+    if (do_replace)
+    {
+	tmp = gtk_label_new(CONV(_("Replace with:")));
+	gtk_misc_set_alignment(GTK_MISC(tmp), (gfloat)0.0, (gfloat)0.5);
+	gtk_table_attach(GTK_TABLE(table), tmp, 0, 1, 1, 2,
+			 GTK_FILL, GTK_EXPAND, 2, 2);
+	frdp->with = gtk_entry_new();
+	gtk_signal_connect(GTK_OBJECT(frdp->with), "activate",
+			   GTK_SIGNAL_FUNC(find_replace_cb),
+			   GINT_TO_POINTER(FRD_R_FINDNEXT));
+	gtk_signal_connect_after(GTK_OBJECT(frdp->with), "key_press_event",
+				 GTK_SIGNAL_FUNC(find_key_press_event),
+				 (gpointer) frdp);
+	gtk_table_attach(GTK_TABLE(table), frdp->with, 1, 1024, 1, 2,
+			 GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2);
+
+	/*
+	 * Make the entry activation only change the input focus onto the
+	 * with item.
+	 */
+	gtk_signal_connect(GTK_OBJECT(frdp->what), "activate",
+			   GTK_SIGNAL_FUNC(entry_activate_cb), frdp->with);
+    }
+    else
+    {
+	/*
+	 * Make the entry activation do the search.
+	 */
+	gtk_signal_connect(GTK_OBJECT(frdp->what), "activate",
+			   GTK_SIGNAL_FUNC(find_replace_cb),
+			   GINT_TO_POINTER(FRD_FINDNEXT));
+    }
+
+    /* whole word only button */
+    frdp->wword = gtk_check_button_new_with_label(CONV(_("Match whole word only")));
+    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->wword),
+							(gboolean)wword);
+    if (do_replace)
+	gtk_table_attach(GTK_TABLE(table), frdp->wword, 0, 1023, 2, 3,
+			 GTK_FILL, GTK_EXPAND, 2, 2);
+    else
+	gtk_table_attach(GTK_TABLE(table), frdp->wword, 0, 1023, 1, 2,
+			 GTK_FILL, GTK_EXPAND, 2, 2);
+
+    /* match case button */
+    frdp->mcase = gtk_check_button_new_with_label(CONV(_("Match case")));
+    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->mcase),
+							     (gboolean)mcase);
+    if (do_replace)
+	gtk_table_attach(GTK_TABLE(table), frdp->mcase, 0, 1023, 3, 4,
+			 GTK_FILL, GTK_EXPAND, 2, 2);
+    else
+	gtk_table_attach(GTK_TABLE(table), frdp->mcase, 0, 1023, 2, 3,
+			 GTK_FILL, GTK_EXPAND, 2, 2);
+
+    tmp = gtk_frame_new(CONV(_("Direction")));
+    if (do_replace)
+	gtk_table_attach(GTK_TABLE(table), tmp, 1023, 1024, 2, 4,
+			 GTK_FILL, GTK_FILL, 2, 2);
+    else
+	gtk_table_attach(GTK_TABLE(table), tmp, 1023, 1024, 1, 3,
+			 GTK_FILL, GTK_FILL, 2, 2);
+    vbox = gtk_vbox_new(FALSE, 0);
+    gtk_container_border_width(GTK_CONTAINER(vbox), 0);
+    gtk_container_add(GTK_CONTAINER(tmp), vbox);
+
+    /* 'Up' and 'Down' buttons */
+    frdp->up = gtk_radio_button_new_with_label(NULL, CONV(_("Up")));
+    gtk_box_pack_start(GTK_BOX(vbox), frdp->up, TRUE, TRUE, 0);
+    frdp->down = gtk_radio_button_new_with_label(
+			gtk_radio_button_group(GTK_RADIO_BUTTON(frdp->up)),
+			CONV(_("Down")));
+    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->down), TRUE);
+#ifdef HAVE_GTK2
+    gtk_container_set_border_width(GTK_CONTAINER(vbox), 2);
+#endif
+    gtk_box_pack_start(GTK_BOX(vbox), frdp->down, TRUE, TRUE, 0);
+
+    /* vbox to hold the action buttons */
+    actionarea = gtk_vbutton_box_new();
+    gtk_container_border_width(GTK_CONTAINER(actionarea), 2);
+#ifndef HAVE_GTK2
+    if (do_replace)
+    {
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(actionarea),
+				  GTK_BUTTONBOX_END);
+	gtk_button_box_set_spacing(GTK_BUTTON_BOX(actionarea), 0);
+    }
+#endif
+    gtk_box_pack_end(GTK_BOX(hbox), actionarea, FALSE, FALSE, 0);
+
+    /* 'Find Next' button */
+#ifdef HAVE_GTK2
+    frdp->find = create_image_button(GTK_STOCK_FIND, _("Find Next"));
+#else
+    frdp->find = gtk_button_new_with_label(_("Find Next"));
+#endif
+    gtk_widget_set_sensitive(frdp->find, sensitive);
+
+    gtk_signal_connect(GTK_OBJECT(frdp->find), "clicked",
+		       GTK_SIGNAL_FUNC(find_replace_cb),
+		       (do_replace) ? GINT_TO_POINTER(FRD_R_FINDNEXT)
+				    : GINT_TO_POINTER(FRD_FINDNEXT));
+
+    GTK_WIDGET_SET_FLAGS(frdp->find, GTK_CAN_DEFAULT);
+    gtk_box_pack_start(GTK_BOX(actionarea), frdp->find, FALSE, FALSE, 0);
+    gtk_widget_grab_default(frdp->find);
+
+    if (do_replace)
+    {
+	/* 'Replace' button */
+#ifdef HAVE_GTK2
+	frdp->replace = create_image_button(GTK_STOCK_CONVERT, _("Replace"));
+#else
+	frdp->replace = gtk_button_new_with_label(_("Replace"));
+#endif
+	gtk_widget_set_sensitive(frdp->replace, sensitive);
+	GTK_WIDGET_SET_FLAGS(frdp->replace, GTK_CAN_DEFAULT);
+	gtk_box_pack_start(GTK_BOX(actionarea), frdp->replace, FALSE, FALSE, 0);
+	gtk_signal_connect(GTK_OBJECT(frdp->replace), "clicked",
+			   GTK_SIGNAL_FUNC(find_replace_cb),
+			   GINT_TO_POINTER(FRD_REPLACE));
+
+	/* 'Replace All' button */
+#ifdef HAVE_GTK2
+	frdp->all = create_image_button(GTK_STOCK_CONVERT, _("Replace All"));
+#else
+	frdp->all = gtk_button_new_with_label(_("Replace All"));
+#endif
+	gtk_widget_set_sensitive(frdp->all, sensitive);
+	GTK_WIDGET_SET_FLAGS(frdp->all, GTK_CAN_DEFAULT);
+	gtk_box_pack_start(GTK_BOX(actionarea), frdp->all, FALSE, FALSE, 0);
+	gtk_signal_connect(GTK_OBJECT(frdp->all), "clicked",
+			   GTK_SIGNAL_FUNC(find_replace_cb),
+			   GINT_TO_POINTER(FRD_REPLACEALL));
+    }
+
+    /* 'Cancel' button */
+#ifdef HAVE_GTK2
+    tmp = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+#else
+    tmp = gtk_button_new_with_label(_("Cancel"));
+#endif
+    GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
+    gtk_box_pack_end(GTK_BOX(actionarea), tmp, FALSE, FALSE, 0);
+    gtk_signal_connect_object(GTK_OBJECT(tmp),
+			      "clicked", GTK_SIGNAL_FUNC(gtk_widget_hide),
+			      GTK_OBJECT(frdp->dialog));
+    gtk_signal_connect_object(GTK_OBJECT(frdp->dialog),
+			      "delete_event", GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete),
+			      GTK_OBJECT(frdp->dialog));
+
+    tmp = gtk_vseparator_new();
+#ifdef HAVE_GTK2
+    gtk_box_pack_end(GTK_BOX(hbox), tmp, FALSE, FALSE, 10);
+#else
+    gtk_box_pack_end(GTK_BOX(hbox), tmp, FALSE, TRUE, 0);
+#endif
+
+#ifndef HAVE_GTK2
+    gtk_widget_grab_focus(frdp->what);
+
+    /* show the frame and realize the frdp->dialog this gives us a window size
+     * request that we'll use to position the window within the boundary of
+     * the mainwin --dbv */
+    gtk_widget_show_all(frame);
+    gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin),
+				      GTK_WIDGET(frdp->dialog), VW_POS_MOUSE);
+    gui_gtk_synch_fonts();
+    gtk_widget_show_all(frdp->dialog);
+#endif
+
+#ifdef HAVE_GTK2
+    /* Suppress automatic show of the unused action area */
+    gtk_widget_hide(GTK_DIALOG(frdp->dialog)->action_area);
+    gtk_widget_show_all(hbox);
+    gtk_widget_show(frdp->dialog);
+#endif
+
+    vim_free(entry_text);
+#ifdef HAVE_GTK2
+    vim_free(conv_buffer);
+#endif
+#undef CONV
+}
+
+    void
+gui_mch_find_dialog(exarg_T *eap)
+{
+    if (gui.in_use)
+	find_replace_dialog_create(eap->arg, FALSE);
+}
+
+    void
+gui_mch_replace_dialog(exarg_T *eap)
+{
+    if (gui.in_use)
+	find_replace_dialog_create(eap->arg, TRUE);
+}
+
+
+#if !defined(HAVE_GTK2) || defined(PROTO)
+/*
+ * Synchronize all gui elements, which are dependant upon the
+ * main text font used. Those are in esp. the find/replace dialogs.
+ * If you don't understand why this should be needed, please try to
+ * search for "pięść" in iso8859-2.
+ *
+ * (<danielk> I converted the comment above to UTF-8 to put
+ *  a stopper to the encoding mess.  Forgive me :)
+ *
+ * Obsolete with GTK2.
+ */
+    void
+gui_gtk_synch_fonts(void)
+{
+    SharedFindReplace *frdp;
+    int do_replace;
+
+    /* OK this loop is a bit tricky... */
+    for (do_replace = 0; do_replace <= 1; ++do_replace)
+    {
+	frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
+	if (frdp->dialog)
+	{
+	    GtkStyle *style;
+
+	    /* synch the font with whats used by the text itself */
+	    style = gtk_style_copy(gtk_widget_get_style(frdp->what));
+	    gdk_font_unref(style->font);
+# ifdef FEAT_XFONTSET
+	    if (gui.fontset != NOFONTSET)
+		style->font = gui.fontset;
+	    else
+# endif
+		style->font = gui.norm_font;
+	    gdk_font_ref(style->font);
+	    gtk_widget_set_style(frdp->what, style);
+	    gtk_style_unref(style);
+	    if (do_replace)
+	    {
+		style = gtk_style_copy(gtk_widget_get_style(frdp->with));
+		gdk_font_unref(style->font);
+# ifdef FEAT_XFONTSET
+		if (gui.fontset != NOFONTSET)
+		    style->font = gui.fontset;
+		else
+# endif
+		    style->font = gui.norm_font;
+		gdk_font_ref(style->font);
+		gtk_widget_set_style(frdp->with, style);
+		gtk_style_unref(style);
+	    }
+	}
+    }
+}
+#endif /* !HAVE_GTK2 */
+
+
+/*
+ * Callback for actions of the find and replace dialogs
+ */
+/*ARGSUSED*/
+    static void
+find_replace_cb(GtkWidget *widget, gpointer data)
+{
+    int			flags;
+    char_u		*find_text;
+    char_u		*repl_text;
+    gboolean		direction_down;
+    SharedFindReplace	*sfr;
+    int			rc;
+
+    flags = (int)(long)data;	    /* avoid a lint warning here */
+
+    /* Get the search/replace strings from the dialog */
+    if (flags == FRD_FINDNEXT)
+    {
+	repl_text = NULL;
+	sfr = &find_widgets;
+    }
+    else
+    {
+	repl_text = (char_u *)gtk_entry_get_text(GTK_ENTRY(repl_widgets.with));
+	sfr = &repl_widgets;
+    }
+
+    find_text = (char_u *)gtk_entry_get_text(GTK_ENTRY(sfr->what));
+    direction_down = GTK_TOGGLE_BUTTON(sfr->down)->active;
+
+    if (GTK_TOGGLE_BUTTON(sfr->wword)->active)
+	flags |= FRD_WHOLE_WORD;
+    if (GTK_TOGGLE_BUTTON(sfr->mcase)->active)
+	flags |= FRD_MATCH_CASE;
+
+#ifdef HAVE_GTK2
+    repl_text = CONVERT_FROM_UTF8(repl_text);
+    find_text = CONVERT_FROM_UTF8(find_text);
+#endif
+    rc = gui_do_findrepl(flags, find_text, repl_text, direction_down);
+#ifdef HAVE_GTK2
+    CONVERT_FROM_UTF8_FREE(repl_text);
+    CONVERT_FROM_UTF8_FREE(find_text);
+#endif
+
+    if (rc && gtk_main_level() > 0)
+	gtk_main_quit(); /* make sure cmd will be handled immediately */
+}
+
+/* our usual callback function */
+/*ARGSUSED*/
+    static void
+entry_activate_cb(GtkWidget *widget, gpointer data)
+{
+    gtk_widget_grab_focus(GTK_WIDGET(data));
+}
+
+/*
+ * Syncing the find/replace dialogs on the fly is utterly useless crack,
+ * and causes nothing but problems.  Please tell me a use case for which
+ * you'd need both a find dialog and a find/replace one at the same time,
+ * without being able to actually use them separately since they're syncing
+ * all the time.  I don't think it's worthwhile to fix this nonsense,
+ * particularly evil incarnation of braindeadness, whatever; I'd much rather
+ * see it extinguished from this planet.  Thanks for listening.  Sorry.
+ */
+    static void
+entry_changed_cb(GtkWidget * entry, GtkWidget * dialog)
+{
+    const gchar	*entry_text;
+    gboolean	nonempty;
+
+    entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
+
+    if (!entry_text)
+	return;			/* shouldn't happen */
+
+    nonempty = (entry_text[0] != '\0');
+
+    if (dialog == find_widgets.dialog)
+    {
+	gtk_widget_set_sensitive(find_widgets.find, nonempty);
+    }
+
+    if (dialog == repl_widgets.dialog)
+    {
+	gtk_widget_set_sensitive(repl_widgets.find, nonempty);
+	gtk_widget_set_sensitive(repl_widgets.replace, nonempty);
+	gtk_widget_set_sensitive(repl_widgets.all, nonempty);
+    }
+}
+
+/*
+ * ":helpfind"
+ */
+/*ARGSUSED*/
+    void
+ex_helpfind(eap)
+    exarg_T	*eap;
+{
+    /* This will fail when menus are not loaded.  Well, it's only for
+     * backwards compatibility anyway. */
+    do_cmdline_cmd((char_u *)"emenu ToolBar.FindHelp");
+}
+
+#if !defined(HAVE_GTK2) || defined(PROTO) /* Crack crack crack.  Brrrr. */
+
+/*  gui_gtk_position_in_parent
+ *
+ *  this function causes a child window to be placed within the boundary of
+ *  the parent (mainwin) window.
+ *
+ *  you can specify where the window will be positioned by the third argument
+ *  (defined in gui.h):
+ *	VW_POS_CENTER		at center of parent window
+ *	VW_POS_MOUSE		center of child at mouse position
+ *	VW_POS_TOP_CENTER	top of child at top of parent centered
+ *				horizontally about the mouse.
+ *
+ *  NOTE: for this function to act as desired the child window must have a
+ *	  window size requested.  this can be accomplished by packing/placing
+ *	  child widgets onto a gtk_frame widget rather than the gtk_window
+ *	  widget...
+ *
+ *  brent -- dbv
+ */
+    void
+gui_gtk_position_in_parent(
+	GtkWidget	*parent,
+	GtkWidget	*child,
+	gui_win_pos_T	where)
+{
+    GtkRequisition	c_size;
+    gint		xPm, yPm;
+    gint		xP, yP, wP, hP, pos_x, pos_y;
+
+    /* make sure the child widget is set up then get its size. */
+    gtk_widget_size_request(child, &c_size);
+
+    /* get origin and size of parent window */
+    gdk_window_get_origin((GdkWindow *)(parent->window), &xP, &yP);
+    gdk_window_get_size((GdkWindow *)(parent->window), &wP, &hP);
+
+    if (c_size.width > wP || c_size.height > hP)
+    {
+	/* doh! maybe the user should consider giving gVim a little more
+	 * screen real estate */
+	gtk_widget_set_uposition(child , xP + 2 , yP + 2);
+	return;
+    }
+
+    if (where == VW_POS_MOUSE)
+    {
+	/* position window at mouse pointer */
+	gtk_widget_get_pointer(parent, &xPm, &yPm);
+	pos_x = xP + xPm - (c_size.width) / 2;
+	pos_y = yP + yPm - (c_size.height) / 2;
+    }
+    else
+    {
+	/* set child x origin so it is in center of Vim window */
+	pos_x =  xP + (wP - c_size.width) / 2;
+
+	if (where == VW_POS_TOP_CENTER)
+	    pos_y = yP + 2;
+	else
+	    /* where == VW_POS_CENTER */
+	    pos_y = yP + (hP - c_size.height) / 2;
+    }
+
+    /* now, make sure the window will be inside the Vim window... */
+    if (pos_x < xP)
+	pos_x = xP + 2;
+    if (pos_y < yP)
+	pos_y = yP + 2;
+    if ((pos_x + c_size.width) > (wP + xP))
+	pos_x = xP + wP - c_size.width - 2;
+    /* Assume 'guiheadroom' indicates the title bar height... */
+    if ((pos_y + c_size.height + p_ghr / 2) > (hP + yP))
+	pos_y = yP + hP - c_size.height - 2 - p_ghr / 2;
+
+    gtk_widget_set_uposition(child, pos_x, pos_y);
+}
+
+#endif /* !HAVE_GTK2 */
+
