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
