xref: /vim-8.2.3635/src/mbyte.c (revision 843ee41e)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  * Multibyte extensions partly by Sung-Hoon Baek
5  *
6  * Do ":help uganda"  in Vim to read copying and usage conditions.
7  * Do ":help credits" in Vim to see a list of people who contributed.
8  * See README.txt for an overview of the Vim source code.
9  */
10 /*
11  * mbyte.c: Code specifically for handling multi-byte characters.
12  *
13  * The encoding used in the core is set with 'encoding'.  When 'encoding' is
14  * changed, the following four variables are set (for speed).
15  * Currently these types of character encodings are supported:
16  *
17  * "enc_dbcs"	    When non-zero it tells the type of double byte character
18  *		    encoding (Chinese, Korean, Japanese, etc.).
19  *		    The cell width on the display is equal to the number of
20  *		    bytes.  (exception: DBCS_JPNU with first byte 0x8e)
21  *		    Recognizing the first or second byte is difficult, it
22  *		    requires checking a byte sequence from the start.
23  * "enc_utf8"	    When TRUE use Unicode characters in UTF-8 encoding.
24  *		    The cell width on the display needs to be determined from
25  *		    the character value.
26  *		    Recognizing bytes is easy: 0xxx.xxxx is a single-byte
27  *		    char, 10xx.xxxx is a trailing byte, 11xx.xxxx is a leading
28  *		    byte of a multi-byte character.
29  *		    To make things complicated, up to two composing characters
30  *		    are allowed.  These are drawn on top of the first char.
31  *		    For most editing the sequence of bytes with composing
32  *		    characters included is considered to be one character.
33  * "enc_unicode"    When 2 use 16-bit Unicode characters (or UTF-16).
34  *		    When 4 use 32-but Unicode characters.
35  *		    Internally characters are stored in UTF-8 encoding to
36  *		    avoid NUL bytes.  Conversion happens when doing I/O.
37  *		    "enc_utf8" will also be TRUE.
38  *
39  * "has_mbyte" is set when "enc_dbcs" or "enc_utf8" is non-zero.
40  *
41  * If none of these is TRUE, 8-bit bytes are used for a character.  The
42  * encoding isn't currently specified (TODO).
43  *
44  * 'encoding' specifies the encoding used in the core.  This is in registers,
45  * text manipulation, buffers, etc.  Conversion has to be done when characters
46  * in another encoding are received or send:
47  *
48  *		       clipboard
49  *			   ^
50  *			   | (2)
51  *			   V
52  *		   +---------------+
53  *	      (1)  |		   | (3)
54  *  keyboard ----->|	 core	   |-----> display
55  *		   |		   |
56  *		   +---------------+
57  *			   ^
58  *			   | (4)
59  *			   V
60  *			 file
61  *
62  * (1) Typed characters arrive in the current locale.  Conversion is to be
63  *     done when 'encoding' is different from 'termencoding'.
64  * (2) Text will be made available with the encoding specified with
65  *     'encoding'.  If this is not sufficient, system-specific conversion
66  *     might be required.
67  * (3) For the GUI the correct font must be selected, no conversion done.
68  *     Otherwise, conversion is to be done when 'encoding' differs from
69  *     'termencoding'.  (Different in the GTK+ 2 port -- 'termencoding'
70  *     is always used for both input and output and must always be set to
71  *     "utf-8".  gui_mch_init() does this automatically.)
72  * (4) The encoding of the file is specified with 'fileencoding'.  Conversion
73  *     is to be done when it's different from 'encoding'.
74  *
75  * The viminfo file is a special case: Only text is converted, not file names.
76  * Vim scripts may contain an ":encoding" command.  This has an effect for
77  * some commands, like ":menutrans"
78  */
79 
80 #include "vim.h"
81 
82 #ifdef WIN32UNIX
83 # ifndef WIN32_LEAN_AND_MEAN
84 #  define WIN32_LEAN_AND_MEAN
85 # endif
86 # include <windows.h>
87 # ifdef WIN32
88 #  undef WIN32	    /* Some windows.h define WIN32, we don't want that here. */
89 # endif
90 #endif
91 
92 #if (defined(WIN3264) || defined(WIN32UNIX)) && !defined(__MINGW32__)
93 # include <winnls.h>
94 #endif
95 
96 #ifdef FEAT_GUI_X11
97 # include <X11/Intrinsic.h>
98 #endif
99 #ifdef X_LOCALE
100 #include <X11/Xlocale.h>
101 #endif
102 
103 #if defined(FEAT_XIM) && defined(HAVE_GTK2)
104 # include <gdk/gdkkeysyms.h>
105 # ifdef WIN3264
106 #  include <gdk/gdkwin32.h>
107 # else
108 #  include <gdk/gdkx.h>
109 # endif
110 #endif
111 
112 #ifdef HAVE_WCHAR_H
113 # include <wchar.h>
114 #endif
115 
116 #if 0
117 /* This has been disabled, because several people reported problems with the
118  * wcwidth() and iswprint() library functions, esp. for Hebrew. */
119 # ifdef __STDC_ISO_10646__
120 #  define USE_WCHAR_FUNCTIONS
121 # endif
122 #endif
123 
124 #if defined(FEAT_MBYTE) || defined(PROTO)
125 
126 static int enc_canon_search __ARGS((char_u *name));
127 static int dbcs_char2len __ARGS((int c));
128 static int dbcs_char2bytes __ARGS((int c, char_u *buf));
129 static int dbcs_ptr2len_check __ARGS((char_u *p));
130 static int dbcs_char2cells __ARGS((int c));
131 static int dbcs_ptr2char __ARGS((char_u *p));
132 
133 /* Lookup table to quickly get the length in bytes of a UTF-8 character from
134  * the first byte of a UTF-8 string.  Bytes which are illegal when used as the
135  * first byte have a one, because these will be used separately. */
136 static char utf8len_tab[256] =
137 {
138     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
139     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
140     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
141     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
142     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/
143     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/
144     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
145     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,1,1,
146 };
147 
148 /*
149  * XIM often causes trouble.  Define XIM_DEBUG to get a log of XIM callbacks
150  * in the "xim.log" file.
151  */
152 /* #define XIM_DEBUG */
153 #ifdef XIM_DEBUG
154     static void
155 xim_log(char *s, ...)
156 {
157     va_list arglist;
158     static FILE *fd = NULL;
159 
160     if (fd == (FILE *)-1)
161 	return;
162     if (fd == NULL)
163     {
164 	fd = fopen("xim.log", "w");
165 	if (fd == NULL)
166 	{
167 	    EMSG("Cannot open xim.log");
168 	    fd = (FILE *)-1;
169 	    return;
170 	}
171     }
172 
173     va_start(arglist, s);
174     vfprintf(fd, s, arglist);
175     va_end(arglist);
176 }
177 #endif
178 
179 #endif
180 
181 #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) || defined(PROTO)
182 /*
183  * Canonical encoding names and their properties.
184  * "iso-8859-n" is handled by enc_canonize() directly.
185  */
186 static struct
187 {   char *name;		int prop;		int codepage;}
188 enc_canon_table[] =
189 {
190 #define IDX_LATIN_1	0
191     {"latin1",		ENC_8BIT + ENC_LATIN1,	1252},
192 #define IDX_ISO_2	1
193     {"iso-8859-2",	ENC_8BIT,		0},
194 #define IDX_ISO_3	2
195     {"iso-8859-3",	ENC_8BIT,		0},
196 #define IDX_ISO_4	3
197     {"iso-8859-4",	ENC_8BIT,		0},
198 #define IDX_ISO_5	4
199     {"iso-8859-5",	ENC_8BIT,		0},
200 #define IDX_ISO_6	5
201     {"iso-8859-6",	ENC_8BIT,		0},
202 #define IDX_ISO_7	6
203     {"iso-8859-7",	ENC_8BIT,		0},
204 #define IDX_CP1255	7
205     {"cp1255",		ENC_8BIT,		1255}, /* close to iso-8859-8 */
206 #define IDX_ISO_8	8
207     {"iso-8859-8",	ENC_8BIT,		0},
208 #define IDX_ISO_9	9
209     {"iso-8859-9",	ENC_8BIT,		0},
210 #define IDX_ISO_10	10
211     {"iso-8859-10",	ENC_8BIT,		0},
212 #define IDX_ISO_11	11
213     {"iso-8859-11",	ENC_8BIT,		0},
214 #define IDX_ISO_13	12
215     {"iso-8859-13",	ENC_8BIT,		0},
216 #define IDX_ISO_14	13
217     {"iso-8859-14",	ENC_8BIT,		0},
218 #define IDX_ISO_15	14
219     {"iso-8859-15",	ENC_8BIT,		0},
220 #define IDX_KOI8_R	15
221     {"koi8-r",		ENC_8BIT,		0},
222 #define IDX_KOI8_U	16
223     {"koi8-u",		ENC_8BIT,		0},
224 #define IDX_UTF8	17
225     {"utf-8",		ENC_UNICODE,		0},
226 #define IDX_UCS2	18
227     {"ucs-2",		ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0},
228 #define IDX_UCS2LE	19
229     {"ucs-2le",		ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0},
230 #define IDX_UTF16	20
231     {"utf-16",		ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0},
232 #define IDX_UTF16LE	21
233     {"utf-16le",	ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0},
234 #define IDX_UCS4	22
235     {"ucs-4",		ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0},
236 #define IDX_UCS4LE	23
237     {"ucs-4le",		ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0},
238 #define IDX_DEBUG	24
239     {"debug",		ENC_DBCS,		DBCS_DEBUG},
240 #define IDX_CP932	25
241     {"cp932",		ENC_DBCS,		DBCS_JPN},
242 #define IDX_CP949	26
243     {"cp949",		ENC_DBCS,		DBCS_KOR},
244 #define IDX_CP936	27
245     {"cp936",		ENC_DBCS,		DBCS_CHS},
246 #define IDX_CP950	28
247     {"cp950",		ENC_DBCS,		DBCS_CHT},
248 #define IDX_EUC_JP	29
249     {"euc-jp",		ENC_DBCS,		DBCS_JPNU},
250 #define IDX_SJIS	30
251     {"sjis",		ENC_DBCS,		DBCS_JPN},
252 #define IDX_EUC_KR	31
253     {"euc-kr",		ENC_DBCS,		DBCS_KORU},
254 #define IDX_EUC_CN	32
255     {"euc-cn",		ENC_DBCS,		DBCS_CHSU},
256 #define IDX_EUC_TW	33
257     {"euc-tw",		ENC_DBCS,		DBCS_CHTU},
258 #define IDX_BIG5	34
259     {"big5",		ENC_DBCS,		DBCS_CHT},
260 #define IDX_CP1251	35
261     {"cp1251",		ENC_8BIT,		1251},
262 #define IDX_MACROMAN	36
263     {"macroman",	ENC_8BIT + ENC_MACROMAN, 0},
264 #define IDX_COUNT	37
265 };
266 
267 /*
268  * Aliases for encoding names.
269  */
270 static struct
271 {   char *name;		int canon;}
272 enc_alias_table[] =
273 {
274     {"ansi",		IDX_LATIN_1},
275     {"iso-8859-1",	IDX_LATIN_1},
276     {"latin2",		IDX_ISO_2},
277     {"latin3",		IDX_ISO_3},
278     {"latin4",		IDX_ISO_4},
279     {"cyrillic",	IDX_ISO_5},
280     {"arabic",		IDX_ISO_6},
281     {"greek",		IDX_ISO_7},
282 #ifdef WIN3264
283     {"hebrew",		IDX_CP1255},
284 #else
285     {"hebrew",		IDX_ISO_8},
286 #endif
287     {"latin5",		IDX_ISO_9},
288     {"turkish",		IDX_ISO_9}, /* ? */
289     {"latin6",		IDX_ISO_10},
290     {"nordic",		IDX_ISO_10}, /* ? */
291     {"thai",		IDX_ISO_11}, /* ? */
292     {"latin7",		IDX_ISO_13},
293     {"latin8",		IDX_ISO_14},
294     {"latin9",		IDX_ISO_15},
295     {"utf8",		IDX_UTF8},
296     {"unicode",		IDX_UCS2},
297     {"ucs2",		IDX_UCS2},
298     {"ucs2be",		IDX_UCS2},
299     {"ucs-2be",		IDX_UCS2},
300     {"ucs2le",		IDX_UCS2LE},
301     {"utf16",		IDX_UTF16},
302     {"utf16be",		IDX_UTF16},
303     {"utf-16be",	IDX_UTF16},
304     {"utf16le",		IDX_UTF16LE},
305     {"ucs4",		IDX_UCS4},
306     {"ucs4be",		IDX_UCS4},
307     {"ucs-4be",		IDX_UCS4},
308     {"ucs4le",		IDX_UCS4LE},
309     {"932",		IDX_CP932},
310     {"949",		IDX_CP949},
311     {"936",		IDX_CP936},
312     {"950",		IDX_CP950},
313     {"eucjp",		IDX_EUC_JP},
314     {"unix-jis",	IDX_EUC_JP},
315     {"ujis",		IDX_EUC_JP},
316     {"shift-jis",	IDX_SJIS},
317     {"euckr",		IDX_EUC_KR},
318     {"5601",		IDX_EUC_KR},	/* Sun: KS C 5601 */
319     {"euccn",		IDX_EUC_CN},
320     {"gb2312",		IDX_EUC_CN},
321     {"euctw",		IDX_EUC_TW},
322 #if defined(WIN3264) || defined(WIN32UNIX) || defined(MACOS)
323     {"japan",		IDX_CP932},
324     {"korea",		IDX_CP949},
325     {"prc",		IDX_CP936},
326     {"chinese",		IDX_CP936},
327     {"taiwan",		IDX_CP950},
328     {"big5",		IDX_CP950},
329 #else
330     {"japan",		IDX_EUC_JP},
331     {"korea",		IDX_EUC_KR},
332     {"prc",		IDX_EUC_CN},
333     {"chinese",		IDX_EUC_CN},
334     {"taiwan",		IDX_EUC_TW},
335     {"cp950",		IDX_BIG5},
336     {"950",		IDX_BIG5},
337 #endif
338     {"mac",		IDX_MACROMAN},
339     {NULL,		0}
340 };
341 
342 #ifndef CP_UTF8
343 # define CP_UTF8 65001	/* magic number from winnls.h */
344 #endif
345 
346 /*
347  * Find encoding "name" in the list of canonical encoding names.
348  * Returns -1 if not found.
349  */
350     static int
351 enc_canon_search(name)
352     char_u	*name;
353 {
354     int		i;
355 
356     for (i = 0; i < IDX_COUNT; ++i)
357 	if (STRCMP(name, enc_canon_table[i].name) == 0)
358 	    return i;
359     return -1;
360 }
361 
362 #endif
363 
364 #if defined(FEAT_MBYTE) || defined(PROTO)
365 
366 /*
367  * Find canonical encoding "name" in the list and return its properties.
368  * Returns 0 if not found.
369  */
370     int
371 enc_canon_props(name)
372     char_u	*name;
373 {
374     int		i;
375 
376     i = enc_canon_search(name);
377     if (i >= 0)
378 	return enc_canon_table[i].prop;
379 #ifdef WIN3264
380     if (name[0] == 'c' && name[1] == 'p' && VIM_ISDIGIT(name[2]))
381     {
382 	CPINFO	cpinfo;
383 
384 	/* Get info on this codepage to find out what it is. */
385 	if (GetCPInfo(atoi(name + 2), &cpinfo) != 0)
386 	{
387 	    if (cpinfo.MaxCharSize == 1) /* some single-byte encoding */
388 		return ENC_8BIT;
389 	    if (cpinfo.MaxCharSize == 2
390 		    && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0))
391 		/* must be a DBCS encoding */
392 		return ENC_DBCS;
393 	}
394 	return 0;
395     }
396 #endif
397     if (STRNCMP(name, "2byte-", 6) == 0)
398 	return ENC_DBCS;
399     if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0)
400 	return ENC_8BIT;
401     return 0;
402 }
403 
404 /*
405  * Set up for using multi-byte characters.
406  * Called in three cases:
407  * - by main() to initialize (p_enc == NULL)
408  * - by set_init_1() after 'encoding' was set to its default.
409  * - by do_set() when 'encoding' has been set.
410  * p_enc must have been passed through enc_canonize() already.
411  * Sets the "enc_unicode", "enc_utf8", "enc_dbcs" and "has_mbyte" flags.
412  * Fills mb_bytelen_tab[] and returns NULL when there are no problems.
413  * When there is something wrong: Returns an error message and doesn't change
414  * anything.
415  */
416     char_u *
417 mb_init()
418 {
419     int		i;
420     int		idx;
421     int		n;
422     int		enc_dbcs_new = 0;
423 #if defined(USE_ICONV) && !defined(WIN3264) && !defined(WIN32UNIX) \
424 	&& !defined(MACOS)
425 # define LEN_FROM_CONV
426     vimconv_T	vimconv;
427     char_u	*p;
428 #endif
429 
430     if (p_enc == NULL)
431     {
432 	/* Just starting up: set the whole table to one's. */
433 	for (i = 0; i < 256; ++i)
434 	    mb_bytelen_tab[i] = 1;
435 	input_conv.vc_type = CONV_NONE;
436 	input_conv.vc_factor = 1;
437 	output_conv.vc_type = CONV_NONE;
438 	return NULL;
439     }
440 
441 #ifdef WIN3264
442     if (p_enc[0] == 'c' && p_enc[1] == 'p' && VIM_ISDIGIT(p_enc[2]))
443     {
444 	CPINFO	cpinfo;
445 
446 	/* Get info on this codepage to find out what it is. */
447 	if (GetCPInfo(atoi(p_enc + 2), &cpinfo) != 0)
448 	{
449 	    if (cpinfo.MaxCharSize == 1)
450 	    {
451 		/* some single-byte encoding */
452 		enc_unicode = 0;
453 		enc_utf8 = FALSE;
454 	    }
455 	    else if (cpinfo.MaxCharSize == 2
456 		    && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0))
457 	    {
458 		/* must be a DBCS encoding, check below */
459 		enc_dbcs_new = atoi(p_enc + 2);
460 	    }
461 	    else
462 		goto codepage_invalid;
463 	}
464 	else if (GetLastError() == ERROR_INVALID_PARAMETER)
465 	{
466 codepage_invalid:
467 	    return (char_u *)N_("E543: Not a valid codepage");
468 	}
469     }
470 #endif
471     else if (STRNCMP(p_enc, "8bit-", 5) == 0
472 	    || STRNCMP(p_enc, "iso-8859-", 9) == 0)
473     {
474 	/* Accept any "8bit-" or "iso-8859-" name. */
475 	enc_unicode = 0;
476 	enc_utf8 = FALSE;
477     }
478     else if (STRNCMP(p_enc, "2byte-", 6) == 0)
479     {
480 #ifdef WIN3264
481 	/* Windows: accept only valid codepage numbers, check below. */
482 	if (p_enc[6] != 'c' || p_enc[7] != 'p'
483 				      || (enc_dbcs_new = atoi(p_enc + 8)) == 0)
484 	    return e_invarg;
485 #else
486 	/* Unix: accept any "2byte-" name, assume current locale. */
487 	enc_dbcs_new = DBCS_2BYTE;
488 #endif
489     }
490     else if ((idx = enc_canon_search(p_enc)) >= 0)
491     {
492 	i = enc_canon_table[idx].prop;
493 	if (i & ENC_UNICODE)
494 	{
495 	    /* Unicode */
496 	    enc_utf8 = TRUE;
497 	    if (i & (ENC_2BYTE | ENC_2WORD))
498 		enc_unicode = 2;
499 	    else if (i & ENC_4BYTE)
500 		enc_unicode = 4;
501 	    else
502 		enc_unicode = 0;
503 	}
504 	else if (i & ENC_DBCS)
505 	{
506 	    /* 2byte, handle below */
507 	    enc_dbcs_new = enc_canon_table[idx].codepage;
508 	}
509 	else
510 	{
511 	    /* Must be 8-bit. */
512 	    enc_unicode = 0;
513 	    enc_utf8 = FALSE;
514 	}
515     }
516     else    /* Don't know what encoding this is, reject it. */
517 	return e_invarg;
518 
519     if (enc_dbcs_new != 0)
520     {
521 #ifdef WIN3264
522 	/* Check if the DBCS code page is OK. */
523 	if (!IsValidCodePage(enc_dbcs_new))
524 	    goto codepage_invalid;
525 #endif
526 	enc_unicode = 0;
527 	enc_utf8 = FALSE;
528     }
529     enc_dbcs = enc_dbcs_new;
530     has_mbyte = (enc_dbcs != 0 || enc_utf8);
531 
532 #ifdef WIN3264
533     enc_codepage = encname2codepage(p_enc);
534 #endif
535 
536     /*
537      * Set the function pointers.
538      */
539     if (enc_utf8)
540     {
541 	mb_ptr2len_check = utfc_ptr2len_check;
542 	mb_char2len = utf_char2len;
543 	mb_char2bytes = utf_char2bytes;
544 	mb_ptr2cells = utf_ptr2cells;
545 	mb_char2cells = utf_char2cells;
546 	mb_off2cells = utf_off2cells;
547 	mb_ptr2char = utf_ptr2char;
548 	mb_head_off = utf_head_off;
549     }
550     else if (enc_dbcs != 0)
551     {
552 	mb_ptr2len_check = dbcs_ptr2len_check;
553 	mb_char2len = dbcs_char2len;
554 	mb_char2bytes = dbcs_char2bytes;
555 	mb_ptr2cells = dbcs_ptr2cells;
556 	mb_char2cells = dbcs_char2cells;
557 	mb_off2cells = dbcs_off2cells;
558 	mb_ptr2char = dbcs_ptr2char;
559 	mb_head_off = dbcs_head_off;
560     }
561     else
562     {
563 	mb_ptr2len_check = latin_ptr2len_check;
564 	mb_char2len = latin_char2len;
565 	mb_char2bytes = latin_char2bytes;
566 	mb_ptr2cells = latin_ptr2cells;
567 	mb_char2cells = latin_char2cells;
568 	mb_off2cells = latin_off2cells;
569 	mb_ptr2char = latin_ptr2char;
570 	mb_head_off = latin_head_off;
571     }
572 
573     /*
574      * Fill the mb_bytelen_tab[] for MB_BYTE2LEN().
575      */
576 #ifdef LEN_FROM_CONV
577     /* When 'encoding' is different from the current locale mblen() won't
578      * work.  Use conversion to "utf-8" instead. */
579     vimconv.vc_type = CONV_NONE;
580     if (enc_dbcs)
581     {
582 	p = enc_locale();
583 	if (p == NULL || STRCMP(p, p_enc) != 0)
584 	{
585 	    convert_setup(&vimconv, p_enc, (char_u *)"utf-8");
586 	    vimconv.vc_fail = TRUE;
587 	}
588 	vim_free(p);
589     }
590 #endif
591 
592     for (i = 0; i < 256; ++i)
593     {
594 	/* Our own function to reliably check the length of UTF-8 characters,
595 	 * independent of mblen(). */
596 	if (enc_utf8)
597 	    n = utf8len_tab[i];
598 	else if (enc_dbcs == 0)
599 	    n = 1;
600 	else
601 	{
602 #if defined(WIN3264) || defined(WIN32UNIX)
603 	    /* enc_dbcs is set by setting 'fileencoding'.  It becomes a Windows
604 	     * CodePage identifier, which we can pass directly in to Windows
605 	     * API */
606 	    n = IsDBCSLeadByteEx(enc_dbcs, (BYTE)i) ? 2 : 1;
607 #else
608 # ifdef MACOS
609 	    /*
610 	     * if mblen() is not available, character which MSB is turned on
611 	     * are treated as leading byte character. (note : This assumption
612 	     * is not always true.)
613 	     */
614 	    n = (i & 0x80) ? 2 : 1;
615 # else
616 	    char buf[MB_MAXBYTES];
617 # ifdef X_LOCALE
618 #  ifndef mblen
619 #   define mblen _Xmblen
620 #  endif
621 # endif
622 	    if (i == NUL)	/* just in case mblen() can't handle "" */
623 		n = 1;
624 	    else
625 	    {
626 		buf[0] = i;
627 		buf[1] = 0;
628 #ifdef LEN_FROM_CONV
629 		if (vimconv.vc_type != CONV_NONE)
630 		{
631 		    /*
632 		     * string_convert() should fail when converting the first
633 		     * byte of a double-byte character.
634 		     */
635 		    p = string_convert(&vimconv, (char_u *)buf, NULL);
636 		    if (p != NULL)
637 		    {
638 			vim_free(p);
639 			n = 1;
640 		    }
641 		    else
642 			n = 2;
643 		}
644 		else
645 #endif
646 		{
647 		    /*
648 		     * mblen() should return -1 for invalid (means the leading
649 		     * multibyte) character.  However there are some platforms
650 		     * where mblen() returns 0 for invalid character.
651 		     * Therefore, following condition includes 0.
652 		     */
653 		    if (mblen(buf, (size_t)1) <= 0)
654 			n = 2;
655 		    else
656 			n = 1;
657 		}
658 	    }
659 # endif
660 #endif
661 	}
662 
663 	mb_bytelen_tab[i] = n;
664     }
665 
666 #ifdef LEN_FROM_CONV
667     convert_setup(&vimconv, NULL, NULL);
668 #endif
669 
670     /* The cell width depends on the type of multi-byte characters. */
671     (void)init_chartab();
672 
673     /* When enc_utf8 is set or reset, (de)allocate ScreenLinesUC[] */
674     screenalloc(FALSE);
675 
676     /* When using Unicode, set default for 'fileencodings'. */
677     if (enc_utf8 && !option_was_set((char_u *)"fencs"))
678 	set_string_option_direct((char_u *)"fencs", -1,
679 				 (char_u *)"ucs-bom,utf-8,latin1", OPT_FREE);
680 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET) && defined(FEAT_GETTEXT)
681     /* GNU gettext 0.10.37 supports this feature: set the codeset used for
682      * translated messages independently from the current locale. */
683     (void)bind_textdomain_codeset(VIMPACKAGE,
684 					  enc_utf8 ? "utf-8" : (char *)p_enc);
685 #endif
686 
687 #ifdef FEAT_AUTOCMD
688     /* Fire an autocommand to let people do custom font setup. This must be
689      * after Vim has been setup for the new encoding. */
690     apply_autocmds(EVENT_ENCODINGCHANGED, NULL, (char_u *)"", FALSE, curbuf);
691 #endif
692 
693 #ifdef FEAT_GUI_KDE
694     if (gui.in_use)
695 	gui_mch_update_codec();
696 #endif
697 
698     return NULL;
699 }
700 
701 /*
702  * Return the size of the BOM for the current buffer:
703  * 0 - no BOM
704  * 2 - UCS-2 or UTF-16 BOM
705  * 4 - UCS-4 BOM
706  * 3 - UTF-8 BOM
707  */
708     int
709 bomb_size()
710 {
711     int n = 0;
712 
713     if (curbuf->b_p_bomb && !curbuf->b_p_bin)
714     {
715 	if (*curbuf->b_p_fenc == NUL)
716 	{
717 	    if (enc_utf8)
718 	    {
719 		if (enc_unicode != 0)
720 		    n = enc_unicode;
721 		else
722 		    n = 3;
723 	    }
724 	}
725 	else if (STRCMP(curbuf->b_p_fenc, "utf-8") == 0)
726 	    n = 3;
727 	else if (STRNCMP(curbuf->b_p_fenc, "ucs-2", 5) == 0
728 		|| STRNCMP(curbuf->b_p_fenc, "utf-16", 6) == 0)
729 	    n = 2;
730 	else if (STRNCMP(curbuf->b_p_fenc, "ucs-4", 5) == 0)
731 	    n = 4;
732     }
733     return n;
734 }
735 
736 /*
737  * Get class of pointer:
738  * 0 for blank or NUL
739  * 1 for punctuation
740  * 2 for an (ASCII) word character
741  * >2 for other word characters
742  */
743     int
744 mb_get_class(p)
745     char_u	*p;
746 {
747     if (MB_BYTE2LEN(p[0]) == 1)
748     {
749 	if (p[0] == NUL || vim_iswhite(p[0]))
750 	    return 0;
751 	if (vim_iswordc(p[0]))
752 	    return 2;
753 	return 1;
754     }
755     if (enc_dbcs != 0 && p[0] != NUL && p[1] != NUL)
756 	return dbcs_class(p[0], p[1]);
757     if (enc_utf8)
758 	return utf_class(utf_ptr2char(p));
759     return 0;
760 }
761 
762 /*
763  * Get class of a double-byte character.  This always returns 3 or bigger.
764  * TODO: Should return 1 for punctuation.
765  */
766     int
767 dbcs_class(lead, trail)
768     unsigned	lead;
769     unsigned	trail;
770 {
771     switch (enc_dbcs)
772     {
773 	/* please add classfy routine for your language in here */
774 
775 	case DBCS_JPNU:	/* ? */
776 	case DBCS_JPN:
777 	    {
778 		/* JIS code classification */
779 		unsigned char lb = lead;
780 		unsigned char tb = trail;
781 
782 		/* convert process code to JIS */
783 # if defined(WIN3264) || defined(WIN32UNIX) || defined(MACOS)
784 		/* process code is SJIS */
785 		if (lb <= 0x9f)
786 		    lb = (lb - 0x81) * 2 + 0x21;
787 		else
788 		    lb = (lb - 0xc1) * 2 + 0x21;
789 		if (tb <= 0x7e)
790 		    tb -= 0x1f;
791 		else if (tb <= 0x9e)
792 		    tb -= 0x20;
793 		else
794 		{
795 		    tb -= 0x7e;
796 		    lb += 1;
797 		}
798 # else
799 		/*
800 		 * XXX: Code page identification can not use with all
801 		 *	    system! So, some other encoding information
802 		 *	    will be needed.
803 		 *	    In japanese: SJIS,EUC,UNICODE,(JIS)
804 		 *	    Note that JIS-code system don't use as
805 		 *	    process code in most system because it uses
806 		 *	    escape sequences(JIS is context depend encoding).
807 		 */
808 		/* assume process code is JAPANESE-EUC */
809 		lb &= 0x7f;
810 		tb &= 0x7f;
811 # endif
812 		/* exceptions */
813 		switch (lb << 8 | tb)
814 		{
815 		    case 0x2121: /* ZENKAKU space */
816 			return 0;
817 		    case 0x2122: /* KU-TEN (Japanese comma) */
818 		    case 0x2123: /* TOU-TEN (Japanese period) */
819 		    case 0x2124: /* ZENKAKU comma */
820 		    case 0x2125: /* ZENKAKU period */
821 			return 1;
822 		    case 0x213c: /* prolongedsound handled as KATAKANA */
823 			return 13;
824 		}
825 		/* sieved by KU code */
826 		switch (lb)
827 		{
828 		    case 0x21:
829 		    case 0x22:
830 			/* special symbols */
831 			return 10;
832 		    case 0x23:
833 			/* alpha-numeric */
834 			return 11;
835 		    case 0x24:
836 			/* hiragana */
837 			return 12;
838 		    case 0x25:
839 			/* katakana */
840 			return 13;
841 		    case 0x26:
842 			/* greek */
843 			return 14;
844 		    case 0x27:
845 			/* russian */
846 			return 15;
847 		    case 0x28:
848 			/* lines */
849 			return 16;
850 		    default:
851 			/* kanji */
852 			return 17;
853 		}
854 	    }
855 
856 	case DBCS_KORU:	/* ? */
857 	case DBCS_KOR:
858 	    {
859 		/* KS code classification */
860 		unsigned char c1 = lead;
861 		unsigned char c2 = trail;
862 
863 		/*
864 		 * 20 : Hangul
865 		 * 21 : Hanja
866 		 * 22 : Symbols
867 		 * 23 : Alpha-numeric/Roman Letter (Full width)
868 		 * 24 : Hangul Letter(Alphabet)
869 		 * 25 : Roman Numeral/Greek Letter
870 		 * 26 : Box Drawings
871 		 * 27 : Unit Symbols
872 		 * 28 : Circled/Parenthesized Letter
873 		 * 29 : Hirigana/Katakana
874 		 * 30 : Cyrillic Letter
875 		 */
876 
877 		if (c1 >= 0xB0 && c1 <= 0xC8)
878 		    /* Hangul */
879 		    return 20;
880 #if defined(WIN3264) || defined(WIN32UNIX)
881 		else if (c1 <= 0xA0 || c2 <= 0xA0)
882 		    /* Extended Hangul Region : MS UHC(Unified Hangul Code) */
883 		    /* c1: 0x81-0xA0 with c2: 0x41-0x5A, 0x61-0x7A, 0x81-0xFE
884 		     * c1: 0xA1-0xC6 with c2: 0x41-0x5A, 0x61-0x7A, 0x81-0xA0
885 		     */
886 		    return 20;
887 #endif
888 
889 		else if (c1 >= 0xCA && c1 <= 0xFD)
890 		    /* Hanja */
891 		    return 21;
892 		else switch (c1)
893 		{
894 		    case 0xA1:
895 		    case 0xA2:
896 			/* Symbols */
897 			return 22;
898 		    case 0xA3:
899 			/* Alpha-numeric */
900 			return 23;
901 		    case 0xA4:
902 			/* Hangul Letter(Alphabet) */
903 			return 24;
904 		    case 0xA5:
905 			/* Roman Numeral/Greek Letter */
906 			return 25;
907 		    case 0xA6:
908 			/* Box Drawings */
909 			return 26;
910 		    case 0xA7:
911 			/* Unit Symbols */
912 			return 27;
913 		    case 0xA8:
914 		    case 0xA9:
915 			if (c2 <= 0xAF)
916 			    return 25;  /* Roman Letter */
917 			else if (c2 >= 0xF6)
918 			    return 22;  /* Symbols */
919 			else
920 			    /* Circled/Parenthesized Letter */
921 			    return 28;
922 		    case 0xAA:
923 		    case 0xAB:
924 			/* Hirigana/Katakana */
925 			return 29;
926 		    case 0xAC:
927 			/* Cyrillic Letter */
928 			return 30;
929 		}
930 	    }
931 	default:
932 	    break;
933     }
934     return 3;
935 }
936 
937 /*
938  * mb_char2len() function pointer.
939  * Return length in bytes of character "c".
940  * Returns 1 for a single-byte character.
941  */
942 /* ARGSUSED */
943     int
944 latin_char2len(c)
945     int		c;
946 {
947     return 1;
948 }
949 
950     static int
951 dbcs_char2len(c)
952     int		c;
953 {
954     if (c >= 0x100)
955 	return 2;
956     return 1;
957 }
958 
959 /*
960  * mb_char2bytes() function pointer.
961  * Convert a character to its bytes.
962  * Returns the length in bytes.
963  */
964     int
965 latin_char2bytes(c, buf)
966     int		c;
967     char_u	*buf;
968 {
969     buf[0] = c;
970     return 1;
971 }
972 
973     static int
974 dbcs_char2bytes(c, buf)
975     int		c;
976     char_u	*buf;
977 {
978     if (c >= 0x100)
979     {
980 	buf[0] = (unsigned)c >> 8;
981 	buf[1] = c;
982 	return 2;
983     }
984     buf[0] = c;
985     return 1;
986 }
987 
988 /*
989  * mb_ptr2len_check() function pointer.
990  * Get byte length of character at "*p" but stop at a NUL.
991  * For UTF-8 this includes following composing characters.
992  * Returns 0 when *p is NUL.
993  *
994  */
995     int
996 latin_ptr2len_check(p)
997     char_u	*p;
998 {
999     return MB_BYTE2LEN(*p);
1000 }
1001 
1002     static int
1003 dbcs_ptr2len_check(p)
1004     char_u	*p;
1005 {
1006     int		len;
1007 
1008     /* Check if second byte is not missing. */
1009     len = MB_BYTE2LEN(*p);
1010     if (len == 2 && p[1] == NUL)
1011 	len = 1;
1012     return len;
1013 }
1014 
1015 struct interval
1016 {
1017     unsigned short first;
1018     unsigned short last;
1019 };
1020 static int intable __ARGS((struct interval *table, size_t size, int c));
1021 
1022 /*
1023  * Return TRUE if "c" is in "table[size / sizeof(struct interval)]".
1024  */
1025     static int
1026 intable(table, size, c)
1027     struct interval	*table;
1028     size_t		size;
1029     int			c;
1030 {
1031     int mid, bot, top;
1032 
1033     /* first quick check for Latin1 etc. characters */
1034     if (c < table[0].first)
1035 	return FALSE;
1036 
1037     /* binary search in table */
1038     bot = 0;
1039     top = size / sizeof(struct interval) - 1;
1040     while (top >= bot)
1041     {
1042 	mid = (bot + top) / 2;
1043 	if (table[mid].last < c)
1044 	    bot = mid + 1;
1045 	else if (table[mid].first > c)
1046 	    top = mid - 1;
1047 	else
1048 	    return TRUE;
1049     }
1050     return FALSE;
1051 }
1052 
1053 /*
1054  * For UTF-8 character "c" return 2 for a double-width character, 1 for others.
1055  * Returns 4 or 6 for an unprintable character.
1056  * Is only correct for characters >= 0x80.
1057  * When p_ambw is "double", return 2 for a character with East Asian Width
1058  * class 'A'(mbiguous).
1059  */
1060     int
1061 utf_char2cells(c)
1062     int		c;
1063 {
1064     /* sorted list of non-overlapping intervals of East Asian Ambiguous
1065      * characters, generated with:
1066      * "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
1067     static struct interval ambiguous[] = {
1068 	{0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
1069 	{0x00AA, 0x00AA}, {0x00AE, 0x00AE}, {0x00B0, 0x00B4},
1070 	{0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
1071 	{0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
1072 	{0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
1073 	{0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
1074 	{0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
1075 	{0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
1076 	{0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
1077 	{0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
1078 	{0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
1079 	{0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
1080 	{0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
1081 	{0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
1082 	{0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
1083 	{0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
1084 	{0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
1085 	{0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1},
1086 	{0x03A3, 0x03A9}, {0x03B1, 0x03C1}, {0x03C3, 0x03C9},
1087 	{0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451},
1088 	{0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019},
1089 	{0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027},
1090 	{0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035},
1091 	{0x203B, 0x203B}, {0x203E, 0x203E}, {0x2074, 0x2074},
1092 	{0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC},
1093 	{0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109},
1094 	{0x2113, 0x2113}, {0x2116, 0x2116}, {0x2121, 0x2122},
1095 	{0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154},
1096 	{0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179},
1097 	{0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2},
1098 	{0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200},
1099 	{0x2202, 0x2203}, {0x2207, 0x2208}, {0x220B, 0x220B},
1100 	{0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215},
1101 	{0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223},
1102 	{0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E},
1103 	{0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248},
1104 	{0x224C, 0x224C}, {0x2252, 0x2252}, {0x2260, 0x2261},
1105 	{0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F},
1106 	{0x2282, 0x2283}, {0x2286, 0x2287}, {0x2295, 0x2295},
1107 	{0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF},
1108 	{0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B},
1109 	{0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595},
1110 	{0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3},
1111 	{0x25B6, 0x25B7}, {0x25BC, 0x25BD}, {0x25C0, 0x25C1},
1112 	{0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1},
1113 	{0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606},
1114 	{0x2609, 0x2609}, {0x260E, 0x260F}, {0x2614, 0x2615},
1115 	{0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640},
1116 	{0x2642, 0x2642}, {0x2660, 0x2661}, {0x2663, 0x2665},
1117 	{0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F},
1118 	{0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF},
1119 	{0xFFFD, 0xFFFD}, /* {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD} */
1120     };
1121 
1122     if (c >= 0x100)
1123     {
1124 #ifdef USE_WCHAR_FUNCTIONS
1125 	/*
1126 	 * Assume the library function wcwidth() works better than our own
1127 	 * stuff.  It should return 1 for ambiguous width chars!
1128 	 */
1129 	int	n = wcwidth(c);
1130 
1131 	if (n < 0)
1132 	    return 6;		/* unprintable, displays <xxxx> */
1133 	if (n > 1)
1134 	    return n;
1135 #else
1136 	if (!utf_printable(c))
1137 	    return 6;		/* unprintable, displays <xxxx> */
1138 	if (c >= 0x1100
1139 	    && (c <= 0x115f			/* Hangul Jamo */
1140 		|| c == 0x2329
1141 		|| c == 0x232a
1142 		|| (c >= 0x2e80 && c <= 0xa4cf
1143 		    && c != 0x303f)		/* CJK ... Yi */
1144 		|| (c >= 0xac00 && c <= 0xd7a3)	/* Hangul Syllables */
1145 		|| (c >= 0xf900 && c <= 0xfaff)	/* CJK Compatibility
1146 						   Ideographs */
1147 		|| (c >= 0xfe30 && c <= 0xfe6f)	/* CJK Compatibility Forms */
1148 		|| (c >= 0xff00 && c <= 0xff60)	/* Fullwidth Forms */
1149 		|| (c >= 0xffe0 && c <= 0xffe6)
1150 		|| (c >= 0x20000 && c <= 0x2fffd)
1151 		|| (c >= 0x30000 && c <= 0x3fffd)))
1152 	    return 2;
1153 #endif
1154     }
1155 
1156     /* Characters below 0x100 are influenced by 'isprint' option */
1157     else if (c >= 0x80 && !vim_isprintc(c))
1158 	return 4;		/* unprintable, displays <xx> */
1159 
1160     if (c >= 0x80 && *p_ambw == 'd' && intable(ambiguous, sizeof(ambiguous), c))
1161 	return 2;
1162 
1163     return 1;
1164 }
1165 
1166 /*
1167  * mb_ptr2cells() function pointer.
1168  * Return the number of display cells character at "*p" occupies.
1169  * This doesn't take care of unprintable characters, use ptr2cells() for that.
1170  */
1171 /*ARGSUSED*/
1172     int
1173 latin_ptr2cells(p)
1174     char_u	*p;
1175 {
1176     return 1;
1177 }
1178 
1179     int
1180 utf_ptr2cells(p)
1181     char_u	*p;
1182 {
1183     int		c;
1184 
1185     /* Need to convert to a wide character. */
1186     if (*p >= 0x80)
1187     {
1188 	c = utf_ptr2char(p);
1189 	/* An illegal byte is displayed as <xx>. */
1190 	if (utf_ptr2len_check(p) == 1 || c == NUL)
1191 	    return 4;
1192 	/* If the char is ASCII it must be an overlong sequence. */
1193 	if (c < 0x80)
1194 	    return char2cells(c);
1195 	return utf_char2cells(c);
1196     }
1197     return 1;
1198 }
1199 
1200     int
1201 dbcs_ptr2cells(p)
1202     char_u	*p;
1203 {
1204     /* Number of cells is equal to number of bytes, except for euc-jp when
1205      * the first byte is 0x8e. */
1206     if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
1207 	return 1;
1208     return MB_BYTE2LEN(*p);
1209 }
1210 
1211 /*
1212  * mb_char2cells() function pointer.
1213  * Return the number of display cells character "c" occupies.
1214  * Only takes care of multi-byte chars, not "^C" and such.
1215  */
1216 /*ARGSUSED*/
1217     int
1218 latin_char2cells(c)
1219     int		c;
1220 {
1221     return 1;
1222 }
1223 
1224     static int
1225 dbcs_char2cells(c)
1226     int		c;
1227 {
1228     /* Number of cells is equal to number of bytes, except for euc-jp when
1229      * the first byte is 0x8e. */
1230     if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
1231 	return 1;
1232     /* use the first byte */
1233     return MB_BYTE2LEN((unsigned)c >> 8);
1234 }
1235 
1236 /*
1237  * mb_off2cells() function pointer.
1238  * Return number of display cells for char at ScreenLines[off].
1239  * Caller must make sure "off" and "off + 1" are valid!
1240  */
1241 /*ARGSUSED*/
1242     int
1243 latin_off2cells(off)
1244     unsigned	off;
1245 {
1246     return 1;
1247 }
1248 
1249     int
1250 dbcs_off2cells(off)
1251     unsigned	off;
1252 {
1253     /* Number of cells is equal to number of bytes, except for euc-jp when
1254      * the first byte is 0x8e. */
1255     if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
1256 	return 1;
1257     return MB_BYTE2LEN(ScreenLines[off]);
1258 }
1259 
1260     int
1261 utf_off2cells(off)
1262     unsigned	off;
1263 {
1264     return ScreenLines[off + 1] == 0 ? 2 : 1;
1265 }
1266 
1267 /*
1268  * mb_ptr2char() function pointer.
1269  * Convert a byte sequence into a character.
1270  */
1271     int
1272 latin_ptr2char(p)
1273     char_u	*p;
1274 {
1275     return *p;
1276 }
1277 
1278     static int
1279 dbcs_ptr2char(p)
1280     char_u	*p;
1281 {
1282     if (MB_BYTE2LEN(*p) > 1 && p[1] != NUL)
1283 	return (p[0] << 8) + p[1];
1284     return *p;
1285 }
1286 
1287 /*
1288  * Convert a UTF-8 byte sequence to a wide character.
1289  * If the sequence is illegal or truncated by a NUL the first byte is
1290  * returned.
1291  * Does not include composing characters, of course.
1292  */
1293     int
1294 utf_ptr2char(p)
1295     char_u	*p;
1296 {
1297     int		len;
1298 
1299     if (p[0] < 0x80)	/* be quick for ASCII */
1300 	return p[0];
1301 
1302     len = utf8len_tab[p[0]];
1303     if ((p[1] & 0xc0) == 0x80)
1304     {
1305 	if (len == 2)
1306 	    return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f);
1307 	if ((p[2] & 0xc0) == 0x80)
1308 	{
1309 	    if (len == 3)
1310 		return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
1311 		    + (p[2] & 0x3f);
1312 	    if ((p[3] & 0xc0) == 0x80)
1313 	    {
1314 		if (len == 4)
1315 		    return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
1316 			+ ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
1317 		if ((p[4] & 0xc0) == 0x80)
1318 		{
1319 		    if (len == 5)
1320 			return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18)
1321 			    + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
1322 			    + (p[4] & 0x3f);
1323 		    if ((p[5] & 0xc0) == 0x80 && len == 6)
1324 			return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24)
1325 			    + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
1326 			    + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f);
1327 		}
1328 	    }
1329 	}
1330     }
1331     /* Illegal value, just return the first byte */
1332     return p[0];
1333 }
1334 
1335 /*
1336  * Get character at **pp and advance *pp to the next character.
1337  * Note: composing characters are skipped!
1338  */
1339     int
1340 mb_ptr2char_adv(pp)
1341     char_u	**pp;
1342 {
1343     int		c;
1344 
1345     c = (*mb_ptr2char)(*pp);
1346     *pp += (*mb_ptr2len_check)(*pp);
1347     return c;
1348 }
1349 
1350 #if defined(FEAT_ARABIC) || defined(PROTO)
1351 /*
1352  * Check whether we are dealing with Arabic combining characters.
1353  * Note: these are NOT really composing characters!
1354  */
1355     int
1356 arabic_combine(one, two)
1357     int		one;	    /* first character */
1358     int		two;	    /* character just after "one" */
1359 {
1360     if (one == a_LAM)
1361 	return arabic_maycombine(two);
1362     return FALSE;
1363 }
1364 
1365 /*
1366  * Check whether we are dealing with a character that could be regarded as an
1367  * Arabic combining character, need to check the character before this.
1368  */
1369     int
1370 arabic_maycombine(two)
1371     int		two;
1372 {
1373     if (p_arshape && !p_tbidi)
1374 	return (two == a_ALEF_MADDA
1375 		    || two == a_ALEF_HAMZA_ABOVE
1376 		    || two == a_ALEF_HAMZA_BELOW
1377 		    || two == a_ALEF);
1378     return FALSE;
1379 }
1380 
1381 /*
1382  * Check if the character pointed to by "p2" is a composing character when it
1383  * comes after "p1".  For Arabic sometimes "ab" is replaced with "c", which
1384  * behaves like a composing character.
1385  */
1386     int
1387 utf_composinglike(p1, p2)
1388     char_u	*p1;
1389     char_u	*p2;
1390 {
1391     int		c2;
1392 
1393     c2 = utf_ptr2char(p2);
1394     if (utf_iscomposing(c2))
1395 	return TRUE;
1396     if (!arabic_maycombine(c2))
1397 	return FALSE;
1398     return arabic_combine(utf_ptr2char(p1), c2);
1399 }
1400 #endif
1401 
1402 /*
1403  * Convert a UTF-8 byte string to a wide chararacter.  Also get up to two
1404  * composing characters.
1405  */
1406     int
1407 utfc_ptr2char(p, p1, p2)
1408     char_u	*p;
1409     int		*p1;	/* return: first composing char or 0 */
1410     int		*p2;	/* return: second composing char or 0 */
1411 {
1412     int		len;
1413     int		c;
1414     int		cc;
1415 
1416     c = utf_ptr2char(p);
1417     len = utf_ptr2len_check(p);
1418     /* Only accept a composing char when the first char isn't illegal. */
1419     if ((len > 1 || *p < 0x80)
1420 	    && p[len] >= 0x80
1421 	    && UTF_COMPOSINGLIKE(p, p + len))
1422     {
1423 	*p1 = utf_ptr2char(p + len);
1424 	len += utf_ptr2len_check(p + len);
1425 	if (p[len] >= 0x80 && utf_iscomposing(cc = utf_ptr2char(p + len)))
1426 	    *p2 = cc;
1427 	else
1428 	    *p2 = 0;
1429     }
1430     else
1431     {
1432 	*p1 = 0;
1433 	*p2 = 0;
1434     }
1435     return c;
1436 }
1437 
1438 /*
1439  * Convert a UTF-8 byte string to a wide chararacter.  Also get up to two
1440  * composing characters.  Use no more than p[maxlen].
1441  */
1442     int
1443 utfc_ptr2char_len(p, p1, p2, maxlen)
1444     char_u	*p;
1445     int		*p1;	/* return: first composing char or 0 */
1446     int		*p2;	/* return: second composing char or 0 */
1447     int		maxlen;
1448 {
1449     int		len;
1450     int		c;
1451     int		cc;
1452 
1453     c = utf_ptr2char(p);
1454     len = utf_ptr2len_check_len(p, maxlen);
1455     /* Only accept a composing char when the first char isn't illegal. */
1456     if ((len > 1 || *p < 0x80)
1457 	    && len < maxlen
1458 	    && p[len] >= 0x80
1459 	    && UTF_COMPOSINGLIKE(p, p + len))
1460     {
1461 	*p1 = utf_ptr2char(p + len);
1462 	len += utf_ptr2len_check_len(p + len, maxlen - len);
1463 	if (len < maxlen
1464 		&& p[len] >= 0x80
1465 		&& utf_iscomposing(cc = utf_ptr2char(p + len)))
1466 	    *p2 = cc;
1467 	else
1468 	    *p2 = 0;
1469     }
1470     else
1471     {
1472 	*p1 = 0;
1473 	*p2 = 0;
1474     }
1475     return c;
1476 }
1477 
1478 /*
1479  * Convert the character at screen position "off" to a sequence of bytes.
1480  * Includes the composing characters.
1481  * "buf" must at least have the length MB_MAXBYTES.
1482  * Returns the produced number of bytes.
1483  */
1484     int
1485 utfc_char2bytes(off, buf)
1486     int		off;
1487     char_u	*buf;
1488 {
1489     int		len;
1490 
1491     len = utf_char2bytes(ScreenLinesUC[off], buf);
1492     if (ScreenLinesC1[off] != 0)
1493     {
1494 	len += utf_char2bytes(ScreenLinesC1[off], buf + len);
1495 	if (ScreenLinesC2[off] != 0)
1496 	    len += utf_char2bytes(ScreenLinesC2[off], buf + len);
1497     }
1498     return len;
1499 }
1500 
1501 /*
1502  * Get the length of a UTF-8 byte sequence, not including any following
1503  * composing characters.
1504  * Returns 0 for "".
1505  * Returns 1 for an illegal byte sequence.
1506  */
1507     int
1508 utf_ptr2len_check(p)
1509     char_u	*p;
1510 {
1511     int		len;
1512     int		i;
1513 
1514     if (*p == NUL)
1515 	return 0;
1516     len = utf8len_tab[*p];
1517     for (i = 1; i < len; ++i)
1518 	if ((p[i] & 0xc0) != 0x80)
1519 	    return 1;
1520     return len;
1521 }
1522 
1523 /*
1524  * Return length of UTF-8 character, obtained from the first byte.
1525  * "b" must be between 0 and 255!
1526  */
1527     int
1528 utf_byte2len(b)
1529     int		b;
1530 {
1531     return utf8len_tab[b];
1532 }
1533 
1534 /*
1535  * Get the length of UTF-8 byte sequence "p[size]".  Does not include any
1536  * following composing characters.
1537  * Returns 1 for "".
1538  * Returns 1 for an illegal byte sequence.
1539  * Returns number > "size" for an incomplete byte sequence.
1540  */
1541     int
1542 utf_ptr2len_check_len(p, size)
1543     char_u	*p;
1544     int		size;
1545 {
1546     int		len;
1547     int		i;
1548 
1549     if (*p == NUL)
1550 	return 1;
1551     len = utf8len_tab[*p];
1552     if (len > size)
1553 	return len;	/* incomplete byte sequence. */
1554     for (i = 1; i < len; ++i)
1555 	if ((p[i] & 0xc0) != 0x80)
1556 	    return 1;
1557     return len;
1558 }
1559 
1560 /*
1561  * Return the number of bytes the UTF-8 encoding of the character at "p" takes.
1562  * This includes following composing characters.
1563  */
1564     int
1565 utfc_ptr2len_check(p)
1566     char_u	*p;
1567 {
1568     int		len;
1569 #ifdef FEAT_ARABIC
1570     int		prevlen;
1571 #endif
1572 
1573     if (*p == NUL)
1574 	return 0;
1575     if (p[0] < 0x80 && p[1] < 0x80)	/* be quick for ASCII */
1576 	return 1;
1577 
1578     /* Skip over first UTF-8 char, stopping at a NUL byte. */
1579     len = utf_ptr2len_check(p);
1580 
1581     /* Check for illegal byte. */
1582     if (len == 1 && p[0] >= 0x80)
1583 	return 1;
1584 
1585     /*
1586      * Check for composing characters.  We can handle only the first two, but
1587      * skip all of them (otherwise the cursor would get stuck).
1588      */
1589 #ifdef FEAT_ARABIC
1590     prevlen = 0;
1591 #endif
1592     for (;;)
1593     {
1594 	if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len))
1595 	    return len;
1596 
1597 	/* Skip over composing char */
1598 #ifdef FEAT_ARABIC
1599 	prevlen = len;
1600 #endif
1601 	len += utf_ptr2len_check(p + len);
1602     }
1603 }
1604 
1605 /*
1606  * Return the number of bytes the UTF-8 encoding of the character at "p[size]"
1607  * takes.  This includes following composing characters.
1608  * Returns 1 for an illegal char or an incomplete byte sequence.
1609  */
1610     int
1611 utfc_ptr2len_check_len(p, size)
1612     char_u	*p;
1613     int		size;
1614 {
1615     int		len;
1616 #ifdef FEAT_ARABIC
1617     int		prevlen;
1618 #endif
1619 
1620     if (*p == NUL)
1621 	return 0;
1622     if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */
1623 	return 1;
1624 
1625     /* Skip over first UTF-8 char, stopping at a NUL byte. */
1626     len = utf_ptr2len_check_len(p, size);
1627 
1628     /* Check for illegal byte and incomplete byte sequence. */
1629     if ((len == 1 && p[0] >= 0x80) || len > size)
1630 	return 1;
1631 
1632     /*
1633      * Check for composing characters.  We can handle only the first two, but
1634      * skip all of them (otherwise the cursor would get stuck).
1635      */
1636 #ifdef FEAT_ARABIC
1637     prevlen = 0;
1638 #endif
1639     while (len < size)
1640     {
1641 	if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len))
1642 	    break;
1643 
1644 	/* Skip over composing char */
1645 #ifdef FEAT_ARABIC
1646 	prevlen = len;
1647 #endif
1648 	len += utf_ptr2len_check_len(p + len, size - len);
1649     }
1650     return len;
1651 }
1652 
1653 /*
1654  * Return the number of bytes the UTF-8 encoding of character "c" takes.
1655  * This does not include composing characters.
1656  */
1657     int
1658 utf_char2len(c)
1659     int		c;
1660 {
1661     if (c < 0x80)
1662 	return 1;
1663     if (c < 0x800)
1664 	return 2;
1665     if (c < 0x10000)
1666 	return 3;
1667     if (c < 0x200000)
1668 	return 4;
1669     if (c < 0x4000000)
1670 	return 5;
1671     return 6;
1672 }
1673 
1674 /*
1675  * Convert Unicode character "c" to UTF-8 string in "buf[]".
1676  * Returns the number of bytes.
1677  * This does not include composing characters.
1678  */
1679     int
1680 utf_char2bytes(c, buf)
1681     int		c;
1682     char_u	*buf;
1683 {
1684     if (c < 0x80)		/* 7 bits */
1685     {
1686 	buf[0] = c;
1687 	return 1;
1688     }
1689     if (c < 0x800)		/* 11 bits */
1690     {
1691 	buf[0] = 0xc0 + ((unsigned)c >> 6);
1692 	buf[1] = 0x80 + (c & 0x3f);
1693 	return 2;
1694     }
1695     if (c < 0x10000)		/* 16 bits */
1696     {
1697 	buf[0] = 0xe0 + ((unsigned)c >> 12);
1698 	buf[1] = 0x80 + (((unsigned)c >> 6) & 0x3f);
1699 	buf[2] = 0x80 + (c & 0x3f);
1700 	return 3;
1701     }
1702     if (c < 0x200000)		/* 21 bits */
1703     {
1704 	buf[0] = 0xf0 + ((unsigned)c >> 18);
1705 	buf[1] = 0x80 + (((unsigned)c >> 12) & 0x3f);
1706 	buf[2] = 0x80 + (((unsigned)c >> 6) & 0x3f);
1707 	buf[3] = 0x80 + (c & 0x3f);
1708 	return 4;
1709     }
1710     if (c < 0x4000000)		/* 26 bits */
1711     {
1712 	buf[0] = 0xf8 + ((unsigned)c >> 24);
1713 	buf[1] = 0x80 + (((unsigned)c >> 18) & 0x3f);
1714 	buf[2] = 0x80 + (((unsigned)c >> 12) & 0x3f);
1715 	buf[3] = 0x80 + (((unsigned)c >> 6) & 0x3f);
1716 	buf[4] = 0x80 + (c & 0x3f);
1717 	return 5;
1718     }
1719 				/* 31 bits */
1720     buf[0] = 0xfc + ((unsigned)c >> 30);
1721     buf[1] = 0x80 + (((unsigned)c >> 24) & 0x3f);
1722     buf[2] = 0x80 + (((unsigned)c >> 18) & 0x3f);
1723     buf[3] = 0x80 + (((unsigned)c >> 12) & 0x3f);
1724     buf[4] = 0x80 + (((unsigned)c >> 6) & 0x3f);
1725     buf[5] = 0x80 + (c & 0x3f);
1726     return 6;
1727 }
1728 
1729 /*
1730  * Return TRUE if "c" is a composing UTF-8 character.  This means it will be
1731  * drawn on top of the preceding character.
1732  * Based on code from Markus Kuhn.
1733  */
1734     int
1735 utf_iscomposing(c)
1736     int		c;
1737 {
1738     /* sorted list of non-overlapping intervals */
1739     static struct interval combining[] =
1740     {
1741 	{0x0300, 0x034f}, {0x0360, 0x036f}, {0x0483, 0x0486}, {0x0488, 0x0489},
1742 	{0x0591, 0x05a1}, {0x05a3, 0x05b9}, {0x05bb, 0x05bd}, {0x05bf, 0x05bf},
1743 	{0x05c1, 0x05c2}, {0x05c4, 0x05c4}, {0x0610, 0x0615}, {0x064b, 0x0658},
1744 	{0x0670, 0x0670}, {0x06d6, 0x06dc}, {0x06de, 0x06e4}, {0x06e7, 0x06e8},
1745 	{0x06ea, 0x06ed}, {0x0711, 0x0711}, {0x0730, 0x074a}, {0x07a6, 0x07b0},
1746 	{0x0901, 0x0903}, {0x093c, 0x093c}, {0x093e, 0x094d}, {0x0951, 0x0954},
1747 	{0x0962, 0x0963}, {0x0981, 0x0983}, {0x09bc, 0x09bc}, {0x09be, 0x09c4},
1748 	{0x09c7, 0x09c8}, {0x09cb, 0x09cd}, {0x09d7, 0x09d7}, {0x09e2, 0x09e3},
1749 	{0x0a01, 0x0a03}, {0x0a3c, 0x0a3c}, {0x0a3e, 0x0a42}, {0x0a47, 0x0a48},
1750 	{0x0a4b, 0x0a4d}, {0x0a70, 0x0a71}, {0x0a81, 0x0a83}, {0x0abc, 0x0abc},
1751 	{0x0abe, 0x0ac5}, {0x0ac7, 0x0ac9}, {0x0acb, 0x0acd}, {0x0ae2, 0x0ae3},
1752 	{0x0b01, 0x0b03}, {0x0b3c, 0x0b3c}, {0x0b3e, 0x0b43}, {0x0b47, 0x0b48},
1753 	{0x0b4b, 0x0b4d}, {0x0b56, 0x0b57}, {0x0b82, 0x0b82}, {0x0bbe, 0x0bc2},
1754 	{0x0bc6, 0x0bc8}, {0x0bca, 0x0bcd}, {0x0bd7, 0x0bd7}, {0x0c01, 0x0c03},
1755 	{0x0c3e, 0x0c44}, {0x0c46, 0x0c48}, {0x0c4a, 0x0c4d}, {0x0c55, 0x0c56},
1756 	{0x0c82, 0x0c83}, {0x0cbc, 0x0cbc}, {0x0cbe, 0x0cc4}, {0x0cc6, 0x0cc8},
1757 	{0x0cca, 0x0ccd}, {0x0cd5, 0x0cd6}, {0x0d02, 0x0d03}, {0x0d3e, 0x0d43},
1758 	{0x0d46, 0x0d48}, {0x0d4a, 0x0d4d}, {0x0d57, 0x0d57}, {0x0d82, 0x0d83},
1759 	{0x0dca, 0x0dca}, {0x0dcf, 0x0dd4}, {0x0dd6, 0x0dd6}, {0x0dd8, 0x0ddf},
1760 	{0x0df2, 0x0df3}, {0x0e31, 0x0e31}, {0x0e34, 0x0e3a}, {0x0e47, 0x0e4e},
1761 	{0x0eb1, 0x0eb1}, {0x0eb4, 0x0eb9}, {0x0ebb, 0x0ebc}, {0x0ec8, 0x0ecd},
1762 	{0x0f18, 0x0f19}, {0x0f35, 0x0f35}, {0x0f37, 0x0f37}, {0x0f39, 0x0f39},
1763 	{0x0f3e, 0x0f3f}, {0x0f71, 0x0f84}, {0x0f86, 0x0f87}, {0x0f90, 0x0f97},
1764 	{0x0f99, 0x0fbc}, {0x0fc6, 0x0fc6}, {0x102c, 0x1032}, {0x1036, 0x1039},
1765 	{0x1056, 0x1059}, {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753},
1766 	{0x1772, 0x1773}, {0x17b6, 0x17d3}, {0x17dd, 0x17dd}, {0x180b, 0x180d},
1767 	{0x18a9, 0x18a9}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x20d0, 0x20ea},
1768 	{0x302a, 0x302f}, {0x3099, 0x309a}, {0xfb1e, 0xfb1e}, {0xfe00, 0xfe0f},
1769 	{0xfe20, 0xfe23},
1770     };
1771 
1772     return intable(combining, sizeof(combining), c);
1773 }
1774 
1775 /*
1776  * Return TRUE for characters that can be displayed in a normal way.
1777  * Only for characters of 0x100 and above!
1778  */
1779     int
1780 utf_printable(c)
1781     int		c;
1782 {
1783 #ifdef USE_WCHAR_FUNCTIONS
1784     /*
1785      * Assume the iswprint() library function works better than our own stuff.
1786      */
1787     return iswprint(c);
1788 #else
1789     /* Sorted list of non-overlapping intervals.
1790      * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */
1791     static struct interval nonprint[] =
1792     {
1793 	{0x070f, 0x070f}, {0x180b, 0x180e}, {0x200b, 0x200f}, {0x202a, 0x202e},
1794 	{0x206a, 0x206f}, {0xd800, 0xdfff}, {0xfeff, 0xfeff}, {0xfff9, 0xfffb},
1795 	{0xfffe, 0xffff}
1796     };
1797 
1798     return !intable(nonprint, sizeof(nonprint), c);
1799 #endif
1800 }
1801 
1802 /*
1803  * Get class of a Unicode character.
1804  * 0: white space
1805  * 1: punctuation
1806  * 2 or bigger: some class of word character.
1807  */
1808     int
1809 utf_class(c)
1810     int		c;
1811 {
1812     /* sorted list of non-overlapping intervals */
1813     static struct clinterval
1814     {
1815 	unsigned short first;
1816 	unsigned short last;
1817 	unsigned short class;
1818     } classes[] =
1819     {
1820 	{0x037e, 0x037e, 1},		/* Greek question mark */
1821 	{0x0387, 0x0387, 1},		/* Greek ano teleia */
1822 	{0x055a, 0x055f, 1},		/* Armenian punctuation */
1823 	{0x0589, 0x0589, 1},		/* Armenian full stop */
1824 	{0x05be, 0x05be, 1},
1825 	{0x05c0, 0x05c0, 1},
1826 	{0x05c3, 0x05c3, 1},
1827 	{0x05f3, 0x05f4, 1},
1828 	{0x060c, 0x060c, 1},
1829 	{0x061b, 0x061b, 1},
1830 	{0x061f, 0x061f, 1},
1831 	{0x066a, 0x066d, 1},
1832 	{0x06d4, 0x06d4, 1},
1833 	{0x0700, 0x070d, 1},		/* Syriac punctuation */
1834 	{0x0964, 0x0965, 1},
1835 	{0x0970, 0x0970, 1},
1836 	{0x0df4, 0x0df4, 1},
1837 	{0x0e4f, 0x0e4f, 1},
1838 	{0x0e5a, 0x0e5b, 1},
1839 	{0x0f04, 0x0f12, 1},
1840 	{0x0f3a, 0x0f3d, 1},
1841 	{0x0f85, 0x0f85, 1},
1842 	{0x104a, 0x104f, 1},		/* Myanmar punctuation */
1843 	{0x10fb, 0x10fb, 1},		/* Georgian punctuation */
1844 	{0x1361, 0x1368, 1},		/* Ethiopic punctuation */
1845 	{0x166d, 0x166e, 1},		/* Canadian Syl. punctuation */
1846 	{0x1680, 0x1680, 0},
1847 	{0x169b, 0x169c, 1},
1848 	{0x16eb, 0x16ed, 1},
1849 	{0x1735, 0x1736, 1},
1850 	{0x17d4, 0x17dc, 1},		/* Khmer punctuation */
1851 	{0x1800, 0x180a, 1},		/* Mongolian punctuation */
1852 	{0x2000, 0x200b, 0},		/* spaces */
1853 	{0x200c, 0x2027, 1},		/* punctuation and symbols */
1854 	{0x2028, 0x2029, 0},
1855 	{0x202a, 0x202e, 1},		/* punctuation and symbols */
1856 	{0x202f, 0x202f, 0},
1857 	{0x2030, 0x205e, 1},		/* punctuation and symbols */
1858 	{0x205f, 0x205f, 0},
1859 	{0x2060, 0x27ff, 1},		/* punctuation and symbols */
1860 	{0x2070, 0x207f, 0x2070},	/* superscript */
1861 	{0x2080, 0x208f, 0x2080},	/* subscript */
1862 	{0x2983, 0x2998, 1},
1863 	{0x29d8, 0x29db, 1},
1864 	{0x29fc, 0x29fd, 1},
1865 	{0x3000, 0x3000, 0},		/* ideographic space */
1866 	{0x3001, 0x3020, 1},		/* ideographic punctuation */
1867 	{0x3030, 0x3030, 1},
1868 	{0x303d, 0x303d, 1},
1869 	{0x3040, 0x309f, 0x3040},	/* Hiragana */
1870 	{0x30a0, 0x30ff, 0x30a0},	/* Katakana */
1871 	{0x3300, 0x9fff, 0x4e00},	/* CJK Ideographs */
1872 	{0xac00, 0xd7a3, 0xac00},	/* Hangul Syllables */
1873 	{0xf900, 0xfaff, 0x4e00},	/* CJK Ideographs */
1874 	{0xfd3e, 0xfd3f, 1},
1875 	{0xfe30, 0xfe6b, 1},		/* punctuation forms */
1876 	{0xff00, 0xff0f, 1},		/* half/fullwidth ASCII */
1877 	{0xff1a, 0xff20, 1},		/* half/fullwidth ASCII */
1878 	{0xff3b, 0xff40, 1},		/* half/fullwidth ASCII */
1879 	{0xff5b, 0xff65, 1},		/* half/fullwidth ASCII */
1880     };
1881     int bot = 0;
1882     int top = sizeof(classes) / sizeof(struct clinterval) - 1;
1883     int mid;
1884 
1885     /* First quick check for Latin1 characters, use 'iskeyword'. */
1886     if (c < 0x100)
1887     {
1888 	if (c == ' ' || c == '\t' || c == NUL)
1889 	    return 0;	    /* blank */
1890 	if (vim_iswordc(c))
1891 	    return 2;	    /* word character */
1892 	return 1;	    /* punctuation */
1893     }
1894 
1895     /* binary search in table */
1896     while (top >= bot)
1897     {
1898 	mid = (bot + top) / 2;
1899 	if (classes[mid].last < c)
1900 	    bot = mid + 1;
1901 	else if (classes[mid].first > c)
1902 	    top = mid - 1;
1903 	else
1904 	    return (int)classes[mid].class;
1905     }
1906 
1907     /* most other characters are "word" characters */
1908     return 2;
1909 }
1910 
1911 /*
1912  * Code for Unicode case-dependent operations.  Based on notes in
1913  * http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
1914  * This code uses simple case folding, not full case folding.
1915  */
1916 
1917 /*
1918  * The following table is built by foldExtract.pl < CaseFolding.txt .
1919  * It must be in numeric order, because we use binary search on it.
1920  * An entry such as {0x41,0x5a,1,32} means that UCS-4 characters in the range
1921  * from 0x41 to 0x5a inclusive, stepping by 1, are folded by adding 32.
1922  */
1923 
1924 typedef struct
1925 {
1926     int rangeStart;
1927     int rangeEnd;
1928     int step;
1929     int offset;
1930 } convertStruct;
1931 
1932 convertStruct foldCase[] =
1933 {
1934 	{0x41,0x5a,1,32}, {0xc0,0xd6,1,32}, {0xd8,0xde,1,32},
1935 	{0x100,0x12e,2,1}, {0x130,0x130,-1,-199}, {0x132,0x136,2,1},
1936 	{0x139,0x147,2,1}, {0x14a,0x176,2,1}, {0x178,0x178,-1,-121},
1937 	{0x179,0x17d,2,1}, {0x181,0x181,-1,210}, {0x182,0x184,2,1},
1938 	{0x186,0x186,-1,206}, {0x187,0x187,-1,1}, {0x189,0x18a,1,205},
1939 	{0x18b,0x18b,-1,1}, {0x18e,0x18e,-1,79}, {0x18f,0x18f,-1,202},
1940 	{0x190,0x190,-1,203}, {0x191,0x191,-1,1}, {0x193,0x193,-1,205},
1941 	{0x194,0x194,-1,207}, {0x196,0x196,-1,211}, {0x197,0x197,-1,209},
1942 	{0x198,0x198,-1,1}, {0x19c,0x19c,-1,211}, {0x19d,0x19d,-1,213},
1943 	{0x19f,0x19f,-1,214}, {0x1a0,0x1a4,2,1}, {0x1a6,0x1a6,-1,218},
1944 	{0x1a7,0x1a7,-1,1}, {0x1a9,0x1a9,-1,218}, {0x1ac,0x1ac,-1,1},
1945 	{0x1ae,0x1ae,-1,218}, {0x1af,0x1af,-1,1}, {0x1b1,0x1b2,1,217},
1946 	{0x1b3,0x1b5,2,1}, {0x1b7,0x1b7,-1,219}, {0x1b8,0x1bc,4,1},
1947 	{0x1c4,0x1c4,-1,2}, {0x1c5,0x1c5,-1,1}, {0x1c7,0x1c7,-1,2},
1948 	{0x1c8,0x1c8,-1,1}, {0x1ca,0x1ca,-1,2}, {0x1cb,0x1db,2,1},
1949 	{0x1de,0x1ee,2,1}, {0x1f1,0x1f1,-1,2}, {0x1f2,0x1f4,2,1},
1950 	{0x1f6,0x1f6,-1,-97}, {0x1f7,0x1f7,-1,-56}, {0x1f8,0x21e,2,1},
1951 	{0x220,0x220,-1,-130}, {0x222,0x232,2,1}, {0x386,0x386,-1,38},
1952 	{0x388,0x38a,1,37}, {0x38c,0x38c,-1,64}, {0x38e,0x38f,1,63},
1953 	{0x391,0x3a1,1,32}, {0x3a3,0x3ab,1,32}, {0x3d8,0x3ee,2,1},
1954 	{0x3f4,0x3f4,-1,-60}, {0x3f7,0x3f7,-1,1}, {0x3f9,0x3f9,-1,-7},
1955 	{0x3fa,0x3fa,-1,1}, {0x400,0x40f,1,80}, {0x410,0x42f,1,32},
1956 	{0x460,0x480,2,1}, {0x48a,0x4be,2,1}, {0x4c1,0x4cd,2,1},
1957 	{0x4d0,0x4f4,2,1}, {0x4f8,0x500,8,1}, {0x502,0x50e,2,1},
1958 	{0x531,0x556,1,48}, {0x1e00,0x1e94,2,1}, {0x1ea0,0x1ef8,2,1},
1959 	{0x1f08,0x1f0f,1,-8}, {0x1f18,0x1f1d,1,-8}, {0x1f28,0x1f2f,1,-8},
1960 	{0x1f38,0x1f3f,1,-8}, {0x1f48,0x1f4d,1,-8}, {0x1f59,0x1f5f,2,-8},
1961 	{0x1f68,0x1f6f,1,-8}, {0x1f88,0x1f8f,1,-8}, {0x1f98,0x1f9f,1,-8},
1962 	{0x1fa8,0x1faf,1,-8}, {0x1fb8,0x1fb9,1,-8}, {0x1fba,0x1fbb,1,-74},
1963 	{0x1fbc,0x1fbc,-1,-9}, {0x1fc8,0x1fcb,1,-86}, {0x1fcc,0x1fcc,-1,-9},
1964 	{0x1fd8,0x1fd9,1,-8}, {0x1fda,0x1fdb,1,-100}, {0x1fe8,0x1fe9,1,-8},
1965 	{0x1fea,0x1feb,1,-112}, {0x1fec,0x1fec,-1,-7}, {0x1ff8,0x1ff9,1,-128},
1966 	{0x1ffa,0x1ffb,1,-126}, {0x1ffc,0x1ffc,-1,-9}, {0x2126,0x2126,-1,-7517},
1967 	{0x212a,0x212a,-1,-8383}, {0x212b,0x212b,-1,-8262},
1968 	{0x2160,0x216f,1,16}, {0x24b6,0x24cf,1,26}, {0xff21,0xff3a,1,32},
1969 	{0x10400,0x10427,1,40}
1970 };
1971 
1972 static int utf_convert(int a, convertStruct table[], int tableSize);
1973 
1974 /*
1975  * Generic conversion function for case operations.
1976  * Return the converted equivalent of "a", which is a UCS-4 character.  Use
1977  * the given conversion "table".  Uses binary search on "table".
1978  */
1979     static int
1980 utf_convert(a, table, tableSize)
1981     int			a;
1982     convertStruct	table[];
1983     int			tableSize;
1984 {
1985     int start, mid, end; /* indices into table */
1986 
1987     start = 0;
1988     end = tableSize / sizeof(convertStruct);
1989     while (start < end)
1990     {
1991 	/* need to search further */
1992 	mid = (end + start) /2;
1993 	if (table[mid].rangeEnd < a)
1994 	    start = mid + 1;
1995 	else
1996 	    end = mid;
1997     }
1998     if (table[start].rangeStart <= a && a <= table[start].rangeEnd
1999 	    && (a - table[start].rangeStart) % table[start].step == 0)
2000 	return (a + table[start].offset);
2001     else
2002 	return a;
2003 }
2004 
2005 /*
2006  * Return the folded-case equivalent of "a", which is a UCS-4 character.  Uses
2007  * simple case folding.
2008  */
2009     int
2010 utf_fold(a)
2011     int		a;
2012 {
2013     return utf_convert(a, foldCase, sizeof(foldCase));
2014 }
2015 
2016 /*
2017  * The following tables are built by upperLowerExtract.pl < UnicodeData.txt .
2018  * They must be in numeric order, because we use binary search on them.
2019  * An entry such as {0x41,0x5a,1,32} means that UCS-4 characters in the range
2020  * from 0x41 to 0x5a inclusive, stepping by 1, are switched to lower (for
2021  * example) by adding 32.
2022  */
2023 convertStruct toLower[] =
2024 {
2025 	{0x41,0x5a,1,32}, {0xc0,0xd6,1,32}, {0xd8,0xde,1,32},
2026 	{0x100,0x12e,2,1}, {0x130,0x130,-1,-199}, {0x132,0x136,2,1},
2027 	{0x139,0x147,2,1}, {0x14a,0x176,2,1}, {0x178,0x178,-1,-121},
2028 	{0x179,0x17d,2,1}, {0x181,0x181,-1,210}, {0x182,0x184,2,1},
2029 	{0x186,0x186,-1,206}, {0x187,0x187,-1,1}, {0x189,0x18a,1,205},
2030 	{0x18b,0x18b,-1,1}, {0x18e,0x18e,-1,79}, {0x18f,0x18f,-1,202},
2031 	{0x190,0x190,-1,203}, {0x191,0x191,-1,1}, {0x193,0x193,-1,205},
2032 	{0x194,0x194,-1,207}, {0x196,0x196,-1,211}, {0x197,0x197,-1,209},
2033 	{0x198,0x198,-1,1}, {0x19c,0x19c,-1,211}, {0x19d,0x19d,-1,213},
2034 	{0x19f,0x19f,-1,214}, {0x1a0,0x1a4,2,1}, {0x1a6,0x1a6,-1,218},
2035 	{0x1a7,0x1a7,-1,1}, {0x1a9,0x1a9,-1,218}, {0x1ac,0x1ac,-1,1},
2036 	{0x1ae,0x1ae,-1,218}, {0x1af,0x1af,-1,1}, {0x1b1,0x1b2,1,217},
2037 	{0x1b3,0x1b5,2,1}, {0x1b7,0x1b7,-1,219}, {0x1b8,0x1bc,4,1},
2038 	{0x1c4,0x1ca,3,2}, {0x1cd,0x1db,2,1}, {0x1de,0x1ee,2,1},
2039 	{0x1f1,0x1f1,-1,2}, {0x1f4,0x1f4,-1,1}, {0x1f6,0x1f6,-1,-97},
2040 	{0x1f7,0x1f7,-1,-56}, {0x1f8,0x21e,2,1}, {0x220,0x220,-1,-130},
2041 	{0x222,0x232,2,1}, {0x386,0x386,-1,38}, {0x388,0x38a,1,37},
2042 	{0x38c,0x38c,-1,64}, {0x38e,0x38f,1,63}, {0x391,0x3a1,1,32},
2043 	{0x3a3,0x3ab,1,32}, {0x3d8,0x3ee,2,1}, {0x3f4,0x3f4,-1,-60},
2044 	{0x3f7,0x3f7,-1,1}, {0x3f9,0x3f9,-1,-7}, {0x3fa,0x3fa,-1,1},
2045 	{0x400,0x40f,1,80}, {0x410,0x42f,1,32}, {0x460,0x480,2,1},
2046 	{0x48a,0x4be,2,1}, {0x4c1,0x4cd,2,1}, {0x4d0,0x4f4,2,1},
2047 	{0x4f8,0x500,8,1}, {0x502,0x50e,2,1}, {0x531,0x556,1,48},
2048 	{0x1e00,0x1e94,2,1}, {0x1ea0,0x1ef8,2,1}, {0x1f08,0x1f0f,1,-8},
2049 	{0x1f18,0x1f1d,1,-8}, {0x1f28,0x1f2f,1,-8}, {0x1f38,0x1f3f,1,-8},
2050 	{0x1f48,0x1f4d,1,-8}, {0x1f59,0x1f5f,2,-8}, {0x1f68,0x1f6f,1,-8},
2051 	{0x1fb8,0x1fb9,1,-8}, {0x1fba,0x1fbb,1,-74}, {0x1fc8,0x1fcb,1,-86},
2052 	{0x1fd8,0x1fd9,1,-8}, {0x1fda,0x1fdb,1,-100}, {0x1fe8,0x1fe9,1,-8},
2053 	{0x1fea,0x1feb,1,-112}, {0x1fec,0x1fec,-1,-7}, {0x1ff8,0x1ff9,1,-128},
2054 	{0x1ffa,0x1ffb,1,-126}, {0x2126,0x2126,-1,-7517}, {0x212a,0x212a,-1,-8383},
2055 	{0x212b,0x212b,-1,-8262}, {0xff21,0xff3a,1,32}, {0x10400,0x10427,1,40}
2056 };
2057 
2058 convertStruct toUpper[] =
2059 {
2060 	{0x61,0x7a,1,-32}, {0xb5,0xb5,-1,743}, {0xe0,0xf6,1,-32},
2061 	{0xf8,0xfe,1,-32}, {0xff,0xff,-1,121}, {0x101,0x12f,2,-1},
2062 	{0x131,0x131,-1,-232}, {0x133,0x137,2,-1}, {0x13a,0x148,2,-1},
2063 	{0x14b,0x177,2,-1}, {0x17a,0x17e,2,-1}, {0x17f,0x17f,-1,-300},
2064 	{0x183,0x185,2,-1}, {0x188,0x18c,4,-1}, {0x192,0x192,-1,-1},
2065 	{0x195,0x195,-1,97}, {0x199,0x199,-1,-1}, {0x19e,0x19e,-1,130},
2066 	{0x1a1,0x1a5,2,-1}, {0x1a8,0x1ad,5,-1}, {0x1b0,0x1b4,4,-1},
2067 	{0x1b6,0x1b9,3,-1}, {0x1bd,0x1bd,-1,-1}, {0x1bf,0x1bf,-1,56},
2068 	{0x1c5,0x1c6,1,-1}, {0x1c8,0x1c9,1,-1}, {0x1cb,0x1cc,1,-1},
2069 	{0x1ce,0x1dc,2,-1}, {0x1dd,0x1dd,-1,-79}, {0x1df,0x1ef,2,-1},
2070 	{0x1f2,0x1f3,1,-1}, {0x1f5,0x1f9,4,-1}, {0x1fb,0x21f,2,-1},
2071 	{0x223,0x233,2,-1}, {0x253,0x253,-1,-210}, {0x254,0x254,-1,-206},
2072 	{0x256,0x257,1,-205}, {0x259,0x259,-1,-202}, {0x25b,0x25b,-1,-203},
2073 	{0x260,0x260,-1,-205}, {0x263,0x263,-1,-207}, {0x268,0x268,-1,-209},
2074 	{0x269,0x26f,6,-211}, {0x272,0x272,-1,-213}, {0x275,0x275,-1,-214},
2075 	{0x280,0x283,3,-218}, {0x288,0x288,-1,-218}, {0x28a,0x28b,1,-217},
2076 	{0x292,0x292,-1,-219}, {0x3ac,0x3ac,-1,-38}, {0x3ad,0x3af,1,-37},
2077 	{0x3b1,0x3c1,1,-32}, {0x3c2,0x3c2,-1,-31}, {0x3c3,0x3cb,1,-32},
2078 	{0x3cc,0x3cc,-1,-64}, {0x3cd,0x3ce,1,-63}, {0x3d0,0x3d0,-1,-62},
2079 	{0x3d1,0x3d1,-1,-57}, {0x3d5,0x3d5,-1,-47}, {0x3d6,0x3d6,-1,-54},
2080 	{0x3d9,0x3ef,2,-1}, {0x3f0,0x3f0,-1,-86}, {0x3f1,0x3f1,-1,-80},
2081 	{0x3f2,0x3f2,-1,7}, {0x3f5,0x3f5,-1,-96}, {0x3f8,0x3fb,3,-1},
2082 	{0x430,0x44f,1,-32}, {0x450,0x45f,1,-80}, {0x461,0x481,2,-1},
2083 	{0x48b,0x4bf,2,-1}, {0x4c2,0x4ce,2,-1}, {0x4d1,0x4f5,2,-1},
2084 	{0x4f9,0x501,8,-1}, {0x503,0x50f,2,-1}, {0x561,0x586,1,-48},
2085 	{0x1e01,0x1e95,2,-1}, {0x1e9b,0x1e9b,-1,-59}, {0x1ea1,0x1ef9,2,-1},
2086 	{0x1f00,0x1f07,1,8}, {0x1f10,0x1f15,1,8}, {0x1f20,0x1f27,1,8},
2087 	{0x1f30,0x1f37,1,8}, {0x1f40,0x1f45,1,8}, {0x1f51,0x1f57,2,8},
2088 	{0x1f60,0x1f67,1,8}, {0x1f70,0x1f71,1,74}, {0x1f72,0x1f75,1,86},
2089 	{0x1f76,0x1f77,1,100}, {0x1f78,0x1f79,1,128}, {0x1f7a,0x1f7b,1,112},
2090 	{0x1f7c,0x1f7d,1,126}, {0x1f80,0x1f87,1,8}, {0x1f90,0x1f97,1,8},
2091 	{0x1fa0,0x1fa7,1,8}, {0x1fb0,0x1fb1,1,8}, {0x1fb3,0x1fb3,-1,9},
2092 	{0x1fbe,0x1fbe,-1,-7205}, {0x1fc3,0x1fc3,-1,9}, {0x1fd0,0x1fd1,1,8},
2093 	{0x1fe0,0x1fe1,1,8}, {0x1fe5,0x1fe5,-1,7}, {0x1ff3,0x1ff3,-1,9},
2094 	{0xff41,0xff5a,1,-32}, {0x10428,0x1044f,1,-40}
2095 };
2096 
2097 /*
2098  * Return the upper-case equivalent of "a", which is a UCS-4 character.  Use
2099  * simple case folding.
2100  */
2101     int
2102 utf_toupper(a)
2103     int		a;
2104 {
2105     /* If 'casemap' contains "keepascii" use ASCII style toupper(). */
2106     if (a < 128 && (cmp_flags & CMP_KEEPASCII))
2107 	return TOUPPER_ASC(a);
2108 
2109 #if defined(HAVE_TOWUPPER) && defined(__STDC__ISO_10646__)
2110     /* If towupper() is availble and handles Unicode, use it. */
2111     if (!(cmp_flags & CMP_INTERNAL))
2112 	return towupper(a);
2113 #endif
2114 
2115     /* For characters below 128 use locale sensitive toupper(). */
2116     if (a < 128)
2117 	return TOUPPER_LOC(a);
2118 
2119     /* For any other characters use the above mapping table. */
2120     return utf_convert(a, toUpper, sizeof(toUpper));
2121 }
2122 
2123     int
2124 utf_islower(a)
2125     int		a;
2126 {
2127     return (utf_toupper(a) != a);
2128 }
2129 
2130 /*
2131  * Return the lower-case equivalent of "a", which is a UCS-4 character.  Use
2132  * simple case folding.
2133  */
2134     int
2135 utf_tolower(a)
2136     int		a;
2137 {
2138     /* If 'casemap' contains "keepascii" use ASCII style tolower(). */
2139     if (a < 128 && (cmp_flags & CMP_KEEPASCII))
2140 	return TOLOWER_ASC(a);
2141 
2142 #if defined(HAVE_TOWLOWER) && defined(__STDC__ISO_10646__)
2143     /* If towlower() is availble and handles Unicode, use it. */
2144     if (!(cmp_flags & CMP_INTERNAL))
2145 	return towlower(a);
2146 #endif
2147 
2148     /* For characters below 128 use locale sensitive tolower(). */
2149     if (a < 128)
2150 	return TOLOWER_LOC(a);
2151 
2152     /* For any other characters use the above mapping table. */
2153     return utf_convert(a, toLower, sizeof(toLower));
2154 }
2155 
2156     int
2157 utf_isupper(a)
2158     int		a;
2159 {
2160     return (utf_tolower(a) != a);
2161 }
2162 
2163 /*
2164  * Version of strnicmp() that handles multi-byte characters.
2165  * Needed for Big5, Sjift-JIS and UTF-8 encoding.  Other DBCS encodings can
2166  * probably use strnicmp(), because there are no ASCII characters in the
2167  * second byte.
2168  * Returns zero if s1 and s2 are equal (ignoring case), the difference between
2169  * two characters otherwise.
2170  */
2171     int
2172 mb_strnicmp(s1, s2, n)
2173     char_u	*s1, *s2;
2174     int		n;
2175 {
2176     int		i, j, l;
2177     int		cdiff;
2178 
2179     for (i = 0; i < n; i += l)
2180     {
2181 	if (s1[i] == NUL && s2[i] == NUL)   /* both strings end */
2182 	    return 0;
2183 	if (enc_utf8)
2184 	{
2185 	    l = utf_byte2len(s1[i]);
2186 	    if (l > n - i)
2187 		l = n - i;		    /* incomplete character */
2188 	    /* Check directly first, it's faster. */
2189 	    for (j = 0; j < l; ++j)
2190 		if (s1[i + j] != s2[i + j])
2191 		    break;
2192 	    if (j < l)
2193 	    {
2194 		/* If one of the two characters is incomplete return -1. */
2195 		if (i + utf_byte2len(s1[i]) > n || i + utf_byte2len(s2[i]) > n)
2196 		    return -1;
2197 		cdiff = utf_fold(utf_ptr2char(s1 + i))
2198 					     - utf_fold(utf_ptr2char(s2 + i));
2199 		if (cdiff != 0)
2200 		    return cdiff;
2201 	    }
2202 	}
2203 	else
2204 	{
2205 	    l = (*mb_ptr2len_check)(s1 + i);
2206 	    if (l <= 1)
2207 	    {
2208 		/* Single byte: first check normally, then with ignore case. */
2209 		if (s1[i] != s2[i])
2210 		{
2211 		    cdiff = TOLOWER_LOC(s1[i]) - TOLOWER_LOC(s2[i]);
2212 		    if (cdiff != 0)
2213 			return cdiff;
2214 		}
2215 	    }
2216 	    else
2217 	    {
2218 		/* For non-Unicode multi-byte don't ignore case. */
2219 		if (l > n - i)
2220 		    l = n - i;
2221 		cdiff = STRNCMP(s1 + i, s2 + i, l);
2222 		if (cdiff != 0)
2223 		    return cdiff;
2224 	    }
2225 	}
2226     }
2227     return 0;
2228 }
2229 
2230 /*
2231  * "g8": show bytes of the UTF-8 char under the cursor.  Doesn't matter what
2232  * 'encoding' has been set to.
2233  */
2234     void
2235 show_utf8()
2236 {
2237     int		len;
2238     char_u	*line;
2239     int		clen;
2240     int		i;
2241 
2242     /* Get the byte length of the char under the cursor, including composing
2243      * characters. */
2244     line = ml_get_cursor();
2245     len = utfc_ptr2len_check(line);
2246     if (len == 0)
2247     {
2248 	MSG("NUL");
2249 	return;
2250     }
2251 
2252     IObuff[0] = NUL;
2253     clen = 0;
2254     for (i = 0; i < len; ++i)
2255     {
2256 	if (clen == 0)
2257 	{
2258 	    /* start of (composing) character, get its length */
2259 	    if (i > 0)
2260 		STRCAT(IObuff, "+ ");
2261 	    clen = utf_ptr2len_check(line + i);
2262 	}
2263 	sprintf((char *)IObuff + STRLEN(IObuff), "%02x ", line[i]);
2264 	--clen;
2265     }
2266 
2267     msg(IObuff);
2268 }
2269 
2270 /*
2271  * mb_head_off() function pointer.
2272  * Return offset from "p" to the first byte of the character it points into.
2273  * Returns 0 when already at the first byte of a character.
2274  */
2275 /*ARGSUSED*/
2276     int
2277 latin_head_off(base, p)
2278     char_u	*base;
2279     char_u	*p;
2280 {
2281     return 0;
2282 }
2283 
2284     int
2285 dbcs_head_off(base, p)
2286     char_u	*base;
2287     char_u	*p;
2288 {
2289     char_u	*q;
2290 
2291     /* It can't be a trailing byte when not using DBCS, at the start of the
2292      * string or the previous byte can't start a double-byte. */
2293     if (p <= base || MB_BYTE2LEN(p[-1]) == 1)
2294 	return 0;
2295 
2296     /* This is slow: need to start at the base and go forward until the
2297      * byte we are looking for.  Return 1 when we went past it, 0 otherwise. */
2298     q = base;
2299     while (q < p)
2300 	q += dbcs_ptr2len_check(q);
2301     return (q == p) ? 0 : 1;
2302 }
2303 
2304 #if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
2305 	|| defined(PROTO)
2306 /*
2307  * Special version of dbcs_head_off() that works for ScreenLines[], where
2308  * single-width DBCS_JPNU characters are stored separately.
2309  */
2310     int
2311 dbcs_screen_head_off(base, p)
2312     char_u	*base;
2313     char_u	*p;
2314 {
2315     char_u	*q;
2316 
2317     /* It can't be a trailing byte when not using DBCS, at the start of the
2318      * string or the previous byte can't start a double-byte.
2319      * For euc-jp an 0x8e byte in the previous cell always means we have a
2320      * lead byte in the current cell. */
2321     if (p <= base
2322 	    || (enc_dbcs == DBCS_JPNU && p[-1] == 0x8e)
2323 	    || MB_BYTE2LEN(p[-1]) == 1)
2324 	return 0;
2325 
2326     /* This is slow: need to start at the base and go forward until the
2327      * byte we are looking for.  Return 1 when we went past it, 0 otherwise.
2328      * For DBCS_JPNU look out for 0x8e, which means the second byte is not
2329      * stored as the next byte. */
2330     q = base;
2331     while (q < p)
2332     {
2333 	if (enc_dbcs == DBCS_JPNU && *q == 0x8e)
2334 	    ++q;
2335 	else
2336 	    q += dbcs_ptr2len_check(q);
2337     }
2338     return (q == p) ? 0 : 1;
2339 }
2340 #endif
2341 
2342     int
2343 utf_head_off(base, p)
2344     char_u	*base;
2345     char_u	*p;
2346 {
2347     char_u	*q;
2348     char_u	*s;
2349     int		c;
2350 #ifdef FEAT_ARABIC
2351     char_u	*j;
2352 #endif
2353 
2354     if (*p < 0x80)		/* be quick for ASCII */
2355 	return 0;
2356 
2357     /* Skip backwards over trailing bytes: 10xx.xxxx
2358      * Skip backwards again if on a composing char. */
2359     for (q = p; ; --q)
2360     {
2361 	/* Move s to the last byte of this char. */
2362 	for (s = q; (s[1] & 0xc0) == 0x80; ++s)
2363 	    ;
2364 	/* Move q to the first byte of this char. */
2365 	while (q > base && (*q & 0xc0) == 0x80)
2366 	    --q;
2367 	/* Check for illegal sequence. Do allow an illegal byte after where we
2368 	 * started. */
2369 	if (utf8len_tab[*q] != (int)(s - q + 1)
2370 				       && utf8len_tab[*q] != (int)(p - q + 1))
2371 	    return 0;
2372 
2373 	if (q <= base)
2374 	    break;
2375 
2376 	c = utf_ptr2char(q);
2377 	if (utf_iscomposing(c))
2378 	    continue;
2379 
2380 #ifdef FEAT_ARABIC
2381 	if (arabic_maycombine(c))
2382 	{
2383 	    /* Advance to get a sneak-peak at the next char */
2384 	    j = q;
2385 	    --j;
2386 	    /* Move j to the first byte of this char. */
2387 	    while (j > base && (*j & 0xc0) == 0x80)
2388 		--j;
2389 	    if (arabic_combine(utf_ptr2char(j), c))
2390 		continue;
2391 	}
2392 #endif
2393 	break;
2394     }
2395 
2396     return (int)(p - q);
2397 }
2398 
2399 /*
2400  * Return the offset from "p" to the first byte of a character.  When "p" is
2401  * at the start of a character 0 is returned, otherwise the offset to the next
2402  * character.  Can start anywhere in a stream of bytes.
2403  */
2404     int
2405 mb_off_next(base, p)
2406     char_u	*base;
2407     char_u	*p;
2408 {
2409     int		i;
2410     int		j;
2411 
2412     if (enc_utf8)
2413     {
2414 	if (*p < 0x80)		/* be quick for ASCII */
2415 	    return 0;
2416 
2417 	/* Find the next character that isn't 10xx.xxxx */
2418 	for (i = 0; (p[i] & 0xc0) == 0x80; ++i)
2419 	    ;
2420 	if (i > 0)
2421 	{
2422 	    /* Check for illegal sequence. */
2423 	    for (j = 0; p - j > base; ++j)
2424 		if ((p[-j] & 0xc0) != 0x80)
2425 		    break;
2426 	    if (utf8len_tab[p[-j]] != i + j)
2427 		return 0;
2428 	}
2429 	return i;
2430     }
2431 
2432     /* Only need to check if we're on a trail byte, it doesn't matter if we
2433      * want the offset to the next or current character. */
2434     return (*mb_head_off)(base, p);
2435 }
2436 
2437 /*
2438  * Return the offset from "p" to the last byte of the character it points
2439  * into.  Can start anywhere in a stream of bytes.
2440  */
2441     int
2442 mb_tail_off(base, p)
2443     char_u	*base;
2444     char_u	*p;
2445 {
2446     int		i;
2447     int		j;
2448 
2449     if (*p == NUL)
2450 	return 0;
2451 
2452     if (enc_utf8)
2453     {
2454 	/* Find the last character that is 10xx.xxxx */
2455 	for (i = 0; (p[i + 1] & 0xc0) == 0x80; ++i)
2456 	    ;
2457 	/* Check for illegal sequence. */
2458 	for (j = 0; p - j > base; ++j)
2459 	    if ((p[-j] & 0xc0) != 0x80)
2460 		break;
2461 	if (utf8len_tab[p[-j]] != i + j + 1)
2462 	    return 0;
2463 	return i;
2464     }
2465 
2466     /* It can't be the first byte if a double-byte when not using DBCS, at the
2467      * end of the string or the byte can't start a double-byte. */
2468     if (enc_dbcs == 0 || p[1] == NUL || MB_BYTE2LEN(*p) == 1)
2469 	return 0;
2470 
2471     /* Return 1 when on the lead byte, 0 when on the tail byte. */
2472     return 1 - dbcs_head_off(base, p);
2473 }
2474 
2475 #if defined(FEAT_GUI) || defined(PROTO)
2476 /*
2477  * Special version of mb_tail_off() for use in ScreenLines[].
2478  */
2479     int
2480 dbcs_screen_tail_off(base, p)
2481     char_u	*base;
2482     char_u	*p;
2483 {
2484     /* It can't be the first byte if a double-byte when not using DBCS, at the
2485      * end of the string or the byte can't start a double-byte.
2486      * For euc-jp an 0x8e byte always means we have a lead byte in the current
2487      * cell. */
2488     if (*p == NUL || p[1] == NUL
2489 	    || (enc_dbcs == DBCS_JPNU && *p == 0x8e)
2490 	    || MB_BYTE2LEN(*p) == 1)
2491 	return 0;
2492 
2493     /* Return 1 when on the lead byte, 0 when on the tail byte. */
2494     return 1 - dbcs_screen_head_off(base, p);
2495 }
2496 #endif
2497 
2498 /*
2499  * If the cursor moves on an trail byte, set the cursor on the lead byte.
2500  * Thus it moves left if necessary.
2501  * Return TRUE when the cursor was adjusted.
2502  */
2503     void
2504 mb_adjust_cursor()
2505 {
2506     mb_adjustpos(&curwin->w_cursor);
2507 }
2508 
2509 /*
2510  * Adjust position "*lp" to point to the first byte of a multi-byte character.
2511  * If it points to a tail byte it's moved backwards to the head byte.
2512  */
2513     void
2514 mb_adjustpos(lp)
2515     pos_T	*lp;
2516 {
2517     char_u	*p;
2518 
2519     if (lp->col > 0
2520 #ifdef FEAT_VIRTUALEDIT
2521 	    || lp->coladd > 1
2522 #endif
2523 	    )
2524     {
2525 	p = ml_get(lp->lnum);
2526 	lp->col -= (*mb_head_off)(p, p + lp->col);
2527 #ifdef FEAT_VIRTUALEDIT
2528 	/* Reset "coladd" when the cursor would be on the right half of a
2529 	 * double-wide character. */
2530 	if (lp->coladd == 1
2531 		&& p[lp->col] != TAB
2532 		&& vim_isprintc((*mb_ptr2char)(p + lp->col))
2533 		&& ptr2cells(p + lp->col) > 1)
2534 	    lp->coladd = 0;
2535 #endif
2536     }
2537 }
2538 
2539 /*
2540  * Return a pointer to the character before "*p", if there is one.
2541  */
2542     char_u *
2543 mb_prevptr(line, p)
2544     char_u *line;	/* start of the string */
2545     char_u *p;
2546 {
2547     if (p > line)
2548 	p = p - (*mb_head_off)(line, p - 1) - 1;
2549     return p;
2550 }
2551 
2552 /*
2553  * Return the character length of "str".  multi-byte characters counts as one.
2554  */
2555     int
2556 mb_charlen(str)
2557     char_u	*str;
2558 {
2559     int count;
2560 
2561     if (str == NULL)
2562 	return 0;
2563 
2564     for (count = 0; *str != NUL; count++)
2565 	str += (*mb_ptr2len_check)(str);
2566 
2567     return count;
2568 }
2569 
2570 /*
2571  * Try to un-escape a multi-byte character.
2572  * Used for the "to" and "from" part of a mapping.
2573  * Return the un-escaped string if it is a multi-byte character, and advance
2574  * "pp" to just after the bytes that formed it.
2575  * Return NULL if no multi-byte char was found.
2576  */
2577     char_u *
2578 mb_unescape(pp)
2579     char_u **pp;
2580 {
2581     static char_u	buf[MB_MAXBYTES + 1];
2582     int			n, m = 0;
2583     char_u		*str = *pp;
2584 
2585     /* Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI
2586      * KS_EXTRA KE_CSI to CSI. */
2587     for (n = 0; str[n] != NUL && m <= MB_MAXBYTES; ++n)
2588     {
2589 	if (str[n] == K_SPECIAL
2590 		&& str[n + 1] == KS_SPECIAL
2591 		&& str[n + 2] == KE_FILLER)
2592 	{
2593 	    buf[m++] = K_SPECIAL;
2594 	    n += 2;
2595 	}
2596 # ifdef FEAT_GUI
2597 	else if (str[n] == CSI
2598 		&& str[n + 1] == KS_EXTRA
2599 		&& str[n + 2] == (int)KE_CSI)
2600 	{
2601 	    buf[m++] = CSI;
2602 	    n += 2;
2603 	}
2604 # endif
2605 	else if (str[n] == K_SPECIAL
2606 # ifdef FEAT_GUI
2607 		|| str[n] == CSI
2608 # endif
2609 		)
2610 	    break;		/* a special key can't be a multibyte char */
2611 	else
2612 	    buf[m++] = str[n];
2613 	buf[m] = NUL;
2614 
2615 	/* Return a multi-byte character if it's found.  An illegal sequence
2616 	 * will result in a 1 here. */
2617 	if ((*mb_ptr2len_check)(buf) > 1)
2618 	{
2619 	    *pp = str + n + 1;
2620 	    return buf;
2621 	}
2622     }
2623     return NULL;
2624 }
2625 
2626 /*
2627  * Return TRUE if the character at "row"/"col" on the screen is the left side
2628  * of a double-width character.
2629  * Caller must make sure "row" and "col" are not invalid!
2630  */
2631     int
2632 mb_lefthalve(row, col)
2633     int	    row;
2634     int	    col;
2635 {
2636 #ifdef FEAT_HANGULIN
2637     if (composing_hangul)
2638 	return TRUE;
2639 #endif
2640     if (enc_dbcs != 0)
2641 	return dbcs_off2cells(LineOffset[row] + col) > 1;
2642     if (enc_utf8)
2643 	return (col + 1 < Columns
2644 		&& ScreenLines[LineOffset[row] + col + 1] == 0);
2645     return FALSE;
2646 }
2647 
2648 # if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
2649 	|| defined(PROTO)
2650 /*
2651  * Correct a position on the screen, if it's the right halve of a double-wide
2652  * char move it to the left halve.  Returns the corrected column.
2653  */
2654     int
2655 mb_fix_col(col, row)
2656     int		col;
2657     int		row;
2658 {
2659     col = check_col(col);
2660     row = check_row(row);
2661     if (has_mbyte && ScreenLines != NULL && col > 0
2662 	    && ((enc_dbcs
2663 		    && ScreenLines[LineOffset[row] + col] != NUL
2664 		    && dbcs_screen_head_off(ScreenLines + LineOffset[row],
2665 					 ScreenLines + LineOffset[row] + col))
2666 		|| (enc_utf8 && ScreenLines[LineOffset[row] + col] == 0)))
2667 	--col;
2668     return col;
2669 }
2670 # endif
2671 #endif
2672 
2673 #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) || defined(PROTO)
2674 static int enc_alias_search __ARGS((char_u *name));
2675 
2676 /*
2677  * Skip the Vim specific head of a 'encoding' name.
2678  */
2679     char_u *
2680 enc_skip(p)
2681     char_u	*p;
2682 {
2683     if (STRNCMP(p, "2byte-", 6) == 0)
2684 	return p + 6;
2685     if (STRNCMP(p, "8bit-", 5) == 0)
2686 	return p + 5;
2687     return p;
2688 }
2689 
2690 /*
2691  * Find the canonical name for encoding "enc".
2692  * When the name isn't recognized, returns "enc" itself, but with all lower
2693  * case characters and '_' replaced with '-'.
2694  * Returns an allocated string.  NULL for out-of-memory.
2695  */
2696     char_u *
2697 enc_canonize(enc)
2698     char_u	*enc;
2699 {
2700     char_u	*r;
2701     char_u	*p, *s;
2702     int		i;
2703 
2704     /* copy "enc" to allocted memory, with room for two '-' */
2705     r = alloc((unsigned)(STRLEN(enc) + 3));
2706     if (r != NULL)
2707     {
2708 	/* Make it all lower case and replace '_' with '-'. */
2709 	p = r;
2710 	for (s = enc; *s != NUL; ++s)
2711 	{
2712 	    if (*s == '_')
2713 		*p++ = '-';
2714 	    else
2715 		*p++ = TOLOWER_ASC(*s);
2716 	}
2717 	*p = NUL;
2718 
2719 	/* Skip "2byte-" and "8bit-". */
2720 	p = enc_skip(r);
2721 
2722 	/* "iso8859" -> "iso-8859" */
2723 	if (STRNCMP(p, "iso8859", 7) == 0)
2724 	{
2725 	    mch_memmove(p + 4, p + 3, STRLEN(p + 2));
2726 	    p[3] = '-';
2727 	}
2728 
2729 	/* "iso-8859n" -> "iso-8859-n" */
2730 	if (STRNCMP(p, "iso-8859", 8) == 0 && p[8] != '-')
2731 	{
2732 	    mch_memmove(p + 9, p + 8, STRLEN(p + 7));
2733 	    p[8] = '-';
2734 	}
2735 
2736 	/* "latin-N" -> "latinN" */
2737 	if (STRNCMP(p, "latin-", 6) == 0)
2738 	    mch_memmove(p + 5, p + 6, STRLEN(p + 5));
2739 
2740 	if (enc_canon_search(p) >= 0)
2741 	{
2742 	    /* canonical name can be used unmodified */
2743 	    if (p != r)
2744 		mch_memmove(r, p, STRLEN(p) + 1);
2745 	}
2746 	else if ((i = enc_alias_search(p)) >= 0)
2747 	{
2748 	    /* alias recognized, get canonical name */
2749 	    vim_free(r);
2750 	    r = vim_strsave((char_u *)enc_canon_table[i].name);
2751 	}
2752     }
2753     return r;
2754 }
2755 
2756 /*
2757  * Search for an encoding alias of "name".
2758  * Returns -1 when not found.
2759  */
2760     static int
2761 enc_alias_search(name)
2762     char_u	*name;
2763 {
2764     int		i;
2765 
2766     for (i = 0; enc_alias_table[i].name != NULL; ++i)
2767 	if (STRCMP(name, enc_alias_table[i].name) == 0)
2768 	    return enc_alias_table[i].canon;
2769     return -1;
2770 }
2771 #endif
2772 
2773 #if defined(FEAT_MBYTE) || defined(PROTO)
2774 
2775 #ifdef HAVE_LANGINFO_H
2776 # include <langinfo.h>
2777 #endif
2778 
2779 /*
2780  * Get the canonicalized encoding of the current locale.
2781  * Returns an allocated string when successful, NULL when not.
2782  */
2783     char_u *
2784 enc_locale()
2785 {
2786 #ifndef WIN3264
2787     char	*s;
2788     char	*p;
2789     int		i;
2790 #endif
2791     char	buf[50];
2792 #ifdef WIN3264
2793     long	acp = GetACP();
2794 
2795     if (acp == 1200)
2796 	STRCPY(buf, "ucs-2le");
2797     else if (acp == 1252)
2798 	STRCPY(buf, "latin1");
2799     else
2800 	sprintf(buf, "cp%ld", acp);
2801 #else
2802 # ifdef HAVE_NL_LANGINFO_CODESET
2803     if ((s = nl_langinfo(CODESET)) == NULL || *s == NUL)
2804 # endif
2805 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
2806 	if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL)
2807 # endif
2808 	    if ((s = getenv("LC_ALL")) == NULL || *s == NUL)
2809 		if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL)
2810 		    s = getenv("LANG");
2811 
2812     if (s == NULL || *s == NUL)
2813 	return FAIL;
2814 
2815     /* The most generic locale format is:
2816      * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
2817      * If there is a '.' remove the part before it.
2818      * if there is something after the codeset, remove it.
2819      * Make the name lowercase and replace '_' with '-'.
2820      * Exception: "ja_JP.EUC" == "euc-jp", "zh_CN.EUC" = "euc-cn",
2821      * "ko_KR.EUC" == "euc-kr"
2822      */
2823     if ((p = (char *)vim_strchr((char_u *)s, '.')) != NULL)
2824     {
2825 	if (p > s + 2 && STRNICMP(p + 1, "EUC", 3) == 0
2826 			&& !isalnum((int)p[4]) && p[4] != '-' && p[-3] == '_')
2827 	{
2828 	    /* copy "XY.EUC" to "euc-XY" to buf[10] */
2829 	    STRCPY(buf + 10, "euc-");
2830 	    buf[14] = p[-2];
2831 	    buf[15] = p[-1];
2832 	    buf[16] = 0;
2833 	    s = buf + 10;
2834 	}
2835 	else
2836 	    s = p + 1;
2837     }
2838     for (i = 0; s[i] != NUL && i < sizeof(buf) - 1; ++i)
2839     {
2840 	if (s[i] == '_' || s[i] == '-')
2841 	    buf[i] = '-';
2842 	else if (isalnum((int)s[i]))
2843 	    buf[i] = TOLOWER_ASC(s[i]);
2844 	else
2845 	    break;
2846     }
2847     buf[i] = NUL;
2848 #endif
2849 
2850     return enc_canonize((char_u *)buf);
2851 }
2852 
2853 #if defined(WIN3264) || defined(PROTO)
2854 /*
2855  * Convert an encoding name to an MS-Windows codepage.
2856  * Returns zero if no codepage can be figured out.
2857  */
2858     int
2859 encname2codepage(name)
2860     char_u	*name;
2861 {
2862     int		cp;
2863     char_u	*p = name;
2864     int		idx;
2865 
2866     if (STRNCMP(p, "8bit-", 5) == 0)
2867 	p += 5;
2868     else if (STRNCMP(p_enc, "2byte-", 6) == 0)
2869 	p += 6;
2870 
2871     if (p[0] == 'c' && p[1] == 'p')
2872 	cp = atoi(p + 2);
2873     else if ((idx = enc_canon_search(p)) >= 0)
2874 	cp = enc_canon_table[idx].codepage;
2875     else
2876 	return 0;
2877     if (IsValidCodePage(cp))
2878 	return cp;
2879     return 0;
2880 }
2881 #endif
2882 
2883 # if defined(USE_ICONV) || defined(PROTO)
2884 
2885 static char_u *iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp));
2886 
2887 /*
2888  * Call iconv_open() with a check if iconv() works properly (there are broken
2889  * versions).
2890  * Returns (void *)-1 if failed.
2891  * (should return iconv_t, but that causes problems with prototypes).
2892  */
2893     void *
2894 my_iconv_open(to, from)
2895     char_u	*to;
2896     char_u	*from;
2897 {
2898     iconv_t	fd;
2899 #define ICONV_TESTLEN 400
2900     char_u	tobuf[ICONV_TESTLEN];
2901     char	*p;
2902     size_t	tolen;
2903     static int	iconv_ok = -1;
2904 
2905     if (iconv_ok == FALSE)
2906 	return (void *)-1;	/* detected a broken iconv() previously */
2907 
2908 #ifdef DYNAMIC_ICONV
2909     /* Check if the iconv.dll can be found. */
2910     if (!iconv_enabled(TRUE))
2911 	return (void *)-1;
2912 #endif
2913 
2914     fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
2915 
2916     if (fd != (iconv_t)-1 && iconv_ok == -1)
2917     {
2918 	/*
2919 	 * Do a dummy iconv() call to check if it actually works.  There is a
2920 	 * version of iconv() on Linux that is broken.  We can't ignore it,
2921 	 * because it's wide-spread.  The symptoms are that after outputting
2922 	 * the initial shift state the "to" pointer is NULL and conversion
2923 	 * stops for no apparent reason after about 8160 characters.
2924 	 */
2925 	p = (char *)tobuf;
2926 	tolen = ICONV_TESTLEN;
2927 	(void)iconv(fd, NULL, NULL, &p, &tolen);
2928 	if (p == NULL)
2929 	{
2930 	    iconv_ok = FALSE;
2931 	    iconv_close(fd);
2932 	    fd = (iconv_t)-1;
2933 	}
2934 	else
2935 	    iconv_ok = TRUE;
2936     }
2937 
2938     return (void *)fd;
2939 }
2940 
2941 /*
2942  * Convert the string "str[slen]" with iconv().
2943  * If "unconvlenp" is not NULL handle the string ending in an incomplete
2944  * sequence and set "*unconvlenp" to the length of it.
2945  * Returns the converted string in allocated memory.  NULL for an error.
2946  */
2947     static char_u *
2948 iconv_string(vcp, str, slen, unconvlenp)
2949     vimconv_T	*vcp;
2950     char_u	*str;
2951     int		slen;
2952     int		*unconvlenp;
2953 {
2954     const char	*from;
2955     size_t	fromlen;
2956     char	*to;
2957     size_t	tolen;
2958     size_t	len = 0;
2959     size_t	done = 0;
2960     char_u	*result = NULL;
2961     char_u	*p;
2962     int		l;
2963 
2964     from = (char *)str;
2965     fromlen = slen;
2966     for (;;)
2967     {
2968 	if (len == 0 || ICONV_ERRNO == ICONV_E2BIG)
2969 	{
2970 	    /* Allocate enough room for most conversions.  When re-allocating
2971 	     * increase the buffer size. */
2972 	    len = len + fromlen * 2 + 40;
2973 	    p = alloc((unsigned)len);
2974 	    if (p != NULL && done > 0)
2975 		mch_memmove(p, result, done);
2976 	    vim_free(result);
2977 	    result = p;
2978 	    if (result == NULL)	/* out of memory */
2979 		break;
2980 	}
2981 
2982 	to = (char *)result + done;
2983 	tolen = len - done - 2;
2984 	/* Avoid a warning for systems with a wrong iconv() prototype by
2985 	 * casting the second argument to void *. */
2986 	if (iconv(vcp->vc_fd, (void *)&from, &fromlen, &to, &tolen)
2987 								!= (size_t)-1)
2988 	{
2989 	    /* Finished, append a NUL. */
2990 	    *to = NUL;
2991 	    break;
2992 	}
2993 
2994 	/* Check both ICONV_EINVAL and EINVAL, because the dynamically loaded
2995 	 * iconv library may use one of them. */
2996 	if (!vcp->vc_fail && unconvlenp != NULL
2997 		&& (ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL))
2998 	{
2999 	    /* Handle an incomplete sequence at the end. */
3000 	    *to = NUL;
3001 	    *unconvlenp = fromlen;
3002 	    break;
3003 	}
3004 
3005 	/* Check both ICONV_EILSEQ and EILSEQ, because the dynamically loaded
3006 	 * iconv library may use one of them. */
3007 	else if (!vcp->vc_fail
3008 		&& (ICONV_ERRNO == ICONV_EILSEQ || ICONV_ERRNO == EILSEQ
3009 		    || ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL))
3010 	{
3011 	    /* Can't convert: insert a '?' and skip a character.  This assumes
3012 	     * conversion from 'encoding' to something else.  In other
3013 	     * situations we don't know what to skip anyway. */
3014 	    *to++ = '?';
3015 	    if ((*mb_ptr2cells)((char_u *)from) > 1)
3016 		*to++ = '?';
3017 	    l = (*mb_ptr2len_check)((char_u *)from);
3018 	    from += l;
3019 	    fromlen -= l;
3020 	}
3021 	else if (ICONV_ERRNO != ICONV_E2BIG)
3022 	{
3023 	    /* conversion failed */
3024 	    vim_free(result);
3025 	    result = NULL;
3026 	    break;
3027 	}
3028 	/* Not enough room or skipping illegal sequence. */
3029 	done = to - (char *)result;
3030     }
3031     return result;
3032 }
3033 
3034 #  if defined(DYNAMIC_ICONV) || defined(PROTO)
3035 /*
3036  * Dynamically load the "iconv.dll" on Win32.
3037  */
3038 
3039 #ifndef DYNAMIC_ICONV	    /* just generating prototypes */
3040 # define HINSTANCE int
3041 #endif
3042 HINSTANCE hIconvDLL = 0;
3043 HINSTANCE hMsvcrtDLL = 0;
3044 
3045 #  ifndef DYNAMIC_ICONV_DLL
3046 #   define DYNAMIC_ICONV_DLL "iconv.dll"
3047 #   define DYNAMIC_ICONV_DLL_ALT "libiconv.dll"
3048 #  endif
3049 #  ifndef DYNAMIC_MSVCRT_DLL
3050 #   define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
3051 #  endif
3052 
3053 /*
3054  * Try opening the iconv.dll and return TRUE if iconv() can be used.
3055  */
3056     int
3057 iconv_enabled(verbose)
3058     int		verbose;
3059 {
3060     if (hIconvDLL != 0 && hMsvcrtDLL != 0)
3061 	return TRUE;
3062     hIconvDLL = LoadLibrary(DYNAMIC_ICONV_DLL);
3063     if (hIconvDLL == 0)		/* sometimes it's called libiconv.dll */
3064 	hIconvDLL = LoadLibrary(DYNAMIC_ICONV_DLL_ALT);
3065     if (hIconvDLL != 0)
3066 	hMsvcrtDLL = LoadLibrary(DYNAMIC_MSVCRT_DLL);
3067     if (hIconvDLL == 0 || hMsvcrtDLL == 0)
3068     {
3069 	/* Only give the message when 'verbose' is set, otherwise it might be
3070 	 * done whenever a conversion is attempted. */
3071 	if (verbose && p_verbose > 0)
3072 	    EMSG2(_(e_loadlib),
3073 		    hIconvDLL == 0 ? DYNAMIC_ICONV_DLL : DYNAMIC_MSVCRT_DLL);
3074 	iconv_end();
3075 	return FALSE;
3076     }
3077 
3078     *((FARPROC*)&iconv)		= GetProcAddress(hIconvDLL, "libiconv");
3079     *((FARPROC*)&iconv_open)	= GetProcAddress(hIconvDLL, "libiconv_open");
3080     *((FARPROC*)&iconv_close)	= GetProcAddress(hIconvDLL, "libiconv_close");
3081     *((FARPROC*)&iconvctl)	= GetProcAddress(hIconvDLL, "libiconvctl");
3082     *((FARPROC*)&iconv_errno)	= GetProcAddress(hMsvcrtDLL, "_errno");
3083     if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
3084 	    || iconvctl == NULL || iconv_errno == NULL)
3085     {
3086 	iconv_end();
3087 	if (verbose && p_verbose > 0)
3088 	    EMSG2(_(e_loadfunc), "for libiconv");
3089 	return FALSE;
3090     }
3091     return TRUE;
3092 }
3093 
3094     void
3095 iconv_end()
3096 {
3097     /* Don't use iconv() when inputting or outputting characters. */
3098     if (input_conv.vc_type == CONV_ICONV)
3099 	convert_setup(&input_conv, NULL, NULL);
3100     if (output_conv.vc_type == CONV_ICONV)
3101 	convert_setup(&output_conv, NULL, NULL);
3102 
3103     if (hIconvDLL != 0)
3104 	FreeLibrary(hIconvDLL);
3105     if (hMsvcrtDLL != 0)
3106 	FreeLibrary(hMsvcrtDLL);
3107     hIconvDLL = 0;
3108     hMsvcrtDLL = 0;
3109 }
3110 #  endif /* DYNAMIC_ICONV */
3111 # endif /* USE_ICONV */
3112 
3113 #endif /* FEAT_MBYTE */
3114 
3115 #if defined(FEAT_XIM) || defined(PROTO)
3116 
3117 # ifdef FEAT_GUI_GTK
3118 static int xim_has_preediting INIT(= FALSE);  /* IM current status */
3119 
3120 /*
3121  * Set preedit_start_col to the current cursor position.
3122  */
3123     static void
3124 init_preedit_start_col(void)
3125 {
3126     if (State & CMDLINE)
3127 	preedit_start_col = cmdline_getvcol_cursor();
3128     else if (curwin != NULL)
3129 	getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL);
3130     /* Prevent that preediting marks the buffer as changed. */
3131     xim_changed_while_preediting = curbuf->b_changed;
3132 }
3133 # endif
3134 
3135 # if defined(HAVE_GTK2) && !defined(PROTO)
3136 
3137 static int im_is_active	       = FALSE;	/* IM is enabled for current mode    */
3138 static int im_preedit_cursor   = 0;	/* cursor offset in characters       */
3139 static int im_preedit_trailing = 0;	/* number of characters after cursor */
3140 
3141 static unsigned long im_commit_handler_id  = 0;
3142 static unsigned int  im_activatekey_keyval = GDK_VoidSymbol;
3143 static unsigned int  im_activatekey_state  = 0;
3144 
3145     void
3146 im_set_active(int active)
3147 {
3148     int was_active;
3149 
3150     was_active = !!im_is_active;
3151     im_is_active = (active && !p_imdisable);
3152 
3153     if (im_is_active != was_active)
3154 	xim_reset();
3155 }
3156 
3157     void
3158 xim_set_focus(int focus)
3159 {
3160     if (xic != NULL)
3161     {
3162 	if (focus)
3163 	    gtk_im_context_focus_in(xic);
3164 	else
3165 	    gtk_im_context_focus_out(xic);
3166     }
3167 }
3168 
3169     void
3170 im_set_position(int row, int col)
3171 {
3172     if (xic != NULL)
3173     {
3174 	GdkRectangle area;
3175 
3176 	area.x = FILL_X(col);
3177 	area.y = FILL_Y(row);
3178 	area.width  = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1);
3179 	area.height = gui.char_height;
3180 
3181 	gtk_im_context_set_cursor_location(xic, &area);
3182     }
3183 }
3184 
3185 #  if 0 || defined(PROTO) /* apparently only used in gui_x11.c */
3186     void
3187 xim_set_preedit(void)
3188 {
3189     im_set_position(gui.row, gui.col);
3190 }
3191 #  endif
3192 
3193     static void
3194 im_add_to_input(char_u *str, int len)
3195 {
3196     /* Convert from 'termencoding' (always "utf-8") to 'encoding' */
3197     if (input_conv.vc_type != CONV_NONE)
3198     {
3199 	str = string_convert(&input_conv, str, &len);
3200 	g_return_if_fail(str != NULL);
3201     }
3202 
3203     add_to_input_buf_csi(str, len);
3204 
3205     if (input_conv.vc_type != CONV_NONE)
3206 	vim_free(str);
3207 
3208     if (p_mh) /* blank out the pointer if necessary */
3209 	gui_mch_mousehide(TRUE);
3210 }
3211 
3212     static void
3213 im_delete_preedit(void)
3214 {
3215     char_u bskey[]  = {CSI, 'k', 'b'};
3216     char_u delkey[] = {CSI, 'k', 'D'};
3217 
3218     if (State & NORMAL)
3219     {
3220 	im_preedit_cursor = 0;
3221 	return;
3222     }
3223     for (; im_preedit_cursor > 0; --im_preedit_cursor)
3224 	add_to_input_buf(bskey, (int)sizeof(bskey));
3225 
3226     for (; im_preedit_trailing > 0; --im_preedit_trailing)
3227 	add_to_input_buf(delkey, (int)sizeof(delkey));
3228 }
3229 
3230     static void
3231 im_correct_cursor(int num_move_back)
3232 {
3233     char_u backkey[] = {CSI, 'k', 'l'};
3234 
3235     if (State & NORMAL)
3236 	return;
3237 #  ifdef FEAT_RIGHTLEFT
3238     if ((State & CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl)
3239 	backkey[2] = 'r';
3240 #  endif
3241     for (; num_move_back > 0; --num_move_back)
3242 	add_to_input_buf(backkey, (int)sizeof(backkey));
3243 }
3244 
3245 static int xim_expected_char = NUL;
3246 static int xim_ignored_char = FALSE;
3247 
3248 /*
3249  * Update the mode and cursor while in an IM callback.
3250  */
3251     static void
3252 im_show_info(void)
3253 {
3254     int	    old_vgetc_busy;
3255     old_vgetc_busy = vgetc_busy;
3256     vgetc_busy = TRUE;
3257     showmode();
3258     vgetc_busy = old_vgetc_busy;
3259     setcursor();
3260     out_flush();
3261 }
3262 
3263 /*
3264  * Callback invoked when the user finished preediting.
3265  * Put the final string into the input buffer.
3266  */
3267 /*ARGSUSED0*/
3268     static void
3269 im_commit_cb(GtkIMContext *context, const gchar *str, gpointer data)
3270 {
3271     int	slen = (int)STRLEN(str);
3272     int	add_to_input = TRUE;
3273     int	clen;
3274     int	len = slen;
3275     int	commit_with_preedit = TRUE;
3276     char_u	*im_str, *p;
3277 
3278 #ifdef XIM_DEBUG
3279     xim_log("im_commit_cb(): %s\n", str);
3280 #endif
3281 
3282     /* The imhangul module doesn't reset the preedit string before
3283      * committing.  Call im_delete_preedit() to work around that. */
3284     im_delete_preedit();
3285 
3286     /* Indicate that preediting has finished. */
3287     if (preedit_start_col == MAXCOL)
3288     {
3289 	init_preedit_start_col();
3290 	commit_with_preedit = FALSE;
3291     }
3292 
3293     /* The thing which setting "preedit_start_col" to MAXCOL means that
3294      * "preedit_start_col" will be set forcely when calling
3295      * preedit_changed_cb() next time.
3296      * "preedit_start_col" should not reset with MAXCOL on this part. Vim
3297      * is simulating the preediting by using add_to_input_str(). when
3298      * preedit begin immediately before committed, the typebuf is not
3299      * flushed to screen, then it can't get correct "preedit_start_col".
3300      * Thus, it should calculate the cells by adding cells of the committed
3301      * string. */
3302     if (input_conv.vc_type != CONV_NONE)
3303     {
3304 	im_str = string_convert(&input_conv, (char_u *)str, &len);
3305 	g_return_if_fail(im_str != NULL);
3306     }
3307     else
3308 	im_str = (char_u *)str;
3309     clen = 0;
3310     for (p = im_str; p < im_str + len; p += (*mb_ptr2len_check)(p))
3311 	clen += (*mb_ptr2cells)(p);
3312     if (input_conv.vc_type != CONV_NONE)
3313 	vim_free(im_str);
3314     preedit_start_col += clen;
3315 
3316     /* Is this a single character that matches a keypad key that's just
3317      * been pressed?  If so, we don't want it to be entered as such - let
3318      * us carry on processing the raw keycode so that it may be used in
3319      * mappings as <kSomething>. */
3320     if (xim_expected_char != NUL)
3321     {
3322 	/* We're currently processing a keypad or other special key */
3323 	if (slen == 1 && str[0] == xim_expected_char)
3324 	{
3325 	    /* It's a match - don't do it here */
3326 	    xim_ignored_char = TRUE;
3327 	    add_to_input = FALSE;
3328 	}
3329 	else
3330 	{
3331 	    /* Not a match */
3332 	    xim_ignored_char = FALSE;
3333 	}
3334     }
3335 
3336     if (add_to_input)
3337 	im_add_to_input((char_u *)str, slen);
3338 
3339     /* Inserting chars while "im_is_active" is set does not cause a change of
3340      * buffer.  When the chars are committed the buffer must be marked as
3341      * changed. */
3342     if (!commit_with_preedit)
3343 	preedit_start_col = MAXCOL;
3344 
3345     /* This flag is used in changed() at next call. */
3346     xim_changed_while_preediting = TRUE;
3347 
3348     if (gtk_main_level() > 0)
3349 	gtk_main_quit();
3350 }
3351 
3352 /*
3353  * Callback invoked after start to the preedit.
3354  */
3355 /*ARGSUSED*/
3356     static void
3357 im_preedit_start_cb(GtkIMContext *context, gpointer data)
3358 {
3359 #ifdef XIM_DEBUG
3360     xim_log("im_preedit_start_cb()\n");
3361 #endif
3362 
3363     im_is_active = TRUE;
3364     gui_update_cursor(TRUE, FALSE);
3365 }
3366 
3367 /*
3368  * Callback invoked after end to the preedit.
3369  */
3370 /*ARGSUSED*/
3371     static void
3372 im_preedit_end_cb(GtkIMContext *context, gpointer data)
3373 {
3374 #ifdef XIM_DEBUG
3375     xim_log("im_preedit_end_cb()\n");
3376 #endif
3377     im_delete_preedit();
3378 
3379     /* Indicate that preediting has finished */
3380     preedit_start_col = MAXCOL;
3381     xim_has_preediting = FALSE;
3382 
3383     im_is_active = FALSE;
3384     gui_update_cursor(TRUE, FALSE);
3385     im_show_info();
3386 }
3387 
3388 /*
3389  * Callback invoked after changes to the preedit string.  If the preedit
3390  * string was empty before, remember the preedit start column so we know
3391  * where to apply feedback attributes.  Delete the previous preedit string
3392  * if there was one, save the new preedit cursor offset, and put the new
3393  * string into the input buffer.
3394  *
3395  * TODO: The pragmatic "put into input buffer" approach used here has
3396  *       several fundamental problems:
3397  *
3398  * - The characters in the preedit string are subject to remapping.
3399  *   That's broken, only the finally committed string should be remapped.
3400  *
3401  * - There is a race condition involved:  The retrieved value for the
3402  *   current cursor position will be wrong if any unprocessed characters
3403  *   are still queued in the input buffer.
3404  *
3405  * - Due to the lack of synchronization between the file buffer in memory
3406  *   and any typed characters, it's practically impossible to implement the
3407  *   "retrieve_surrounding" and "delete_surrounding" signals reliably.  IM
3408  *   modules for languages such as Thai are likely to rely on this feature
3409  *   for proper operation.
3410  *
3411  * Conclusions:  I think support for preediting needs to be moved to the
3412  * core parts of Vim.  Ideally, until it has been committed, the preediting
3413  * string should only be displayed and not affect the buffer content at all.
3414  * The question how to deal with the synchronization issue still remains.
3415  * Circumventing the input buffer is probably not desirable.  Anyway, I think
3416  * implementing "retrieve_surrounding" is the only hard problem.
3417  *
3418  * One way to solve all of this in a clean manner would be to queue all key
3419  * press/release events "as is" in the input buffer, and apply the IM filtering
3420  * at the receiving end of the queue.  This, however, would have a rather large
3421  * impact on the code base.  If there is an easy way to force processing of all
3422  * remaining input from within the "retrieve_surrounding" signal handler, this
3423  * might not be necessary.  Gotta ask on vim-dev for opinions.
3424  */
3425 /*ARGSUSED1*/
3426     static void
3427 im_preedit_changed_cb(GtkIMContext *context, gpointer data)
3428 {
3429     char    *preedit_string = NULL;
3430     int	    cursor_index    = 0;
3431     int	    num_move_back   = 0;
3432     char_u  *str;
3433     char_u  *p;
3434     int	    i;
3435 
3436     gtk_im_context_get_preedit_string(context,
3437 				      &preedit_string, NULL,
3438 				      &cursor_index);
3439 
3440 #ifdef XIM_DEBUG
3441     xim_log("im_preedit_changed_cb(): %s\n", preedit_string);
3442 #endif
3443 
3444     g_return_if_fail(preedit_string != NULL); /* just in case */
3445 
3446     /* If preedit_start_col is MAXCOL set it to the current cursor position. */
3447     if (preedit_start_col == MAXCOL && preedit_string[0] != '\0')
3448     {
3449 	xim_has_preediting = TRUE;
3450 
3451 	/* Urgh, this breaks if the input buffer isn't empty now */
3452 	init_preedit_start_col();
3453     }
3454     else if (cursor_index == 0 && preedit_string[0] == '\0')
3455     {
3456 	if (preedit_start_col == MAXCOL)
3457 	    xim_has_preediting = FALSE;
3458 
3459 	/* If at the start position (after typing backspace)
3460 	 * preedit_start_col must be reset. */
3461 	preedit_start_col = MAXCOL;
3462     }
3463 
3464     im_delete_preedit();
3465 
3466     /*
3467      * Compute the end of the preediting area: "preedit_end_col".
3468      * According to the documentation of gtk_im_context_get_preedit_string(),
3469      * the cursor_pos output argument returns the offset in bytes.  This is
3470      * unfortunately not true -- real life shows the offset is in characters,
3471      * and the GTK+ source code agrees with me.  Will file a bug later.
3472      */
3473     if (preedit_start_col != MAXCOL)
3474 	preedit_end_col = preedit_start_col;
3475     str = (char_u *)preedit_string;
3476     for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i)
3477     {
3478 	int is_composing;
3479 
3480 	is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p)));
3481 	/*
3482 	 * These offsets are used as counters when generating <BS> and <Del>
3483 	 * to delete the preedit string.  So don't count composing characters
3484 	 * unless 'delcombine' is enabled.
3485 	 */
3486 	if (!is_composing || p_deco)
3487 	{
3488 	    if (i < cursor_index)
3489 		++im_preedit_cursor;
3490 	    else
3491 		++im_preedit_trailing;
3492 	}
3493 	if (!is_composing && i >= cursor_index)
3494 	{
3495 	    /* This is essentially the same as im_preedit_trailing, except
3496 	     * composing characters are not counted even if p_deco is set. */
3497 	    ++num_move_back;
3498 	}
3499 	if (preedit_start_col != MAXCOL)
3500 	    preedit_end_col += utf_ptr2cells(p);
3501     }
3502 
3503     if (p > str)
3504     {
3505 	im_add_to_input(str, (int)(p - str));
3506 	im_correct_cursor(num_move_back);
3507     }
3508 
3509     g_free(preedit_string);
3510 
3511     if (gtk_main_level() > 0)
3512 	gtk_main_quit();
3513 }
3514 
3515 /*
3516  * Translate the Pango attributes at iter to Vim highlighting attributes.
3517  * Ignore attributes not supported by Vim highlighting.  This shouldn't have
3518  * too much impact -- right now we handle even more attributes than necessary
3519  * for the IM modules I tested with.
3520  */
3521     static int
3522 translate_pango_attributes(PangoAttrIterator *iter)
3523 {
3524     PangoAttribute  *attr;
3525     int		    char_attr = HL_NORMAL;
3526 
3527     attr = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
3528     if (attr != NULL && ((PangoAttrInt *)attr)->value
3529 						 != (int)PANGO_UNDERLINE_NONE)
3530 	char_attr |= HL_UNDERLINE;
3531 
3532     attr = pango_attr_iterator_get(iter, PANGO_ATTR_WEIGHT);
3533     if (attr != NULL && ((PangoAttrInt *)attr)->value >= (int)PANGO_WEIGHT_BOLD)
3534 	char_attr |= HL_BOLD;
3535 
3536     attr = pango_attr_iterator_get(iter, PANGO_ATTR_STYLE);
3537     if (attr != NULL && ((PangoAttrInt *)attr)->value
3538 						   != (int)PANGO_STYLE_NORMAL)
3539 	char_attr |= HL_ITALIC;
3540 
3541     attr = pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
3542     if (attr != NULL)
3543     {
3544 	const PangoColor *color = &((PangoAttrColor *)attr)->color;
3545 
3546 	/* Assume inverse if black background is requested */
3547 	if ((color->red | color->green | color->blue) == 0)
3548 	    char_attr |= HL_INVERSE;
3549     }
3550 
3551     return char_attr;
3552 }
3553 
3554 /*
3555  * Retrieve the highlighting attributes at column col in the preedit string.
3556  * Return -1 if not in preediting mode or if col is out of range.
3557  */
3558     int
3559 im_get_feedback_attr(int col)
3560 {
3561     char	    *preedit_string = NULL;
3562     PangoAttrList   *attr_list	    = NULL;
3563     int		    char_attr	    = -1;
3564 
3565     if (xic == NULL)
3566 	return char_attr;
3567 
3568     gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
3569 
3570     if (preedit_string != NULL && attr_list != NULL)
3571     {
3572 	int index;
3573 
3574 	/* Get the byte index as used by PangoAttrIterator */
3575 	for (index = 0; col > 0 && preedit_string[index] != '\0'; --col)
3576 	    index += utfc_ptr2len_check((char_u *)preedit_string + index);
3577 
3578 	if (preedit_string[index] != '\0')
3579 	{
3580 	    PangoAttrIterator	*iter;
3581 	    int			start, end;
3582 
3583 	    char_attr = HL_NORMAL;
3584 	    iter = pango_attr_list_get_iterator(attr_list);
3585 
3586 	    /* Extract all relevant attributes from the list. */
3587 	    do
3588 	    {
3589 		pango_attr_iterator_range(iter, &start, &end);
3590 
3591 		if (index >= start && index < end)
3592 		    char_attr |= translate_pango_attributes(iter);
3593 	    }
3594 	    while (pango_attr_iterator_next(iter));
3595 
3596 	    pango_attr_iterator_destroy(iter);
3597 	}
3598     }
3599 
3600     if (attr_list != NULL)
3601 	pango_attr_list_unref(attr_list);
3602     g_free(preedit_string);
3603 
3604     return char_attr;
3605 }
3606 
3607     void
3608 xim_init(void)
3609 {
3610 #ifdef XIM_DEBUG
3611     xim_log("xim_init()\n");
3612 #endif
3613 
3614     g_return_if_fail(gui.drawarea != NULL);
3615     g_return_if_fail(gui.drawarea->window != NULL);
3616 
3617     xic = gtk_im_multicontext_new();
3618     g_object_ref(xic);
3619 
3620     im_commit_handler_id = g_signal_connect(G_OBJECT(xic), "commit",
3621 					    G_CALLBACK(&im_commit_cb), NULL);
3622     g_signal_connect(G_OBJECT(xic), "preedit_changed",
3623 		     G_CALLBACK(&im_preedit_changed_cb), NULL);
3624     g_signal_connect(G_OBJECT(xic), "preedit_start",
3625 		     G_CALLBACK(&im_preedit_start_cb), NULL);
3626     g_signal_connect(G_OBJECT(xic), "preedit_end",
3627 		     G_CALLBACK(&im_preedit_end_cb), NULL);
3628 
3629     gtk_im_context_set_client_window(xic, gui.drawarea->window);
3630 }
3631 
3632     void
3633 im_shutdown(void)
3634 {
3635 #ifdef XIM_DEBUG
3636     xim_log("im_shutdown()\n");
3637 #endif
3638 
3639     if (xic != NULL)
3640     {
3641 	gtk_im_context_focus_out(xic);
3642 	g_object_unref(xic);
3643 	xic = NULL;
3644     }
3645     im_is_active = FALSE;
3646     im_commit_handler_id = 0;
3647     preedit_start_col = MAXCOL;
3648     xim_has_preediting = FALSE;
3649 }
3650 
3651 /*
3652  * Convert the string argument to keyval and state for GdkEventKey.
3653  * If str is valid return TRUE, otherwise FALSE.
3654  *
3655  * See 'imactivatekey' for documentation of the format.
3656  */
3657     static int
3658 im_string_to_keyval(const char *str, unsigned int *keyval, unsigned int *state)
3659 {
3660     const char	    *mods_end;
3661     unsigned	    tmp_keyval;
3662     unsigned	    tmp_state = 0;
3663 
3664     mods_end = strrchr(str, '-');
3665     mods_end = (mods_end != NULL) ? mods_end + 1 : str;
3666 
3667     /* Parse modifier keys */
3668     while (str < mods_end)
3669 	switch (*str++)
3670 	{
3671 	    case '-':							break;
3672 	    case 'S': case 's': tmp_state |= (unsigned)GDK_SHIFT_MASK;	break;
3673 	    case 'L': case 'l': tmp_state |= (unsigned)GDK_LOCK_MASK;	break;
3674 	    case 'C': case 'c': tmp_state |= (unsigned)GDK_CONTROL_MASK;break;
3675 	    case '1':		tmp_state |= (unsigned)GDK_MOD1_MASK;	break;
3676 	    case '2':		tmp_state |= (unsigned)GDK_MOD2_MASK;	break;
3677 	    case '3':		tmp_state |= (unsigned)GDK_MOD3_MASK;	break;
3678 	    case '4':		tmp_state |= (unsigned)GDK_MOD4_MASK;	break;
3679 	    case '5':		tmp_state |= (unsigned)GDK_MOD5_MASK;	break;
3680 	    default:
3681 		return FALSE;
3682 	}
3683 
3684     tmp_keyval = gdk_keyval_from_name(str);
3685 
3686     if (tmp_keyval == 0 || tmp_keyval == GDK_VoidSymbol)
3687 	return FALSE;
3688 
3689     if (keyval != NULL)
3690 	*keyval = tmp_keyval;
3691     if (state != NULL)
3692 	*state = tmp_state;
3693 
3694     return TRUE;
3695 }
3696 
3697 /*
3698  * Return TRUE if p_imak is valid, otherwise FALSE.  As a special case, an
3699  * empty string is also regarded as valid.
3700  *
3701  * Note: The numerical key value of p_imak is cached if it was valid; thus
3702  * boldly assuming im_xim_isvalid_imactivate() will always be called whenever
3703  * 'imak' changes.  This is currently the case but not obvious -- should
3704  * probably rename the function for clarity.
3705  */
3706     int
3707 im_xim_isvalid_imactivate(void)
3708 {
3709     if (p_imak[0] == NUL)
3710     {
3711 	im_activatekey_keyval = GDK_VoidSymbol;
3712 	im_activatekey_state  = 0;
3713 	return TRUE;
3714     }
3715 
3716     return im_string_to_keyval((const char *)p_imak,
3717 			       &im_activatekey_keyval,
3718 			       &im_activatekey_state);
3719 }
3720 
3721     static void
3722 im_synthesize_keypress(unsigned int keyval, unsigned int state)
3723 {
3724     GdkEventKey *event;
3725 
3726 #  ifdef HAVE_GTK_MULTIHEAD
3727     event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS);
3728     g_object_ref(gui.drawarea->window); /* unreffed by gdk_event_free() */
3729 #  else
3730     event = (GdkEventKey *)g_malloc0((gulong)sizeof(GdkEvent));
3731     event->type = GDK_KEY_PRESS;
3732 #  endif
3733     event->window = gui.drawarea->window;
3734     event->send_event = TRUE;
3735     event->time = GDK_CURRENT_TIME;
3736     event->state  = state;
3737     event->keyval = keyval;
3738     event->hardware_keycode = /* needed for XIM */
3739 	XKeysymToKeycode(GDK_WINDOW_XDISPLAY(event->window), (KeySym)keyval);
3740     event->length = 0;
3741     event->string = NULL;
3742 
3743     gtk_im_context_filter_keypress(xic, event);
3744 
3745     /* For consistency, also send the corresponding release event. */
3746     event->type = GDK_KEY_RELEASE;
3747     event->send_event = FALSE;
3748     gtk_im_context_filter_keypress(xic, event);
3749 
3750 #  ifdef HAVE_GTK_MULTIHEAD
3751     gdk_event_free((GdkEvent *)event);
3752 #  else
3753     g_free(event);
3754 #  endif
3755 }
3756 
3757     void
3758 xim_reset(void)
3759 {
3760     if (xic != NULL)
3761     {
3762 	/*
3763 	 * The third-party imhangul module (and maybe others too) ignores
3764 	 * gtk_im_context_reset() or at least doesn't reset the active state.
3765 	 * Thus sending imactivatekey would turn it off if it was on before,
3766 	 * which is clearly not what we want.  Fortunately we can work around
3767 	 * that for imhangul by sending GDK_Escape, but I don't know if it
3768 	 * works with all IM modules that support an activation key :/
3769 	 *
3770 	 * An alternative approach would be to destroy the IM context and
3771 	 * recreate it.  But that means loading/unloading the IM module on
3772 	 * every mode switch, which causes a quite noticable delay even on
3773 	 * my rather fast box...
3774 	 * *
3775 	 * Moreover, there are some XIM which cannot respond to
3776 	 * im_synthesize_keypress(). we hope that they reset by
3777 	 * xim_shutdown().
3778 	 */
3779 	if (im_activatekey_keyval != GDK_VoidSymbol && im_is_active)
3780 	    im_synthesize_keypress(GDK_Escape, 0U);
3781 
3782 	gtk_im_context_reset(xic);
3783 
3784 	/*
3785 	 * HACK for Ami: This sequence of function calls makes Ami handle
3786 	 * the IM reset gratiously, without breaking loads of other stuff.
3787 	 * It seems to force English mode as well, which is exactly what we
3788 	 * want because it makes the Ami status display work reliably.
3789 	 */
3790 	gtk_im_context_set_use_preedit(xic, FALSE);
3791 
3792 	if (p_imdisable)
3793 	    im_shutdown();
3794 	else
3795 	{
3796 	    gtk_im_context_set_use_preedit(xic, TRUE);
3797 	    xim_set_focus(gui.in_focus);
3798 
3799 	    if (im_activatekey_keyval != GDK_VoidSymbol)
3800 	    {
3801 		if (im_is_active)
3802 		{
3803 		    g_signal_handler_block(xic, im_commit_handler_id);
3804 		    im_synthesize_keypress(im_activatekey_keyval,
3805 						    im_activatekey_state);
3806 		    g_signal_handler_unblock(xic, im_commit_handler_id);
3807 		}
3808 	    }
3809 	    else
3810 	    {
3811 		im_shutdown();
3812 		xim_init();
3813 		xim_set_focus(gui.in_focus);
3814 	    }
3815 	}
3816     }
3817 
3818     preedit_start_col = MAXCOL;
3819     xim_has_preediting = FALSE;
3820 }
3821 
3822     int
3823 xim_queue_key_press_event(GdkEventKey *event, int down)
3824 {
3825     if (down)
3826     {
3827 	/*
3828 	 * Workaround GTK2 XIM 'feature' that always converts keypad keys to
3829 	 * chars., even when not part of an IM sequence (ref. feature of
3830 	 * gdk/gdkkeyuni.c).
3831 	 * Flag any keypad keys that might represent a single char.
3832 	 * If this (on its own - i.e., not part of an IM sequence) is
3833 	 * committed while we're processing one of these keys, we can ignore
3834 	 * that commit and go ahead & process it ourselves.  That way we can
3835 	 * still distinguish keypad keys for use in mappings.
3836 	 */
3837 	switch (event->keyval)
3838 	{
3839 	    case GDK_KP_Add:      xim_expected_char = '+';  break;
3840 	    case GDK_KP_Subtract: xim_expected_char = '-';  break;
3841 	    case GDK_KP_Divide:   xim_expected_char = '/';  break;
3842 	    case GDK_KP_Multiply: xim_expected_char = '*';  break;
3843 	    case GDK_KP_Decimal:  xim_expected_char = '.';  break;
3844 	    case GDK_KP_Equal:    xim_expected_char = '=';  break;
3845 	    case GDK_KP_0:	  xim_expected_char = '0';  break;
3846 	    case GDK_KP_1:	  xim_expected_char = '1';  break;
3847 	    case GDK_KP_2:	  xim_expected_char = '2';  break;
3848 	    case GDK_KP_3:	  xim_expected_char = '3';  break;
3849 	    case GDK_KP_4:	  xim_expected_char = '4';  break;
3850 	    case GDK_KP_5:	  xim_expected_char = '5';  break;
3851 	    case GDK_KP_6:	  xim_expected_char = '6';  break;
3852 	    case GDK_KP_7:	  xim_expected_char = '7';  break;
3853 	    case GDK_KP_8:	  xim_expected_char = '8';  break;
3854 	    case GDK_KP_9:	  xim_expected_char = '9';  break;
3855 	    default:		  xim_expected_char = NUL;
3856 	}
3857 	xim_ignored_char = FALSE;
3858     }
3859 
3860     /*
3861      * When typing fFtT, XIM may be activated. Thus it must pass
3862      * gtk_im_context_filter_keypress() in Normal mode.
3863      * And while doing :sh too.
3864      */
3865     if (xic != NULL && !p_imdisable
3866 		    && (State & (INSERT | CMDLINE | NORMAL | EXTERNCMD)) != 0)
3867     {
3868 	/*
3869 	 * Filter 'imactivatekey' and map it to CTRL-^.  This way, Vim is
3870 	 * always aware of the current status of IM, and can even emulate
3871 	 * the activation key for modules that don't support one.
3872 	 */
3873 	if (event->keyval == im_activatekey_keyval
3874 	     && (event->state & im_activatekey_state) == im_activatekey_state)
3875 	{
3876 	    unsigned int state_mask;
3877 
3878 	    /* Require the state of the 3 most used modifiers to match exactly.
3879 	     * Otherwise e.g. <S-C-space> would be unusable for other purposes
3880 	     * if the IM activate key is <S-space>. */
3881 	    state_mask  = im_activatekey_state;
3882 	    state_mask |= ((int)GDK_SHIFT_MASK | (int)GDK_CONTROL_MASK
3883 							| (int)GDK_MOD1_MASK);
3884 
3885 	    if ((event->state & state_mask) != im_activatekey_state)
3886 		return FALSE;
3887 
3888 	    /* Don't send it a second time on GDK_KEY_RELEASE. */
3889 	    if (event->type != GDK_KEY_PRESS)
3890 		return TRUE;
3891 
3892 	    if (map_to_exists_mode((char_u *)"", LANGMAP))
3893 	    {
3894 		im_set_active(FALSE);
3895 
3896 		/* ":lmap" mappings exists, toggle use of mappings. */
3897 		State ^= LANGMAP;
3898 		if (State & LANGMAP)
3899 		{
3900 		    curbuf->b_p_iminsert = B_IMODE_NONE;
3901 		    State &= ~LANGMAP;
3902 		}
3903 		else
3904 		{
3905 		    curbuf->b_p_iminsert = B_IMODE_LMAP;
3906 		    State |= LANGMAP;
3907 		}
3908 		return TRUE;
3909 	    }
3910 
3911 	    return gtk_im_context_filter_keypress(xic, event);
3912 	}
3913 
3914 	/* Don't filter events through the IM context if IM isn't active
3915 	 * right now.  Unlike with GTK+ 1.2 we cannot rely on the IM module
3916 	 * not doing anything before the activation key was sent. */
3917 	if (im_activatekey_keyval == GDK_VoidSymbol || im_is_active)
3918 	{
3919 	    int imresult = gtk_im_context_filter_keypress(xic, event);
3920 
3921 	    /* Some XIM send following sequence:
3922 	     * 1. preedited string.
3923 	     * 2. committed string.
3924 	     * 3. line changed key.
3925 	     * 4. preedited string.
3926 	     * 5. remove preedited string.
3927 	     * if 3, Vim can't move back the above line for 5.
3928 	     * thus, this part should not parse the key. */
3929 	    if (!imresult && preedit_start_col != MAXCOL
3930 					       && event->keyval == GDK_Return)
3931 	    {
3932 		im_synthesize_keypress(GDK_Return, 0U);
3933 		return FALSE;
3934 	    }
3935 
3936 	    /* If XIM tried to commit a keypad key as a single char.,
3937 	     * ignore it so we can use the keypad key 'raw', for mappings. */
3938 	    if (xim_expected_char != NUL && xim_ignored_char)
3939 		/* We had a keypad key, and XIM tried to thieve it */
3940 		return FALSE;
3941 
3942 	    /* Normal processing */
3943 	    return imresult;
3944 	}
3945     }
3946 
3947     return FALSE;
3948 }
3949 
3950     int
3951 im_get_status(void)
3952 {
3953     return im_is_active;
3954 }
3955 
3956 # else /* !HAVE_GTK2 */
3957 
3958 static int	xim_is_active = FALSE;  /* XIM should be active in the current
3959 					   mode */
3960 static int	xim_has_focus = FALSE;	/* XIM is really being used for Vim */
3961 #ifdef FEAT_GUI_X11
3962 static XIMStyle	input_style;
3963 static int	status_area_enabled = TRUE;
3964 #endif
3965 
3966 #ifdef FEAT_GUI_GTK
3967 # ifdef WIN3264
3968 #  include <gdk/gdkwin32.h>
3969 # else
3970 #  include <gdk/gdkx.h>
3971 # endif
3972 #else
3973 # ifdef PROTO
3974 /* Define a few things to be able to generate prototypes while not configured
3975  * for GTK. */
3976 #  define GSList int
3977 #  define gboolean int
3978    typedef int GdkEvent;
3979    typedef int GdkEventKey;
3980 #  define GdkIC int
3981 # endif
3982 #endif
3983 
3984 #if defined(FEAT_GUI_GTK) || defined(PROTO) || defined(FEAT_GUI_KDE)
3985 static int	preedit_buf_len = 0;
3986 static int	xim_can_preediting INIT(= FALSE);	/* XIM in showmode() */
3987 static int	xim_input_style;
3988 #ifndef FEAT_GUI_GTK
3989 # define gboolean int
3990 #endif
3991 static gboolean	use_status_area = 0;
3992 
3993 static int im_xim_str2keycode __ARGS((unsigned int *code, unsigned int *state));
3994 static void im_xim_send_event_imactivate __ARGS((void));
3995 
3996 /*
3997  * Convert string to keycode and state for XKeyEvent.
3998  * When string is valid return OK, when invalid return FAIL.
3999  *
4000  * See 'imactivatekey' documentation for the format.
4001  */
4002     static int
4003 im_xim_str2keycode(code, state)
4004     unsigned int *code;
4005     unsigned int *state;
4006 {
4007     int		retval = OK;
4008     int		len;
4009     unsigned	keycode = 0, keystate = 0;
4010     Window	window;
4011     Display	*display;
4012     char_u	*flag_end;
4013     char_u	*str;
4014 
4015     if (*p_imak != NUL)
4016     {
4017 	len = STRLEN(p_imak);
4018 	for (flag_end = p_imak + len - 1;
4019 			    flag_end > p_imak && *flag_end != '-'; --flag_end)
4020 	    ;
4021 
4022 	/* Parse modifier keys */
4023 	for (str = p_imak; str < flag_end; ++str)
4024 	{
4025 	    switch (*str)
4026 	    {
4027 		case 's': case 'S':
4028 		    keystate |= ShiftMask;
4029 		    break;
4030 		case 'l': case 'L':
4031 		    keystate |= LockMask;
4032 		    break;
4033 		case 'c': case 'C':
4034 		    keystate |= ControlMask;
4035 		    break;
4036 		case '1':
4037 		    keystate |= Mod1Mask;
4038 		    break;
4039 		case '2':
4040 		    keystate |= Mod2Mask;
4041 		    break;
4042 		case '3':
4043 		    keystate |= Mod3Mask;
4044 		    break;
4045 		case '4':
4046 		    keystate |= Mod4Mask;
4047 		    break;
4048 		case '5':
4049 		    keystate |= Mod5Mask;
4050 		    break;
4051 		case '-':
4052 		    break;
4053 		default:
4054 		    retval = FAIL;
4055 	    }
4056 	}
4057 	if (*str == '-')
4058 	    ++str;
4059 
4060 	/* Get keycode from string. */
4061 	gui_get_x11_windis(&window, &display);
4062 	if (display)
4063 	    keycode = XKeysymToKeycode(display, XStringToKeysym((char *)str));
4064 	if (keycode == 0)
4065 	    retval = FAIL;
4066 
4067 	if (code != NULL)
4068 	    *code = keycode;
4069 	if (state != NULL)
4070 	    *state = keystate;
4071     }
4072     return retval;
4073 }
4074 
4075     static void
4076 im_xim_send_event_imactivate()
4077 {
4078     /* Force turn on preedit state by symulate keypress event.
4079      * Keycode and state is specified by 'imactivatekey'.
4080      */
4081     XKeyEvent ev;
4082 
4083     gui_get_x11_windis(&ev.window, &ev.display);
4084     ev.root = RootWindow(ev.display, DefaultScreen(ev.display));
4085     ev.subwindow = None;
4086     ev.time = CurrentTime;
4087     ev.x = 1;
4088     ev.y = 1;
4089     ev.x_root = 1;
4090     ev.y_root = 1;
4091     ev.same_screen = 1;
4092     ev.type = KeyPress;
4093     if (im_xim_str2keycode(&ev.keycode, &ev.state) == OK)
4094 	XSendEvent(ev.display, ev.window, 1, KeyPressMask, (XEvent*)&ev);
4095 }
4096 
4097 /*
4098  * Return TRUE if 'imactivatekey' has a valid value.
4099  */
4100     int
4101 im_xim_isvalid_imactivate()
4102 {
4103     return im_xim_str2keycode(NULL, NULL) == OK;
4104 }
4105 #endif /* FEAT_GUI_GTK */
4106 
4107 /*
4108  * Switch using XIM on/off.  This is used by the code that changes "State".
4109  */
4110     void
4111 im_set_active(active)
4112     int		active;
4113 {
4114     if (xic == NULL)
4115 	return;
4116 
4117     /* If 'imdisable' is set, XIM is never active. */
4118     if (p_imdisable)
4119 	active = FALSE;
4120 #if !defined (FEAT_GUI_GTK) && !defined (FEAT_GUI_KDE)
4121     else if (input_style & XIMPreeditPosition)
4122 	/* There is a problem in switching XIM off when preediting is used,
4123 	 * and it is not clear how this can be solved.  For now, keep XIM on
4124 	 * all the time, like it was done in Vim 5.8. */
4125 	active = TRUE;
4126 #endif
4127 
4128     /* Remember the active state, it is needed when Vim gets keyboard focus. */
4129     xim_is_active = active;
4130 
4131 #ifdef FEAT_GUI_GTK
4132     /* When 'imactivatekey' has valid key-string, try to control XIM preedit
4133      * state.  When 'imactivatekey' has no or invalid string, try old XIM
4134      * focus control.
4135      */
4136     if (*p_imak != NUL)
4137     {
4138 	/* BASIC STRATEGY:
4139 	 * Destroy old Input Context (XIC), and create new one.  New XIC
4140 	 * would have a state of preedit that is off.  When argument:active
4141 	 * is false, that's all.  Else argument:active is true, send a key
4142 	 * event specified by 'imactivatekey' to activate XIM preedit state.
4143 	 */
4144 
4145 	xim_is_active = TRUE; /* Disable old XIM focus control */
4146 	/* If we can monitor preedit state with preedit callback functions,
4147 	 * try least creation of new XIC.
4148 	 */
4149 	if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
4150 	{
4151 	    if (xim_can_preediting && !active)
4152 	    {
4153 		/* Force turn off preedit state.  With some IM
4154 		 * implementations, we cannot turn off preedit state by
4155 		 * symulate keypress event.  It is why using such a method
4156 		 * that destroy old IC (input context), and create new one.
4157 		 * When create new IC, its preedit state is usually off.
4158 		 */
4159 		xim_reset();
4160 		xim_set_focus(FALSE);
4161 		gdk_ic_destroy(xic);
4162 		xim_init();
4163 		xim_can_preediting = FALSE;
4164 	    }
4165 	    else if (!xim_can_preediting && active)
4166 		im_xim_send_event_imactivate();
4167 	}
4168 	else
4169 	{
4170 	    /* First, force destroy old IC, and create new one.  It
4171 	     * symulates "turning off preedit state".
4172 	     */
4173 	    xim_set_focus(FALSE);
4174 	    gdk_ic_destroy(xic);
4175 	    xim_init();
4176 	    xim_can_preediting = FALSE;
4177 
4178 	    /* 2nd, when requested to activate IM, symulate this by sending
4179 	     * the event.
4180 	     */
4181 	    if (active)
4182 	    {
4183 		im_xim_send_event_imactivate();
4184 		xim_can_preediting = TRUE;
4185 	    }
4186 	}
4187     }
4188     else
4189     {
4190 # ifndef XIMPreeditUnKnown
4191 	/* X11R5 doesn't have these, it looks safe enough to define here. */
4192 	typedef unsigned long XIMPreeditState;
4193 #  define XIMPreeditUnKnown	0L
4194 #  define XIMPreeditEnable	1L
4195 #  define XIMPreeditDisable	(1L<<1)
4196 #  define XNPreeditState	"preeditState"
4197 # endif
4198 	XIMPreeditState preedit_state = XIMPreeditUnKnown;
4199 	XVaNestedList preedit_attr;
4200 	XIC pxic;
4201 
4202 	preedit_attr = XVaCreateNestedList(0,
4203 				XNPreeditState, &preedit_state,
4204 				NULL);
4205 	pxic = ((GdkICPrivate *)xic)->xic;
4206 
4207 	if (!XGetICValues(pxic, XNPreeditAttributes, preedit_attr, NULL))
4208 	{
4209 	    XFree(preedit_attr);
4210 	    preedit_attr = XVaCreateNestedList(0,
4211 				XNPreeditState,
4212 				active ? XIMPreeditEnable : XIMPreeditDisable,
4213 				NULL);
4214 	    XSetICValues(pxic, XNPreeditAttributes, preedit_attr, NULL);
4215 	    xim_can_preediting = active;
4216 	    xim_is_active = active;
4217 	}
4218 	XFree(preedit_attr);
4219     }
4220     if (xim_input_style & XIMPreeditCallbacks)
4221     {
4222 	preedit_buf_len = 0;
4223 	init_preedit_start_col();
4224     }
4225 #else
4226 # if 0
4227 	/* When had tested kinput2 + canna + Athena GUI version with
4228 	 * 'imactivatekey' is "s-space", im_xim_send_event_imactivate() did not
4229 	 * work correctly.  It just inserted one space.  I don't know why we
4230 	 * couldn't switch state of XIM preediting.  This is reason why these
4231 	 * codes are commented out.
4232 	 */
4233 	/* First, force destroy old IC, and create new one.  It symulates
4234 	 * "turning off preedit state".
4235 	 */
4236 	xim_set_focus(FALSE);
4237 	XDestroyIC(xic);
4238 	xic = NULL;
4239 	xim_init();
4240 
4241 	/* 2nd, when requested to activate IM, symulate this by sending the
4242 	 * event.
4243 	 */
4244 	if (active)
4245 	    im_xim_send_event_imactivate();
4246 # endif
4247 #endif
4248     xim_set_preedit();
4249 }
4250 
4251 /*
4252  * Adjust using XIM for gaining or losing keyboard focus.  Also called when
4253  * "xim_is_active" changes.
4254  */
4255     void
4256 xim_set_focus(focus)
4257     int		focus;
4258 {
4259     if (xic == NULL)
4260 	return;
4261 
4262     /*
4263      * XIM only gets focus when the Vim window has keyboard focus and XIM has
4264      * been set active for the current mode.
4265      */
4266     if (focus && xim_is_active)
4267     {
4268 	if (!xim_has_focus)
4269 	{
4270 	    xim_has_focus = TRUE;
4271 #ifdef FEAT_GUI_GTK
4272 	    gdk_im_begin(xic, gui.drawarea->window);
4273 #else
4274 	    XSetICFocus(xic);
4275 #endif
4276 	}
4277     }
4278     else
4279     {
4280 	if (xim_has_focus)
4281 	{
4282 	    xim_has_focus = FALSE;
4283 #ifdef FEAT_GUI_GTK
4284 	    gdk_im_end();
4285 #else
4286 	    XUnsetICFocus(xic);
4287 #endif
4288 	}
4289     }
4290 }
4291 
4292 /*ARGSUSED*/
4293     void
4294 im_set_position(row, col)
4295     int		row;
4296     int		col;
4297 {
4298     xim_set_preedit();
4299 }
4300 
4301 /*
4302  * Set the XIM to the current cursor position.
4303  */
4304     void
4305 xim_set_preedit()
4306 {
4307     if (xic == NULL)
4308 	return;
4309 
4310     xim_set_focus(TRUE);
4311 
4312 #ifdef FEAT_GUI_GTK
4313     if (gdk_im_ready())
4314     {
4315 	int		attrmask;
4316 	GdkICAttr	*attr;
4317 
4318 	if (!xic_attr)
4319 	    return;
4320 
4321 	attr = xic_attr;
4322 	attrmask = 0;
4323 
4324 # ifdef FEAT_XFONTSET
4325 	if ((xim_input_style & (int)GDK_IM_PREEDIT_POSITION)
4326 		&& gui.fontset != NOFONTSET
4327 		&& gui.fontset->type == GDK_FONT_FONTSET)
4328 	{
4329 	    if (!xim_has_focus)
4330 	    {
4331 		if (attr->spot_location.y >= 0)
4332 		{
4333 		    attr->spot_location.x = 0;
4334 		    attr->spot_location.y = -100;
4335 		    attrmask |= (int)GDK_IC_SPOT_LOCATION;
4336 		}
4337 	    }
4338 	    else
4339 	    {
4340 		gint	width, height;
4341 
4342 		if (attr->spot_location.x != TEXT_X(gui.col)
4343 		    || attr->spot_location.y != TEXT_Y(gui.row))
4344 		{
4345 		    attr->spot_location.x = TEXT_X(gui.col);
4346 		    attr->spot_location.y = TEXT_Y(gui.row);
4347 		    attrmask |= (int)GDK_IC_SPOT_LOCATION;
4348 		}
4349 
4350 		gdk_window_get_size(gui.drawarea->window, &width, &height);
4351 		width -= 2 * gui.border_offset;
4352 		height -= 2 * gui.border_offset;
4353 		if (xim_input_style & (int)GDK_IM_STATUS_AREA)
4354 		    height -= gui.char_height;
4355 		if (attr->preedit_area.width != width
4356 		    || attr->preedit_area.height != height)
4357 		{
4358 		    attr->preedit_area.x = gui.border_offset;
4359 		    attr->preedit_area.y = gui.border_offset;
4360 		    attr->preedit_area.width = width;
4361 		    attr->preedit_area.height = height;
4362 		    attrmask |= (int)GDK_IC_PREEDIT_AREA;
4363 		}
4364 
4365 		if (attr->preedit_fontset != gui.current_font)
4366 		{
4367 		    attr->preedit_fontset = gui.current_font;
4368 		    attrmask |= (int)GDK_IC_PREEDIT_FONTSET;
4369 		}
4370 	    }
4371 	}
4372 # endif /* FEAT_XFONTSET */
4373 
4374 	if (xim_fg_color == INVALCOLOR)
4375 	{
4376 	    xim_fg_color = gui.def_norm_pixel;
4377 	    xim_bg_color = gui.def_back_pixel;
4378 	}
4379 	if (attr->preedit_foreground.pixel != xim_fg_color)
4380 	{
4381 	    attr->preedit_foreground.pixel = xim_fg_color;
4382 	    attrmask |= (int)GDK_IC_PREEDIT_FOREGROUND;
4383 	}
4384 	if (attr->preedit_background.pixel != xim_bg_color)
4385 	{
4386 	    attr->preedit_background.pixel = xim_bg_color;
4387 	    attrmask |= (int)GDK_IC_PREEDIT_BACKGROUND;
4388 	}
4389 
4390 	if (attrmask != 0)
4391 	    gdk_ic_set_attr(xic, attr, (GdkICAttributesType)attrmask);
4392     }
4393 #else /* FEAT_GUI_GTK */
4394 # ifdef FEAT_GUI_KDE
4395 # else
4396     {
4397 	XVaNestedList attr_list;
4398 	XRectangle spot_area;
4399 	XPoint over_spot;
4400 	int line_space;
4401 
4402 	if (!xim_has_focus)
4403 	{
4404 	    /* hide XIM cursor */
4405 	    over_spot.x = 0;
4406 	    over_spot.y = -100; /* arbitrary invisible position */
4407 	    attr_list = (XVaNestedList) XVaCreateNestedList(0,
4408 							    XNSpotLocation,
4409 							    &over_spot,
4410 							    NULL);
4411 	    XSetICValues(xic, XNPreeditAttributes, attr_list, NULL);
4412 	    XFree(attr_list);
4413 	    return;
4414 	}
4415 
4416 	if (input_style & XIMPreeditPosition)
4417 	{
4418 	    if (xim_fg_color == INVALCOLOR)
4419 	    {
4420 		xim_fg_color = gui.def_norm_pixel;
4421 		xim_bg_color = gui.def_back_pixel;
4422 	    }
4423 	    over_spot.x = TEXT_X(gui.col);
4424 	    over_spot.y = TEXT_Y(gui.row);
4425 	    spot_area.x = 0;
4426 	    spot_area.y = 0;
4427 	    spot_area.height = gui.char_height * Rows;
4428 	    spot_area.width  = gui.char_width * Columns;
4429 	    line_space = gui.char_height;
4430 	    attr_list = (XVaNestedList) XVaCreateNestedList(0,
4431 					    XNSpotLocation, &over_spot,
4432 					    XNForeground, (Pixel) xim_fg_color,
4433 					    XNBackground, (Pixel) xim_bg_color,
4434 					    XNArea, &spot_area,
4435 					    XNLineSpace, line_space,
4436 					    NULL);
4437 	    if (XSetICValues(xic, XNPreeditAttributes, attr_list, NULL))
4438 		EMSG(_("E284: Cannot set IC values"));
4439 	    XFree(attr_list);
4440 	}
4441     }
4442 # endif /* FEAT_GUI_KDE */
4443 #endif /* FEAT_GUI_GTK */
4444 }
4445 
4446 /*
4447  * Set up the status area.
4448  *
4449  * This should use a separate Widget, but that seems not possible, because
4450  * preedit_area and status_area should be set to the same window as for the
4451  * text input.  Unfortunately this means the status area pollutes the text
4452  * window...
4453  */
4454     void
4455 xim_set_status_area()
4456 {
4457     if (xic == NULL)
4458 	return;
4459 
4460 #ifdef FEAT_GUI_GTK
4461 # if defined(FEAT_XFONTSET)
4462     if (use_status_area)
4463     {
4464 	GdkICAttr	*attr;
4465 	int		style;
4466 	gint		width, height;
4467 	GtkWidget	*widget;
4468 	int		attrmask;
4469 
4470 	if (!xic_attr)
4471 	    return;
4472 
4473 	attr = xic_attr;
4474 	attrmask = 0;
4475 	style = (int)gdk_ic_get_style(xic);
4476 	if ((style & (int)GDK_IM_STATUS_MASK) == (int)GDK_IM_STATUS_AREA)
4477 	{
4478 	    if (gui.fontset != NOFONTSET
4479 		    && gui.fontset->type == GDK_FONT_FONTSET)
4480 	    {
4481 		widget = gui.mainwin;
4482 		gdk_window_get_size(widget->window, &width, &height);
4483 
4484 		attrmask |= (int)GDK_IC_STATUS_AREA;
4485 		attr->status_area.x = 0;
4486 		attr->status_area.y = height - gui.char_height - 1;
4487 		attr->status_area.width = width;
4488 		attr->status_area.height = gui.char_height;
4489 	    }
4490 	}
4491 	if (attrmask != 0)
4492 	    gdk_ic_set_attr(xic, attr, (GdkICAttributesType)attrmask);
4493     }
4494 # endif
4495 #else
4496 # ifdef FEAT_GUI_KDE
4497 # else
4498     {
4499 	XVaNestedList preedit_list = 0, status_list = 0, list = 0;
4500 	XRectangle pre_area, status_area;
4501 
4502 	if (input_style & XIMStatusArea)
4503 	{
4504 	    if (input_style & XIMPreeditArea)
4505 	    {
4506 		XRectangle *needed_rect;
4507 
4508 		/* to get status_area width */
4509 		status_list = XVaCreateNestedList(0, XNAreaNeeded,
4510 						  &needed_rect, NULL);
4511 		XGetICValues(xic, XNStatusAttributes, status_list, NULL);
4512 		XFree(status_list);
4513 
4514 		status_area.width = needed_rect->width;
4515 	    }
4516 	    else
4517 		status_area.width = gui.char_width * Columns;
4518 
4519 	    status_area.x = 0;
4520 	    status_area.y = gui.char_height * Rows + gui.border_offset;
4521 	    if (gui.which_scrollbars[SBAR_BOTTOM])
4522 		status_area.y += gui.scrollbar_height;
4523 #ifdef FEAT_MENU
4524 	    if (gui.menu_is_active)
4525 		status_area.y += gui.menu_height;
4526 #endif
4527 	    status_area.height = gui.char_height;
4528 	    status_list = XVaCreateNestedList(0, XNArea, &status_area, NULL);
4529 	}
4530 	else
4531 	{
4532 	    status_area.x = 0;
4533 	    status_area.y = gui.char_height * Rows + gui.border_offset;
4534 	    if (gui.which_scrollbars[SBAR_BOTTOM])
4535 		status_area.y += gui.scrollbar_height;
4536 #ifdef FEAT_MENU
4537 	    if (gui.menu_is_active)
4538 		status_area.y += gui.menu_height;
4539 #endif
4540 	    status_area.width = 0;
4541 	    status_area.height = gui.char_height;
4542 	}
4543 
4544 	if (input_style & XIMPreeditArea)   /* off-the-spot */
4545 	{
4546 	    pre_area.x = status_area.x + status_area.width;
4547 	    pre_area.y = gui.char_height * Rows + gui.border_offset;
4548 	    pre_area.width = gui.char_width * Columns - pre_area.x;
4549 	    if (gui.which_scrollbars[SBAR_BOTTOM])
4550 		pre_area.y += gui.scrollbar_height;
4551 #ifdef FEAT_MENU
4552 	    if (gui.menu_is_active)
4553 		pre_area.y += gui.menu_height;
4554 #endif
4555 	    pre_area.height = gui.char_height;
4556 	    preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
4557 	}
4558 	else if (input_style & XIMPreeditPosition)   /* over-the-spot */
4559 	{
4560 	    pre_area.x = 0;
4561 	    pre_area.y = 0;
4562 	    pre_area.height = gui.char_height * Rows;
4563 	    pre_area.width = gui.char_width * Columns;
4564 	    preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
4565 	}
4566 
4567 	if (preedit_list && status_list)
4568 	    list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
4569 				       XNStatusAttributes, status_list, NULL);
4570 	else if (preedit_list)
4571 	    list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
4572 				       NULL);
4573 	else if (status_list)
4574 	    list = XVaCreateNestedList(0, XNStatusAttributes, status_list,
4575 				       NULL);
4576 	else
4577 	    list = NULL;
4578 
4579 	if (list)
4580 	{
4581 	    XSetICValues(xic, XNVaNestedList, list, NULL);
4582 	    XFree(list);
4583 	}
4584 	if (status_list)
4585 	    XFree(status_list);
4586 	if (preedit_list)
4587 	    XFree(preedit_list);
4588     }
4589 # endif /* FEAT_GUI_KDE */
4590 #endif
4591 }
4592 
4593 #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
4594 static char e_xim[] = N_("E285: Failed to create input context");
4595 #endif
4596 
4597 #if defined(FEAT_GUI_X11) || defined(PROTO)
4598 # if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(sun)
4599 #  define USE_X11R6_XIM
4600 # endif
4601 
4602 static int xim_real_init __ARGS((Window x11_window, Display *x11_display));
4603 
4604 
4605 #ifdef USE_X11R6_XIM
4606 static void xim_instantiate_cb __ARGS((Display *display, XPointer client_data, XPointer	call_data));
4607 static void xim_destroy_cb __ARGS((XIM im, XPointer client_data, XPointer call_data));
4608 
4609 /*ARGSUSED*/
4610     static void
4611 xim_instantiate_cb(display, client_data, call_data)
4612     Display	*display;
4613     XPointer	client_data;
4614     XPointer	call_data;
4615 {
4616     Window	x11_window;
4617     Display	*x11_display;
4618 
4619 #ifdef XIM_DEBUG
4620     xim_log("xim_instantiate_cb()\n");
4621 #endif
4622 
4623     gui_get_x11_windis(&x11_window, &x11_display);
4624     if (display != x11_display)
4625 	return;
4626 
4627     xim_real_init(x11_window, x11_display);
4628     gui_set_shellsize(FALSE, FALSE);
4629     if (xic != NULL)
4630 	XUnregisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
4631 					 xim_instantiate_cb, NULL);
4632 }
4633 
4634 /*ARGSUSED*/
4635     static void
4636 xim_destroy_cb(im, client_data, call_data)
4637     XIM		im;
4638     XPointer	client_data;
4639     XPointer	call_data;
4640 {
4641     Window	x11_window;
4642     Display	*x11_display;
4643 
4644 #ifdef XIM_DEBUG
4645     xim_log("xim_destroy_cb()\n");
4646 #endif
4647     gui_get_x11_windis(&x11_window, &x11_display);
4648 
4649     xic = NULL;
4650     status_area_enabled = FALSE;
4651 
4652     gui_set_shellsize(FALSE, FALSE);
4653 
4654     XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
4655 				   xim_instantiate_cb, NULL);
4656 }
4657 #endif
4658 
4659     void
4660 xim_init()
4661 {
4662     Window	x11_window;
4663     Display	*x11_display;
4664 
4665 #ifdef XIM_DEBUG
4666     xim_log("xim_init()\n");
4667 #endif
4668 
4669     gui_get_x11_windis(&x11_window, &x11_display);
4670 
4671     xic = NULL;
4672 
4673     if (xim_real_init(x11_window, x11_display))
4674 	return;
4675 
4676     gui_set_shellsize(FALSE, FALSE);
4677 
4678 #ifdef USE_X11R6_XIM
4679     XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
4680 				   xim_instantiate_cb, NULL);
4681 #endif
4682 }
4683 
4684     static int
4685 xim_real_init(x11_window, x11_display)
4686     Window	x11_window;
4687     Display	*x11_display;
4688 {
4689     int		i;
4690     char	*p,
4691 		*s,
4692 		*ns,
4693 		*end,
4694 		tmp[1024];
4695 #define IMLEN_MAX 40
4696     char	buf[IMLEN_MAX + 7];
4697     XIM		xim = NULL;
4698     XIMStyles	*xim_styles;
4699     XIMStyle	this_input_style = 0;
4700     Boolean	found;
4701     XPoint	over_spot;
4702     XVaNestedList preedit_list, status_list;
4703 
4704     input_style = 0;
4705     status_area_enabled = FALSE;
4706 
4707     if (xic != NULL)
4708 	return FALSE;
4709 
4710     if (gui.rsrc_input_method != NULL && *gui.rsrc_input_method != NUL)
4711     {
4712 	strcpy(tmp, gui.rsrc_input_method);
4713 	for (ns = s = tmp; ns != NULL && *s != NUL;)
4714 	{
4715 	    s = (char *)skipwhite((char_u *)s);
4716 	    if (*s == NUL)
4717 		break;
4718 	    if ((ns = end = strchr(s, ',')) == NULL)
4719 		end = s + strlen(s);
4720 	    while (isspace(((char_u *)end)[-1]))
4721 		end--;
4722 	    *end = NUL;
4723 
4724 	    if (strlen(s) <= IMLEN_MAX)
4725 	    {
4726 		strcpy(buf, "@im=");
4727 		strcat(buf, s);
4728 		if ((p = XSetLocaleModifiers(buf)) != NULL && *p != NUL
4729 			&& (xim = XOpenIM(x11_display, NULL, NULL, NULL))
4730 								      != NULL)
4731 		    break;
4732 	    }
4733 
4734 	    s = ns + 1;
4735 	}
4736     }
4737 
4738     if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p != NUL)
4739 	xim = XOpenIM(x11_display, NULL, NULL, NULL);
4740 
4741     /* This is supposed to be useful to obtain characters through
4742      * XmbLookupString() without really using a XIM. */
4743     if (xim == NULL && (p = XSetLocaleModifiers("@im=none")) != NULL
4744 								 && *p != NUL)
4745 	xim = XOpenIM(x11_display, NULL, NULL, NULL);
4746 
4747     if (xim == NULL)
4748     {
4749 	/* Only give this message when verbose is set, because too many people
4750 	 * got this message when they didn't want to use a XIM. */
4751 	if (p_verbose > 0)
4752 	    EMSG(_("E286: Failed to open input method"));
4753 	return FALSE;
4754     }
4755 
4756 #ifdef USE_X11R6_XIM
4757     {
4758 	XIMCallback destroy_cb;
4759 
4760 	destroy_cb.callback = xim_destroy_cb;
4761 	destroy_cb.client_data = NULL;
4762 	if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL))
4763 	    EMSG(_("E287: Warning: Could not set destroy callback to IM"));
4764     }
4765 #endif
4766 
4767     if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles)
4768     {
4769 	EMSG(_("E288: input method doesn't support any style"));
4770 	XCloseIM(xim);
4771 	return FALSE;
4772     }
4773 
4774     found = False;
4775     strcpy(tmp, gui.rsrc_preedit_type_name);
4776     for (s = tmp; s && !found; )
4777     {
4778 	while (*s && isspace((unsigned char)*s))
4779 	    s++;
4780 	if (!*s)
4781 	    break;
4782 	if ((ns = end = strchr(s, ',')) != 0)
4783 	    ns++;
4784 	else
4785 	    end = s + strlen(s);
4786 	while (isspace((unsigned char)*end))
4787 	    end--;
4788 	*end = '\0';
4789 
4790 	if (!strcmp(s, "OverTheSpot"))
4791 	    this_input_style = (XIMPreeditPosition | XIMStatusArea);
4792 	else if (!strcmp(s, "OffTheSpot"))
4793 	    this_input_style = (XIMPreeditArea | XIMStatusArea);
4794 	else if (!strcmp(s, "Root"))
4795 	    this_input_style = (XIMPreeditNothing | XIMStatusNothing);
4796 
4797 	for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
4798 	{
4799 	    if (this_input_style == xim_styles->supported_styles[i])
4800 	    {
4801 		found = True;
4802 		break;
4803 	    }
4804 	}
4805 	if (!found)
4806 	    for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
4807 	    {
4808 		if ((xim_styles->supported_styles[i] & this_input_style)
4809 			== (this_input_style & ~XIMStatusArea))
4810 		{
4811 		    this_input_style &= ~XIMStatusArea;
4812 		    found = True;
4813 		    break;
4814 		}
4815 	    }
4816 
4817 	s = ns;
4818     }
4819     XFree(xim_styles);
4820 
4821     if (!found)
4822     {
4823 	/* Only give this message when verbose is set, because too many people
4824 	 * got this message when they didn't want to use a XIM. */
4825 	if (p_verbose > 0)
4826 	    EMSG(_("E289: input method doesn't support my preedit type"));
4827 	XCloseIM(xim);
4828 	return FALSE;
4829     }
4830 
4831     over_spot.x = TEXT_X(gui.col);
4832     over_spot.y = TEXT_Y(gui.row);
4833     input_style = this_input_style;
4834 
4835     /* A crash was reported when trying to pass gui.norm_font as XNFontSet,
4836      * thus that has been removed.  Hopefully the default works... */
4837 #ifdef FEAT_XFONTSET
4838     if (gui.fontset != NOFONTSET)
4839     {
4840 	preedit_list = XVaCreateNestedList(0,
4841 				XNSpotLocation, &over_spot,
4842 				XNForeground, (Pixel)gui.def_norm_pixel,
4843 				XNBackground, (Pixel)gui.def_back_pixel,
4844 				XNFontSet, (XFontSet)gui.fontset,
4845 				NULL);
4846 	status_list = XVaCreateNestedList(0,
4847 				XNForeground, (Pixel)gui.def_norm_pixel,
4848 				XNBackground, (Pixel)gui.def_back_pixel,
4849 				XNFontSet, (XFontSet)gui.fontset,
4850 				NULL);
4851     }
4852     else
4853 #endif
4854     {
4855 	preedit_list = XVaCreateNestedList(0,
4856 				XNSpotLocation, &over_spot,
4857 				XNForeground, (Pixel)gui.def_norm_pixel,
4858 				XNBackground, (Pixel)gui.def_back_pixel,
4859 				NULL);
4860 	status_list = XVaCreateNestedList(0,
4861 				XNForeground, (Pixel)gui.def_norm_pixel,
4862 				XNBackground, (Pixel)gui.def_back_pixel,
4863 				NULL);
4864     }
4865 
4866     xic = XCreateIC(xim,
4867 		    XNInputStyle, input_style,
4868 		    XNClientWindow, x11_window,
4869 		    XNFocusWindow, gui.wid,
4870 		    XNPreeditAttributes, preedit_list,
4871 		    XNStatusAttributes, status_list,
4872 		    NULL);
4873     XFree(status_list);
4874     XFree(preedit_list);
4875     if (xic != NULL)
4876     {
4877 	if (input_style & XIMStatusArea)
4878 	{
4879 	    xim_set_status_area();
4880 	    status_area_enabled = TRUE;
4881 	}
4882 	else
4883 	    gui_set_shellsize(FALSE, FALSE);
4884     }
4885     else
4886     {
4887 	EMSG(_(e_xim));
4888 	XCloseIM(xim);
4889 	return FALSE;
4890     }
4891 
4892     return TRUE;
4893 }
4894 
4895 #endif /* FEAT_GUI_X11 */
4896 
4897 #if defined(FEAT_GUI_GTK) || defined(PROTO)
4898 
4899 # ifdef FEAT_XFONTSET
4900 static char e_overthespot[] = N_("E290: over-the-spot style requires fontset");
4901 # endif
4902 
4903 # ifdef PROTO
4904 typedef int GdkIC;
4905 # endif
4906 
4907     void
4908 xim_decide_input_style()
4909 {
4910     /* GDK_IM_STATUS_CALLBACKS was disabled, enabled it to allow Japanese
4911      * OverTheSpot. */
4912     int supported_style = (int)GDK_IM_PREEDIT_NONE |
4913 				 (int)GDK_IM_PREEDIT_NOTHING |
4914 				 (int)GDK_IM_PREEDIT_POSITION |
4915 				 (int)GDK_IM_PREEDIT_CALLBACKS |
4916 				 (int)GDK_IM_STATUS_CALLBACKS |
4917 				 (int)GDK_IM_STATUS_AREA |
4918 				 (int)GDK_IM_STATUS_NONE |
4919 				 (int)GDK_IM_STATUS_NOTHING;
4920 
4921 #ifdef XIM_DEBUG
4922     xim_log("xim_decide_input_style()\n");
4923 #endif
4924 
4925     if (!gdk_im_ready())
4926 	xim_input_style = 0;
4927     else
4928     {
4929 	if (gtk_major_version > 1
4930 		|| (gtk_major_version == 1
4931 		    && (gtk_minor_version > 2
4932 			|| (gtk_minor_version == 2 && gtk_micro_version >= 3))))
4933 	    use_status_area = TRUE;
4934 	else
4935 	{
4936 	    EMSG(_("E291: Your GTK+ is older than 1.2.3. Status area disabled"));
4937 	    use_status_area = FALSE;
4938 	}
4939 #ifdef FEAT_XFONTSET
4940 	if (gui.fontset == NOFONTSET || gui.fontset->type != GDK_FONT_FONTSET)
4941 #endif
4942 	    supported_style &= ~((int)GDK_IM_PREEDIT_POSITION
4943 						   | (int)GDK_IM_STATUS_AREA);
4944 	if (!use_status_area)
4945 	    supported_style &= ~(int)GDK_IM_STATUS_AREA;
4946 	xim_input_style = (int)gdk_im_decide_style((GdkIMStyle)supported_style);
4947     }
4948 }
4949 
4950 /*ARGSUSED*/
4951     static void
4952 preedit_start_cbproc(XIC xic, XPointer client_data, XPointer call_data)
4953 {
4954 #ifdef XIM_DEBUG
4955     xim_log("xim_decide_input_style()\n");
4956 #endif
4957 
4958     draw_feedback = NULL;
4959     xim_can_preediting = TRUE;
4960     xim_has_preediting = TRUE;
4961     gui_update_cursor(TRUE, FALSE);
4962     if (showmode() > 0)
4963     {
4964 	setcursor();
4965 	out_flush();
4966     }
4967 }
4968 
4969     static void
4970 xim_back_delete(int n)
4971 {
4972     char_u str[3];
4973 
4974     str[0] = CSI;
4975     str[1] = 'k';
4976     str[2] = 'b';
4977     while (n-- > 0)
4978 	add_to_input_buf(str, 3);
4979 }
4980 
4981 static GSList *key_press_event_queue = NULL;
4982 static gboolean processing_queued_event = FALSE;
4983 
4984 /*ARGSUSED*/
4985     static void
4986 preedit_draw_cbproc(XIC xic, XPointer client_data, XPointer call_data)
4987 {
4988     XIMPreeditDrawCallbackStruct *draw_data;
4989     XIMText	*text;
4990     char	*src;
4991     GSList	*event_queue;
4992 
4993 #ifdef XIM_DEBUG
4994     xim_log("preedit_draw_cbproc()\n");
4995 #endif
4996 
4997     draw_data = (XIMPreeditDrawCallbackStruct *) call_data;
4998     text = (XIMText *) draw_data->text;
4999 
5000     if ((text == NULL && draw_data->chg_length == preedit_buf_len)
5001 						      || preedit_buf_len == 0)
5002     {
5003 	init_preedit_start_col();
5004 	vim_free(draw_feedback);
5005 	draw_feedback = NULL;
5006     }
5007     if (draw_data->chg_length > 0)
5008     {
5009 	int bs_cnt;
5010 
5011 	if (draw_data->chg_length > preedit_buf_len)
5012 	    bs_cnt = preedit_buf_len;
5013 	else
5014 	    bs_cnt = draw_data->chg_length;
5015 	xim_back_delete(bs_cnt);
5016 	preedit_buf_len -= bs_cnt;
5017     }
5018     if (text != NULL)
5019     {
5020 	int		len;
5021 #ifdef FEAT_MBYTE
5022 	char_u		*buf = NULL;
5023 	unsigned int	nfeedback = 0;
5024 #endif
5025 	char_u		*ptr;
5026 
5027 	src = text->string.multi_byte;
5028 	if (src != NULL && !text->encoding_is_wchar)
5029 	{
5030 	    len = strlen(src);
5031 	    ptr = (char_u *)src;
5032 	    /* Avoid the enter for decision */
5033 	    if (*ptr == '\n')
5034 		return;
5035 
5036 #ifdef FEAT_MBYTE
5037 	    if (input_conv.vc_type != CONV_NONE
5038 		    && (buf = string_convert(&input_conv,
5039 						 (char_u *)src, &len)) != NULL)
5040 	    {
5041 		/* Converted from 'termencoding' to 'encoding'. */
5042 		add_to_input_buf_csi(buf, len);
5043 		ptr = buf;
5044 	    }
5045 	    else
5046 #endif
5047 		add_to_input_buf_csi((char_u *)src, len);
5048 	    /* Add count of character to preedit_buf_len  */
5049 	    while (*ptr != NUL)
5050 	    {
5051 #ifdef FEAT_MBYTE
5052 		if (draw_data->text->feedback != NULL)
5053 		{
5054 		    if (draw_feedback == NULL)
5055 			draw_feedback = (char *)alloc(draw_data->chg_first
5056 							      + text->length);
5057 		    else
5058 			draw_feedback = realloc(draw_feedback,
5059 					 draw_data->chg_first + text->length);
5060 		    if (draw_feedback != NULL)
5061 		    {
5062 			draw_feedback[nfeedback + draw_data->chg_first]
5063 				       = draw_data->text->feedback[nfeedback];
5064 			nfeedback++;
5065 		    }
5066 		}
5067 		if (has_mbyte)
5068 		    ptr += mb_ptr2len_check(ptr);
5069 		else
5070 #endif
5071 		    ptr++;
5072 		preedit_buf_len++;
5073 	    }
5074 #ifdef FEAT_MBYTE
5075 	    vim_free(buf);
5076 #endif
5077 	    preedit_end_col = MAXCOL;
5078 	}
5079     }
5080     if (text != NULL || draw_data->chg_length > 0)
5081     {
5082 	event_queue = key_press_event_queue;
5083 	processing_queued_event = TRUE;
5084 	while (event_queue != NULL && processing_queued_event)
5085 	{
5086 	    GdkEvent *ev = event_queue->data;
5087 
5088 	    gboolean *ret;
5089 	    gtk_signal_emit_by_name((GtkObject*)gui.mainwin, "key_press_event",
5090 								    ev, &ret);
5091 	    gdk_event_free(ev);
5092 	    event_queue = event_queue->next;
5093 	}
5094 	processing_queued_event = FALSE;
5095 	if (key_press_event_queue)
5096 	{
5097 	    g_slist_free(key_press_event_queue);
5098 	    key_press_event_queue = NULL;
5099 	}
5100     }
5101     if (gtk_main_level() > 0)
5102 	gtk_main_quit();
5103 }
5104 
5105 /*
5106  * Retrieve the highlighting attributes at column col in the preedit string.
5107  * Return -1 if not in preediting mode or if col is out of range.
5108  */
5109     int
5110 im_get_feedback_attr(int col)
5111 {
5112     if (draw_feedback != NULL && col < preedit_buf_len)
5113     {
5114 	if (draw_feedback[col] & XIMReverse)
5115 	    return HL_INVERSE;
5116 	else if (draw_feedback[col] & XIMUnderline)
5117 	    return HL_UNDERLINE;
5118 	else
5119 	    return hl_attr(HLF_V);
5120     }
5121 
5122     return -1;
5123 }
5124 
5125 /*ARGSUSED*/
5126     static void
5127 preedit_caret_cbproc(XIC xic, XPointer client_data, XPointer call_data)
5128 {
5129 #ifdef XIM_DEBUG
5130     xim_log("preedit_caret_cbproc()\n");
5131 #endif
5132 }
5133 
5134 /*ARGSUSED*/
5135     static void
5136 preedit_done_cbproc(XIC xic, XPointer client_data, XPointer call_data)
5137 {
5138 #ifdef XIM_DEBUG
5139     xim_log("preedit_done_cbproc()\n");
5140 #endif
5141 
5142     vim_free(draw_feedback);
5143     draw_feedback = NULL;
5144     xim_can_preediting = FALSE;
5145     xim_has_preediting = FALSE;
5146     gui_update_cursor(TRUE, FALSE);
5147     if (showmode() > 0)
5148     {
5149 	setcursor();
5150 	out_flush();
5151     }
5152 }
5153 
5154     void
5155 xim_reset(void)
5156 {
5157     char *text;
5158 
5159 #ifdef XIM_DEBUG
5160     xim_log("xim_reset()\n");
5161 #endif
5162 
5163     if (xic != NULL)
5164     {
5165 	text = XmbResetIC(((GdkICPrivate *)xic)->xic);
5166 	if (text != NULL && !(xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS))
5167 	    add_to_input_buf_csi((char_u *)text, strlen(text));
5168 	else
5169 	    preedit_buf_len = 0;
5170 	if (text != NULL)
5171 	    XFree(text);
5172     }
5173 }
5174 
5175 /*ARGSUSED*/
5176     int
5177 xim_queue_key_press_event(GdkEventKey *event, int down)
5178 {
5179 #ifdef XIM_DEBUG
5180     xim_log("xim_queue_key_press_event()\n");
5181 #endif
5182 
5183     if (preedit_buf_len <= 0)
5184 	return FALSE;
5185     if (processing_queued_event)
5186 	processing_queued_event = FALSE;
5187 
5188     key_press_event_queue = g_slist_append(key_press_event_queue,
5189 					   gdk_event_copy((GdkEvent *)event));
5190     return TRUE;
5191 }
5192 
5193 /*ARGSUSED*/
5194     static void
5195 preedit_callback_setup(GdkIC *ic)
5196 {
5197     XIC xxic;
5198     XVaNestedList preedit_attr;
5199     XIMCallback preedit_start_cb;
5200     XIMCallback preedit_draw_cb;
5201     XIMCallback preedit_caret_cb;
5202     XIMCallback preedit_done_cb;
5203 
5204     xxic = ((GdkICPrivate*)xic)->xic;
5205     preedit_start_cb.callback = (XIMProc)preedit_start_cbproc;
5206     preedit_draw_cb.callback = (XIMProc)preedit_draw_cbproc;
5207     preedit_caret_cb.callback = (XIMProc)preedit_caret_cbproc;
5208     preedit_done_cb.callback = (XIMProc)preedit_done_cbproc;
5209     preedit_attr
5210 	= XVaCreateNestedList (0,
5211 			       XNPreeditStartCallback, &preedit_start_cb,
5212 			       XNPreeditDrawCallback, &preedit_draw_cb,
5213 			       XNPreeditCaretCallback, &preedit_caret_cb,
5214 			       XNPreeditDoneCallback, &preedit_done_cb,
5215 			       0);
5216     XSetICValues (xxic, XNPreeditAttributes, preedit_attr, 0);
5217     XFree(preedit_attr);
5218 }
5219 
5220 /*ARGSUSED*/
5221     static void
5222 reset_state_setup(GdkIC *ic)
5223 {
5224 #ifdef USE_X11R6_XIM
5225     /* don't change the input context when we call reset */
5226     XSetICValues(((GdkICPrivate*)ic)->xic, XNResetState, XIMPreserveState, 0);
5227 #endif
5228 }
5229 
5230     void
5231 xim_init(void)
5232 {
5233 #ifdef XIM_DEBUG
5234     xim_log("xim_init()\n");
5235 #endif
5236 
5237     xic = NULL;
5238     xic_attr = NULL;
5239 
5240     if (!gdk_im_ready())
5241     {
5242 	if (p_verbose > 0)
5243 	    EMSG(_("E292: Input Method Server is not running"));
5244 	return;
5245     }
5246     if ((xic_attr = gdk_ic_attr_new()) != NULL)
5247     {
5248 #ifdef FEAT_XFONTSET
5249 	gint width, height;
5250 #endif
5251 	int		mask;
5252 	GdkColormap	*colormap;
5253 	GdkICAttr	*attr = xic_attr;
5254 	int		attrmask = (int)GDK_IC_ALL_REQ;
5255 	GtkWidget	*widget = gui.drawarea;
5256 
5257 	attr->style = (GdkIMStyle)xim_input_style;
5258 	attr->client_window = gui.mainwin->window;
5259 
5260 	if ((colormap = gtk_widget_get_colormap(widget)) !=
5261 	    gtk_widget_get_default_colormap())
5262 	{
5263 	    attrmask |= (int)GDK_IC_PREEDIT_COLORMAP;
5264 	    attr->preedit_colormap = colormap;
5265 	}
5266 	attrmask |= (int)GDK_IC_PREEDIT_FOREGROUND;
5267 	attrmask |= (int)GDK_IC_PREEDIT_BACKGROUND;
5268 	attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
5269 	attr->preedit_background = widget->style->base[GTK_STATE_NORMAL];
5270 
5271 #ifdef FEAT_XFONTSET
5272 	if ((xim_input_style & (int)GDK_IM_PREEDIT_MASK)
5273 					      == (int)GDK_IM_PREEDIT_POSITION)
5274 	{
5275 	    if (gui.fontset == NOFONTSET
5276 		    || gui.fontset->type != GDK_FONT_FONTSET)
5277 	    {
5278 		EMSG(_(e_overthespot));
5279 	    }
5280 	    else
5281 	    {
5282 		gdk_window_get_size(widget->window, &width, &height);
5283 
5284 		attrmask |= (int)GDK_IC_PREEDIT_POSITION_REQ;
5285 		attr->spot_location.x = TEXT_X(0);
5286 		attr->spot_location.y = TEXT_Y(0);
5287 		attr->preedit_area.x = gui.border_offset;
5288 		attr->preedit_area.y = gui.border_offset;
5289 		attr->preedit_area.width = width - 2*gui.border_offset;
5290 		attr->preedit_area.height = height - 2*gui.border_offset;
5291 		attr->preedit_fontset = gui.fontset;
5292 	    }
5293 	}
5294 
5295 	if ((xim_input_style & (int)GDK_IM_STATUS_MASK)
5296 						   == (int)GDK_IM_STATUS_AREA)
5297 	{
5298 	    if (gui.fontset == NOFONTSET
5299 		    || gui.fontset->type != GDK_FONT_FONTSET)
5300 	    {
5301 		EMSG(_(e_overthespot));
5302 	    }
5303 	    else
5304 	    {
5305 		gdk_window_get_size(gui.mainwin->window, &width, &height);
5306 		attrmask |= (int)GDK_IC_STATUS_AREA_REQ;
5307 		attr->status_area.x = 0;
5308 		attr->status_area.y = height - gui.char_height - 1;
5309 		attr->status_area.width = width;
5310 		attr->status_area.height = gui.char_height;
5311 		attr->status_fontset = gui.fontset;
5312 	    }
5313 	}
5314 	else if ((xim_input_style & (int)GDK_IM_STATUS_MASK)
5315 					      == (int)GDK_IM_STATUS_CALLBACKS)
5316 	{
5317 	    /* FIXME */
5318 	}
5319 #endif
5320 
5321 	xic = gdk_ic_new(attr, (GdkICAttributesType)attrmask);
5322 
5323 	if (xic == NULL)
5324 	    EMSG(_(e_xim));
5325 	else
5326 	{
5327 	    mask = (int)gdk_window_get_events(widget->window);
5328 	    mask |= (int)gdk_ic_get_events(xic);
5329 	    gdk_window_set_events(widget->window, (GdkEventMask)mask);
5330 	    if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
5331 		preedit_callback_setup(xic);
5332 	    reset_state_setup(xic);
5333 	}
5334     }
5335 }
5336 
5337     void
5338 im_shutdown(void)
5339 {
5340 #ifdef XIM_DEBUG
5341     xim_log("im_shutdown()\n");
5342 #endif
5343 
5344     if (xic != NULL)
5345     {
5346 	gdk_im_end();
5347 	gdk_ic_destroy(xic);
5348 	xic = NULL;
5349     }
5350     xim_is_active = FALSE;
5351     xim_can_preediting = FALSE;
5352     preedit_start_col = MAXCOL;
5353     xim_has_preediting = FALSE;
5354 }
5355 
5356 #endif /* FEAT_GUI_GTK */
5357 
5358     int
5359 xim_get_status_area_height()
5360 {
5361 #ifdef FEAT_GUI_GTK
5362     if (xim_input_style & (int)GDK_IM_STATUS_AREA)
5363 	return gui.char_height;
5364 #elif defined FEAT_GUI_KDE
5365 #warning FIXME
5366 #else
5367     if (status_area_enabled)
5368 	return gui.char_height;
5369 #endif
5370     return 0;
5371 }
5372 
5373 /*
5374  * Get IM status.  When IM is on, return TRUE.  Else return FALSE.
5375  * FIXME: This doesn't work correctly: Having focus doesn't always mean XIM is
5376  * active, when not having focus XIM may still be active (e.g., when using a
5377  * tear-off menu item).
5378  */
5379     int
5380 im_get_status()
5381 {
5382 #  ifdef FEAT_GUI_GTK
5383     if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
5384 	return xim_can_preediting;
5385 #  endif
5386     return xim_has_focus;
5387 }
5388 
5389 # endif /* !HAVE_GTK2 */
5390 
5391 # if defined(FEAT_GUI_GTK) || defined(PROTO)
5392     int
5393 im_is_preediting()
5394 {
5395     return xim_has_preediting;
5396 }
5397 # endif
5398 #endif /* FEAT_XIM */
5399 
5400 #if defined(FEAT_MBYTE) || defined(PROTO)
5401 
5402 /*
5403  * Setup "vcp" for conversion from "from" to "to".
5404  * The names must have been made canonical with enc_canonize().
5405  * vcp->vc_type must have been initialized to CONV_NONE.
5406  * Note: cannot be used for conversion from/to ucs-2 and ucs-4 (will use utf-8
5407  * instead).
5408  * Afterwards invoke with "from" and "to" equal to NULL to cleanup.
5409  * Return FAIL when conversion is not supported, OK otherwise.
5410  */
5411     int
5412 convert_setup(vcp, from, to)
5413     vimconv_T	*vcp;
5414     char_u	*from;
5415     char_u	*to;
5416 {
5417     int		from_prop;
5418     int		to_prop;
5419 
5420     /* Reset to no conversion. */
5421 # ifdef USE_ICONV
5422     if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1)
5423 	iconv_close(vcp->vc_fd);
5424 # endif
5425     vcp->vc_type = CONV_NONE;
5426     vcp->vc_factor = 1;
5427     vcp->vc_fail = FALSE;
5428 
5429     /* No conversion when one of the names is empty or they are equal. */
5430     if (from == NULL || *from == NUL || to == NULL || *to == NUL
5431 						     || STRCMP(from, to) == 0)
5432 	return OK;
5433 
5434     from_prop = enc_canon_props(from);
5435     to_prop = enc_canon_props(to);
5436     if ((from_prop & ENC_LATIN1) && (to_prop & ENC_UNICODE))
5437     {
5438 	/* Internal latin1 -> utf-8 conversion. */
5439 	vcp->vc_type = CONV_TO_UTF8;
5440 	vcp->vc_factor = 2;	/* up to twice as long */
5441     }
5442     else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN1))
5443     {
5444 	/* Internal utf-8 -> latin1 conversion. */
5445 	vcp->vc_type = CONV_TO_LATIN1;
5446     }
5447 #ifdef WIN3264
5448     /* Win32-specific codepage <-> codepage conversion without iconv. */
5449     else if (((from_prop & ENC_UNICODE) || encname2codepage(from) > 0)
5450 	    && ((to_prop & ENC_UNICODE) || encname2codepage(to) > 0))
5451     {
5452 	vcp->vc_type = CONV_CODEPAGE;
5453 	vcp->vc_factor = 2;	/* up to twice as long */
5454 	vcp->vc_cpfrom = (from_prop & ENC_UNICODE) ? 0 : encname2codepage(from);
5455 	vcp->vc_cpto = (to_prop & ENC_UNICODE) ? 0 : encname2codepage(to);
5456     }
5457 #endif
5458 #ifdef MACOS_X
5459     else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_LATIN1))
5460     {
5461 	vcp->vc_type = CONV_MAC_LATIN1;
5462     }
5463     else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_UNICODE))
5464     {
5465 	vcp->vc_type = CONV_MAC_UTF8;
5466 	vcp->vc_factor = 2;	/* up to twice as long */
5467     }
5468     else if ((from_prop & ENC_LATIN1) && (to_prop & ENC_MACROMAN))
5469     {
5470 	vcp->vc_type = CONV_LATIN1_MAC;
5471     }
5472     else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_MACROMAN))
5473     {
5474 	vcp->vc_type = CONV_UTF8_MAC;
5475     }
5476 #endif
5477 # ifdef USE_ICONV
5478     else
5479     {
5480 	/* Use iconv() for conversion. */
5481 	vcp->vc_fd = (iconv_t)my_iconv_open(
5482 		(to_prop & ENC_UNICODE) ? (char_u *)"utf-8" : to,
5483 		(from_prop & ENC_UNICODE) ? (char_u *)"utf-8" : from);
5484 	if (vcp->vc_fd != (iconv_t)-1)
5485 	{
5486 	    vcp->vc_type = CONV_ICONV;
5487 	    vcp->vc_factor = 4;	/* could be longer too... */
5488 	}
5489     }
5490 # endif
5491     if (vcp->vc_type == CONV_NONE)
5492 	return FAIL;
5493     return OK;
5494 }
5495 
5496 #if defined(FEAT_GUI) || defined(AMIGA) || defined(WIN3264) \
5497 	|| defined(MSDOS) || defined(PROTO)
5498 /*
5499  * Do conversion on typed input characters in-place.
5500  * The input and output are not NUL terminated!
5501  * Returns the length after conversion.
5502  */
5503     int
5504 convert_input(ptr, len, maxlen)
5505     char_u	*ptr;
5506     int		len;
5507     int		maxlen;
5508 {
5509     return convert_input_safe(ptr, len, maxlen, NULL, NULL);
5510 }
5511 #endif
5512 
5513 /*
5514  * Like convert_input(), but when there is an incomplete byte sequence at the
5515  * end return that as an allocated string in "restp" and set "*restlenp" to
5516  * the length.  If "restp" is NULL it is not used.
5517  */
5518     int
5519 convert_input_safe(ptr, len, maxlen, restp, restlenp)
5520     char_u	*ptr;
5521     int		len;
5522     int		maxlen;
5523     char_u	**restp;
5524     int		*restlenp;
5525 {
5526     char_u	*d;
5527     int		dlen = len;
5528     int		unconvertlen = 0;
5529 
5530     d = string_convert_ext(&input_conv, ptr, &dlen,
5531 					restp == NULL ? NULL : &unconvertlen);
5532     if (d != NULL)
5533     {
5534 	if (dlen <= maxlen)
5535 	{
5536 	    if (unconvertlen > 0)
5537 	    {
5538 		/* Move the unconverted characters to allocated memory. */
5539 		*restp = alloc(unconvertlen);
5540 		if (*restp != NULL)
5541 		    mch_memmove(*restp, ptr + len - unconvertlen, unconvertlen);
5542 		*restlenp = unconvertlen;
5543 	    }
5544 	    mch_memmove(ptr, d, dlen);
5545 	}
5546 	else
5547 	    /* result is too long, keep the unconverted text (the caller must
5548 	     * have done something wrong!) */
5549 	    dlen = len;
5550 	vim_free(d);
5551     }
5552     return dlen;
5553 }
5554 
5555 #if defined(MACOS_X)
5556 static char_u *mac_string_convert __ARGS((char_u *ptr, int len, int *lenp, int fail_on_error, CFStringEncoding from, CFStringEncoding to, int *unconvlenp));
5557 
5558 /*
5559  * A Mac version of string_convert_ext() for special cases.
5560  */
5561     static char_u *
5562 mac_string_convert(ptr, len, lenp, fail_on_error, from, to, unconvlenp)
5563     char_u		*ptr;
5564     int			len;
5565     int			*lenp;
5566     int			fail_on_error;
5567     CFStringEncoding	from;
5568     CFStringEncoding	to;
5569     int			*unconvlenp;
5570 {
5571     char_u		*retval, *d;
5572     CFStringRef		cfstr;
5573     int			buflen, in, out, l, i;
5574 
5575     if (unconvlenp != NULL)
5576 	*unconvlenp = 0;
5577     cfstr = CFStringCreateWithBytes(NULL, ptr, len, from, 0);
5578     /* When conversion failed, try excluding bytes from the end, helps when
5579      * there is an incomplete byte sequence.  Only do up to 6 bytes to avoid
5580      * looping a long time when there really is something unconvertable. */
5581     while (cfstr == NULL && unconvlenp != NULL && len > 1 && *unconvlenp < 6)
5582     {
5583 	--len;
5584 	++*unconvlenp;
5585 	cfstr = CFStringCreateWithBytes(NULL, ptr, len, from, 0);
5586     }
5587     if (cfstr == NULL)
5588 	return NULL;
5589     if (to == kCFStringEncodingUTF8)
5590 	buflen = len * 6 + 1;
5591     else
5592 	buflen = len + 1;
5593     retval = alloc(buflen);
5594     if (retval == NULL)
5595     {
5596 	CFRelease(cfstr);
5597 	return NULL;
5598     }
5599     if (!CFStringGetCString(cfstr, retval, buflen, to))
5600     {
5601 	CFRelease(cfstr);
5602 	if (fail_on_error)
5603 	{
5604 	    vim_free(retval);
5605 	    return NULL;
5606 	}
5607 
5608 	/* conversion failed for the whole string, but maybe it will work
5609 	 * for each character */
5610 	for (d = retval, in = 0, out = 0; in < len && out < buflen - 1;)
5611 	{
5612 	    if (from == kCFStringEncodingUTF8)
5613 		l = utf_ptr2len_check(ptr + in);
5614 	    else
5615 		l = 1;
5616 	    cfstr = CFStringCreateWithBytes(NULL, ptr + in, l, from, 0);
5617 	    if (cfstr == NULL)
5618 	    {
5619 		*d++ = '?';
5620 		out++;
5621 	    }
5622 	    else
5623 	    {
5624 		if (!CFStringGetCString(cfstr, d, buflen - out, to))
5625 		{
5626 		    *d++ = '?';
5627 		    out++;
5628 		}
5629 		else
5630 		{
5631 		    i = strlen(d);
5632 		    d += i;
5633 		    out += i;
5634 		}
5635 		CFRelease(cfstr);
5636 	    }
5637 	    in += l;
5638 	}
5639 	*d = NUL;
5640 	if (lenp != NULL)
5641 	    *lenp = out;
5642 	return retval;
5643     }
5644     CFRelease(cfstr);
5645     if (lenp != NULL)
5646 	*lenp = strlen(retval);
5647     return retval;
5648 }
5649 #endif
5650 
5651 /*
5652  * Convert text "ptr[*lenp]" according to "vcp".
5653  * Returns the result in allocated memory and sets "*lenp".
5654  * When "lenp" is NULL, use NUL terminated strings.
5655  * Illegal chars are often changed to "?", unless vcp->vc_fail is set.
5656  * When something goes wrong, NULL is returned and "*lenp" is unchanged.
5657  */
5658     char_u *
5659 string_convert(vcp, ptr, lenp)
5660     vimconv_T	*vcp;
5661     char_u	*ptr;
5662     int		*lenp;
5663 {
5664     return string_convert_ext(vcp, ptr, lenp, NULL);
5665 }
5666 
5667 /*
5668  * Like string_convert(), but when "unconvlenp" is not NULL and there are is
5669  * an incomplete sequence at the end it is not converted and "*unconvlenp" is
5670  * set to the number of remaining bytes.
5671  */
5672     char_u *
5673 string_convert_ext(vcp, ptr, lenp, unconvlenp)
5674     vimconv_T	*vcp;
5675     char_u	*ptr;
5676     int		*lenp;
5677     int		*unconvlenp;
5678 {
5679     char_u	*retval = NULL;
5680     char_u	*d;
5681     int		len;
5682     int		i;
5683     int		l;
5684     int		c;
5685 
5686     if (lenp == NULL)
5687 	len = (int)STRLEN(ptr);
5688     else
5689 	len = *lenp;
5690     if (len == 0)
5691 	return vim_strsave((char_u *)"");
5692 
5693     switch (vcp->vc_type)
5694     {
5695 	case CONV_TO_UTF8:	/* latin1 to utf-8 conversion */
5696 	    retval = alloc(len * 2 + 1);
5697 	    if (retval == NULL)
5698 		break;
5699 	    d = retval;
5700 	    for (i = 0; i < len; ++i)
5701 	    {
5702 		if (ptr[i] < 0x80)
5703 		    *d++ = ptr[i];
5704 		else
5705 		{
5706 		    *d++ = 0xc0 + ((unsigned)ptr[i] >> 6);
5707 		    *d++ = 0x80 + (ptr[i] & 0x3f);
5708 		}
5709 	    }
5710 	    *d = NUL;
5711 	    if (lenp != NULL)
5712 		*lenp = (int)(d - retval);
5713 	    break;
5714 
5715 	case CONV_TO_LATIN1:	/* utf-8 to latin1 conversion */
5716 	    retval = alloc(len + 1);
5717 	    if (retval == NULL)
5718 		break;
5719 	    d = retval;
5720 	    for (i = 0; i < len; ++i)
5721 	    {
5722 		l = utf_ptr2len_check(ptr + i);
5723 		if (l == 0)
5724 		    *d++ = NUL;
5725 		else if (l == 1)
5726 		{
5727 		    if (unconvlenp != NULL && utf8len_tab[ptr[i]] > len - i)
5728 		    {
5729 			/* Incomplete sequence at the end. */
5730 			*unconvlenp = len - i;
5731 			break;
5732 		    }
5733 		    *d++ = ptr[i];
5734 		}
5735 		else
5736 		{
5737 		    c = utf_ptr2char(ptr + i);
5738 		    if (!utf_iscomposing(c))	/* skip composing chars */
5739 		    {
5740 			if (c < 0x100)
5741 			    *d++ = c;
5742 			else if (vcp->vc_fail)
5743 			{
5744 			    vim_free(retval);
5745 			    return NULL;
5746 			}
5747 			else
5748 			{
5749 			    *d++ = 0xbf;
5750 			    if (utf_char2cells(c) > 1)
5751 				*d++ = '?';
5752 			}
5753 		    }
5754 		    i += l - 1;
5755 		}
5756 	    }
5757 	    *d = NUL;
5758 	    if (lenp != NULL)
5759 		*lenp = (int)(d - retval);
5760 	    break;
5761 
5762 # ifdef MACOS_X
5763 	case CONV_MAC_LATIN1:
5764 	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
5765 					kCFStringEncodingMacRoman,
5766 					kCFStringEncodingISOLatin1,
5767 					unconvlenp);
5768 	    break;
5769 
5770 	case CONV_LATIN1_MAC:
5771 	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
5772 					kCFStringEncodingISOLatin1,
5773 					kCFStringEncodingMacRoman,
5774 					unconvlenp);
5775 	    break;
5776 
5777 	case CONV_MAC_UTF8:
5778 	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
5779 					kCFStringEncodingMacRoman,
5780 					kCFStringEncodingUTF8,
5781 					unconvlenp);
5782 	    break;
5783 
5784 	case CONV_UTF8_MAC:
5785 	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
5786 					kCFStringEncodingUTF8,
5787 					kCFStringEncodingMacRoman,
5788 					unconvlenp);
5789 	    break;
5790 # endif
5791 
5792 # ifdef USE_ICONV
5793 	case CONV_ICONV:	/* conversion with output_conv.vc_fd */
5794 	    retval = iconv_string(vcp, ptr, len, unconvlenp);
5795 	    if (retval != NULL && lenp != NULL)
5796 		*lenp = (int)STRLEN(retval);
5797 	    break;
5798 # endif
5799 # ifdef WIN3264
5800 	case CONV_CODEPAGE:		/* codepage -> codepage */
5801 	{
5802 	    int		retlen;
5803 	    int		tmp_len;
5804 	    short_u	*tmp;
5805 
5806 	    /* 1. codepage/UTF-8  ->  ucs-2. */
5807 	    if (vcp->vc_cpfrom == 0)
5808 		tmp_len = utf8_to_ucs2(ptr, len, NULL, NULL);
5809 	    else
5810 		tmp_len = MultiByteToWideChar(vcp->vc_cpfrom, 0,
5811 							      ptr, len, 0, 0);
5812 	    tmp = (short_u *)alloc(sizeof(short_u) * tmp_len);
5813 	    if (tmp == NULL)
5814 		break;
5815 	    if (vcp->vc_cpfrom == 0)
5816 		utf8_to_ucs2(ptr, len, tmp, unconvlenp);
5817 	    else
5818 		MultiByteToWideChar(vcp->vc_cpfrom, 0, ptr, len, tmp, tmp_len);
5819 
5820 	    /* 2. ucs-2  ->  codepage/UTF-8. */
5821 	    if (vcp->vc_cpto == 0)
5822 		retlen = ucs2_to_utf8(tmp, tmp_len, NULL);
5823 	    else
5824 		retlen = WideCharToMultiByte(vcp->vc_cpto, 0,
5825 						    tmp, tmp_len, 0, 0, 0, 0);
5826 	    retval = alloc(retlen + 1);
5827 	    if (retval != NULL)
5828 	    {
5829 		if (vcp->vc_cpto == 0)
5830 		    ucs2_to_utf8(tmp, tmp_len, retval);
5831 		else
5832 		    WideCharToMultiByte(vcp->vc_cpto, 0,
5833 					  tmp, tmp_len, retval, retlen, 0, 0);
5834 		retval[retlen] = NUL;
5835 		if (lenp != NULL)
5836 		    *lenp = retlen;
5837 	    }
5838 	    vim_free(tmp);
5839 	    break;
5840 	}
5841 # endif
5842     }
5843 
5844     return retval;
5845 }
5846 #endif
5847