patch 8.0.1336: cannot use imactivatefunc() unless compiled with +xim

Problem:    Cannot use imactivatefunc() unless compiled with +xim.
Solution:   Allow using imactivatefunc() when not compiled with +xim.
            (Yasuhiro Matsumoto, closes #2349)
diff --git a/src/Makefile b/src/Makefile
index 09cf21e..7ccd766 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2190,6 +2190,7 @@
 	test_highlight \
 	test_history \
 	test_hlsearch \
+	test_iminsert \
 	test_increment \
 	test_increment_dbcs \
 	test_ins_complete \
diff --git a/src/mbyte.c b/src/mbyte.c
index 3592ddb..54186d9c 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -4782,6 +4782,20 @@
 
 #endif /* FEAT_MBYTE */
 
+#ifdef FEAT_EVAL
+    static void
+call_imactivatefunc(int active)
+{
+    char_u *argv[1];
+
+    if (active)
+	argv[0] = (char_u *)"1";
+    else
+	argv[0] = (char_u *)"0";
+    (void)call_func_retnr(p_imaf, 1, argv, FALSE);
+}
+#endif
+
 #if defined(FEAT_XIM) || defined(PROTO)
 
 # if defined(FEAT_GUI_GTK) || defined(PROTO)
@@ -4824,7 +4838,14 @@
     im_is_active = (active && !p_imdisable);
 
     if (im_is_active != was_active)
-	xim_reset();
+    {
+#ifdef FEAT_EVAL
+	if (p_imaf[0] != NUL)
+	    call_imactivatefunc(im_is_active);
+	else
+#endif
+	    xim_reset();
+    }
 }
 
     void
@@ -5666,15 +5687,7 @@
 
 #  ifdef FEAT_EVAL
 	    if (p_imaf[0] != NUL)
-	    {
-		char_u *argv[1];
-
-		if (im_is_active)
-		    argv[0] = (char_u *)"1";
-		else
-		    argv[0] = (char_u *)"0";
-		(void)call_func_retnr(p_imaf, 1, argv, FALSE);
-	    }
+		call_imactivatefunc(im_is_active);
 	    else
 #  endif
 		if (im_activatekey_keyval != GDK_VoidSymbol)
@@ -6442,6 +6455,45 @@
 }
 # endif
 
+#else /* !defined(FEAT_XIM) */
+
+# ifndef FEAT_GUI_W32
+    int
+im_get_status()
+{
+#  ifdef FEAT_EVAL
+    if (p_imsf[0] != NUL)
+    {
+	int is_active;
+
+	/* FIXME: Don't execute user function in unsafe situation. */
+	if (exiting
+#   ifdef FEAT_AUTOCMD
+		|| is_autocmd_blocked()
+#   endif
+		)
+	    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, FALSE);
+	--msg_silent;
+	return (is_active > 0);
+    }
+#  endif
+    return FALSE;
+}
+
+    void
+im_set_active(int active)
+{
+#  ifdef(USE_IM_CONTROL) && defined(FEAT_EVAL)
+    if (p_imaf[0] != NUL)
+	call_imactivatefunc(p_imdisable ? FALSE : active);
+#  endif
+}
+# endif
+
 #endif /* FEAT_XIM */
 
 #if defined(FEAT_MBYTE) || defined(PROTO)
diff --git a/src/option.c b/src/option.c
index e09191f..ac0918d 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1539,7 +1539,7 @@
 			    (char_u *)&p_ic, PV_NONE,
 			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
     {"imactivatefunc","imaf",P_STRING|P_VI_DEF|P_SECURE,
-# if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+#if defined(FEAT_EVAL) && defined(USE_IM_CONTROL)
 			    (char_u *)&p_imaf, PV_NONE,
 			    {(char_u *)"", (char_u *)NULL}
 # else
@@ -1582,7 +1582,7 @@
 			    {(char_u *)B_IMODE_USE_INSERT, (char_u *)0L}
 			    SCRIPTID_INIT},
     {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE,
-#if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+#if defined(FEAT_EVAL) && defined(USE_IM_CONTROL)
 			    (char_u *)&p_imsf, PV_NONE,
 			    {(char_u *)"", (char_u *)NULL}
 #else
diff --git a/src/option.h b/src/option.h
index d963c1f..57126a3 100644
--- a/src/option.h
+++ b/src/option.h
@@ -581,11 +581,13 @@
 EXTERN int	p_ic;		/* 'ignorecase' */
 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
 EXTERN char_u	*p_imak;	/* 'imactivatekey' */
+#define IM_ON_THE_SPOT		0L
+#define IM_OVER_THE_SPOT	1L
+EXTERN long	p_imst;		/* 'imstyle' */
+#endif
+#if defined(FEAT_EVAL) && defined(USE_IM_CONTROL)
 EXTERN char_u	*p_imaf;	/* 'imactivatefunc' */
 EXTERN char_u	*p_imsf;	/* 'imstatusfunc' */
-EXTERN long	p_imst;		/* 'imstyle' */
-# define IM_ON_THE_SPOT		0L
-# define IM_OVER_THE_SPOT	1L
 #endif
 #ifdef USE_IM_CONTROL
 EXTERN int	p_imcmdline;	/* 'imcmdline' */
diff --git a/src/structs.h b/src/structs.h
index 774104c..6aaccc5 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2091,12 +2091,8 @@
 #define B_IMODE_USE_INSERT -1	/*	Use b_p_iminsert value for search */
 #define B_IMODE_NONE 0		/*	Input via none */
 #define B_IMODE_LMAP 1		/*	Input via langmap */
-#ifndef USE_IM_CONTROL
-# define B_IMODE_LAST 1
-#else
-# define B_IMODE_IM 2		/*	Input via input method */
-# define B_IMODE_LAST 2
-#endif
+#define B_IMODE_IM 2		/*	Input via input method */
+#define B_IMODE_LAST 2
 
 #ifdef FEAT_KEYMAP
     short	b_kmap_state;	/* using "lmap" mappings */
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index d9ff056..df79e9a 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -115,6 +115,7 @@
 	    test_highlight.res \
 	    test_history.res \
 	    test_hlsearch.res \
+	    test_iminsert.res \
 	    test_increment.res \
 	    test_increment_dbcs.res \
 	    test_ins_complete.res \
diff --git a/src/testdir/test_iminsert.vim b/src/testdir/test_iminsert.vim
new file mode 100644
index 0000000..603135a
--- /dev/null
+++ b/src/testdir/test_iminsert.vim
@@ -0,0 +1,29 @@
+if !has('multi_byte')
+  finish
+endif
+
+source view_util.vim
+
+let s:imactivatefunc_called = 0
+let s:imstatusfunc_called = 0
+
+func IM_activatefunc(active)
+  let s:imactivatefunc_called = 1
+endfunc
+
+func IM_statusfunc()
+  let s:imstatusfunc_called = 1
+  return 0
+endfunc
+
+func Test_iminsert2()
+  set imactivatefunc=IM_activatefunc
+  set imstatusfunc=IM_statusfunc
+  set iminsert=2
+  normal! i
+  set iminsert=0
+  set imactivatefunc=
+  set imstatusfunc=
+  call assert_equal(1, s:imactivatefunc_called)
+  call assert_equal(1, s:imstatusfunc_called)
+endfunc
diff --git a/src/version.c b/src/version.c
index e0ba19e..57c4576 100644
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1336,
+/**/
     1335,
 /**/
     1334,
diff --git a/src/vim.h b/src/vim.h
index 83ffb29..1d481ca 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -536,9 +536,7 @@
 /*
  * Check input method control.
  */
-#if defined(FEAT_XIM) \
-    || (defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) \
-    || (defined(FEAT_GUI_MAC) && defined(FEAT_MBYTE))
+#if defined(FEAT_MBYTE)
 # define USE_IM_CONTROL
 #endif