/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/*
 * winclip.c
 *
 * Routines common to both Win16 and Win32 for clipboard handling.
 * Also used by Cygwin, using os_unix.c.
 */

#include "vimio.h"
#include "vim.h"

/*
 * Compile only the clipboard handling features when compiling for cygwin
 * posix environment.
 */
#ifdef FEAT_CYGWIN_WIN32_CLIPBOARD
# define WIN3264
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include "winclip.pro"
#endif

/*
 * When generating prototypes for Win32 on Unix, these lines make the syntax
 * errors disappear.  They do not need to be correct.
 */
#ifdef PROTO
#define WINAPI
#define WINBASEAPI
typedef int DWORD;
typedef int LPBOOL;
typedef int LPCSTR;
typedef int LPCWSTR;
typedef int LPSTR;
typedef int LPWSTR;
typedef int UINT;
#endif

#if defined(FEAT_MBYTE) || defined(PROTO)
/*
 * Convert an UTF-8 string to UTF-16.
 * "instr[inlen]" is the input.  "inlen" is in bytes.
 * When "outstr" is NULL only return the number of UTF-16 words produced.
 * Otherwise "outstr" must be a buffer of sufficient size.
 * Returns the number of UTF-16 words produced.
 */
    int
utf8_to_utf16(char_u *instr, int inlen, short_u *outstr, int *unconvlenp)
{
    int		outlen = 0;
    char_u	*p = instr;
    int		todo = inlen;
    int		l;
    int		ch;

    while (todo > 0)
    {
	/* Only convert if we have a complete sequence. */
	l = utf_ptr2len_len(p, todo);
	if (l > todo)
	{
	    /* Return length of incomplete sequence. */
	    if (unconvlenp != NULL)
		*unconvlenp = todo;
	    break;
	}

	ch = utf_ptr2char(p);
	if (ch >= 0x10000)
	{
	    /* non-BMP character, encoding with surrogate pairs */
	    ++outlen;
	    if (outstr != NULL)
	    {
		*outstr++ = (0xD800 - (0x10000 >> 10)) + (ch >> 10);
		*outstr++ = 0xDC00 | (ch & 0x3FF);
	    }
	}
	else if (outstr != NULL)
	    *outstr++ = ch;
	++outlen;
	p += l;
	todo -= l;
    }

    return outlen;
}

/*
 * Convert an UTF-16 string to UTF-8.
 * The input is "instr[inlen]" with "inlen" in number of UTF-16 words.
 * When "outstr" is NULL only return the required number of bytes.
 * Otherwise "outstr" must be a buffer of sufficient size.
 * Return the number of bytes produced.
 */
    int
utf16_to_utf8(short_u *instr, int inlen, char_u *outstr)
{
    int		outlen = 0;
    int		todo = inlen;
    short_u	*p = instr;
    int		l;
    int		ch, ch2;

    while (todo > 0)
    {
	ch = *p;
	if (ch >= 0xD800 && ch <= 0xDBFF && todo > 1)
	{
	    /* surrogate pairs handling */
	    ch2 = p[1];
	    if (ch2 >= 0xDC00 && ch2 <= 0xDFFF)
	    {
		ch = ((ch - 0xD800) << 10) + (ch2 & 0x3FF) + 0x10000;
		++p;
		--todo;
	    }
	}
	if (outstr != NULL)
	{
	    l = utf_char2bytes(ch, outstr);
	    outstr += l;
	}
	else
	    l = utf_char2len(ch);
	++p;
	outlen += l;
	--todo;
    }

    return outlen;
}

/*
 * Call MultiByteToWideChar() and allocate memory for the result.
 * Returns the result in "*out[*outlen]" with an extra zero appended.
 * "outlen" is in words.
 */
    void
MultiByteToWideChar_alloc(UINT cp, DWORD flags,
	LPCSTR in, int inlen,
	LPWSTR *out, int *outlen)
{
    *outlen = MultiByteToWideChar(cp, flags, in, inlen, 0, 0);
    /* Add one one word to avoid a zero-length alloc(). */
    *out = (LPWSTR)alloc(sizeof(WCHAR) * (*outlen + 1));
    if (*out != NULL)
    {
	MultiByteToWideChar(cp, flags, in, inlen, *out, *outlen);
	(*out)[*outlen] = 0;
    }
}

/*
 * Call WideCharToMultiByte() and allocate memory for the result.
 * Returns the result in "*out[*outlen]" with an extra NUL appended.
 */
    void
WideCharToMultiByte_alloc(UINT cp, DWORD flags,
	LPCWSTR in, int inlen,
	LPSTR *out, int *outlen,
	LPCSTR def, LPBOOL useddef)
{
    *outlen = WideCharToMultiByte(cp, flags, in, inlen, NULL, 0, def, useddef);
    /* Add one one byte to avoid a zero-length alloc(). */
    *out = (LPSTR)alloc((unsigned)*outlen + 1);
    if (*out != NULL)
    {
	WideCharToMultiByte(cp, flags, in, inlen, *out, *outlen, def, useddef);
	(*out)[*outlen] = 0;
    }
}

#endif /* FEAT_MBYTE */

#ifdef FEAT_CLIPBOARD
/*
 * Clipboard stuff, for cutting and pasting text to other windows.
 */

    void
win_clip_init(void)
{
    clip_init(TRUE);

    /*
     * Vim's own clipboard format recognises whether the text is char, line,
     * or rectangular block.  Only useful for copying between two Vims.
     * "VimClipboard" was used for previous versions, using the first
     * character to specify MCHAR, MLINE or MBLOCK.
     */
    clip_star.format = RegisterClipboardFormat("VimClipboard2");
    clip_star.format_raw = RegisterClipboardFormat("VimRawBytes");
}

/* Type used for the clipboard type of Vim's data. */
typedef struct
{
    int type;		/* MCHAR, MBLOCK or MLINE */
    int txtlen;		/* length of CF_TEXT in bytes */
    int ucslen;		/* length of CF_UNICODETEXT in words */
    int rawlen;		/* length of clip_star.format_raw, including encoding,
			   excluding terminating NUL */
} VimClipType_t;

/*
 * Make vim the owner of the current selection.  Return OK upon success.
 */
/*ARGSUSED*/
    int
clip_mch_own_selection(VimClipboard *cbd)
{
    /*
     * Never actually own the clipboard.  If another application sets the
     * clipboard, we don't want to think that we still own it.
     */
    return FAIL;
}

/*
 * Make vim NOT the owner of the current selection.
 */
/*ARGSUSED*/
    void
clip_mch_lose_selection(VimClipboard *cbd)
{
    /* Nothing needs to be done here */
}

/*
 * Copy "str[*size]" into allocated memory, changing CR-NL to NL.
 * Return the allocated result and the size in "*size".
 * Returns NULL when out of memory.
 */
    static char_u *
crnl_to_nl(const char_u *str, int *size)
{
    int		pos = 0;
    int		str_len = *size;
    char_u	*ret;
    char_u	*retp;

    /* Avoid allocating zero bytes, it generates an error message. */
    ret = lalloc((long_u)(str_len == 0 ? 1 : str_len), TRUE);
    if (ret != NULL)
    {
	retp = ret;
	for (pos = 0; pos < str_len; ++pos)
	{
	    if (str[pos] == '\r' && str[pos + 1] == '\n')
	    {
		++pos;
		--(*size);
	    }
	    *retp++ = str[pos];
	}
    }

    return ret;
}

/*
 * Wait for another process to Close the Clipboard.
 * Returns TRUE for success.
 */
    static int
vim_open_clipboard(void)
{
    int delay = 10;

    while (!OpenClipboard(NULL))
    {
	if (delay > 500)
	    return FALSE;  /* waited too long, give up */
	Sleep(delay);
	delay *= 2;	/* wait for 10, 20, 40, 80, etc. msec */
    }
    return TRUE;
}

/*
 * Get the current selection and put it in the clipboard register.
 *
 * NOTE: Must use GlobalLock/Unlock here to ensure Win32s compatibility.
 * On NT/W95 the clipboard data is a fixed global memory object and
 * so its handle = its pointer.
 * On Win32s, however, co-operation with the Win16 system means that
 * the clipboard data is moveable and its handle is not a pointer at all,
 * so we can't just cast the return value of GetClipboardData to (char_u*).
 * <VN>
 */
    void
clip_mch_request_selection(VimClipboard *cbd)
{
    VimClipType_t	metadata = { -1, -1, -1, -1 };
    HGLOBAL		hMem = NULL;
    char_u		*str = NULL;
#if defined(FEAT_MBYTE) && defined(WIN3264)
    char_u		*to_free = NULL;
#endif
#ifdef FEAT_MBYTE
    HGLOBAL		rawh = NULL;
#endif
    int			str_size = 0;
    int			maxlen;
    size_t		n;

    /*
     * Don't pass GetActiveWindow() as an argument to OpenClipboard() because
     * then we can't paste back into the same window for some reason - webb.
     */
    if (!vim_open_clipboard())
	return;

    /* Check for vim's own clipboard format first.  This only gets the type of
     * the data, still need to use CF_UNICODETEXT or CF_TEXT for the text. */
    if (IsClipboardFormatAvailable(cbd->format))
    {
	VimClipType_t	*meta_p;
	HGLOBAL		meta_h;

	/* We have metadata on the clipboard; try to get it. */
	if ((meta_h = GetClipboardData(cbd->format)) != NULL
		&& (meta_p = (VimClipType_t *)GlobalLock(meta_h)) != NULL)
	{
	    /* The size of "VimClipType_t" changed, "rawlen" was added later.
	     * Only copy what is available for backwards compatibility. */
	    n = sizeof(VimClipType_t);
	    if (GlobalSize(meta_h) < n)
		n = GlobalSize(meta_h);
	    memcpy(&metadata, meta_p, n);
	    GlobalUnlock(meta_h);
	}
    }

#ifdef FEAT_MBYTE
    /* Check for Vim's raw clipboard format first.  This is used without
     * conversion, but only if 'encoding' matches. */
    if (IsClipboardFormatAvailable(cbd->format_raw)
				      && metadata.rawlen > (int)STRLEN(p_enc))
    {
	/* We have raw data on the clipboard; try to get it. */
	if ((rawh = GetClipboardData(cbd->format_raw)) != NULL)
	{
	    char_u	*rawp;

	    rawp = (char_u *)GlobalLock(rawh);
	    if (rawp != NULL && STRCMP(p_enc, rawp) == 0)
	    {
		n = STRLEN(p_enc) + 1;
		str = rawp + n;
		str_size = (int)(metadata.rawlen - n);
	    }
	    else
	    {
		GlobalUnlock(rawh);
		rawh = NULL;
	    }
	}
    }
    if (str == NULL)
    {
#endif

#if defined(FEAT_MBYTE) && defined(WIN3264)
    /* Try to get the clipboard in Unicode if it's not an empty string. */
    if (IsClipboardFormatAvailable(CF_UNICODETEXT) && metadata.ucslen != 0)
    {
	HGLOBAL hMemW;

	if ((hMemW = GetClipboardData(CF_UNICODETEXT)) != NULL)
	{
	    WCHAR *hMemWstr = (WCHAR *)GlobalLock(hMemW);

	    /* Use the length of our metadata if possible, but limit it to the
	     * GlobalSize() for safety. */
	    maxlen = (int)(GlobalSize(hMemW) / sizeof(WCHAR));
	    if (metadata.ucslen >= 0)
	    {
		if (metadata.ucslen > maxlen)
		    str_size = maxlen;
		else
		    str_size = metadata.ucslen;
	    }
	    else
	    {
		for (str_size = 0; str_size < maxlen; ++str_size)
		    if (hMemWstr[str_size] == NUL)
			break;
	    }
	    to_free = str = utf16_to_enc((short_u *)hMemWstr, &str_size);
	    GlobalUnlock(hMemW);
	}
    }
    else
#endif
    /* Get the clipboard in the Active codepage. */
    if (IsClipboardFormatAvailable(CF_TEXT))
    {
	if ((hMem = GetClipboardData(CF_TEXT)) != NULL)
	{
	    str = (char_u *)GlobalLock(hMem);

	    /* The length is either what our metadata says or the strlen().
	     * But limit it to the GlobalSize() for safety. */
	    maxlen = (int)GlobalSize(hMem);
	    if (metadata.txtlen >= 0)
	    {
		if (metadata.txtlen > maxlen)
		    str_size = maxlen;
		else
		    str_size = metadata.txtlen;
	    }
	    else
	    {
		for (str_size = 0; str_size < maxlen; ++str_size)
		    if (str[str_size] == NUL)
			break;
	    }

# if defined(FEAT_MBYTE) && defined(WIN3264)
	    /* The text is in the active codepage.  Convert to 'encoding',
	     * going through UTF-16. */
	    acp_to_enc(str, str_size, &to_free, &maxlen);
	    if (to_free != NULL)
	    {
		str_size = maxlen;
		str = to_free;
	    }
# endif
	}
    }
#ifdef FEAT_MBYTE
    }
#endif

    if (str != NULL && *str != NUL)
    {
	char_u *temp_clipboard;

	/* If the type is not known detect it. */
	if (metadata.type == -1)
	    metadata.type = MAUTO;

	/* Translate <CR><NL> into <NL>. */
	temp_clipboard = crnl_to_nl(str, &str_size);
	if (temp_clipboard != NULL)
	{
	    clip_yank_selection(metadata.type, temp_clipboard, str_size, cbd);
	    vim_free(temp_clipboard);
	}
    }

    /* unlock the global object */
    if (hMem != NULL)
	GlobalUnlock(hMem);
#ifdef FEAT_MBYTE
    if (rawh != NULL)
	GlobalUnlock(rawh);
#endif
    CloseClipboard();
#if defined(FEAT_MBYTE) && defined(WIN3264)
    vim_free(to_free);
#endif
}

/*
 * Send the current selection to the clipboard.
 */
    void
clip_mch_set_selection(VimClipboard *cbd)
{
    char_u		*str = NULL;
    VimClipType_t	metadata;
    long_u		txtlen;
    HGLOBAL		hMemRaw = NULL;
    HGLOBAL		hMem = NULL;
    HGLOBAL		hMemVim = NULL;
# if defined(FEAT_MBYTE) && defined(WIN3264)
    HGLOBAL		hMemW = NULL;
# endif

    /* If the '*' register isn't already filled in, fill it in now */
    cbd->owned = TRUE;
    clip_get_selection(cbd);
    cbd->owned = FALSE;

    /* Get the text to be put on the clipboard, with CR-LF. */
    metadata.type = clip_convert_selection(&str, &txtlen, cbd);
    if (metadata.type < 0)
	return;
    metadata.txtlen = (int)txtlen;
    metadata.ucslen = 0;
    metadata.rawlen = 0;

#ifdef FEAT_MBYTE
    /* Always set the raw bytes: 'encoding', NUL and the text.  This is used
     * when copy/paste from/to Vim with the same 'encoding', so that illegal
     * bytes can also be copied and no conversion is needed. */
    {
	LPSTR lpszMemRaw;

	metadata.rawlen = (int)(txtlen + STRLEN(p_enc) + 1);
	hMemRaw = (LPSTR)GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
							 metadata.rawlen + 1);
	lpszMemRaw = (LPSTR)GlobalLock(hMemRaw);
	if (lpszMemRaw != NULL)
	{
	    STRCPY(lpszMemRaw, p_enc);
	    memcpy(lpszMemRaw + STRLEN(p_enc) + 1, str, txtlen + 1);
	    GlobalUnlock(hMemRaw);
	}
	else
	    metadata.rawlen = 0;
    }
#endif

# if defined(FEAT_MBYTE) && defined(WIN3264)
    {
	WCHAR		*out;
	int		len = metadata.txtlen;

	/* Convert the text to UTF-16. This is put on the clipboard as
	 * CF_UNICODETEXT. */
	out = (WCHAR *)enc_to_utf16(str, &len);
	if (out != NULL)
	{
	    WCHAR *lpszMemW;

	    /* Convert the text for CF_TEXT to Active codepage. Otherwise it's
	     * p_enc, which has no relation to the Active codepage. */
	    metadata.txtlen = WideCharToMultiByte(GetACP(), 0, out, len,
							       NULL, 0, 0, 0);
	    vim_free(str);
	    str = (char_u *)alloc((unsigned)(metadata.txtlen == 0 ? 1
							  : metadata.txtlen));
	    if (str == NULL)
	    {
		vim_free(out);
		return;		/* out of memory */
	    }
	    WideCharToMultiByte(GetACP(), 0, out, len,
					   (LPSTR)str, metadata.txtlen, 0, 0);

	    /* Allocate memory for the UTF-16 text, add one NUL word to
	     * terminate the string. */
	    hMemW = (LPSTR)GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
						   (len + 1) * sizeof(WCHAR));
	    lpszMemW = (WCHAR *)GlobalLock(hMemW);
	    if (lpszMemW != NULL)
	    {
		memcpy(lpszMemW, out, len * sizeof(WCHAR));
		lpszMemW[len] = NUL;
		GlobalUnlock(hMemW);
	    }
	    vim_free(out);
	    metadata.ucslen = len;
	}
    }
# endif

    /* Allocate memory for the text, add one NUL byte to terminate the string.
     */
    hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, metadata.txtlen + 1);
    {
	LPSTR lpszMem = (LPSTR)GlobalLock(hMem);

	if (lpszMem)
	{
	    vim_strncpy((char_u *)lpszMem, str, metadata.txtlen);
	    GlobalUnlock(hMem);
	}
    }

    /* Set up metadata: */
    {
	VimClipType_t *lpszMemVim = NULL;

	hMemVim = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
						       sizeof(VimClipType_t));
	lpszMemVim = (VimClipType_t *)GlobalLock(hMemVim);
	memcpy(lpszMemVim, &metadata, sizeof(metadata));
	GlobalUnlock(hMemVim);
    }

    /*
     * Open the clipboard, clear it and put our text on it.
     * Always set our Vim format.  Put Unicode and plain text on it.
     *
     * Don't pass GetActiveWindow() as an argument to OpenClipboard()
     * because then we can't paste back into the same window for some
     * reason - webb.
     */
    if (vim_open_clipboard())
    {
	if (EmptyClipboard())
	{
	    SetClipboardData(cbd->format, hMemVim);
	    hMemVim = 0;
# if defined(FEAT_MBYTE) && defined(WIN3264)
	    if (hMemW != NULL)
	    {
		if (SetClipboardData(CF_UNICODETEXT, hMemW) != NULL)
		    hMemW = NULL;
	    }
# endif
	    /* Always use CF_TEXT.  On Win98 Notepad won't obtain the
	     * CF_UNICODETEXT text, only CF_TEXT. */
	    SetClipboardData(CF_TEXT, hMem);
	    hMem = 0;
	}
	CloseClipboard();
    }

    vim_free(str);
    /* Free any allocations we didn't give to the clipboard: */
    if (hMemRaw)
	GlobalFree(hMemRaw);
    if (hMem)
	GlobalFree(hMem);
# if defined(FEAT_MBYTE) && defined(WIN3264)
    if (hMemW)
	GlobalFree(hMemW);
# endif
    if (hMemVim)
	GlobalFree(hMemVim);
}

#endif /* FEAT_CLIPBOARD */

#if defined(FEAT_MBYTE) || defined(PROTO)
/*
 * Note: the following two functions are only guaranteed to work when using
 * valid MS-Windows codepages or when iconv() is available.
 */

/*
 * Convert "str" from 'encoding' to UTF-16.
 * Input in "str" with length "*lenp".  When "lenp" is NULL, use strlen().
 * Output is returned as an allocated string.  "*lenp" is set to the length of
 * the result.  A trailing NUL is always added.
 * Returns NULL when out of memory.
 */
    short_u *
enc_to_utf16(char_u *str, int *lenp)
{
    vimconv_T	conv;
    WCHAR	*ret;
    char_u	*allocbuf = NULL;
    int		len_loc;
    int		length;

    if (lenp == NULL)
    {
	len_loc = (int)STRLEN(str) + 1;
	lenp = &len_loc;
    }

    if (enc_codepage > 0)
    {
	/* We can do any CP### -> UTF-16 in one pass, and we can do it
	 * without iconv() (convert_* may need iconv). */
	MultiByteToWideChar_alloc(enc_codepage, 0, (LPCSTR)str, *lenp,
							       &ret, &length);
    }
    else
    {
	/* Use "latin1" by default, we might be called before we have p_enc
	 * set up.  Convert to utf-8 first, works better with iconv().  Does
	 * nothing if 'encoding' is "utf-8". */
	conv.vc_type = CONV_NONE;
	if (convert_setup(&conv, p_enc ? p_enc : (char_u *)"latin1",
						   (char_u *)"utf-8") == FAIL)
	    return NULL;
	if (conv.vc_type != CONV_NONE)
	{
	    str = allocbuf = string_convert(&conv, str, lenp);
	    if (str == NULL)
		return NULL;
	}
	convert_setup(&conv, NULL, NULL);

	length = utf8_to_utf16(str, *lenp, NULL, NULL);
	ret = (WCHAR *)alloc((unsigned)((length + 1) * sizeof(WCHAR)));
	if (ret != NULL)
	{
	    utf8_to_utf16(str, *lenp, (short_u *)ret, NULL);
	    ret[length] = 0;
	}

	vim_free(allocbuf);
    }

    *lenp = length;
    return (short_u *)ret;
}

/*
 * Convert an UTF-16 string to 'encoding'.
 * Input in "str" with length (counted in wide characters) "*lenp".  When
 * "lenp" is NULL, use wcslen().
 * Output is returned as an allocated string.  If "*lenp" is not NULL it is
 * set to the length of the result.
 * Returns NULL when out of memory.
 */
    char_u *
utf16_to_enc(short_u *str, int *lenp)
{
    vimconv_T	conv;
    char_u	*utf8_str = NULL, *enc_str = NULL;
    int		len_loc;

    if (lenp == NULL)
    {
	len_loc = (int)wcslen(str) + 1;
	lenp = &len_loc;
    }

    if (enc_codepage > 0)
    {
	/* We can do any UTF-16 -> CP### in one pass. */
	int length;

	WideCharToMultiByte_alloc(enc_codepage, 0, str, *lenp,
					    (LPSTR *)&enc_str, &length, 0, 0);
	*lenp = length;
	return enc_str;
    }

    /* Avoid allocating zero bytes, it generates an error message. */
    utf8_str = alloc(utf16_to_utf8(str, *lenp == 0 ? 1 : *lenp, NULL));
    if (utf8_str != NULL)
    {
	*lenp = utf16_to_utf8(str, *lenp, utf8_str);

	/* We might be called before we have p_enc set up. */
	conv.vc_type = CONV_NONE;
	convert_setup(&conv, (char_u *)"utf-8",
					    p_enc? p_enc: (char_u *)"latin1");
	if (conv.vc_type == CONV_NONE)
	{
	    /* p_enc is utf-8, so we're done. */
	    enc_str = utf8_str;
	}
	else
	{
	    enc_str = string_convert(&conv, utf8_str, lenp);
	    vim_free(utf8_str);
	}

	convert_setup(&conv, NULL, NULL);
    }

    return enc_str;
}
#endif /* FEAT_MBYTE */

#if (defined(FEAT_MBYTE) && defined(WIN3264)) || defined(PROTO)
/*
 * Convert from the active codepage to 'encoding'.
 * Input is "str[str_size]".
 * The result is in allocated memory: "out[outlen]".  With terminating NUL.
 */
    void
acp_to_enc(
    char_u	*str,
    int		str_size,
    char_u	**out,
    int		*outlen)

{
    LPWSTR	widestr;

    MultiByteToWideChar_alloc(GetACP(), 0, (LPCSTR)str, str_size,
							    &widestr, outlen);
    if (widestr != NULL)
    {
	++*outlen;	/* Include the 0 after the string */
	*out = utf16_to_enc((short_u *)widestr, outlen);
	vim_free(widestr);
    }
}

/*
 * Convert from 'encoding' to the active codepage.
 * Input is "str[str_size]".
 * The result is in allocated memory: "out[outlen]".  With terminating NUL.
 */
    void
enc_to_acp(
    char_u	*str,
    int		str_size,
    char_u	**out,
    int		*outlen)

{
    LPWSTR	widestr;
    int		len = str_size;

    widestr = (WCHAR *)enc_to_utf16(str, &len);
    if (widestr != NULL)
    {
	WideCharToMultiByte_alloc(GetACP(), 0, widestr, len,
						(LPSTR *)out, outlen, 0, 0);
	vim_free(widestr);
    }
}
#endif
