diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index d0b82f1..39f1e84 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -741,6 +741,7 @@
 	$(OUTDIR)/findfile.o \
 	$(OUTDIR)/fold.o \
 	$(OUTDIR)/getchar.o \
+	$(OUTDIR)/gui_xim.o \
 	$(OUTDIR)/hardcopy.o \
 	$(OUTDIR)/hashtab.o \
 	$(OUTDIR)/highlight.o \
diff --git a/src/Make_morph.mak b/src/Make_morph.mak
index 4efc1d6..ce615b2 100644
--- a/src/Make_morph.mak
+++ b/src/Make_morph.mak
@@ -61,6 +61,7 @@
 	findfile.c						\
 	fold.c							\
 	getchar.c						\
+	gui_xim.c						\
 	hardcopy.c						\
 	hashtab.c						\
 	highlight.c						\
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index aec94a9..8559c9d 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -761,6 +761,7 @@
 	$(OUTDIR)\findfile.obj \
 	$(OUTDIR)\fold.obj \
 	$(OUTDIR)\getchar.obj \
+	$(OUTDIR)\gui_xim.obj \
 	$(OUTDIR)\hardcopy.obj \
 	$(OUTDIR)\hashtab.obj \
 	$(OUTDIR)\highlight.obj \
@@ -1591,6 +1592,8 @@
 
 $(OUTDIR)/getchar.obj:	$(OUTDIR) getchar.c  $(INCL)
 
+$(OUTDIR)/gui_xim.obj:	$(OUTDIR) gui_xim.c  $(INCL)
+
 $(OUTDIR)/hardcopy.obj:	$(OUTDIR) hardcopy.c  $(INCL) version.h
 
 $(OUTDIR)/hashtab.obj:	$(OUTDIR) hashtab.c  $(INCL)
@@ -1908,6 +1911,7 @@
 	proto/filepath.pro \
 	proto/findfile.pro \
 	proto/getchar.pro \
+	proto/gui_xim.pro \
 	proto/hardcopy.pro \
 	proto/hashtab.pro \
 	proto/highlight.pro \
diff --git a/src/Make_vms.mms b/src/Make_vms.mms
index e5ff857..1194acd 100644
--- a/src/Make_vms.mms
+++ b/src/Make_vms.mms
@@ -334,6 +334,7 @@
 	findfile.c \
 	fold.c \
 	getchar.c \
+	gui_xim.c \
 	hardcopy.c \
 	hashtab.c \
 	highlight.c \
@@ -445,6 +446,7 @@
 	findfile.obj \
 	fold.obj \
 	getchar.obj \
+	gui_xim.obj \
 	hardcopy.obj \
 	hashtab.obj \
 	highlight.obj \
@@ -818,6 +820,10 @@
  ascii.h keymap.h term.h macros.h structs.h regexp.h \
  gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
  globals.h
+gui_xim.obj : gui_xim.c vim.h [.auto]config.h feature.h os_unix.h \
+ ascii.h keymap.h term.h macros.h structs.h regexp.h \
+ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
+ globals.h
 hardcopy.obj : hardcopy.c vim.h [.auto]config.h feature.h os_unix.h \
  ascii.h keymap.h term.h macros.h structs.h regexp.h \
  gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
diff --git a/src/Makefile b/src/Makefile
index 9a8e24f..520ef0b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1636,6 +1636,7 @@
 	findfile.c \
 	fold.c \
 	getchar.c \
+	gui_xim.c \
 	hardcopy.c \
 	hashtab.c \
 	highlight.c \
@@ -1785,6 +1786,7 @@
 	objects/findfile.o \
 	objects/fold.o \
 	objects/getchar.o \
+	objects/gui_xim.o \
 	objects/hardcopy.o \
 	objects/hashtab.o \
 	objects/highlight.o \
@@ -1950,6 +1952,7 @@
 	findfile.pro \
 	fold.pro \
 	getchar.pro \
+	gui_xim.pro \
 	gui_beval.pro \
 	hardcopy.pro \
 	hashtab.pro \
@@ -3301,6 +3304,9 @@
 objects/gui_x11.o: gui_x11.c
 	$(CCC) -o $@ gui_x11.c
 
+objects/gui_xim.o: gui_xim.c
+	$(CCC) -o $@ gui_xim.c
+
 objects/gui_photon.o: gui_photon.c
 	$(CCC) -o $@ gui_photon.c
 
@@ -4239,6 +4245,11 @@
  proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
  proto.h globals.h ../runtime/vim32x32.xpm ../runtime/vim16x16.xpm \
  ../runtime/vim48x48.xpm
+objects/gui_xim.o: gui_xim.c vim.h protodef.h auto/config.h feature.h os_unix.h \
+ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
+ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
+ proto.h globals.h ../runtime/vim32x32.xpm ../runtime/vim16x16.xpm \
+ ../runtime/vim48x48.xpm
 objects/gui_at_sb.o: gui_at_sb.c vim.h protodef.h auto/config.h feature.h \
  os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
  proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
diff --git a/src/gui_xim.c b/src/gui_xim.c
new file mode 100644
index 0000000..e3a48b5
--- /dev/null
+++ b/src/gui_xim.c
@@ -0,0 +1,1777 @@
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * 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.
+ */
+
+/*
+ * gui_xim.c: functions for the X Input Method
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_GUI_GTK) && defined(FEAT_XIM)
+# if GTK_CHECK_VERSION(3,0,0)
+#  include <gdk/gdkkeysyms-compat.h>
+# else
+#  include <gdk/gdkkeysyms.h>
+# endif
+# ifdef MSWIN
+#  include <gdk/gdkwin32.h>
+# else
+#  include <gdk/gdkx.h>
+# endif
+#endif
+
+/*
+ * XIM often causes trouble.  Define XIM_DEBUG to get a log of XIM callbacks
+ * in the "xim.log" file.
+ */
+// #define XIM_DEBUG
+#ifdef XIM_DEBUG
+    static void
+xim_log(char *s, ...)
+{
+    va_list arglist;
+    static FILE *fd = NULL;
+
+    if (fd == (FILE *)-1)
+	return;
+    if (fd == NULL)
+    {
+	fd = mch_fopen("xim.log", "w");
+	if (fd == NULL)
+	{
+	    emsg("Cannot open xim.log");
+	    fd = (FILE *)-1;
+	    return;
+	}
+    }
+
+    va_start(arglist, s);
+    vfprintf(fd, s, arglist);
+    va_end(arglist);
+}
+#endif
+
+#ifdef FEAT_GUI
+# define USE_IMACTIVATEFUNC (!gui.in_use && *p_imaf != NUL)
+# define USE_IMSTATUSFUNC (!gui.in_use && *p_imsf != NUL)
+#else
+# define USE_IMACTIVATEFUNC (*p_imaf != NUL)
+# define USE_IMSTATUSFUNC (*p_imsf != NUL)
+#endif
+
+#if defined(FEAT_EVAL) && \
+    (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL))
+    static void
+call_imactivatefunc(int active)
+{
+    typval_T argv[2];
+
+    argv[0].v_type = VAR_NUMBER;
+    argv[0].vval.v_number = active ? 1 : 0;
+    argv[1].v_type = VAR_UNKNOWN;
+    (void)call_func_retnr(p_imaf, 1, argv);
+}
+
+    static int
+call_imstatusfunc(void)
+{
+    int is_active;
+
+    // FIXME: Don't execute user function in unsafe situation.
+    if (exiting || is_autocmd_blocked())
+	return FALSE;
+    // FIXME: :py print 'xxx' is shown duplicate result.
+    // Use silent to avoid it.
+    ++msg_silent;
+    is_active = call_func_retnr(p_imsf, 0, NULL);
+    --msg_silent;
+    return (is_active > 0);
+}
+#endif
+
+#if defined(FEAT_XIM) || defined(PROTO)
+
+# if defined(FEAT_GUI_GTK) || defined(PROTO)
+static int xim_has_preediting INIT(= FALSE);  // IM current status
+
+/*
+ * Set preedit_start_col to the current cursor position.
+ */
+    static void
+init_preedit_start_col(void)
+{
+    if (State & CMDLINE)
+	preedit_start_col = cmdline_getvcol_cursor();
+    else if (curwin != NULL && curwin->w_buffer != NULL)
+	getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL);
+    // Prevent that preediting marks the buffer as changed.
+    xim_changed_while_preediting = curbuf->b_changed;
+}
+
+static int im_is_active	       = FALSE;	// IM is enabled for current mode
+static int preedit_is_active   = FALSE;
+static int im_preedit_cursor   = 0;	// cursor offset in characters
+static int im_preedit_trailing = 0;	// number of characters after cursor
+
+static unsigned long im_commit_handler_id  = 0;
+static unsigned int  im_activatekey_keyval = GDK_VoidSymbol;
+static unsigned int  im_activatekey_state  = 0;
+
+static GtkWidget *preedit_window = NULL;
+static GtkWidget *preedit_label = NULL;
+
+static void im_preedit_window_set_position(void);
+
+    void
+im_set_active(int active)
+{
+    int was_active;
+
+    was_active = !!im_get_status();
+    im_is_active = (active && !p_imdisable);
+
+    if (im_is_active != was_active)
+	xim_reset();
+}
+
+    void
+xim_set_focus(int focus)
+{
+    if (xic != NULL)
+    {
+	if (focus)
+	    gtk_im_context_focus_in(xic);
+	else
+	    gtk_im_context_focus_out(xic);
+    }
+}
+
+    void
+im_set_position(int row, int col)
+{
+    if (xic != NULL)
+    {
+	GdkRectangle area;
+
+	area.x = FILL_X(col);
+	area.y = FILL_Y(row);
+	area.width  = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1);
+	area.height = gui.char_height;
+
+	gtk_im_context_set_cursor_location(xic, &area);
+
+	if (p_imst == IM_OVER_THE_SPOT)
+	    im_preedit_window_set_position();
+    }
+}
+
+#  if 0 || defined(PROTO) // apparently only used in gui_x11.c
+    void
+xim_set_preedit(void)
+{
+    im_set_position(gui.row, gui.col);
+}
+#  endif
+
+    static void
+im_add_to_input(char_u *str, int len)
+{
+    // Convert from 'termencoding' (always "utf-8") to 'encoding'
+    if (input_conv.vc_type != CONV_NONE)
+    {
+	str = string_convert(&input_conv, str, &len);
+	g_return_if_fail(str != NULL);
+    }
+
+    add_to_input_buf_csi(str, len);
+
+    if (input_conv.vc_type != CONV_NONE)
+	vim_free(str);
+
+    if (p_mh) // blank out the pointer if necessary
+	gui_mch_mousehide(TRUE);
+}
+
+     static void
+im_preedit_window_set_position(void)
+{
+    int x, y, width, height;
+    int screen_x, screen_y, screen_width, screen_height;
+
+    if (preedit_window == NULL)
+	return;
+
+    gui_gtk_get_screen_geom_of_win(gui.drawarea,
+			  &screen_x, &screen_y, &screen_width, &screen_height);
+    gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y);
+    gtk_window_get_size(GTK_WINDOW(preedit_window), &width, &height);
+    x = x + FILL_X(gui.col);
+    y = y + FILL_Y(gui.row);
+    if (x + width > screen_x + screen_width)
+	x = screen_x + screen_width - width;
+    if (y + height > screen_y + screen_height)
+	y = screen_y + screen_height - height;
+    gtk_window_move(GTK_WINDOW(preedit_window), x, y);
+}
+
+    static void
+im_preedit_window_open()
+{
+    char *preedit_string;
+#if !GTK_CHECK_VERSION(3,16,0)
+    char buf[8];
+#endif
+    PangoAttrList *attr_list;
+    PangoLayout *layout;
+#if GTK_CHECK_VERSION(3,0,0)
+# if !GTK_CHECK_VERSION(3,16,0)
+    GdkRGBA color;
+# endif
+#else
+    GdkColor color;
+#endif
+    gint w, h;
+
+    if (preedit_window == NULL)
+    {
+	preedit_window = gtk_window_new(GTK_WINDOW_POPUP);
+	gtk_window_set_transient_for(GTK_WINDOW(preedit_window),
+						     GTK_WINDOW(gui.mainwin));
+	preedit_label = gtk_label_new("");
+	gtk_widget_set_name(preedit_label, "vim-gui-preedit-area");
+	gtk_container_add(GTK_CONTAINER(preedit_window), preedit_label);
+    }
+
+#if GTK_CHECK_VERSION(3,16,0)
+    {
+	GtkStyleContext * const context
+				  = gtk_widget_get_style_context(gui.drawarea);
+	GtkCssProvider * const provider = gtk_css_provider_new();
+	gchar		   *css = NULL;
+	const char * const fontname
+			   = pango_font_description_get_family(gui.norm_font);
+	gint	fontsize
+		= pango_font_description_get_size(gui.norm_font) / PANGO_SCALE;
+	gchar	*fontsize_propval = NULL;
+
+	if (!pango_font_description_get_size_is_absolute(gui.norm_font))
+	{
+	    // fontsize was given in points.  Convert it into that in pixels
+	    // to use with CSS.
+	    GdkScreen * const screen
+		  = gdk_window_get_screen(gtk_widget_get_window(gui.mainwin));
+	    const gdouble dpi = gdk_screen_get_resolution(screen);
+	    fontsize = dpi * fontsize / 72;
+	}
+	if (fontsize > 0)
+	    fontsize_propval = g_strdup_printf("%dpx", fontsize);
+	else
+	    fontsize_propval = g_strdup_printf("inherit");
+
+	css = g_strdup_printf(
+		"widget#vim-gui-preedit-area {\n"
+		"  font-family: %s,monospace;\n"
+		"  font-size: %s;\n"
+		"  color: #%.2lx%.2lx%.2lx;\n"
+		"  background-color: #%.2lx%.2lx%.2lx;\n"
+		"}\n",
+		fontname != NULL ? fontname : "inherit",
+		fontsize_propval,
+		(gui.norm_pixel >> 16) & 0xff,
+		(gui.norm_pixel >> 8) & 0xff,
+		gui.norm_pixel & 0xff,
+		(gui.back_pixel >> 16) & 0xff,
+		(gui.back_pixel >> 8) & 0xff,
+		gui.back_pixel & 0xff);
+
+	gtk_css_provider_load_from_data(provider, css, -1, NULL);
+	gtk_style_context_add_provider(context,
+				     GTK_STYLE_PROVIDER(provider), G_MAXUINT);
+
+	g_free(css);
+	g_free(fontsize_propval);
+	g_object_unref(provider);
+    }
+#elif GTK_CHECK_VERSION(3,0,0)
+    gtk_widget_override_font(preedit_label, gui.norm_font);
+
+    vim_snprintf(buf, sizeof(buf), "#%06X", gui.norm_pixel);
+    gdk_rgba_parse(&color, buf);
+    gtk_widget_override_color(preedit_label, GTK_STATE_FLAG_NORMAL, &color);
+
+    vim_snprintf(buf, sizeof(buf), "#%06X", gui.back_pixel);
+    gdk_rgba_parse(&color, buf);
+    gtk_widget_override_background_color(preedit_label, GTK_STATE_FLAG_NORMAL,
+								      &color);
+#else
+    gtk_widget_modify_font(preedit_label, gui.norm_font);
+
+    vim_snprintf(buf, sizeof(buf), "#%06X", (unsigned)gui.norm_pixel);
+    gdk_color_parse(buf, &color);
+    gtk_widget_modify_fg(preedit_label, GTK_STATE_NORMAL, &color);
+
+    vim_snprintf(buf, sizeof(buf), "#%06X", (unsigned)gui.back_pixel);
+    gdk_color_parse(buf, &color);
+    gtk_widget_modify_bg(preedit_window, GTK_STATE_NORMAL, &color);
+#endif
+
+    gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
+
+    if (preedit_string[0] != NUL)
+    {
+	gtk_label_set_text(GTK_LABEL(preedit_label), preedit_string);
+	gtk_label_set_attributes(GTK_LABEL(preedit_label), attr_list);
+
+	layout = gtk_label_get_layout(GTK_LABEL(preedit_label));
+	pango_layout_get_pixel_size(layout, &w, &h);
+	h = MAX(h, gui.char_height);
+	gtk_window_resize(GTK_WINDOW(preedit_window), w, h);
+
+	gtk_widget_show_all(preedit_window);
+
+	im_preedit_window_set_position();
+    }
+
+    g_free(preedit_string);
+    pango_attr_list_unref(attr_list);
+}
+
+    static void
+im_preedit_window_close()
+{
+    if (preedit_window != NULL)
+	gtk_widget_hide(preedit_window);
+}
+
+    static void
+im_show_preedit()
+{
+    im_preedit_window_open();
+
+    if (p_mh) // blank out the pointer if necessary
+	gui_mch_mousehide(TRUE);
+}
+
+    static void
+im_delete_preedit(void)
+{
+    char_u bskey[]  = {CSI, 'k', 'b'};
+    char_u delkey[] = {CSI, 'k', 'D'};
+
+    if (p_imst == IM_OVER_THE_SPOT)
+    {
+	im_preedit_window_close();
+	return;
+    }
+
+    if (State & NORMAL
+#ifdef FEAT_TERMINAL
+	    && !term_use_loop()
+#endif
+       )
+    {
+	im_preedit_cursor = 0;
+	return;
+    }
+    for (; im_preedit_cursor > 0; --im_preedit_cursor)
+	add_to_input_buf(bskey, (int)sizeof(bskey));
+
+    for (; im_preedit_trailing > 0; --im_preedit_trailing)
+	add_to_input_buf(delkey, (int)sizeof(delkey));
+}
+
+/*
+ * Move the cursor left by "num_move_back" characters.
+ * Note that ins_left() checks im_is_preediting() to avoid breaking undo for
+ * these K_LEFT keys.
+ */
+    static void
+im_correct_cursor(int num_move_back)
+{
+    char_u backkey[] = {CSI, 'k', 'l'};
+
+    if (State & NORMAL)
+	return;
+#  ifdef FEAT_RIGHTLEFT
+    if ((State & CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl)
+	backkey[2] = 'r';
+#  endif
+    for (; num_move_back > 0; --num_move_back)
+	add_to_input_buf(backkey, (int)sizeof(backkey));
+}
+
+static int xim_expected_char = NUL;
+static int xim_ignored_char = FALSE;
+
+/*
+ * Update the mode and cursor while in an IM callback.
+ */
+    static void
+im_show_info(void)
+{
+    int	    old_vgetc_busy;
+
+    old_vgetc_busy = vgetc_busy;
+    vgetc_busy = TRUE;
+    showmode();
+    vgetc_busy = old_vgetc_busy;
+    if ((State & NORMAL) || (State & INSERT))
+	setcursor();
+    out_flush();
+}
+
+/*
+ * Callback invoked when the user finished preediting.
+ * Put the final string into the input buffer.
+ */
+    static void
+im_commit_cb(GtkIMContext *context UNUSED,
+	     const gchar *str,
+	     gpointer data UNUSED)
+{
+    int		slen = (int)STRLEN(str);
+    int		add_to_input = TRUE;
+    int		clen;
+    int		len = slen;
+    int		commit_with_preedit = TRUE;
+    char_u	*im_str;
+
+#ifdef XIM_DEBUG
+    xim_log("im_commit_cb(): %s\n", str);
+#endif
+
+    if (p_imst == IM_ON_THE_SPOT)
+    {
+	// The imhangul module doesn't reset the preedit string before
+	// committing.  Call im_delete_preedit() to work around that.
+	im_delete_preedit();
+
+	// Indicate that preediting has finished.
+	if (preedit_start_col == MAXCOL)
+	{
+	    init_preedit_start_col();
+	    commit_with_preedit = FALSE;
+	}
+
+	// The thing which setting "preedit_start_col" to MAXCOL means that
+	// "preedit_start_col" will be set forcedly when calling
+	// preedit_changed_cb() next time.
+	// "preedit_start_col" should not reset with MAXCOL on this part. Vim
+	// is simulating the preediting by using add_to_input_str(). when
+	// preedit begin immediately before committed, the typebuf is not
+	// flushed to screen, then it can't get correct "preedit_start_col".
+	// Thus, it should calculate the cells by adding cells of the committed
+	// string.
+	if (input_conv.vc_type != CONV_NONE)
+	{
+	    im_str = string_convert(&input_conv, (char_u *)str, &len);
+	    g_return_if_fail(im_str != NULL);
+	}
+	else
+	    im_str = (char_u *)str;
+
+	clen = mb_string2cells(im_str, len);
+
+	if (input_conv.vc_type != CONV_NONE)
+	    vim_free(im_str);
+	preedit_start_col += clen;
+    }
+
+    // Is this a single character that matches a keypad key that's just
+    // been pressed?  If so, we don't want it to be entered as such - let
+    // us carry on processing the raw keycode so that it may be used in
+    // mappings as <kSomething>.
+    if (xim_expected_char != NUL)
+    {
+	// We're currently processing a keypad or other special key
+	if (slen == 1 && str[0] == xim_expected_char)
+	{
+	    // It's a match - don't do it here
+	    xim_ignored_char = TRUE;
+	    add_to_input = FALSE;
+	}
+	else
+	{
+	    // Not a match
+	    xim_ignored_char = FALSE;
+	}
+    }
+
+    if (add_to_input)
+	im_add_to_input((char_u *)str, slen);
+
+    if (p_imst == IM_ON_THE_SPOT)
+    {
+	// Inserting chars while "im_is_active" is set does not cause a
+	// change of buffer.  When the chars are committed the buffer must be
+	// marked as changed.
+	if (!commit_with_preedit)
+	    preedit_start_col = MAXCOL;
+
+	// This flag is used in changed() at next call.
+	xim_changed_while_preediting = TRUE;
+    }
+
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*
+ * Callback invoked after start to the preedit.
+ */
+    static void
+im_preedit_start_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_preedit_start_cb()\n");
+#endif
+
+    im_is_active = TRUE;
+    preedit_is_active = TRUE;
+    gui_update_cursor(TRUE, FALSE);
+    im_show_info();
+}
+
+/*
+ * Callback invoked after end to the preedit.
+ */
+    static void
+im_preedit_end_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_preedit_end_cb()\n");
+#endif
+    im_delete_preedit();
+
+    // Indicate that preediting has finished
+    if (p_imst == IM_ON_THE_SPOT)
+	preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+
+#if 0
+    // Removal of this line suggested by Takuhiro Nishioka.  Fixes that IM was
+    // switched off unintentionally.  We now use preedit_is_active (added by
+    // SungHyun Nam).
+    im_is_active = FALSE;
+#endif
+    preedit_is_active = FALSE;
+    gui_update_cursor(TRUE, FALSE);
+    im_show_info();
+}
+
+/*
+ * Callback invoked after changes to the preedit string.  If the preedit
+ * string was empty before, remember the preedit start column so we know
+ * where to apply feedback attributes.  Delete the previous preedit string
+ * if there was one, save the new preedit cursor offset, and put the new
+ * string into the input buffer.
+ *
+ * TODO: The pragmatic "put into input buffer" approach used here has
+ *       several fundamental problems:
+ *
+ * - The characters in the preedit string are subject to remapping.
+ *   That's broken, only the finally committed string should be remapped.
+ *
+ * - There is a race condition involved:  The retrieved value for the
+ *   current cursor position will be wrong if any unprocessed characters
+ *   are still queued in the input buffer.
+ *
+ * - Due to the lack of synchronization between the file buffer in memory
+ *   and any typed characters, it's practically impossible to implement the
+ *   "retrieve_surrounding" and "delete_surrounding" signals reliably.  IM
+ *   modules for languages such as Thai are likely to rely on this feature
+ *   for proper operation.
+ *
+ * Conclusions:  I think support for preediting needs to be moved to the
+ * core parts of Vim.  Ideally, until it has been committed, the preediting
+ * string should only be displayed and not affect the buffer content at all.
+ * The question how to deal with the synchronization issue still remains.
+ * Circumventing the input buffer is probably not desirable.  Anyway, I think
+ * implementing "retrieve_surrounding" is the only hard problem.
+ *
+ * One way to solve all of this in a clean manner would be to queue all key
+ * press/release events "as is" in the input buffer, and apply the IM filtering
+ * at the receiving end of the queue.  This, however, would have a rather large
+ * impact on the code base.  If there is an easy way to force processing of all
+ * remaining input from within the "retrieve_surrounding" signal handler, this
+ * might not be necessary.  Gotta ask on vim-dev for opinions.
+ */
+    static void
+im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED)
+{
+    char    *preedit_string = NULL;
+    int	    cursor_index    = 0;
+    int	    num_move_back   = 0;
+    char_u  *str;
+    char_u  *p;
+    int	    i;
+
+    if (p_imst == IM_ON_THE_SPOT)
+	gtk_im_context_get_preedit_string(context,
+					  &preedit_string, NULL,
+					  &cursor_index);
+    else
+	gtk_im_context_get_preedit_string(context,
+					  &preedit_string, NULL,
+					  NULL);
+
+#ifdef XIM_DEBUG
+    xim_log("im_preedit_changed_cb(): %s\n", preedit_string);
+#endif
+
+    g_return_if_fail(preedit_string != NULL); // just in case
+
+    if (p_imst == IM_OVER_THE_SPOT)
+    {
+	if (preedit_string[0] == NUL)
+	{
+	    xim_has_preediting = FALSE;
+	    im_delete_preedit();
+	}
+	else
+	{
+	    xim_has_preediting = TRUE;
+	    im_show_preedit();
+	}
+    }
+    else
+    {
+	// If preedit_start_col is MAXCOL set it to the current cursor position.
+	if (preedit_start_col == MAXCOL && preedit_string[0] != '\0')
+	{
+	    xim_has_preediting = TRUE;
+
+	    // Urgh, this breaks if the input buffer isn't empty now
+	    init_preedit_start_col();
+	}
+	else if (cursor_index == 0 && preedit_string[0] == '\0')
+	{
+	    xim_has_preediting = FALSE;
+
+	    // If at the start position (after typing backspace)
+	    // preedit_start_col must be reset.
+	    preedit_start_col = MAXCOL;
+	}
+
+	im_delete_preedit();
+
+	/*
+	 * Compute the end of the preediting area: "preedit_end_col".
+	 * According to the documentation of gtk_im_context_get_preedit_string(),
+	 * the cursor_pos output argument returns the offset in bytes.  This is
+	 * unfortunately not true -- real life shows the offset is in characters,
+	 * and the GTK+ source code agrees with me.  Will file a bug later.
+	 */
+	if (preedit_start_col != MAXCOL)
+	    preedit_end_col = preedit_start_col;
+	str = (char_u *)preedit_string;
+	for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i)
+	{
+	    int is_composing;
+
+	    is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p)));
+	    /*
+	     * These offsets are used as counters when generating <BS> and <Del>
+	     * to delete the preedit string.  So don't count composing characters
+	     * unless 'delcombine' is enabled.
+	     */
+	    if (!is_composing || p_deco)
+	    {
+		if (i < cursor_index)
+		    ++im_preedit_cursor;
+		else
+		    ++im_preedit_trailing;
+	    }
+	    if (!is_composing && i >= cursor_index)
+	    {
+		// This is essentially the same as im_preedit_trailing, except
+		// composing characters are not counted even if p_deco is set.
+		++num_move_back;
+	    }
+	    if (preedit_start_col != MAXCOL)
+		preedit_end_col += utf_ptr2cells(p);
+	}
+
+	if (p > str)
+	{
+	    im_add_to_input(str, (int)(p - str));
+	    im_correct_cursor(num_move_back);
+	}
+    }
+
+    g_free(preedit_string);
+
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*
+ * Translate the Pango attributes at iter to Vim highlighting attributes.
+ * Ignore attributes not supported by Vim highlighting.  This shouldn't have
+ * too much impact -- right now we handle even more attributes than necessary
+ * for the IM modules I tested with.
+ */
+    static int
+translate_pango_attributes(PangoAttrIterator *iter)
+{
+    PangoAttribute  *attr;
+    int		    char_attr = HL_NORMAL;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
+    if (attr != NULL && ((PangoAttrInt *)attr)->value
+						 != (int)PANGO_UNDERLINE_NONE)
+	char_attr |= HL_UNDERLINE;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_WEIGHT);
+    if (attr != NULL && ((PangoAttrInt *)attr)->value >= (int)PANGO_WEIGHT_BOLD)
+	char_attr |= HL_BOLD;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_STYLE);
+    if (attr != NULL && ((PangoAttrInt *)attr)->value
+						   != (int)PANGO_STYLE_NORMAL)
+	char_attr |= HL_ITALIC;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
+    if (attr != NULL)
+    {
+	const PangoColor *color = &((PangoAttrColor *)attr)->color;
+
+	// Assume inverse if black background is requested
+	if ((color->red | color->green | color->blue) == 0)
+	    char_attr |= HL_INVERSE;
+    }
+
+    return char_attr;
+}
+
+/*
+ * Retrieve the highlighting attributes at column col in the preedit string.
+ * Return -1 if not in preediting mode or if col is out of range.
+ */
+    int
+im_get_feedback_attr(int col)
+{
+    char	    *preedit_string = NULL;
+    PangoAttrList   *attr_list	    = NULL;
+    int		    char_attr	    = -1;
+
+    if (xic == NULL)
+	return char_attr;
+
+    gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
+
+    if (preedit_string != NULL && attr_list != NULL)
+    {
+	int idx;
+
+	// Get the byte index as used by PangoAttrIterator
+	for (idx = 0; col > 0 && preedit_string[idx] != '\0'; --col)
+	    idx += utfc_ptr2len((char_u *)preedit_string + idx);
+
+	if (preedit_string[idx] != '\0')
+	{
+	    PangoAttrIterator	*iter;
+	    int			start, end;
+
+	    char_attr = HL_NORMAL;
+	    iter = pango_attr_list_get_iterator(attr_list);
+
+	    // Extract all relevant attributes from the list.
+	    do
+	    {
+		pango_attr_iterator_range(iter, &start, &end);
+
+		if (idx >= start && idx < end)
+		    char_attr |= translate_pango_attributes(iter);
+	    }
+	    while (pango_attr_iterator_next(iter));
+
+	    pango_attr_iterator_destroy(iter);
+	}
+    }
+
+    if (attr_list != NULL)
+	pango_attr_list_unref(attr_list);
+    g_free(preedit_string);
+
+    return char_attr;
+}
+
+    void
+xim_init(void)
+{
+#ifdef XIM_DEBUG
+    xim_log("xim_init()\n");
+#endif
+
+    g_return_if_fail(gui.drawarea != NULL);
+    g_return_if_fail(gtk_widget_get_window(gui.drawarea) != NULL);
+
+    xic = gtk_im_multicontext_new();
+    g_object_ref(xic);
+
+    im_commit_handler_id = g_signal_connect(G_OBJECT(xic), "commit",
+					    G_CALLBACK(&im_commit_cb), NULL);
+    g_signal_connect(G_OBJECT(xic), "preedit_changed",
+		     G_CALLBACK(&im_preedit_changed_cb), NULL);
+    g_signal_connect(G_OBJECT(xic), "preedit_start",
+		     G_CALLBACK(&im_preedit_start_cb), NULL);
+    g_signal_connect(G_OBJECT(xic), "preedit_end",
+		     G_CALLBACK(&im_preedit_end_cb), NULL);
+
+    gtk_im_context_set_client_window(xic, gtk_widget_get_window(gui.drawarea));
+}
+
+    void
+im_shutdown(void)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_shutdown()\n");
+#endif
+
+    if (xic != NULL)
+    {
+	gtk_im_context_focus_out(xic);
+	g_object_unref(xic);
+	xic = NULL;
+    }
+    im_is_active = FALSE;
+    im_commit_handler_id = 0;
+    if (p_imst == IM_ON_THE_SPOT)
+	preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+}
+
+/*
+ * Convert the string argument to keyval and state for GdkEventKey.
+ * If str is valid return TRUE, otherwise FALSE.
+ *
+ * See 'imactivatekey' for documentation of the format.
+ */
+    static int
+im_string_to_keyval(const char *str, unsigned int *keyval, unsigned int *state)
+{
+    const char	    *mods_end;
+    unsigned	    tmp_keyval;
+    unsigned	    tmp_state = 0;
+
+    mods_end = strrchr(str, '-');
+    mods_end = (mods_end != NULL) ? mods_end + 1 : str;
+
+    // Parse modifier keys
+    while (str < mods_end)
+	switch (*str++)
+	{
+	    case '-':							break;
+	    case 'S': case 's': tmp_state |= (unsigned)GDK_SHIFT_MASK;	break;
+	    case 'L': case 'l': tmp_state |= (unsigned)GDK_LOCK_MASK;	break;
+	    case 'C': case 'c': tmp_state |= (unsigned)GDK_CONTROL_MASK;break;
+	    case '1':		tmp_state |= (unsigned)GDK_MOD1_MASK;	break;
+	    case '2':		tmp_state |= (unsigned)GDK_MOD2_MASK;	break;
+	    case '3':		tmp_state |= (unsigned)GDK_MOD3_MASK;	break;
+	    case '4':		tmp_state |= (unsigned)GDK_MOD4_MASK;	break;
+	    case '5':		tmp_state |= (unsigned)GDK_MOD5_MASK;	break;
+	    default:
+		return FALSE;
+	}
+
+    tmp_keyval = gdk_keyval_from_name(str);
+
+    if (tmp_keyval == 0 || tmp_keyval == GDK_VoidSymbol)
+	return FALSE;
+
+    if (keyval != NULL)
+	*keyval = tmp_keyval;
+    if (state != NULL)
+	*state = tmp_state;
+
+    return TRUE;
+}
+
+/*
+ * Return TRUE if p_imak is valid, otherwise FALSE.  As a special case, an
+ * empty string is also regarded as valid.
+ *
+ * Note: The numerical key value of p_imak is cached if it was valid; thus
+ * boldly assuming im_xim_isvalid_imactivate() will always be called whenever
+ * 'imak' changes.  This is currently the case but not obvious -- should
+ * probably rename the function for clarity.
+ */
+    int
+im_xim_isvalid_imactivate(void)
+{
+    if (p_imak[0] == NUL)
+    {
+	im_activatekey_keyval = GDK_VoidSymbol;
+	im_activatekey_state  = 0;
+	return TRUE;
+    }
+
+    return im_string_to_keyval((const char *)p_imak,
+			       &im_activatekey_keyval,
+			       &im_activatekey_state);
+}
+
+    static void
+im_synthesize_keypress(unsigned int keyval, unsigned int state)
+{
+    GdkEventKey *event;
+
+    event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS);
+    g_object_ref(gtk_widget_get_window(gui.drawarea));
+					// unreffed by gdk_event_free()
+    event->window = gtk_widget_get_window(gui.drawarea);
+    event->send_event = TRUE;
+    event->time = GDK_CURRENT_TIME;
+    event->state  = state;
+    event->keyval = keyval;
+    event->hardware_keycode = // needed for XIM
+	XKeysymToKeycode(GDK_WINDOW_XDISPLAY(event->window), (KeySym)keyval);
+    event->length = 0;
+    event->string = NULL;
+
+    gtk_im_context_filter_keypress(xic, event);
+
+    // For consistency, also send the corresponding release event.
+    event->type = GDK_KEY_RELEASE;
+    event->send_event = FALSE;
+    gtk_im_context_filter_keypress(xic, event);
+
+    gdk_event_free((GdkEvent *)event);
+}
+
+    void
+xim_reset(void)
+{
+# ifdef FEAT_EVAL
+    if (USE_IMACTIVATEFUNC)
+	call_imactivatefunc(im_is_active);
+    else
+# endif
+    if (xic != NULL)
+    {
+	gtk_im_context_reset(xic);
+
+	if (p_imdisable)
+	    im_shutdown();
+	else
+	{
+	    xim_set_focus(gui.in_focus);
+
+	    if (im_activatekey_keyval != GDK_VoidSymbol)
+	    {
+		if (im_is_active)
+		{
+		    g_signal_handler_block(xic, im_commit_handler_id);
+		    im_synthesize_keypress(im_activatekey_keyval,
+						    im_activatekey_state);
+		    g_signal_handler_unblock(xic, im_commit_handler_id);
+		}
+	    }
+	    else
+	    {
+		im_shutdown();
+		xim_init();
+		xim_set_focus(gui.in_focus);
+	    }
+	}
+    }
+
+    if (p_imst == IM_ON_THE_SPOT)
+	preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+}
+
+    int
+xim_queue_key_press_event(GdkEventKey *event, int down)
+{
+    if (down)
+    {
+	/*
+	 * Workaround GTK2 XIM 'feature' that always converts keypad keys to
+	 * chars., even when not part of an IM sequence (ref. feature of
+	 * gdk/gdkkeyuni.c).
+	 * Flag any keypad keys that might represent a single char.
+	 * If this (on its own - i.e., not part of an IM sequence) is
+	 * committed while we're processing one of these keys, we can ignore
+	 * that commit and go ahead & process it ourselves.  That way we can
+	 * still distinguish keypad keys for use in mappings.
+	 * Also add GDK_space to make <S-Space> work.
+	 */
+	switch (event->keyval)
+	{
+	    case GDK_KP_Add:      xim_expected_char = '+';  break;
+	    case GDK_KP_Subtract: xim_expected_char = '-';  break;
+	    case GDK_KP_Divide:   xim_expected_char = '/';  break;
+	    case GDK_KP_Multiply: xim_expected_char = '*';  break;
+	    case GDK_KP_Decimal:  xim_expected_char = '.';  break;
+	    case GDK_KP_Equal:    xim_expected_char = '=';  break;
+	    case GDK_KP_0:	  xim_expected_char = '0';  break;
+	    case GDK_KP_1:	  xim_expected_char = '1';  break;
+	    case GDK_KP_2:	  xim_expected_char = '2';  break;
+	    case GDK_KP_3:	  xim_expected_char = '3';  break;
+	    case GDK_KP_4:	  xim_expected_char = '4';  break;
+	    case GDK_KP_5:	  xim_expected_char = '5';  break;
+	    case GDK_KP_6:	  xim_expected_char = '6';  break;
+	    case GDK_KP_7:	  xim_expected_char = '7';  break;
+	    case GDK_KP_8:	  xim_expected_char = '8';  break;
+	    case GDK_KP_9:	  xim_expected_char = '9';  break;
+	    case GDK_space:	  xim_expected_char = ' ';  break;
+	    default:		  xim_expected_char = NUL;
+	}
+	xim_ignored_char = FALSE;
+    }
+
+    /*
+     * When typing fFtT, XIM may be activated. Thus it must pass
+     * gtk_im_context_filter_keypress() in Normal mode.
+     * And while doing :sh too.
+     */
+    if (xic != NULL && !p_imdisable
+		    && (State & (INSERT | CMDLINE | NORMAL | EXTERNCMD)) != 0)
+    {
+	/*
+	 * Filter 'imactivatekey' and map it to CTRL-^.  This way, Vim is
+	 * always aware of the current status of IM, and can even emulate
+	 * the activation key for modules that don't support one.
+	 */
+	if (event->keyval == im_activatekey_keyval
+	     && (event->state & im_activatekey_state) == im_activatekey_state)
+	{
+	    unsigned int state_mask;
+
+	    // Require the state of the 3 most used modifiers to match exactly.
+	    // Otherwise e.g. <S-C-space> would be unusable for other purposes
+	    // if the IM activate key is <S-space>.
+	    state_mask  = im_activatekey_state;
+	    state_mask |= ((int)GDK_SHIFT_MASK | (int)GDK_CONTROL_MASK
+							| (int)GDK_MOD1_MASK);
+
+	    if ((event->state & state_mask) != im_activatekey_state)
+		return FALSE;
+
+	    // Don't send it a second time on GDK_KEY_RELEASE.
+	    if (event->type != GDK_KEY_PRESS)
+		return TRUE;
+
+	    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+	    {
+		im_set_active(FALSE);
+
+		// ":lmap" mappings exists, toggle use of mappings.
+		State ^= LANGMAP;
+		if (State & LANGMAP)
+		{
+		    curbuf->b_p_iminsert = B_IMODE_NONE;
+		    State &= ~LANGMAP;
+		}
+		else
+		{
+		    curbuf->b_p_iminsert = B_IMODE_LMAP;
+		    State |= LANGMAP;
+		}
+		return TRUE;
+	    }
+
+	    return gtk_im_context_filter_keypress(xic, event);
+	}
+
+	// Don't filter events through the IM context if IM isn't active
+	// right now.  Unlike with GTK+ 1.2 we cannot rely on the IM module
+	// not doing anything before the activation key was sent.
+	if (im_activatekey_keyval == GDK_VoidSymbol || im_is_active)
+	{
+	    int imresult = gtk_im_context_filter_keypress(xic, event);
+
+	    if (p_imst == IM_ON_THE_SPOT)
+	    {
+		// Some XIM send following sequence:
+		// 1. preedited string.
+		// 2. committed string.
+		// 3. line changed key.
+		// 4. preedited string.
+		// 5. remove preedited string.
+		// if 3, Vim can't move back the above line for 5.
+		// thus, this part should not parse the key.
+		if (!imresult && preedit_start_col != MAXCOL
+					    && event->keyval == GDK_Return)
+		{
+		    im_synthesize_keypress(GDK_Return, 0U);
+		    return FALSE;
+		}
+	    }
+
+	    // If XIM tried to commit a keypad key as a single char.,
+	    // ignore it so we can use the keypad key 'raw', for mappings.
+	    if (xim_expected_char != NUL && xim_ignored_char)
+		// We had a keypad key, and XIM tried to thieve it
+		return FALSE;
+
+	    // This is supposed to fix a problem with iBus, that space
+	    // characters don't work in input mode.
+	    xim_expected_char = NUL;
+
+	    // Normal processing
+	    return imresult;
+	}
+    }
+
+    return FALSE;
+}
+
+    int
+im_get_status(void)
+{
+#  ifdef FEAT_EVAL
+    if (USE_IMSTATUSFUNC)
+	return call_imstatusfunc();
+#  endif
+    return im_is_active;
+}
+
+    int
+preedit_get_status(void)
+{
+    return preedit_is_active;
+}
+
+    int
+im_is_preediting(void)
+{
+    return xim_has_preediting;
+}
+
+# else // !FEAT_GUI_GTK
+
+static int	xim_is_active = FALSE;  // XIM should be active in the current
+					// mode
+static int	xim_has_focus = FALSE;	// XIM is really being used for Vim
+#  ifdef FEAT_GUI_X11
+static XIMStyle	input_style;
+static int	status_area_enabled = TRUE;
+#  endif
+
+/*
+ * Switch using XIM on/off.  This is used by the code that changes "State".
+ * When 'imactivatefunc' is defined use that function instead.
+ */
+    void
+im_set_active(int active_arg)
+{
+    int active = active_arg;
+
+    // If 'imdisable' is set, XIM is never active.
+    if (p_imdisable)
+	active = FALSE;
+    else if (input_style & XIMPreeditPosition)
+	// There is a problem in switching XIM off when preediting is used,
+	// and it is not clear how this can be solved.  For now, keep XIM on
+	// all the time, like it was done in Vim 5.8.
+	active = TRUE;
+
+#  if defined(FEAT_EVAL)
+    if (USE_IMACTIVATEFUNC)
+    {
+	if (active != im_get_status())
+	{
+	    call_imactivatefunc(active);
+	    xim_has_focus = active;
+	}
+	return;
+    }
+#  endif
+
+    if (xic == NULL)
+	return;
+
+    // Remember the active state, it is needed when Vim gets keyboard focus.
+    xim_is_active = active;
+    xim_set_preedit();
+}
+
+/*
+ * Adjust using XIM for gaining or losing keyboard focus.  Also called when
+ * "xim_is_active" changes.
+ */
+    void
+xim_set_focus(int focus)
+{
+    if (xic == NULL)
+	return;
+
+    /*
+     * XIM only gets focus when the Vim window has keyboard focus and XIM has
+     * been set active for the current mode.
+     */
+    if (focus && xim_is_active)
+    {
+	if (!xim_has_focus)
+	{
+	    xim_has_focus = TRUE;
+	    XSetICFocus(xic);
+	}
+    }
+    else
+    {
+	if (xim_has_focus)
+	{
+	    xim_has_focus = FALSE;
+	    XUnsetICFocus(xic);
+	}
+    }
+}
+
+    void
+im_set_position(int row UNUSED, int col UNUSED)
+{
+    xim_set_preedit();
+}
+
+/*
+ * Set the XIM to the current cursor position.
+ */
+    void
+xim_set_preedit(void)
+{
+    XVaNestedList attr_list;
+    XRectangle spot_area;
+    XPoint over_spot;
+    int line_space;
+
+    if (xic == NULL)
+	return;
+
+    xim_set_focus(TRUE);
+
+    if (!xim_has_focus)
+    {
+	// hide XIM cursor
+	over_spot.x = 0;
+	over_spot.y = -100; // arbitrary invisible position
+	attr_list = (XVaNestedList) XVaCreateNestedList(0,
+							XNSpotLocation,
+							&over_spot,
+							NULL);
+	XSetICValues(xic, XNPreeditAttributes, attr_list, NULL);
+	XFree(attr_list);
+	return;
+    }
+
+    if (input_style & XIMPreeditPosition)
+    {
+	if (xim_fg_color == INVALCOLOR)
+	{
+	    xim_fg_color = gui.def_norm_pixel;
+	    xim_bg_color = gui.def_back_pixel;
+	}
+	over_spot.x = TEXT_X(gui.col);
+	over_spot.y = TEXT_Y(gui.row);
+	spot_area.x = 0;
+	spot_area.y = 0;
+	spot_area.height = gui.char_height * Rows;
+	spot_area.width  = gui.char_width * Columns;
+	line_space = gui.char_height;
+	attr_list = (XVaNestedList) XVaCreateNestedList(0,
+					XNSpotLocation, &over_spot,
+					XNForeground, (Pixel) xim_fg_color,
+					XNBackground, (Pixel) xim_bg_color,
+					XNArea, &spot_area,
+					XNLineSpace, line_space,
+					NULL);
+	if (XSetICValues(xic, XNPreeditAttributes, attr_list, NULL))
+	    emsg(_("E284: Cannot set IC values"));
+	XFree(attr_list);
+    }
+}
+
+#  if defined(FEAT_GUI_X11)
+static char e_xim[] = N_("E285: Failed to create input context");
+#  endif
+
+#  if defined(FEAT_GUI_X11) || defined(PROTO)
+#   if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(SUN_SYSTEM)
+#    define USE_X11R6_XIM
+#   endif
+
+static int xim_real_init(Window x11_window, Display *x11_display);
+
+
+#  ifdef USE_X11R6_XIM
+    static void
+xim_instantiate_cb(
+    Display	*display,
+    XPointer	client_data UNUSED,
+    XPointer	call_data UNUSED)
+{
+    Window	x11_window;
+    Display	*x11_display;
+
+#   ifdef XIM_DEBUG
+    xim_log("xim_instantiate_cb()\n");
+#   endif
+
+    gui_get_x11_windis(&x11_window, &x11_display);
+    if (display != x11_display)
+	return;
+
+    xim_real_init(x11_window, x11_display);
+    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+    if (xic != NULL)
+	XUnregisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
+					 xim_instantiate_cb, NULL);
+}
+
+    static void
+xim_destroy_cb(
+    XIM		im UNUSED,
+    XPointer	client_data UNUSED,
+    XPointer	call_data UNUSED)
+{
+    Window	x11_window;
+    Display	*x11_display;
+
+#   ifdef XIM_DEBUG
+    xim_log("xim_destroy_cb()\n");
+   #endif
+    gui_get_x11_windis(&x11_window, &x11_display);
+
+    xic = NULL;
+    status_area_enabled = FALSE;
+
+    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+
+    XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
+				   xim_instantiate_cb, NULL);
+}
+#  endif
+
+    void
+xim_init(void)
+{
+    Window	x11_window;
+    Display	*x11_display;
+
+#  ifdef XIM_DEBUG
+    xim_log("xim_init()\n");
+#  endif
+
+    gui_get_x11_windis(&x11_window, &x11_display);
+
+    xic = NULL;
+
+    if (xim_real_init(x11_window, x11_display))
+	return;
+
+    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+
+#  ifdef USE_X11R6_XIM
+    XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
+				   xim_instantiate_cb, NULL);
+#  endif
+}
+
+    static int
+xim_real_init(Window x11_window, Display *x11_display)
+{
+    int		i;
+    char	*p,
+		*s,
+		*ns,
+		*end,
+		tmp[1024];
+#  define IMLEN_MAX 40
+    char	buf[IMLEN_MAX + 7];
+    XIM		xim = NULL;
+    XIMStyles	*xim_styles;
+    XIMStyle	this_input_style = 0;
+    Boolean	found;
+    XPoint	over_spot;
+    XVaNestedList preedit_list, status_list;
+
+    input_style = 0;
+    status_area_enabled = FALSE;
+
+    if (xic != NULL)
+	return FALSE;
+
+    if (gui.rsrc_input_method != NULL && *gui.rsrc_input_method != NUL)
+    {
+	strcpy(tmp, gui.rsrc_input_method);
+	for (ns = s = tmp; ns != NULL && *s != NUL;)
+	{
+	    s = (char *)skipwhite((char_u *)s);
+	    if (*s == NUL)
+		break;
+	    if ((ns = end = strchr(s, ',')) == NULL)
+		end = s + strlen(s);
+	    while (isspace(((char_u *)end)[-1]))
+		end--;
+	    *end = NUL;
+
+	    if (strlen(s) <= IMLEN_MAX)
+	    {
+		strcpy(buf, "@im=");
+		strcat(buf, s);
+		if ((p = XSetLocaleModifiers(buf)) != NULL && *p != NUL
+			&& (xim = XOpenIM(x11_display, NULL, NULL, NULL))
+								      != NULL)
+		    break;
+	    }
+
+	    s = ns + 1;
+	}
+    }
+
+    if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p != NUL)
+	xim = XOpenIM(x11_display, NULL, NULL, NULL);
+
+    // This is supposed to be useful to obtain characters through
+    // XmbLookupString() without really using a XIM.
+    if (xim == NULL && (p = XSetLocaleModifiers("@im=none")) != NULL
+								 && *p != NUL)
+	xim = XOpenIM(x11_display, NULL, NULL, NULL);
+
+    if (xim == NULL)
+    {
+	// Only give this message when verbose is set, because too many people
+	// got this message when they didn't want to use a XIM.
+	if (p_verbose > 0)
+	{
+	    verbose_enter();
+	    emsg(_("E286: Failed to open input method"));
+	    verbose_leave();
+	}
+	return FALSE;
+    }
+
+#  ifdef USE_X11R6_XIM
+    {
+	XIMCallback destroy_cb;
+
+	destroy_cb.callback = xim_destroy_cb;
+	destroy_cb.client_data = NULL;
+	if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL))
+	    emsg(_("E287: Warning: Could not set destroy callback to IM"));
+    }
+#  endif
+
+    if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles)
+    {
+	emsg(_("E288: input method doesn't support any style"));
+	XCloseIM(xim);
+	return FALSE;
+    }
+
+    found = False;
+    strcpy(tmp, gui.rsrc_preedit_type_name);
+    for (s = tmp; s && !found; )
+    {
+	while (*s && isspace((unsigned char)*s))
+	    s++;
+	if (!*s)
+	    break;
+	if ((ns = end = strchr(s, ',')) != 0)
+	    ns++;
+	else
+	    end = s + strlen(s);
+	while (isspace((unsigned char)*end))
+	    end--;
+	*end = '\0';
+
+	if (!strcmp(s, "OverTheSpot"))
+	    this_input_style = (XIMPreeditPosition | XIMStatusArea);
+	else if (!strcmp(s, "OffTheSpot"))
+	    this_input_style = (XIMPreeditArea | XIMStatusArea);
+	else if (!strcmp(s, "Root"))
+	    this_input_style = (XIMPreeditNothing | XIMStatusNothing);
+
+	for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
+	{
+	    if (this_input_style == xim_styles->supported_styles[i])
+	    {
+		found = True;
+		break;
+	    }
+	}
+	if (!found)
+	    for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
+	    {
+		if ((xim_styles->supported_styles[i] & this_input_style)
+			== (this_input_style & ~XIMStatusArea))
+		{
+		    this_input_style &= ~XIMStatusArea;
+		    found = True;
+		    break;
+		}
+	    }
+
+	s = ns;
+    }
+    XFree(xim_styles);
+
+    if (!found)
+    {
+	// Only give this message when verbose is set, because too many people
+	// got this message when they didn't want to use a XIM.
+	if (p_verbose > 0)
+	{
+	    verbose_enter();
+	    emsg(_("E289: input method doesn't support my preedit type"));
+	    verbose_leave();
+	}
+	XCloseIM(xim);
+	return FALSE;
+    }
+
+    over_spot.x = TEXT_X(gui.col);
+    over_spot.y = TEXT_Y(gui.row);
+    input_style = this_input_style;
+
+    // A crash was reported when trying to pass gui.norm_font as XNFontSet,
+    // thus that has been removed.  Hopefully the default works...
+#  ifdef FEAT_XFONTSET
+    if (gui.fontset != NOFONTSET)
+    {
+	preedit_list = XVaCreateNestedList(0,
+				XNSpotLocation, &over_spot,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				XNFontSet, (XFontSet)gui.fontset,
+				NULL);
+	status_list = XVaCreateNestedList(0,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				XNFontSet, (XFontSet)gui.fontset,
+				NULL);
+    }
+    else
+#  endif
+    {
+	preedit_list = XVaCreateNestedList(0,
+				XNSpotLocation, &over_spot,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				NULL);
+	status_list = XVaCreateNestedList(0,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				NULL);
+    }
+
+    xic = XCreateIC(xim,
+		    XNInputStyle, input_style,
+		    XNClientWindow, x11_window,
+		    XNFocusWindow, gui.wid,
+		    XNPreeditAttributes, preedit_list,
+		    XNStatusAttributes, status_list,
+		    NULL);
+    XFree(status_list);
+    XFree(preedit_list);
+    if (xic != NULL)
+    {
+	if (input_style & XIMStatusArea)
+	{
+	    xim_set_status_area();
+	    status_area_enabled = TRUE;
+	}
+	else
+	    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+    }
+    else
+    {
+	if (!is_not_a_term())
+	    emsg(_(e_xim));
+	XCloseIM(xim);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+#  endif // FEAT_GUI_X11
+
+/*
+ * Get IM status.  When IM is on, return TRUE.  Else return FALSE.
+ * FIXME: This doesn't work correctly: Having focus doesn't always mean XIM is
+ * active, when not having focus XIM may still be active (e.g., when using a
+ * tear-off menu item).
+ */
+    int
+im_get_status(void)
+{
+#  ifdef FEAT_EVAL
+    if (USE_IMSTATUSFUNC)
+	return call_imstatusfunc();
+#  endif
+    return xim_has_focus;
+}
+
+# endif // !FEAT_GUI_GTK
+
+# if !defined(FEAT_GUI_GTK) || defined(PROTO)
+/*
+ * Set up the status area.
+ *
+ * This should use a separate Widget, but that seems not possible, because
+ * preedit_area and status_area should be set to the same window as for the
+ * text input.  Unfortunately this means the status area pollutes the text
+ * window...
+ */
+    void
+xim_set_status_area(void)
+{
+    XVaNestedList preedit_list = 0, status_list = 0, list = 0;
+    XRectangle pre_area, status_area;
+
+    if (xic == NULL)
+	return;
+
+    if (input_style & XIMStatusArea)
+    {
+	if (input_style & XIMPreeditArea)
+	{
+	    XRectangle *needed_rect;
+
+	    // to get status_area width
+	    status_list = XVaCreateNestedList(0, XNAreaNeeded,
+					      &needed_rect, NULL);
+	    XGetICValues(xic, XNStatusAttributes, status_list, NULL);
+	    XFree(status_list);
+
+	    status_area.width = needed_rect->width;
+	}
+	else
+	    status_area.width = gui.char_width * Columns;
+
+	status_area.x = 0;
+	status_area.y = gui.char_height * Rows + gui.border_offset;
+	if (gui.which_scrollbars[SBAR_BOTTOM])
+	    status_area.y += gui.scrollbar_height;
+#ifdef FEAT_MENU
+	if (gui.menu_is_active)
+	    status_area.y += gui.menu_height;
+#endif
+	status_area.height = gui.char_height;
+	status_list = XVaCreateNestedList(0, XNArea, &status_area, NULL);
+    }
+    else
+    {
+	status_area.x = 0;
+	status_area.y = gui.char_height * Rows + gui.border_offset;
+	if (gui.which_scrollbars[SBAR_BOTTOM])
+	    status_area.y += gui.scrollbar_height;
+#ifdef FEAT_MENU
+	if (gui.menu_is_active)
+	    status_area.y += gui.menu_height;
+#endif
+	status_area.width = 0;
+	status_area.height = gui.char_height;
+    }
+
+    if (input_style & XIMPreeditArea)   // off-the-spot
+    {
+	pre_area.x = status_area.x + status_area.width;
+	pre_area.y = gui.char_height * Rows + gui.border_offset;
+	pre_area.width = gui.char_width * Columns - pre_area.x;
+	if (gui.which_scrollbars[SBAR_BOTTOM])
+	    pre_area.y += gui.scrollbar_height;
+#ifdef FEAT_MENU
+	if (gui.menu_is_active)
+	    pre_area.y += gui.menu_height;
+#endif
+	pre_area.height = gui.char_height;
+	preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
+    }
+    else if (input_style & XIMPreeditPosition)   // over-the-spot
+    {
+	pre_area.x = 0;
+	pre_area.y = 0;
+	pre_area.height = gui.char_height * Rows;
+	pre_area.width = gui.char_width * Columns;
+	preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
+    }
+
+    if (preedit_list && status_list)
+	list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
+				   XNStatusAttributes, status_list, NULL);
+    else if (preedit_list)
+	list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
+				   NULL);
+    else if (status_list)
+	list = XVaCreateNestedList(0, XNStatusAttributes, status_list,
+				   NULL);
+    else
+	list = NULL;
+
+    if (list)
+    {
+	XSetICValues(xic, XNVaNestedList, list, NULL);
+	XFree(list);
+    }
+    if (status_list)
+	XFree(status_list);
+    if (preedit_list)
+	XFree(preedit_list);
+}
+
+    int
+xim_get_status_area_height(void)
+{
+    if (status_area_enabled)
+	return gui.char_height;
+    return 0;
+}
+# endif
+
+#else // !defined(FEAT_XIM)
+
+# if defined(IME_WITHOUT_XIM) || defined(VIMDLL) || defined(PROTO)
+static int im_was_set_active = FALSE;
+
+    int
+#  ifdef VIMDLL
+mbyte_im_get_status(void)
+#  else
+im_get_status(void)
+#  endif
+{
+#  if defined(FEAT_EVAL)
+    if (USE_IMSTATUSFUNC)
+	return call_imstatusfunc();
+#  endif
+    return im_was_set_active;
+}
+
+    void
+#  ifdef VIMDLL
+mbyte_im_set_active(int active_arg)
+#  else
+im_set_active(int active_arg)
+#  endif
+{
+#  if defined(FEAT_EVAL)
+    int	    active = !p_imdisable && active_arg;
+
+    if (USE_IMACTIVATEFUNC && active != im_get_status())
+    {
+	call_imactivatefunc(active);
+	im_was_set_active = active;
+    }
+#  endif
+}
+
+#  if defined(FEAT_GUI) && !defined(FEAT_GUI_HAIKU) && !defined(VIMDLL)
+    void
+im_set_position(int row UNUSED, int col UNUSED)
+{
+}
+#  endif
+# endif
+
+#endif // FEAT_XIM
diff --git a/src/mbyte.c b/src/mbyte.c
index 802df49..de732c4 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -111,19 +111,6 @@
 # endif
 #endif
 
-#if defined(FEAT_GUI_GTK) && defined(FEAT_XIM)
-# if GTK_CHECK_VERSION(3,0,0)
-#  include <gdk/gdkkeysyms-compat.h>
-# else
-#  include <gdk/gdkkeysyms.h>
-# endif
-# ifdef MSWIN
-#  include <gdk/gdkwin32.h>
-# else
-#  include <gdk/gdkx.h>
-# endif
-#endif
-
 #ifdef HAVE_WCHAR_H
 # include <wchar.h>
 #endif
@@ -179,37 +166,6 @@
     3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0,
 };
 
-/*
- * XIM often causes trouble.  Define XIM_DEBUG to get a log of XIM callbacks
- * in the "xim.log" file.
- */
-// #define XIM_DEBUG
-#ifdef XIM_DEBUG
-    static void
-xim_log(char *s, ...)
-{
-    va_list arglist;
-    static FILE *fd = NULL;
-
-    if (fd == (FILE *)-1)
-	return;
-    if (fd == NULL)
-    {
-	fd = mch_fopen("xim.log", "w");
-	if (fd == NULL)
-	{
-	    emsg("Cannot open xim.log");
-	    fd = (FILE *)-1;
-	    return;
-	}
-    }
-
-    va_start(arglist, s);
-    vfprintf(fd, s, arglist);
-    va_end(arglist);
-}
-#endif
-
 
 /*
  * Canonical encoding names and their properties.
@@ -4778,1726 +4734,6 @@
 #  endif // DYNAMIC_ICONV
 # endif // USE_ICONV
 
-
-#ifdef FEAT_GUI
-# define USE_IMACTIVATEFUNC (!gui.in_use && *p_imaf != NUL)
-# define USE_IMSTATUSFUNC (!gui.in_use && *p_imsf != NUL)
-#else
-# define USE_IMACTIVATEFUNC (*p_imaf != NUL)
-# define USE_IMSTATUSFUNC (*p_imsf != NUL)
-#endif
-
-#if defined(FEAT_EVAL) && \
-    (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL))
-    static void
-call_imactivatefunc(int active)
-{
-    typval_T argv[2];
-
-    argv[0].v_type = VAR_NUMBER;
-    argv[0].vval.v_number = active ? 1 : 0;
-    argv[1].v_type = VAR_UNKNOWN;
-    (void)call_func_retnr(p_imaf, 1, argv);
-}
-
-    static int
-call_imstatusfunc(void)
-{
-    int is_active;
-
-    // FIXME: Don't execute user function in unsafe situation.
-    if (exiting || is_autocmd_blocked())
-	return FALSE;
-    // FIXME: :py print 'xxx' is shown duplicate result.
-    // Use silent to avoid it.
-    ++msg_silent;
-    is_active = call_func_retnr(p_imsf, 0, NULL);
-    --msg_silent;
-    return (is_active > 0);
-}
-#endif
-
-#if defined(FEAT_XIM) || defined(PROTO)
-
-# if defined(FEAT_GUI_GTK) || defined(PROTO)
-static int xim_has_preediting INIT(= FALSE);  // IM current status
-
-/*
- * Set preedit_start_col to the current cursor position.
- */
-    static void
-init_preedit_start_col(void)
-{
-    if (State & CMDLINE)
-	preedit_start_col = cmdline_getvcol_cursor();
-    else if (curwin != NULL && curwin->w_buffer != NULL)
-	getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL);
-    // Prevent that preediting marks the buffer as changed.
-    xim_changed_while_preediting = curbuf->b_changed;
-}
-
-static int im_is_active	       = FALSE;	// IM is enabled for current mode
-static int preedit_is_active   = FALSE;
-static int im_preedit_cursor   = 0;	// cursor offset in characters
-static int im_preedit_trailing = 0;	// number of characters after cursor
-
-static unsigned long im_commit_handler_id  = 0;
-static unsigned int  im_activatekey_keyval = GDK_VoidSymbol;
-static unsigned int  im_activatekey_state  = 0;
-
-static GtkWidget *preedit_window = NULL;
-static GtkWidget *preedit_label = NULL;
-
-static void im_preedit_window_set_position(void);
-
-    void
-im_set_active(int active)
-{
-    int was_active;
-
-    was_active = !!im_get_status();
-    im_is_active = (active && !p_imdisable);
-
-    if (im_is_active != was_active)
-	xim_reset();
-}
-
-    void
-xim_set_focus(int focus)
-{
-    if (xic != NULL)
-    {
-	if (focus)
-	    gtk_im_context_focus_in(xic);
-	else
-	    gtk_im_context_focus_out(xic);
-    }
-}
-
-    void
-im_set_position(int row, int col)
-{
-    if (xic != NULL)
-    {
-	GdkRectangle area;
-
-	area.x = FILL_X(col);
-	area.y = FILL_Y(row);
-	area.width  = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1);
-	area.height = gui.char_height;
-
-	gtk_im_context_set_cursor_location(xic, &area);
-
-	if (p_imst == IM_OVER_THE_SPOT)
-	    im_preedit_window_set_position();
-    }
-}
-
-#  if 0 || defined(PROTO) // apparently only used in gui_x11.c
-    void
-xim_set_preedit(void)
-{
-    im_set_position(gui.row, gui.col);
-}
-#  endif
-
-    static void
-im_add_to_input(char_u *str, int len)
-{
-    // Convert from 'termencoding' (always "utf-8") to 'encoding'
-    if (input_conv.vc_type != CONV_NONE)
-    {
-	str = string_convert(&input_conv, str, &len);
-	g_return_if_fail(str != NULL);
-    }
-
-    add_to_input_buf_csi(str, len);
-
-    if (input_conv.vc_type != CONV_NONE)
-	vim_free(str);
-
-    if (p_mh) // blank out the pointer if necessary
-	gui_mch_mousehide(TRUE);
-}
-
-     static void
-im_preedit_window_set_position(void)
-{
-    int x, y, width, height;
-    int screen_x, screen_y, screen_width, screen_height;
-
-    if (preedit_window == NULL)
-	return;
-
-    gui_gtk_get_screen_geom_of_win(gui.drawarea,
-			  &screen_x, &screen_y, &screen_width, &screen_height);
-    gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y);
-    gtk_window_get_size(GTK_WINDOW(preedit_window), &width, &height);
-    x = x + FILL_X(gui.col);
-    y = y + FILL_Y(gui.row);
-    if (x + width > screen_x + screen_width)
-	x = screen_x + screen_width - width;
-    if (y + height > screen_y + screen_height)
-	y = screen_y + screen_height - height;
-    gtk_window_move(GTK_WINDOW(preedit_window), x, y);
-}
-
-    static void
-im_preedit_window_open()
-{
-    char *preedit_string;
-#if !GTK_CHECK_VERSION(3,16,0)
-    char buf[8];
-#endif
-    PangoAttrList *attr_list;
-    PangoLayout *layout;
-#if GTK_CHECK_VERSION(3,0,0)
-# if !GTK_CHECK_VERSION(3,16,0)
-    GdkRGBA color;
-# endif
-#else
-    GdkColor color;
-#endif
-    gint w, h;
-
-    if (preedit_window == NULL)
-    {
-	preedit_window = gtk_window_new(GTK_WINDOW_POPUP);
-	gtk_window_set_transient_for(GTK_WINDOW(preedit_window),
-						     GTK_WINDOW(gui.mainwin));
-	preedit_label = gtk_label_new("");
-	gtk_widget_set_name(preedit_label, "vim-gui-preedit-area");
-	gtk_container_add(GTK_CONTAINER(preedit_window), preedit_label);
-    }
-
-#if GTK_CHECK_VERSION(3,16,0)
-    {
-	GtkStyleContext * const context
-				  = gtk_widget_get_style_context(gui.drawarea);
-	GtkCssProvider * const provider = gtk_css_provider_new();
-	gchar		   *css = NULL;
-	const char * const fontname
-			   = pango_font_description_get_family(gui.norm_font);
-	gint	fontsize
-		= pango_font_description_get_size(gui.norm_font) / PANGO_SCALE;
-	gchar	*fontsize_propval = NULL;
-
-	if (!pango_font_description_get_size_is_absolute(gui.norm_font))
-	{
-	    // fontsize was given in points.  Convert it into that in pixels
-	    // to use with CSS.
-	    GdkScreen * const screen
-		  = gdk_window_get_screen(gtk_widget_get_window(gui.mainwin));
-	    const gdouble dpi = gdk_screen_get_resolution(screen);
-	    fontsize = dpi * fontsize / 72;
-	}
-	if (fontsize > 0)
-	    fontsize_propval = g_strdup_printf("%dpx", fontsize);
-	else
-	    fontsize_propval = g_strdup_printf("inherit");
-
-	css = g_strdup_printf(
-		"widget#vim-gui-preedit-area {\n"
-		"  font-family: %s,monospace;\n"
-		"  font-size: %s;\n"
-		"  color: #%.2lx%.2lx%.2lx;\n"
-		"  background-color: #%.2lx%.2lx%.2lx;\n"
-		"}\n",
-		fontname != NULL ? fontname : "inherit",
-		fontsize_propval,
-		(gui.norm_pixel >> 16) & 0xff,
-		(gui.norm_pixel >> 8) & 0xff,
-		gui.norm_pixel & 0xff,
-		(gui.back_pixel >> 16) & 0xff,
-		(gui.back_pixel >> 8) & 0xff,
-		gui.back_pixel & 0xff);
-
-	gtk_css_provider_load_from_data(provider, css, -1, NULL);
-	gtk_style_context_add_provider(context,
-				     GTK_STYLE_PROVIDER(provider), G_MAXUINT);
-
-	g_free(css);
-	g_free(fontsize_propval);
-	g_object_unref(provider);
-    }
-#elif GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_font(preedit_label, gui.norm_font);
-
-    vim_snprintf(buf, sizeof(buf), "#%06X", gui.norm_pixel);
-    gdk_rgba_parse(&color, buf);
-    gtk_widget_override_color(preedit_label, GTK_STATE_FLAG_NORMAL, &color);
-
-    vim_snprintf(buf, sizeof(buf), "#%06X", gui.back_pixel);
-    gdk_rgba_parse(&color, buf);
-    gtk_widget_override_background_color(preedit_label, GTK_STATE_FLAG_NORMAL,
-								      &color);
-#else
-    gtk_widget_modify_font(preedit_label, gui.norm_font);
-
-    vim_snprintf(buf, sizeof(buf), "#%06X", (unsigned)gui.norm_pixel);
-    gdk_color_parse(buf, &color);
-    gtk_widget_modify_fg(preedit_label, GTK_STATE_NORMAL, &color);
-
-    vim_snprintf(buf, sizeof(buf), "#%06X", (unsigned)gui.back_pixel);
-    gdk_color_parse(buf, &color);
-    gtk_widget_modify_bg(preedit_window, GTK_STATE_NORMAL, &color);
-#endif
-
-    gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
-
-    if (preedit_string[0] != NUL)
-    {
-	gtk_label_set_text(GTK_LABEL(preedit_label), preedit_string);
-	gtk_label_set_attributes(GTK_LABEL(preedit_label), attr_list);
-
-	layout = gtk_label_get_layout(GTK_LABEL(preedit_label));
-	pango_layout_get_pixel_size(layout, &w, &h);
-	h = MAX(h, gui.char_height);
-	gtk_window_resize(GTK_WINDOW(preedit_window), w, h);
-
-	gtk_widget_show_all(preedit_window);
-
-	im_preedit_window_set_position();
-    }
-
-    g_free(preedit_string);
-    pango_attr_list_unref(attr_list);
-}
-
-    static void
-im_preedit_window_close()
-{
-    if (preedit_window != NULL)
-	gtk_widget_hide(preedit_window);
-}
-
-    static void
-im_show_preedit()
-{
-    im_preedit_window_open();
-
-    if (p_mh) // blank out the pointer if necessary
-	gui_mch_mousehide(TRUE);
-}
-
-    static void
-im_delete_preedit(void)
-{
-    char_u bskey[]  = {CSI, 'k', 'b'};
-    char_u delkey[] = {CSI, 'k', 'D'};
-
-    if (p_imst == IM_OVER_THE_SPOT)
-    {
-	im_preedit_window_close();
-	return;
-    }
-
-    if (State & NORMAL
-#ifdef FEAT_TERMINAL
-	    && !term_use_loop()
-#endif
-       )
-    {
-	im_preedit_cursor = 0;
-	return;
-    }
-    for (; im_preedit_cursor > 0; --im_preedit_cursor)
-	add_to_input_buf(bskey, (int)sizeof(bskey));
-
-    for (; im_preedit_trailing > 0; --im_preedit_trailing)
-	add_to_input_buf(delkey, (int)sizeof(delkey));
-}
-
-/*
- * Move the cursor left by "num_move_back" characters.
- * Note that ins_left() checks im_is_preediting() to avoid breaking undo for
- * these K_LEFT keys.
- */
-    static void
-im_correct_cursor(int num_move_back)
-{
-    char_u backkey[] = {CSI, 'k', 'l'};
-
-    if (State & NORMAL)
-	return;
-#  ifdef FEAT_RIGHTLEFT
-    if ((State & CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl)
-	backkey[2] = 'r';
-#  endif
-    for (; num_move_back > 0; --num_move_back)
-	add_to_input_buf(backkey, (int)sizeof(backkey));
-}
-
-static int xim_expected_char = NUL;
-static int xim_ignored_char = FALSE;
-
-/*
- * Update the mode and cursor while in an IM callback.
- */
-    static void
-im_show_info(void)
-{
-    int	    old_vgetc_busy;
-
-    old_vgetc_busy = vgetc_busy;
-    vgetc_busy = TRUE;
-    showmode();
-    vgetc_busy = old_vgetc_busy;
-    if ((State & NORMAL) || (State & INSERT))
-	setcursor();
-    out_flush();
-}
-
-/*
- * Callback invoked when the user finished preediting.
- * Put the final string into the input buffer.
- */
-    static void
-im_commit_cb(GtkIMContext *context UNUSED,
-	     const gchar *str,
-	     gpointer data UNUSED)
-{
-    int		slen = (int)STRLEN(str);
-    int		add_to_input = TRUE;
-    int		clen;
-    int		len = slen;
-    int		commit_with_preedit = TRUE;
-    char_u	*im_str;
-
-#ifdef XIM_DEBUG
-    xim_log("im_commit_cb(): %s\n", str);
-#endif
-
-    if (p_imst == IM_ON_THE_SPOT)
-    {
-	// The imhangul module doesn't reset the preedit string before
-	// committing.  Call im_delete_preedit() to work around that.
-	im_delete_preedit();
-
-	// Indicate that preediting has finished.
-	if (preedit_start_col == MAXCOL)
-	{
-	    init_preedit_start_col();
-	    commit_with_preedit = FALSE;
-	}
-
-	// The thing which setting "preedit_start_col" to MAXCOL means that
-	// "preedit_start_col" will be set forcedly when calling
-	// preedit_changed_cb() next time.
-	// "preedit_start_col" should not reset with MAXCOL on this part. Vim
-	// is simulating the preediting by using add_to_input_str(). when
-	// preedit begin immediately before committed, the typebuf is not
-	// flushed to screen, then it can't get correct "preedit_start_col".
-	// Thus, it should calculate the cells by adding cells of the committed
-	// string.
-	if (input_conv.vc_type != CONV_NONE)
-	{
-	    im_str = string_convert(&input_conv, (char_u *)str, &len);
-	    g_return_if_fail(im_str != NULL);
-	}
-	else
-	    im_str = (char_u *)str;
-
-	clen = mb_string2cells(im_str, len);
-
-	if (input_conv.vc_type != CONV_NONE)
-	    vim_free(im_str);
-	preedit_start_col += clen;
-    }
-
-    // Is this a single character that matches a keypad key that's just
-    // been pressed?  If so, we don't want it to be entered as such - let
-    // us carry on processing the raw keycode so that it may be used in
-    // mappings as <kSomething>.
-    if (xim_expected_char != NUL)
-    {
-	// We're currently processing a keypad or other special key
-	if (slen == 1 && str[0] == xim_expected_char)
-	{
-	    // It's a match - don't do it here
-	    xim_ignored_char = TRUE;
-	    add_to_input = FALSE;
-	}
-	else
-	{
-	    // Not a match
-	    xim_ignored_char = FALSE;
-	}
-    }
-
-    if (add_to_input)
-	im_add_to_input((char_u *)str, slen);
-
-    if (p_imst == IM_ON_THE_SPOT)
-    {
-	// Inserting chars while "im_is_active" is set does not cause a
-	// change of buffer.  When the chars are committed the buffer must be
-	// marked as changed.
-	if (!commit_with_preedit)
-	    preedit_start_col = MAXCOL;
-
-	// This flag is used in changed() at next call.
-	xim_changed_while_preediting = TRUE;
-    }
-
-    if (gtk_main_level() > 0)
-	gtk_main_quit();
-}
-
-/*
- * Callback invoked after start to the preedit.
- */
-    static void
-im_preedit_start_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
-{
-#ifdef XIM_DEBUG
-    xim_log("im_preedit_start_cb()\n");
-#endif
-
-    im_is_active = TRUE;
-    preedit_is_active = TRUE;
-    gui_update_cursor(TRUE, FALSE);
-    im_show_info();
-}
-
-/*
- * Callback invoked after end to the preedit.
- */
-    static void
-im_preedit_end_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
-{
-#ifdef XIM_DEBUG
-    xim_log("im_preedit_end_cb()\n");
-#endif
-    im_delete_preedit();
-
-    // Indicate that preediting has finished
-    if (p_imst == IM_ON_THE_SPOT)
-	preedit_start_col = MAXCOL;
-    xim_has_preediting = FALSE;
-
-#if 0
-    // Removal of this line suggested by Takuhiro Nishioka.  Fixes that IM was
-    // switched off unintentionally.  We now use preedit_is_active (added by
-    // SungHyun Nam).
-    im_is_active = FALSE;
-#endif
-    preedit_is_active = FALSE;
-    gui_update_cursor(TRUE, FALSE);
-    im_show_info();
-}
-
-/*
- * Callback invoked after changes to the preedit string.  If the preedit
- * string was empty before, remember the preedit start column so we know
- * where to apply feedback attributes.  Delete the previous preedit string
- * if there was one, save the new preedit cursor offset, and put the new
- * string into the input buffer.
- *
- * TODO: The pragmatic "put into input buffer" approach used here has
- *       several fundamental problems:
- *
- * - The characters in the preedit string are subject to remapping.
- *   That's broken, only the finally committed string should be remapped.
- *
- * - There is a race condition involved:  The retrieved value for the
- *   current cursor position will be wrong if any unprocessed characters
- *   are still queued in the input buffer.
- *
- * - Due to the lack of synchronization between the file buffer in memory
- *   and any typed characters, it's practically impossible to implement the
- *   "retrieve_surrounding" and "delete_surrounding" signals reliably.  IM
- *   modules for languages such as Thai are likely to rely on this feature
- *   for proper operation.
- *
- * Conclusions:  I think support for preediting needs to be moved to the
- * core parts of Vim.  Ideally, until it has been committed, the preediting
- * string should only be displayed and not affect the buffer content at all.
- * The question how to deal with the synchronization issue still remains.
- * Circumventing the input buffer is probably not desirable.  Anyway, I think
- * implementing "retrieve_surrounding" is the only hard problem.
- *
- * One way to solve all of this in a clean manner would be to queue all key
- * press/release events "as is" in the input buffer, and apply the IM filtering
- * at the receiving end of the queue.  This, however, would have a rather large
- * impact on the code base.  If there is an easy way to force processing of all
- * remaining input from within the "retrieve_surrounding" signal handler, this
- * might not be necessary.  Gotta ask on vim-dev for opinions.
- */
-    static void
-im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED)
-{
-    char    *preedit_string = NULL;
-    int	    cursor_index    = 0;
-    int	    num_move_back   = 0;
-    char_u  *str;
-    char_u  *p;
-    int	    i;
-
-    if (p_imst == IM_ON_THE_SPOT)
-	gtk_im_context_get_preedit_string(context,
-					  &preedit_string, NULL,
-					  &cursor_index);
-    else
-	gtk_im_context_get_preedit_string(context,
-					  &preedit_string, NULL,
-					  NULL);
-
-#ifdef XIM_DEBUG
-    xim_log("im_preedit_changed_cb(): %s\n", preedit_string);
-#endif
-
-    g_return_if_fail(preedit_string != NULL); // just in case
-
-    if (p_imst == IM_OVER_THE_SPOT)
-    {
-	if (preedit_string[0] == NUL)
-	{
-	    xim_has_preediting = FALSE;
-	    im_delete_preedit();
-	}
-	else
-	{
-	    xim_has_preediting = TRUE;
-	    im_show_preedit();
-	}
-    }
-    else
-    {
-	// If preedit_start_col is MAXCOL set it to the current cursor position.
-	if (preedit_start_col == MAXCOL && preedit_string[0] != '\0')
-	{
-	    xim_has_preediting = TRUE;
-
-	    // Urgh, this breaks if the input buffer isn't empty now
-	    init_preedit_start_col();
-	}
-	else if (cursor_index == 0 && preedit_string[0] == '\0')
-	{
-	    xim_has_preediting = FALSE;
-
-	    // If at the start position (after typing backspace)
-	    // preedit_start_col must be reset.
-	    preedit_start_col = MAXCOL;
-	}
-
-	im_delete_preedit();
-
-	/*
-	 * Compute the end of the preediting area: "preedit_end_col".
-	 * According to the documentation of gtk_im_context_get_preedit_string(),
-	 * the cursor_pos output argument returns the offset in bytes.  This is
-	 * unfortunately not true -- real life shows the offset is in characters,
-	 * and the GTK+ source code agrees with me.  Will file a bug later.
-	 */
-	if (preedit_start_col != MAXCOL)
-	    preedit_end_col = preedit_start_col;
-	str = (char_u *)preedit_string;
-	for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i)
-	{
-	    int is_composing;
-
-	    is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p)));
-	    /*
-	     * These offsets are used as counters when generating <BS> and <Del>
-	     * to delete the preedit string.  So don't count composing characters
-	     * unless 'delcombine' is enabled.
-	     */
-	    if (!is_composing || p_deco)
-	    {
-		if (i < cursor_index)
-		    ++im_preedit_cursor;
-		else
-		    ++im_preedit_trailing;
-	    }
-	    if (!is_composing && i >= cursor_index)
-	    {
-		// This is essentially the same as im_preedit_trailing, except
-		// composing characters are not counted even if p_deco is set.
-		++num_move_back;
-	    }
-	    if (preedit_start_col != MAXCOL)
-		preedit_end_col += utf_ptr2cells(p);
-	}
-
-	if (p > str)
-	{
-	    im_add_to_input(str, (int)(p - str));
-	    im_correct_cursor(num_move_back);
-	}
-    }
-
-    g_free(preedit_string);
-
-    if (gtk_main_level() > 0)
-	gtk_main_quit();
-}
-
-/*
- * Translate the Pango attributes at iter to Vim highlighting attributes.
- * Ignore attributes not supported by Vim highlighting.  This shouldn't have
- * too much impact -- right now we handle even more attributes than necessary
- * for the IM modules I tested with.
- */
-    static int
-translate_pango_attributes(PangoAttrIterator *iter)
-{
-    PangoAttribute  *attr;
-    int		    char_attr = HL_NORMAL;
-
-    attr = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
-    if (attr != NULL && ((PangoAttrInt *)attr)->value
-						 != (int)PANGO_UNDERLINE_NONE)
-	char_attr |= HL_UNDERLINE;
-
-    attr = pango_attr_iterator_get(iter, PANGO_ATTR_WEIGHT);
-    if (attr != NULL && ((PangoAttrInt *)attr)->value >= (int)PANGO_WEIGHT_BOLD)
-	char_attr |= HL_BOLD;
-
-    attr = pango_attr_iterator_get(iter, PANGO_ATTR_STYLE);
-    if (attr != NULL && ((PangoAttrInt *)attr)->value
-						   != (int)PANGO_STYLE_NORMAL)
-	char_attr |= HL_ITALIC;
-
-    attr = pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
-    if (attr != NULL)
-    {
-	const PangoColor *color = &((PangoAttrColor *)attr)->color;
-
-	// Assume inverse if black background is requested
-	if ((color->red | color->green | color->blue) == 0)
-	    char_attr |= HL_INVERSE;
-    }
-
-    return char_attr;
-}
-
-/*
- * Retrieve the highlighting attributes at column col in the preedit string.
- * Return -1 if not in preediting mode or if col is out of range.
- */
-    int
-im_get_feedback_attr(int col)
-{
-    char	    *preedit_string = NULL;
-    PangoAttrList   *attr_list	    = NULL;
-    int		    char_attr	    = -1;
-
-    if (xic == NULL)
-	return char_attr;
-
-    gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
-
-    if (preedit_string != NULL && attr_list != NULL)
-    {
-	int idx;
-
-	// Get the byte index as used by PangoAttrIterator
-	for (idx = 0; col > 0 && preedit_string[idx] != '\0'; --col)
-	    idx += utfc_ptr2len((char_u *)preedit_string + idx);
-
-	if (preedit_string[idx] != '\0')
-	{
-	    PangoAttrIterator	*iter;
-	    int			start, end;
-
-	    char_attr = HL_NORMAL;
-	    iter = pango_attr_list_get_iterator(attr_list);
-
-	    // Extract all relevant attributes from the list.
-	    do
-	    {
-		pango_attr_iterator_range(iter, &start, &end);
-
-		if (idx >= start && idx < end)
-		    char_attr |= translate_pango_attributes(iter);
-	    }
-	    while (pango_attr_iterator_next(iter));
-
-	    pango_attr_iterator_destroy(iter);
-	}
-    }
-
-    if (attr_list != NULL)
-	pango_attr_list_unref(attr_list);
-    g_free(preedit_string);
-
-    return char_attr;
-}
-
-    void
-xim_init(void)
-{
-#ifdef XIM_DEBUG
-    xim_log("xim_init()\n");
-#endif
-
-    g_return_if_fail(gui.drawarea != NULL);
-    g_return_if_fail(gtk_widget_get_window(gui.drawarea) != NULL);
-
-    xic = gtk_im_multicontext_new();
-    g_object_ref(xic);
-
-    im_commit_handler_id = g_signal_connect(G_OBJECT(xic), "commit",
-					    G_CALLBACK(&im_commit_cb), NULL);
-    g_signal_connect(G_OBJECT(xic), "preedit_changed",
-		     G_CALLBACK(&im_preedit_changed_cb), NULL);
-    g_signal_connect(G_OBJECT(xic), "preedit_start",
-		     G_CALLBACK(&im_preedit_start_cb), NULL);
-    g_signal_connect(G_OBJECT(xic), "preedit_end",
-		     G_CALLBACK(&im_preedit_end_cb), NULL);
-
-    gtk_im_context_set_client_window(xic, gtk_widget_get_window(gui.drawarea));
-}
-
-    void
-im_shutdown(void)
-{
-#ifdef XIM_DEBUG
-    xim_log("im_shutdown()\n");
-#endif
-
-    if (xic != NULL)
-    {
-	gtk_im_context_focus_out(xic);
-	g_object_unref(xic);
-	xic = NULL;
-    }
-    im_is_active = FALSE;
-    im_commit_handler_id = 0;
-    if (p_imst == IM_ON_THE_SPOT)
-	preedit_start_col = MAXCOL;
-    xim_has_preediting = FALSE;
-}
-
-/*
- * Convert the string argument to keyval and state for GdkEventKey.
- * If str is valid return TRUE, otherwise FALSE.
- *
- * See 'imactivatekey' for documentation of the format.
- */
-    static int
-im_string_to_keyval(const char *str, unsigned int *keyval, unsigned int *state)
-{
-    const char	    *mods_end;
-    unsigned	    tmp_keyval;
-    unsigned	    tmp_state = 0;
-
-    mods_end = strrchr(str, '-');
-    mods_end = (mods_end != NULL) ? mods_end + 1 : str;
-
-    // Parse modifier keys
-    while (str < mods_end)
-	switch (*str++)
-	{
-	    case '-':							break;
-	    case 'S': case 's': tmp_state |= (unsigned)GDK_SHIFT_MASK;	break;
-	    case 'L': case 'l': tmp_state |= (unsigned)GDK_LOCK_MASK;	break;
-	    case 'C': case 'c': tmp_state |= (unsigned)GDK_CONTROL_MASK;break;
-	    case '1':		tmp_state |= (unsigned)GDK_MOD1_MASK;	break;
-	    case '2':		tmp_state |= (unsigned)GDK_MOD2_MASK;	break;
-	    case '3':		tmp_state |= (unsigned)GDK_MOD3_MASK;	break;
-	    case '4':		tmp_state |= (unsigned)GDK_MOD4_MASK;	break;
-	    case '5':		tmp_state |= (unsigned)GDK_MOD5_MASK;	break;
-	    default:
-		return FALSE;
-	}
-
-    tmp_keyval = gdk_keyval_from_name(str);
-
-    if (tmp_keyval == 0 || tmp_keyval == GDK_VoidSymbol)
-	return FALSE;
-
-    if (keyval != NULL)
-	*keyval = tmp_keyval;
-    if (state != NULL)
-	*state = tmp_state;
-
-    return TRUE;
-}
-
-/*
- * Return TRUE if p_imak is valid, otherwise FALSE.  As a special case, an
- * empty string is also regarded as valid.
- *
- * Note: The numerical key value of p_imak is cached if it was valid; thus
- * boldly assuming im_xim_isvalid_imactivate() will always be called whenever
- * 'imak' changes.  This is currently the case but not obvious -- should
- * probably rename the function for clarity.
- */
-    int
-im_xim_isvalid_imactivate(void)
-{
-    if (p_imak[0] == NUL)
-    {
-	im_activatekey_keyval = GDK_VoidSymbol;
-	im_activatekey_state  = 0;
-	return TRUE;
-    }
-
-    return im_string_to_keyval((const char *)p_imak,
-			       &im_activatekey_keyval,
-			       &im_activatekey_state);
-}
-
-    static void
-im_synthesize_keypress(unsigned int keyval, unsigned int state)
-{
-    GdkEventKey *event;
-
-    event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS);
-    g_object_ref(gtk_widget_get_window(gui.drawarea));
-					// unreffed by gdk_event_free()
-    event->window = gtk_widget_get_window(gui.drawarea);
-    event->send_event = TRUE;
-    event->time = GDK_CURRENT_TIME;
-    event->state  = state;
-    event->keyval = keyval;
-    event->hardware_keycode = // needed for XIM
-	XKeysymToKeycode(GDK_WINDOW_XDISPLAY(event->window), (KeySym)keyval);
-    event->length = 0;
-    event->string = NULL;
-
-    gtk_im_context_filter_keypress(xic, event);
-
-    // For consistency, also send the corresponding release event.
-    event->type = GDK_KEY_RELEASE;
-    event->send_event = FALSE;
-    gtk_im_context_filter_keypress(xic, event);
-
-    gdk_event_free((GdkEvent *)event);
-}
-
-    void
-xim_reset(void)
-{
-# ifdef FEAT_EVAL
-    if (USE_IMACTIVATEFUNC)
-	call_imactivatefunc(im_is_active);
-    else
-# endif
-    if (xic != NULL)
-    {
-	gtk_im_context_reset(xic);
-
-	if (p_imdisable)
-	    im_shutdown();
-	else
-	{
-	    xim_set_focus(gui.in_focus);
-
-	    if (im_activatekey_keyval != GDK_VoidSymbol)
-	    {
-		if (im_is_active)
-		{
-		    g_signal_handler_block(xic, im_commit_handler_id);
-		    im_synthesize_keypress(im_activatekey_keyval,
-						    im_activatekey_state);
-		    g_signal_handler_unblock(xic, im_commit_handler_id);
-		}
-	    }
-	    else
-	    {
-		im_shutdown();
-		xim_init();
-		xim_set_focus(gui.in_focus);
-	    }
-	}
-    }
-
-    if (p_imst == IM_ON_THE_SPOT)
-	preedit_start_col = MAXCOL;
-    xim_has_preediting = FALSE;
-}
-
-    int
-xim_queue_key_press_event(GdkEventKey *event, int down)
-{
-    if (down)
-    {
-	/*
-	 * Workaround GTK2 XIM 'feature' that always converts keypad keys to
-	 * chars., even when not part of an IM sequence (ref. feature of
-	 * gdk/gdkkeyuni.c).
-	 * Flag any keypad keys that might represent a single char.
-	 * If this (on its own - i.e., not part of an IM sequence) is
-	 * committed while we're processing one of these keys, we can ignore
-	 * that commit and go ahead & process it ourselves.  That way we can
-	 * still distinguish keypad keys for use in mappings.
-	 * Also add GDK_space to make <S-Space> work.
-	 */
-	switch (event->keyval)
-	{
-	    case GDK_KP_Add:      xim_expected_char = '+';  break;
-	    case GDK_KP_Subtract: xim_expected_char = '-';  break;
-	    case GDK_KP_Divide:   xim_expected_char = '/';  break;
-	    case GDK_KP_Multiply: xim_expected_char = '*';  break;
-	    case GDK_KP_Decimal:  xim_expected_char = '.';  break;
-	    case GDK_KP_Equal:    xim_expected_char = '=';  break;
-	    case GDK_KP_0:	  xim_expected_char = '0';  break;
-	    case GDK_KP_1:	  xim_expected_char = '1';  break;
-	    case GDK_KP_2:	  xim_expected_char = '2';  break;
-	    case GDK_KP_3:	  xim_expected_char = '3';  break;
-	    case GDK_KP_4:	  xim_expected_char = '4';  break;
-	    case GDK_KP_5:	  xim_expected_char = '5';  break;
-	    case GDK_KP_6:	  xim_expected_char = '6';  break;
-	    case GDK_KP_7:	  xim_expected_char = '7';  break;
-	    case GDK_KP_8:	  xim_expected_char = '8';  break;
-	    case GDK_KP_9:	  xim_expected_char = '9';  break;
-	    case GDK_space:	  xim_expected_char = ' ';  break;
-	    default:		  xim_expected_char = NUL;
-	}
-	xim_ignored_char = FALSE;
-    }
-
-    /*
-     * When typing fFtT, XIM may be activated. Thus it must pass
-     * gtk_im_context_filter_keypress() in Normal mode.
-     * And while doing :sh too.
-     */
-    if (xic != NULL && !p_imdisable
-		    && (State & (INSERT | CMDLINE | NORMAL | EXTERNCMD)) != 0)
-    {
-	/*
-	 * Filter 'imactivatekey' and map it to CTRL-^.  This way, Vim is
-	 * always aware of the current status of IM, and can even emulate
-	 * the activation key for modules that don't support one.
-	 */
-	if (event->keyval == im_activatekey_keyval
-	     && (event->state & im_activatekey_state) == im_activatekey_state)
-	{
-	    unsigned int state_mask;
-
-	    // Require the state of the 3 most used modifiers to match exactly.
-	    // Otherwise e.g. <S-C-space> would be unusable for other purposes
-	    // if the IM activate key is <S-space>.
-	    state_mask  = im_activatekey_state;
-	    state_mask |= ((int)GDK_SHIFT_MASK | (int)GDK_CONTROL_MASK
-							| (int)GDK_MOD1_MASK);
-
-	    if ((event->state & state_mask) != im_activatekey_state)
-		return FALSE;
-
-	    // Don't send it a second time on GDK_KEY_RELEASE.
-	    if (event->type != GDK_KEY_PRESS)
-		return TRUE;
-
-	    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
-	    {
-		im_set_active(FALSE);
-
-		// ":lmap" mappings exists, toggle use of mappings.
-		State ^= LANGMAP;
-		if (State & LANGMAP)
-		{
-		    curbuf->b_p_iminsert = B_IMODE_NONE;
-		    State &= ~LANGMAP;
-		}
-		else
-		{
-		    curbuf->b_p_iminsert = B_IMODE_LMAP;
-		    State |= LANGMAP;
-		}
-		return TRUE;
-	    }
-
-	    return gtk_im_context_filter_keypress(xic, event);
-	}
-
-	// Don't filter events through the IM context if IM isn't active
-	// right now.  Unlike with GTK+ 1.2 we cannot rely on the IM module
-	// not doing anything before the activation key was sent.
-	if (im_activatekey_keyval == GDK_VoidSymbol || im_is_active)
-	{
-	    int imresult = gtk_im_context_filter_keypress(xic, event);
-
-	    if (p_imst == IM_ON_THE_SPOT)
-	    {
-		// Some XIM send following sequence:
-		// 1. preedited string.
-		// 2. committed string.
-		// 3. line changed key.
-		// 4. preedited string.
-		// 5. remove preedited string.
-		// if 3, Vim can't move back the above line for 5.
-		// thus, this part should not parse the key.
-		if (!imresult && preedit_start_col != MAXCOL
-					    && event->keyval == GDK_Return)
-		{
-		    im_synthesize_keypress(GDK_Return, 0U);
-		    return FALSE;
-		}
-	    }
-
-	    // If XIM tried to commit a keypad key as a single char.,
-	    // ignore it so we can use the keypad key 'raw', for mappings.
-	    if (xim_expected_char != NUL && xim_ignored_char)
-		// We had a keypad key, and XIM tried to thieve it
-		return FALSE;
-
-	    // This is supposed to fix a problem with iBus, that space
-	    // characters don't work in input mode.
-	    xim_expected_char = NUL;
-
-	    // Normal processing
-	    return imresult;
-	}
-    }
-
-    return FALSE;
-}
-
-    int
-im_get_status(void)
-{
-#  ifdef FEAT_EVAL
-    if (USE_IMSTATUSFUNC)
-	return call_imstatusfunc();
-#  endif
-    return im_is_active;
-}
-
-    int
-preedit_get_status(void)
-{
-    return preedit_is_active;
-}
-
-    int
-im_is_preediting(void)
-{
-    return xim_has_preediting;
-}
-
-# else // !FEAT_GUI_GTK
-
-static int	xim_is_active = FALSE;  // XIM should be active in the current
-					// mode
-static int	xim_has_focus = FALSE;	// XIM is really being used for Vim
-#  ifdef FEAT_GUI_X11
-static XIMStyle	input_style;
-static int	status_area_enabled = TRUE;
-#  endif
-
-/*
- * Switch using XIM on/off.  This is used by the code that changes "State".
- * When 'imactivatefunc' is defined use that function instead.
- */
-    void
-im_set_active(int active_arg)
-{
-    int active = active_arg;
-
-    // If 'imdisable' is set, XIM is never active.
-    if (p_imdisable)
-	active = FALSE;
-    else if (input_style & XIMPreeditPosition)
-	// There is a problem in switching XIM off when preediting is used,
-	// and it is not clear how this can be solved.  For now, keep XIM on
-	// all the time, like it was done in Vim 5.8.
-	active = TRUE;
-
-#  if defined(FEAT_EVAL)
-    if (USE_IMACTIVATEFUNC)
-    {
-	if (active != im_get_status())
-	{
-	    call_imactivatefunc(active);
-	    xim_has_focus = active;
-	}
-	return;
-    }
-#  endif
-
-    if (xic == NULL)
-	return;
-
-    // Remember the active state, it is needed when Vim gets keyboard focus.
-    xim_is_active = active;
-    xim_set_preedit();
-}
-
-/*
- * Adjust using XIM for gaining or losing keyboard focus.  Also called when
- * "xim_is_active" changes.
- */
-    void
-xim_set_focus(int focus)
-{
-    if (xic == NULL)
-	return;
-
-    /*
-     * XIM only gets focus when the Vim window has keyboard focus and XIM has
-     * been set active for the current mode.
-     */
-    if (focus && xim_is_active)
-    {
-	if (!xim_has_focus)
-	{
-	    xim_has_focus = TRUE;
-	    XSetICFocus(xic);
-	}
-    }
-    else
-    {
-	if (xim_has_focus)
-	{
-	    xim_has_focus = FALSE;
-	    XUnsetICFocus(xic);
-	}
-    }
-}
-
-    void
-im_set_position(int row UNUSED, int col UNUSED)
-{
-    xim_set_preedit();
-}
-
-/*
- * Set the XIM to the current cursor position.
- */
-    void
-xim_set_preedit(void)
-{
-    XVaNestedList attr_list;
-    XRectangle spot_area;
-    XPoint over_spot;
-    int line_space;
-
-    if (xic == NULL)
-	return;
-
-    xim_set_focus(TRUE);
-
-    if (!xim_has_focus)
-    {
-	// hide XIM cursor
-	over_spot.x = 0;
-	over_spot.y = -100; // arbitrary invisible position
-	attr_list = (XVaNestedList) XVaCreateNestedList(0,
-							XNSpotLocation,
-							&over_spot,
-							NULL);
-	XSetICValues(xic, XNPreeditAttributes, attr_list, NULL);
-	XFree(attr_list);
-	return;
-    }
-
-    if (input_style & XIMPreeditPosition)
-    {
-	if (xim_fg_color == INVALCOLOR)
-	{
-	    xim_fg_color = gui.def_norm_pixel;
-	    xim_bg_color = gui.def_back_pixel;
-	}
-	over_spot.x = TEXT_X(gui.col);
-	over_spot.y = TEXT_Y(gui.row);
-	spot_area.x = 0;
-	spot_area.y = 0;
-	spot_area.height = gui.char_height * Rows;
-	spot_area.width  = gui.char_width * Columns;
-	line_space = gui.char_height;
-	attr_list = (XVaNestedList) XVaCreateNestedList(0,
-					XNSpotLocation, &over_spot,
-					XNForeground, (Pixel) xim_fg_color,
-					XNBackground, (Pixel) xim_bg_color,
-					XNArea, &spot_area,
-					XNLineSpace, line_space,
-					NULL);
-	if (XSetICValues(xic, XNPreeditAttributes, attr_list, NULL))
-	    emsg(_("E284: Cannot set IC values"));
-	XFree(attr_list);
-    }
-}
-
-#  if defined(FEAT_GUI_X11)
-static char e_xim[] = N_("E285: Failed to create input context");
-#  endif
-
-#  if defined(FEAT_GUI_X11) || defined(PROTO)
-#   if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(SUN_SYSTEM)
-#    define USE_X11R6_XIM
-#   endif
-
-static int xim_real_init(Window x11_window, Display *x11_display);
-
-
-#  ifdef USE_X11R6_XIM
-    static void
-xim_instantiate_cb(
-    Display	*display,
-    XPointer	client_data UNUSED,
-    XPointer	call_data UNUSED)
-{
-    Window	x11_window;
-    Display	*x11_display;
-
-#   ifdef XIM_DEBUG
-    xim_log("xim_instantiate_cb()\n");
-#   endif
-
-    gui_get_x11_windis(&x11_window, &x11_display);
-    if (display != x11_display)
-	return;
-
-    xim_real_init(x11_window, x11_display);
-    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
-    if (xic != NULL)
-	XUnregisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
-					 xim_instantiate_cb, NULL);
-}
-
-    static void
-xim_destroy_cb(
-    XIM		im UNUSED,
-    XPointer	client_data UNUSED,
-    XPointer	call_data UNUSED)
-{
-    Window	x11_window;
-    Display	*x11_display;
-
-#   ifdef XIM_DEBUG
-    xim_log("xim_destroy_cb()\n");
-   #endif
-    gui_get_x11_windis(&x11_window, &x11_display);
-
-    xic = NULL;
-    status_area_enabled = FALSE;
-
-    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
-
-    XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
-				   xim_instantiate_cb, NULL);
-}
-#  endif
-
-    void
-xim_init(void)
-{
-    Window	x11_window;
-    Display	*x11_display;
-
-#  ifdef XIM_DEBUG
-    xim_log("xim_init()\n");
-#  endif
-
-    gui_get_x11_windis(&x11_window, &x11_display);
-
-    xic = NULL;
-
-    if (xim_real_init(x11_window, x11_display))
-	return;
-
-    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
-
-#  ifdef USE_X11R6_XIM
-    XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
-				   xim_instantiate_cb, NULL);
-#  endif
-}
-
-    static int
-xim_real_init(Window x11_window, Display *x11_display)
-{
-    int		i;
-    char	*p,
-		*s,
-		*ns,
-		*end,
-		tmp[1024];
-#  define IMLEN_MAX 40
-    char	buf[IMLEN_MAX + 7];
-    XIM		xim = NULL;
-    XIMStyles	*xim_styles;
-    XIMStyle	this_input_style = 0;
-    Boolean	found;
-    XPoint	over_spot;
-    XVaNestedList preedit_list, status_list;
-
-    input_style = 0;
-    status_area_enabled = FALSE;
-
-    if (xic != NULL)
-	return FALSE;
-
-    if (gui.rsrc_input_method != NULL && *gui.rsrc_input_method != NUL)
-    {
-	strcpy(tmp, gui.rsrc_input_method);
-	for (ns = s = tmp; ns != NULL && *s != NUL;)
-	{
-	    s = (char *)skipwhite((char_u *)s);
-	    if (*s == NUL)
-		break;
-	    if ((ns = end = strchr(s, ',')) == NULL)
-		end = s + strlen(s);
-	    while (isspace(((char_u *)end)[-1]))
-		end--;
-	    *end = NUL;
-
-	    if (strlen(s) <= IMLEN_MAX)
-	    {
-		strcpy(buf, "@im=");
-		strcat(buf, s);
-		if ((p = XSetLocaleModifiers(buf)) != NULL && *p != NUL
-			&& (xim = XOpenIM(x11_display, NULL, NULL, NULL))
-								      != NULL)
-		    break;
-	    }
-
-	    s = ns + 1;
-	}
-    }
-
-    if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p != NUL)
-	xim = XOpenIM(x11_display, NULL, NULL, NULL);
-
-    // This is supposed to be useful to obtain characters through
-    // XmbLookupString() without really using a XIM.
-    if (xim == NULL && (p = XSetLocaleModifiers("@im=none")) != NULL
-								 && *p != NUL)
-	xim = XOpenIM(x11_display, NULL, NULL, NULL);
-
-    if (xim == NULL)
-    {
-	// Only give this message when verbose is set, because too many people
-	// got this message when they didn't want to use a XIM.
-	if (p_verbose > 0)
-	{
-	    verbose_enter();
-	    emsg(_("E286: Failed to open input method"));
-	    verbose_leave();
-	}
-	return FALSE;
-    }
-
-#  ifdef USE_X11R6_XIM
-    {
-	XIMCallback destroy_cb;
-
-	destroy_cb.callback = xim_destroy_cb;
-	destroy_cb.client_data = NULL;
-	if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL))
-	    emsg(_("E287: Warning: Could not set destroy callback to IM"));
-    }
-#  endif
-
-    if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles)
-    {
-	emsg(_("E288: input method doesn't support any style"));
-	XCloseIM(xim);
-	return FALSE;
-    }
-
-    found = False;
-    strcpy(tmp, gui.rsrc_preedit_type_name);
-    for (s = tmp; s && !found; )
-    {
-	while (*s && isspace((unsigned char)*s))
-	    s++;
-	if (!*s)
-	    break;
-	if ((ns = end = strchr(s, ',')) != 0)
-	    ns++;
-	else
-	    end = s + strlen(s);
-	while (isspace((unsigned char)*end))
-	    end--;
-	*end = '\0';
-
-	if (!strcmp(s, "OverTheSpot"))
-	    this_input_style = (XIMPreeditPosition | XIMStatusArea);
-	else if (!strcmp(s, "OffTheSpot"))
-	    this_input_style = (XIMPreeditArea | XIMStatusArea);
-	else if (!strcmp(s, "Root"))
-	    this_input_style = (XIMPreeditNothing | XIMStatusNothing);
-
-	for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
-	{
-	    if (this_input_style == xim_styles->supported_styles[i])
-	    {
-		found = True;
-		break;
-	    }
-	}
-	if (!found)
-	    for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
-	    {
-		if ((xim_styles->supported_styles[i] & this_input_style)
-			== (this_input_style & ~XIMStatusArea))
-		{
-		    this_input_style &= ~XIMStatusArea;
-		    found = True;
-		    break;
-		}
-	    }
-
-	s = ns;
-    }
-    XFree(xim_styles);
-
-    if (!found)
-    {
-	// Only give this message when verbose is set, because too many people
-	// got this message when they didn't want to use a XIM.
-	if (p_verbose > 0)
-	{
-	    verbose_enter();
-	    emsg(_("E289: input method doesn't support my preedit type"));
-	    verbose_leave();
-	}
-	XCloseIM(xim);
-	return FALSE;
-    }
-
-    over_spot.x = TEXT_X(gui.col);
-    over_spot.y = TEXT_Y(gui.row);
-    input_style = this_input_style;
-
-    // A crash was reported when trying to pass gui.norm_font as XNFontSet,
-    // thus that has been removed.  Hopefully the default works...
-#  ifdef FEAT_XFONTSET
-    if (gui.fontset != NOFONTSET)
-    {
-	preedit_list = XVaCreateNestedList(0,
-				XNSpotLocation, &over_spot,
-				XNForeground, (Pixel)gui.def_norm_pixel,
-				XNBackground, (Pixel)gui.def_back_pixel,
-				XNFontSet, (XFontSet)gui.fontset,
-				NULL);
-	status_list = XVaCreateNestedList(0,
-				XNForeground, (Pixel)gui.def_norm_pixel,
-				XNBackground, (Pixel)gui.def_back_pixel,
-				XNFontSet, (XFontSet)gui.fontset,
-				NULL);
-    }
-    else
-#  endif
-    {
-	preedit_list = XVaCreateNestedList(0,
-				XNSpotLocation, &over_spot,
-				XNForeground, (Pixel)gui.def_norm_pixel,
-				XNBackground, (Pixel)gui.def_back_pixel,
-				NULL);
-	status_list = XVaCreateNestedList(0,
-				XNForeground, (Pixel)gui.def_norm_pixel,
-				XNBackground, (Pixel)gui.def_back_pixel,
-				NULL);
-    }
-
-    xic = XCreateIC(xim,
-		    XNInputStyle, input_style,
-		    XNClientWindow, x11_window,
-		    XNFocusWindow, gui.wid,
-		    XNPreeditAttributes, preedit_list,
-		    XNStatusAttributes, status_list,
-		    NULL);
-    XFree(status_list);
-    XFree(preedit_list);
-    if (xic != NULL)
-    {
-	if (input_style & XIMStatusArea)
-	{
-	    xim_set_status_area();
-	    status_area_enabled = TRUE;
-	}
-	else
-	    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
-    }
-    else
-    {
-	if (!is_not_a_term())
-	    emsg(_(e_xim));
-	XCloseIM(xim);
-	return FALSE;
-    }
-
-    return TRUE;
-}
-
-#  endif // FEAT_GUI_X11
-
-/*
- * Get IM status.  When IM is on, return TRUE.  Else return FALSE.
- * FIXME: This doesn't work correctly: Having focus doesn't always mean XIM is
- * active, when not having focus XIM may still be active (e.g., when using a
- * tear-off menu item).
- */
-    int
-im_get_status(void)
-{
-#  ifdef FEAT_EVAL
-    if (USE_IMSTATUSFUNC)
-	return call_imstatusfunc();
-#  endif
-    return xim_has_focus;
-}
-
-# endif // !FEAT_GUI_GTK
-
-# if !defined(FEAT_GUI_GTK) || defined(PROTO)
-/*
- * Set up the status area.
- *
- * This should use a separate Widget, but that seems not possible, because
- * preedit_area and status_area should be set to the same window as for the
- * text input.  Unfortunately this means the status area pollutes the text
- * window...
- */
-    void
-xim_set_status_area(void)
-{
-    XVaNestedList preedit_list = 0, status_list = 0, list = 0;
-    XRectangle pre_area, status_area;
-
-    if (xic == NULL)
-	return;
-
-    if (input_style & XIMStatusArea)
-    {
-	if (input_style & XIMPreeditArea)
-	{
-	    XRectangle *needed_rect;
-
-	    // to get status_area width
-	    status_list = XVaCreateNestedList(0, XNAreaNeeded,
-					      &needed_rect, NULL);
-	    XGetICValues(xic, XNStatusAttributes, status_list, NULL);
-	    XFree(status_list);
-
-	    status_area.width = needed_rect->width;
-	}
-	else
-	    status_area.width = gui.char_width * Columns;
-
-	status_area.x = 0;
-	status_area.y = gui.char_height * Rows + gui.border_offset;
-	if (gui.which_scrollbars[SBAR_BOTTOM])
-	    status_area.y += gui.scrollbar_height;
-#ifdef FEAT_MENU
-	if (gui.menu_is_active)
-	    status_area.y += gui.menu_height;
-#endif
-	status_area.height = gui.char_height;
-	status_list = XVaCreateNestedList(0, XNArea, &status_area, NULL);
-    }
-    else
-    {
-	status_area.x = 0;
-	status_area.y = gui.char_height * Rows + gui.border_offset;
-	if (gui.which_scrollbars[SBAR_BOTTOM])
-	    status_area.y += gui.scrollbar_height;
-#ifdef FEAT_MENU
-	if (gui.menu_is_active)
-	    status_area.y += gui.menu_height;
-#endif
-	status_area.width = 0;
-	status_area.height = gui.char_height;
-    }
-
-    if (input_style & XIMPreeditArea)   // off-the-spot
-    {
-	pre_area.x = status_area.x + status_area.width;
-	pre_area.y = gui.char_height * Rows + gui.border_offset;
-	pre_area.width = gui.char_width * Columns - pre_area.x;
-	if (gui.which_scrollbars[SBAR_BOTTOM])
-	    pre_area.y += gui.scrollbar_height;
-#ifdef FEAT_MENU
-	if (gui.menu_is_active)
-	    pre_area.y += gui.menu_height;
-#endif
-	pre_area.height = gui.char_height;
-	preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
-    }
-    else if (input_style & XIMPreeditPosition)   // over-the-spot
-    {
-	pre_area.x = 0;
-	pre_area.y = 0;
-	pre_area.height = gui.char_height * Rows;
-	pre_area.width = gui.char_width * Columns;
-	preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
-    }
-
-    if (preedit_list && status_list)
-	list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
-				   XNStatusAttributes, status_list, NULL);
-    else if (preedit_list)
-	list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
-				   NULL);
-    else if (status_list)
-	list = XVaCreateNestedList(0, XNStatusAttributes, status_list,
-				   NULL);
-    else
-	list = NULL;
-
-    if (list)
-    {
-	XSetICValues(xic, XNVaNestedList, list, NULL);
-	XFree(list);
-    }
-    if (status_list)
-	XFree(status_list);
-    if (preedit_list)
-	XFree(preedit_list);
-}
-
-    int
-xim_get_status_area_height(void)
-{
-    if (status_area_enabled)
-	return gui.char_height;
-    return 0;
-}
-# endif
-
-#else // !defined(FEAT_XIM)
-
-# if defined(IME_WITHOUT_XIM) || defined(VIMDLL)
-static int im_was_set_active = FALSE;
-
-    int
-#  ifdef VIMDLL
-mbyte_im_get_status(void)
-#  else
-im_get_status(void)
-#  endif
-{
-#  if defined(FEAT_EVAL)
-    if (USE_IMSTATUSFUNC)
-	return call_imstatusfunc();
-#  endif
-    return im_was_set_active;
-}
-
-    void
-#  ifdef VIMDLL
-mbyte_im_set_active(int active_arg)
-#  else
-im_set_active(int active_arg)
-#  endif
-{
-#  if defined(FEAT_EVAL)
-    int	    active = !p_imdisable && active_arg;
-
-    if (USE_IMACTIVATEFUNC && active != im_get_status())
-    {
-	call_imactivatefunc(active);
-	im_was_set_active = active;
-    }
-#  endif
-}
-
-#  if defined(FEAT_GUI) && !defined(FEAT_GUI_HAIKU) && !defined(VIMDLL)
-    void
-im_set_position(int row UNUSED, int col UNUSED)
-{
-}
-#  endif
-# endif
-
-#endif // FEAT_XIM
-
 #if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * "getimstatus()" function
diff --git a/src/proto.h b/src/proto.h
index b73350a..eec7ad5 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -92,6 +92,7 @@
 # include "findfile.pro"
 # include "fold.pro"
 # include "getchar.pro"
+# include "gui_xim.pro"
 # include "hardcopy.pro"
 # include "hashtab.pro"
 # include "highlight.pro"
diff --git a/src/proto/gui_xim.pro b/src/proto/gui_xim.pro
new file mode 100644
index 0000000..01fb56c
--- /dev/null
+++ b/src/proto/gui_xim.pro
@@ -0,0 +1,17 @@
+/* gui_xim.c */
+void im_set_active(int active);
+void xim_set_focus(int focus);
+void im_set_position(int row, int col);
+void xim_set_preedit(void);
+int im_get_feedback_attr(int col);
+void xim_init(void);
+void im_shutdown(void);
+int im_xim_isvalid_imactivate(void);
+void xim_reset(void);
+int xim_queue_key_press_event(GdkEventKey *event, int down);
+int im_get_status(void);
+int preedit_get_status(void);
+int im_is_preediting(void);
+void xim_set_status_area(void);
+int xim_get_status_area_height(void);
+/* vim: set ft=c : */
diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro
index cbfa909..7b8c4fe 100644
--- a/src/proto/mbyte.pro
+++ b/src/proto/mbyte.pro
@@ -74,21 +74,6 @@
 void *my_iconv_open(char_u *to, char_u *from);
 int iconv_enabled(int verbose);
 void iconv_end(void);
-void im_set_active(int active);
-void xim_set_focus(int focus);
-void im_set_position(int row, int col);
-void xim_set_preedit(void);
-int im_get_feedback_attr(int col);
-void xim_init(void);
-void im_shutdown(void);
-int im_xim_isvalid_imactivate(void);
-void xim_reset(void);
-int xim_queue_key_press_event(GdkEventKey *event, int down);
-int im_get_status(void);
-int preedit_get_status(void);
-int im_is_preediting(void);
-void xim_set_status_area(void);
-int xim_get_status_area_height(void);
 void f_getimstatus(typval_T *argvars, typval_T *rettv);
 int convert_setup(vimconv_T *vcp, char_u *from, char_u *to);
 int convert_setup_ext(vimconv_T *vcp, char_u *from, int from_unicode_is_utf8, char_u *to, int to_unicode_is_utf8);
diff --git a/src/version.c b/src/version.c
index 7138ac5..ec8cda7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    872,
+/**/
     871,
 /**/
     870,
