/* 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 <martin@dalecki.de>
 *
 * 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
# ifdef bind_textdomain_codeset
#  undef bind_textdomain_codeset
# 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

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);
#ifndef HAVE_GTK2
static void gui_gtk_position_in_parent(GtkWidget *parent, GtkWidget *child, gui_win_pos_T where);
#endif

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

/*ARGSUSED*/
    static gint
toolbar_button_focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
{
    /* When we're in a GtkPlug, we don't have window focus events, only widget focus.
     * To emulate stand-alone gvim, if a button gets focus (e.g., <Tab> into GtkPlug)
     * immediately pass it to mainwin.
     */
    if (gtk_socket_id != 0)
	gtk_widget_grab_focus(gui.drawarea);

    return TRUE;
}
#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 necessary, since there is no other way in GTK+ 1 to get the
 * not automatically parsed accelerator 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]);
	    if (tooltip != NULL && !utf_valid_string(tooltip, NULL))
		/* Invalid text, can happen when 'encoding' is changed.  Avoid
		 * a nasty GTK error message, skip the tooltip. */
		CONVERT_TO_UTF8_FREE(tooltip);

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

	    if (gtk_socket_id != 0)
		gtk_signal_connect(GTK_OBJECT(menu->id), "focus_in_event",
			GTK_SIGNAL_FUNC(toolbar_button_focus_in_event), NULL);

	    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 == NULL || 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 (!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 accelerators 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);
# else
#  if 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
# 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		idx = 0;

    for (node = menu->parent->children; node != menu; node = node->next)
    {
	g_return_val_if_fail(node != NULL, -1);
	++idx;
    }

    return idx;
}
#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]);
	if (tooltip == NULL || utf_valid_string(tooltip, NULL))
	    /* Only set the tooltip when it's valid utf-8. */
# 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
 */
#if defined(HAVE_GTK2) && GTK_CHECK_VERSION(2,4,0)
# define USE_FILE_CHOOSER
#endif

#ifndef USE_FILE_CHOOSER
/*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;
}
#endif

/*
 * 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)
{
#ifdef USE_FILE_CHOOSER
    GtkWidget		*fc;
#endif
    char_u		dirbuf[MAXPATHL];

# ifdef HAVE_GTK2
    title = CONVERT_TO_UTF8(title);
# endif

    /* GTK has a bug, it only works with an absolute path. */
    if (initdir == NULL || *initdir == NUL)
	mch_dirname(dirbuf, MAXPATHL);
    else if (vim_FullName(initdir, dirbuf, MAXPATHL - 2, FALSE) == FAIL)
	dirbuf[0] = NUL;
    /* Always need a trailing slash for a directory. */
    add_pathsep(dirbuf);

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

#ifdef USE_FILE_CHOOSER
    /* We create the dialog each time, so that the button text can be "Open"
     * or "Save" according to the action. */
    fc = gtk_file_chooser_dialog_new((const gchar *)title,
	    GTK_WINDOW(gui.mainwin),
	    saving ? GTK_FILE_CHOOSER_ACTION_SAVE
					   : GTK_FILE_CHOOSER_ACTION_OPEN,
	    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
	    saving ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
	    NULL);
    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc),
						       (const gchar *)dirbuf);

    gui.browse_fname = NULL;
    if (gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_ACCEPT)
    {
	char *filename;

	filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
	gui.browse_fname = (char_u *)g_strdup(filename);
	g_free(filename);
    }
    gtk_widget_destroy(GTK_WIDGET(fc));

#else

    if (gui.filedlg == NULL)
    {
	GtkFileSelection	*fs;	/* shortcut */

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

    /* Concatenate "initdir" and "dflt". */
    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);
#endif

# ifdef HAVE_GTK2
    CONVERT_TO_UTF8_FREE(title);
# endif
    if (gui.browse_fname == NULL)
	return NULL;

    /* shorten the file name if possible */
    return vim_strsave(shorten_fname1(gui.browse_fname));
}

#if defined(HAVE_GTK2) || defined(PROTO)

/*
 * Put up a directory selector
 * Returns the selected name in allocated memory, or NULL for Cancel.
 * title			title for the window
 * dflt				default name
 * initdir			initial directory, NULL for current dir
 */
/*ARGSUSED*/
    char_u *
gui_mch_browsedir(
	       char_u *title,
	       char_u *initdir)
{
# if defined(GTK_FILE_CHOOSER)	    /* Only in GTK 2.4 and later. */
    char_u		dirbuf[MAXPATHL];
    char_u		*p;
    GtkWidget		*dirdlg;	    /* file selection dialog */
    char_u		*dirname = NULL;

    title = CONVERT_TO_UTF8(title);

    dirdlg = gtk_file_chooser_dialog_new(
	    (const gchar *)title,
	    GTK_WINDOW(gui.mainwin),
	    GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
	    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
	    GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
	    NULL);

    CONVERT_TO_UTF8_FREE(title);

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

    /* GTK appears to insist on an absolute path. */
    if (initdir == NULL || *initdir == NUL
	       || vim_FullName(initdir, dirbuf, MAXPATHL - 10, FALSE) == FAIL)
	mch_dirname(dirbuf, MAXPATHL - 10);

    /* Always need a trailing slash for a directory.
     * Also add a dummy file name, so that we get to the directory. */
    add_pathsep(dirbuf);
    STRCAT(dirbuf, "@zd(*&1|");
    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dirdlg),
						      (const gchar *)dirbuf);

    /* Run the dialog. */
    if (gtk_dialog_run(GTK_DIALOG(dirdlg)) == GTK_RESPONSE_ACCEPT)
	dirname = (char_u *)gtk_file_chooser_get_filename(
						    GTK_FILE_CHOOSER(dirdlg));
    gtk_widget_destroy(dirdlg);
    if (dirname == NULL)
	return NULL;

    /* shorten the file name if possible */
    p = vim_strsave(shorten_fname1(dirname));
    g_free(dirname);
    return p;

# else
    /* For GTK 2.2 and earlier: fall back to ordinary file selector. */
    return gui_mch_browse(0, title, NULL, NULL, initdir, NULL);
# endif
}
#endif


#endif	/* FEAT_BROWSE */

#if defined(FEAT_GUI_DIALOG) && !defined(HAVE_GTK2)

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));
	vim_strncpy(dialog_textfield, (char_u *)text, IOSIZE - 1);
    }

    /* 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 (or Space) when there is no default button. */
    if (data->ignore_enter && (event->keyval == GDK_Return
						     || event->keyval == ' '))
	return TRUE;
    else    /* A different key was pressed, return to normal behavior */
	data->ignore_enter = FALSE;

    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,
		    (GtkAccelFlags)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)) || defined(PROTO)

    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; )
	{
	    if (*p == DLG_BUTTON_SEP)
	    {
		*p++ = NUL;
		array[count++] = (char *)p;
	    }
	    else if (*p == DLG_HOTKEY_CHAR)
		*p++ = '_';
	    else
		mb_ptr_adv(p);
	}
	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	    idx;

    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 (idx = 1; idx <= n_buttons; ++idx)
    {
	char	*label;
	char_u	*label8;

	label = buttons[idx - 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, idx);
	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 (or Space) when there is no default button. */
    if (di->ignore_enter && (event->keyval == GDK_Return
						     || event->keyval == ' '))
	return TRUE;
    else    /* A different key was pressed, return to normal behavior */
	di->ignore_enter = FALSE;

    /* 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 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 (response == GTK_RESPONSE_ACCEPT)	    /* Enter pressed */
	    response = def_but;
	if (textfield != NULL)
	{
	    text = (char_u *)gtk_entry_get_text(GTK_ENTRY(entry));
	    text = CONVERT_FROM_UTF8(text);

	    vim_strncpy(textfield, text, IOSIZE - 1);

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

/* Ugly global variable to pass "mouse_pos" flag from gui_make_popup() to
 * popup_menu_position_func(). */
static int popup_mouse_pos;

/*
 * 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)
{
    gdk_window_get_origin(gui.drawarea->window, x, y);

    if (popup_mouse_pos)
    {
	int	mx, my;

	gui_mch_getmouse(&mx, &my);
	*x += mx;
	*y += my;
    }
    else if (curwin != NULL && gui.drawarea != NULL && gui.drawarea->window != NULL)
    {
	/* 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, int mouse_pos)
{
    vimmenu_T *menu;

    popup_mouse_pos = mouse_pos;

    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 delightful 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
 */
    static 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))

    gtk_widget_set_uposition(child, pos_x, pos_y);
}

#endif /* !HAVE_GTK2 */
