| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.836 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.836 |
| Problem: Clipboard does not work on Win32 when compiled with Cygwin. |
| Solution: Move the Win32 clipboard code to a separate file and use it when |
| building with os_unix.c. (Frodak Baksik, Ken Takata) |
| Files: src/Make_bc5.mak, src/Make_cyg.mak, src/Make_ivc.mak, |
| src/Make_ming.mak, src/Make_mvc.mak, src/Make_w16.mak, |
| src/Makefile, src/config.h.in, src/configure.in, |
| src/auto/configure, src/feature.h, src/globals.h, src/mbyte.c, |
| src/os_mswin.c, src/os_unix.c, src/os_win32.c, src/proto.h, |
| src/proto/os_mswin.pro, src/proto/winclip.pro, src/term.c, |
| src/vim.h, src/winclip.c |
| |
| |
| |
| |
| |
| *** 694,700 **** |
| |
| !if ($(OSTYPE)==WIN32) |
| vimobj = $(vimobj) \ |
| ! $(OBJDIR)\os_win32.obj $(OBJDIR)\os_mswin.obj |
| !elif ($(OSTYPE)==DOS16) |
| vimobj = $(vimobj) \ |
| $(OBJDIR)\os_msdos.obj |
| --- 694,700 ---- |
| |
| !if ($(OSTYPE)==WIN32) |
| vimobj = $(vimobj) \ |
| ! $(OBJDIR)\os_win32.obj $(OBJDIR)\os_mswin.obj $(OBJDIR)\winclip.obj |
| !elif ($(OSTYPE)==DOS16) |
| vimobj = $(vimobj) \ |
| $(OBJDIR)\os_msdos.obj |
| |
| |
| |
| *** 547,552 **** |
| --- 547,553 ---- |
| $(OUTDIR)/option.o \ |
| $(OUTDIR)/os_win32.o \ |
| $(OUTDIR)/os_mswin.o \ |
| + $(OUTDIR)/winclip.o \ |
| $(OUTDIR)/pathdef.o \ |
| $(OUTDIR)/popupmnu.o \ |
| $(OUTDIR)/quickfix.o \ |
| |
| |
| |
| *** 241,246 **** |
| --- 241,247 ---- |
| "$(INTDIR)/ops.obj" \ |
| "$(INTDIR)/option.obj" \ |
| "$(INTDIR)/os_mswin.obj" \ |
| + "$(INTDIR)/winclip.obj" \ |
| "$(INTDIR)/os_win32.obj" \ |
| "$(INTDIR)/popupmnu.obj" \ |
| "$(INTDIR)/quickfix.obj" \ |
| |
| *** 600,605 **** |
| --- 601,610 ---- |
| # End Source File |
| # Begin Source File |
| |
| + SOURCE=.\winclip.c |
| + # End Source File |
| + # Begin Source File |
| + |
| SOURCE=.\os_win32.c |
| # End Source File |
| # Begin Source File |
| |
| |
| |
| *** 523,528 **** |
| --- 523,529 ---- |
| $(OUTDIR)/option.o \ |
| $(OUTDIR)/os_win32.o \ |
| $(OUTDIR)/os_mswin.o \ |
| + $(OUTDIR)/winclip.o \ |
| $(OUTDIR)/pathdef.o \ |
| $(OUTDIR)/popupmnu.o \ |
| $(OUTDIR)/quickfix.o \ |
| |
| |
| |
| *** 543,548 **** |
| --- 543,549 ---- |
| $(OUTDIR)\ops.obj \ |
| $(OUTDIR)\option.obj \ |
| $(OUTDIR)\os_mswin.obj \ |
| + $(OUTDIR)\winclip.obj \ |
| $(OUTDIR)\os_win32.obj \ |
| $(OUTDIR)\pathdef.obj \ |
| $(OUTDIR)\popupmnu.obj \ |
| |
| *** 1149,1154 **** |
| --- 1150,1157 ---- |
| |
| $(OUTDIR)/os_mswin.obj: $(OUTDIR) os_mswin.c $(INCL) |
| |
| + $(OUTDIR)/winclip.obj: $(OUTDIR) winclip.c $(INCL) |
| + |
| $(OUTDIR)/os_win32.obj: $(OUTDIR) os_win32.c $(INCL) os_win32.h |
| |
| $(OUTDIR)/os_w32exe.obj: $(OUTDIR) os_w32exe.c $(INCL) |
| |
| *** 1256,1261 **** |
| --- 1259,1265 ---- |
| proto/ops.pro \ |
| proto/option.pro \ |
| proto/os_mswin.pro \ |
| + proto/winclip.pro \ |
| proto/os_win32.pro \ |
| proto/popupmnu.pro \ |
| proto/quickfix.pro \ |
| |
| |
| |
| *** 107,112 **** |
| --- 107,113 ---- |
| $(INTDIR)\os_win16.obj\ |
| $(INTDIR)\os_msdos.obj\ |
| $(INTDIR)\os_mswin.obj\ |
| + $(INTDIR)\winclip.obj\ |
| $(INTDIR)\popupmnu.obj\ |
| $(INTDIR)\quickfix.obj\ |
| $(INTDIR)\regexp.obj\ |
| |
| |
| |
| *** 1638,1644 **** |
| RSRC_DIR = os_mac_rsrc |
| |
| PRO_MANUAL = os_amiga.pro os_msdos.pro os_win16.pro os_win32.pro \ |
| ! os_mswin.pro os_beos.pro os_vms.pro $(PERL_PRO) |
| |
| # Default target is making the executable and tools |
| all: $(VIMTARGET) $(TOOLS) languages $(GUI_BUNDLE) |
| --- 1638,1644 ---- |
| RSRC_DIR = os_mac_rsrc |
| |
| PRO_MANUAL = os_amiga.pro os_msdos.pro os_win16.pro os_win32.pro \ |
| ! os_mswin.pro winclip.pro os_beos.pro os_vms.pro $(PERL_PRO) |
| |
| # Default target is making the executable and tools |
| all: $(VIMTARGET) $(TOOLS) languages $(GUI_BUNDLE) |
| |
| *** 1792,1797 **** |
| --- 1792,1801 ---- |
| $(CPROTO) -DWIN16 -DWIN32 -UHAVE_CONFIG_H $< > proto/$@ |
| echo "/* vim: set ft=c : */" >> proto/$@ |
| |
| + winclip.pro: winclip.c |
| + $(CPROTO) -DWIN16 -DWIN32 -UHAVE_CONFIG_H $< > proto/$@ |
| + echo "/* vim: set ft=c : */" >> proto/$@ |
| + |
| os_beos.pro: os_beos.c |
| $(CPROTO) -D__BEOS__ -UHAVE_CONFIG_H $< > proto/$@ |
| echo "/* vim: set ft=c : */" >> proto/$@ |
| |
| *** 2642,2647 **** |
| --- 2646,2657 ---- |
| objects/os_unix.o: os_unix.c |
| $(CCC) -o $@ os_unix.c |
| |
| + objects/os_mswin.o: os_mswin.c |
| + $(CCC) -o $@ os_mswin.c |
| + |
| + objects/winclip.o: winclip.c |
| + $(CCC) -o $@ winclip.c |
| + |
| objects/pathdef.o: auto/pathdef.c |
| $(CCC) -o $@ auto/pathdef.c |
| |
| |
| *** 2970,2975 **** |
| --- 2980,2989 ---- |
| ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \ |
| gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \ |
| arabic.h version.h |
| + objects/winclip.o: winclip.c vimio.h vim.h auto/config.h feature.h os_unix.h \ |
| + auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \ |
| + regexp.h gui.h ex_cmds.h proto.h globals.h farsi.h arabic.h \ |
| + proto/winclip.pro |
| objects/window.o: window.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \ |
| ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \ |
| gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \ |
| |
| |
| |
| *** 439,441 **** |
| --- 439,444 ---- |
| |
| /* Define if fcntl()'s F_SETFD command knows about FD_CLOEXEC */ |
| #undef HAVE_FD_CLOEXEC |
| + |
| + /* Define if you want Cygwin to use the WIN32 clipboard, not compatible with X11*/ |
| + #undef FEAT_CYGWIN_WIN32_CLIPBOARD |
| |
| |
| |
| *** 2474,2479 **** |
| --- 2474,2494 ---- |
| dnl end of GUI-checking |
| dnl --------------------------------------------------------------------------- |
| |
| + dnl Check for Cygwin, which needs an extra source file if not using X11 |
| + AC_MSG_CHECKING(for CYGWIN environment) |
| + case `uname` in |
| + CYGWIN*) CYGWIN=yes; AC_MSG_RESULT(yes) |
| + AC_MSG_CHECKING(for CYGWIN clipboard support) |
| + if test "x$with_x" = "xno" ; then |
| + OS_EXTRA_SRC=winclip.c; OS_EXTRA_OBJ=objects/winclip.o |
| + AC_MSG_RESULT(yes) |
| + AC_DEFINE(FEAT_CYGWIN_WIN32_CLIPBOARD) |
| + else |
| + AC_MSG_RESULT(no - using X11) |
| + fi ;; |
| + |
| + *) CYGWIN=no; AC_MSG_RESULT(no);; |
| + esac |
| |
| dnl Only really enable hangul input when GUI and XFONTSET are available |
| if test "$enable_hangulinput" = "yes"; then |
| |
| |
| |
| *** 8846,8851 **** |
| --- 8846,8872 ---- |
| |
| |
| |
| + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CYGWIN environment" >&5 |
| + $as_echo_n "checking for CYGWIN environment... " >&6; } |
| + case `uname` in |
| + CYGWIN*) CYGWIN=yes; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 |
| + $as_echo "yes" >&6; } |
| + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CYGWIN clipboard support" >&5 |
| + $as_echo_n "checking for CYGWIN clipboard support... " >&6; } |
| + if test "x$with_x" = "xno" ; then |
| + OS_EXTRA_SRC=winclip.c; OS_EXTRA_OBJ=objects/winclip.o |
| + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 |
| + $as_echo "yes" >&6; } |
| + $as_echo "#define FEAT_CYGWIN_WIN32_CLIPBOARD 1" >>confdefs.h |
| + |
| + else |
| + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - using X11" >&5 |
| + $as_echo "no - using X11" >&6; } |
| + fi ;; |
| + |
| + *) CYGWIN=no; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 |
| + $as_echo "no" >&6; };; |
| + esac |
| |
| if test "$enable_hangulinput" = "yes"; then |
| if test "x$GUITYPE" = "xNONE"; then |
| |
| |
| |
| *** 1129,1134 **** |
| --- 1129,1139 ---- |
| * +xterm_clipboard Unix only: Include code for handling the clipboard |
| * in an xterm like in the GUI. |
| */ |
| + |
| + #ifdef FEAT_CYGWIN_WIN32_CLIPBOARD |
| + # define FEAT_CLIPBOARD |
| + #endif |
| + |
| #ifdef FEAT_GUI |
| # ifndef FEAT_CLIPBOARD |
| # define FEAT_CLIPBOARD |
| |
| |
| |
| *** 802,808 **** |
| EXTERN int enc_unicode INIT(= 0); /* 2: UCS-2 or UTF-16, 4: UCS-4 */ |
| EXTERN int enc_utf8 INIT(= FALSE); /* UTF-8 encoded Unicode */ |
| EXTERN int enc_latin1like INIT(= TRUE); /* 'encoding' is latin1 comp. */ |
| ! # ifdef WIN3264 |
| /* Codepage nr of 'encoding'. Negative means it's not been set yet, zero |
| * means 'encoding' is not a valid codepage. */ |
| EXTERN int enc_codepage INIT(= -1); |
| --- 802,808 ---- |
| EXTERN int enc_unicode INIT(= 0); /* 2: UCS-2 or UTF-16, 4: UCS-4 */ |
| EXTERN int enc_utf8 INIT(= FALSE); /* UTF-8 encoded Unicode */ |
| EXTERN int enc_latin1like INIT(= TRUE); /* 'encoding' is latin1 comp. */ |
| ! # if defined(WIN3264) || defined(FEAT_CYGWIN_WIN32_CLIPBOARD) |
| /* Codepage nr of 'encoding'. Negative means it's not been set yet, zero |
| * means 'encoding' is not a valid codepage. */ |
| EXTERN int enc_codepage INIT(= -1); |
| |
| |
| |
| *** 613,619 **** |
| enc_dbcs = enc_dbcs_new; |
| has_mbyte = (enc_dbcs != 0 || enc_utf8); |
| |
| ! #ifdef WIN3264 |
| enc_codepage = encname2codepage(p_enc); |
| enc_latin9 = (STRCMP(p_enc, "iso-8859-15") == 0); |
| #endif |
| --- 613,619 ---- |
| enc_dbcs = enc_dbcs_new; |
| has_mbyte = (enc_dbcs != 0 || enc_utf8); |
| |
| ! #if defined(WIN3264) || defined(FEAT_CYGWIN_WIN32_CLIPBOARD) |
| enc_codepage = encname2codepage(p_enc); |
| enc_latin9 = (STRCMP(p_enc, "iso-8859-15") == 0); |
| #endif |
| |
| *** 4089,4095 **** |
| return enc_canonize((char_u *)buf); |
| } |
| |
| ! #if defined(WIN3264) || defined(PROTO) |
| /* |
| * Convert an encoding name to an MS-Windows codepage. |
| * Returns zero if no codepage can be figured out. |
| --- 4089,4095 ---- |
| return enc_canonize((char_u *)buf); |
| } |
| |
| ! #if defined(WIN3264) || defined(PROTO) || defined(FEAT_CYGWIN_WIN32_CLIPBOARD) |
| /* |
| * Convert an encoding name to an MS-Windows codepage. |
| * Returns zero if no codepage can be figured out. |
| |
| |
| |
| *** 905,1640 **** |
| } |
| #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 = 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. |
| - */ |
| - |
| - /* 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, |
| - 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(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, 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(str, str_size, out, outlen) |
| - char_u *str; |
| - int str_size; |
| - char_u **out; |
| - int *outlen; |
| - |
| - { |
| - LPWSTR widestr; |
| - |
| - MultiByteToWideChar_alloc(GetACP(), 0, 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); |
| - } |
| - } |
| - #endif |
| - |
| - |
| /* |
| * Debugging helper: expose the MCH_WRITE_DUMP stuff to other modules |
| */ |
| --- 905,910 ---- |
| |
| |
| |
| *** 61,66 **** |
| --- 61,71 ---- |
| # include <cygwin/version.h> |
| # include <sys/cygwin.h> /* for cygwin_conv_to_posix_path() and/or |
| * for cygwin_conv_path() */ |
| + # ifdef FEAT_CYGWIN_WIN32_CLIPBOARD |
| + # define WIN32_LEAN_AND_MEAN |
| + # include <windows.h> |
| + # include "winclip.pro" |
| + # endif |
| # endif |
| #endif |
| |
| |
| *** 1223,1228 **** |
| --- 1228,1236 ---- |
| #ifdef MACOS_CONVERT |
| mac_conv_init(); |
| #endif |
| + #ifdef FEAT_CYGWIN_WIN32_CLIPBOARD |
| + win_clip_init(); |
| + #endif |
| } |
| |
| static void |
| |
| |
| |
| *** 1851,1866 **** |
| set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0); |
| |
| #ifdef FEAT_CLIPBOARD |
| ! 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"); |
| #endif |
| } |
| |
| --- 1851,1857 ---- |
| set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0); |
| |
| #ifdef FEAT_CLIPBOARD |
| ! win_clip_init(); |
| #endif |
| } |
| |
| |
| *** 2345,2360 **** |
| #endif |
| |
| #ifdef FEAT_CLIPBOARD |
| ! 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"); |
| #endif |
| |
| /* This will be NULL on anything but NT 4.0 */ |
| --- 2336,2342 ---- |
| #endif |
| |
| #ifdef FEAT_CLIPBOARD |
| ! win_clip_init(); |
| #endif |
| |
| /* This will be NULL on anything but NT 4.0 */ |
| |
| |
| |
| *** 47,56 **** |
| --- 47,58 ---- |
| typedef int LPBOOL; |
| # include "os_win16.pro" |
| # include "os_mswin.pro" |
| + # include "winclip.pro" |
| # endif |
| # ifdef WIN3264 |
| # include "os_win32.pro" |
| # include "os_mswin.pro" |
| + # include "winclip.pro" |
| # if (defined(__GNUC__) && !defined(__MINGW32__)) \ |
| || (defined(__BORLANDC__) && __BORLANDC__ < 0x502) |
| extern int _stricoll __ARGS((char *a, char *b)); |
| |
| |
| |
| *** 22,38 **** |
| int can_end_termcap_mode __ARGS((int give_msg)); |
| int mch_screenmode __ARGS((char_u *arg)); |
| int mch_libcall __ARGS((char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result)); |
| - int utf8_to_utf16 __ARGS((char_u *instr, int inlen, short_u *outstr, int *unconvlenp)); |
| - int utf16_to_utf8 __ARGS((short_u *instr, int inlen, char_u *outstr)); |
| - void MultiByteToWideChar_alloc __ARGS((UINT cp, DWORD flags, LPCSTR in, int inlen, LPWSTR *out, int *outlen)); |
| - void WideCharToMultiByte_alloc __ARGS((UINT cp, DWORD flags, LPCWSTR in, int inlen, LPSTR *out, int *outlen, LPCSTR def, LPBOOL useddef)); |
| - int clip_mch_own_selection __ARGS((VimClipboard *cbd)); |
| - void clip_mch_lose_selection __ARGS((VimClipboard *cbd)); |
| - void clip_mch_request_selection __ARGS((VimClipboard *cbd)); |
| - void clip_mch_set_selection __ARGS((VimClipboard *cbd)); |
| - short_u *enc_to_utf16 __ARGS((char_u *str, int *lenp)); |
| - char_u *utf16_to_enc __ARGS((short_u *str, int *lenp)); |
| - void acp_to_enc __ARGS((char_u *str, int str_size, char_u **out, int *outlen)); |
| void DumpPutS __ARGS((const char *psz)); |
| int mch_get_winpos __ARGS((int *x, int *y)); |
| void mch_set_winpos __ARGS((int x, int y)); |
| --- 22,27 ---- |
| |
| |
| |
| |
| --- 1,14 ---- |
| + /* winclip.c */ |
| + int utf8_to_utf16 __ARGS((char_u *instr, int inlen, short_u *outstr, int *unconvlenp)); |
| + int utf16_to_utf8 __ARGS((short_u *instr, int inlen, char_u *outstr)); |
| + void MultiByteToWideChar_alloc __ARGS((UINT cp, DWORD flags, LPCSTR in, int inlen, LPWSTR *out, int *outlen)); |
| + void WideCharToMultiByte_alloc __ARGS((UINT cp, DWORD flags, LPCWSTR in, int inlen, LPSTR *out, int *outlen, LPCSTR def, LPBOOL useddef)); |
| + void win_clip_init __ARGS((void)); |
| + int clip_mch_own_selection __ARGS((VimClipboard *cbd)); |
| + void clip_mch_lose_selection __ARGS((VimClipboard *cbd)); |
| + void clip_mch_request_selection __ARGS((VimClipboard *cbd)); |
| + void clip_mch_set_selection __ARGS((VimClipboard *cbd)); |
| + short_u *enc_to_utf16 __ARGS((char_u *str, int *lenp)); |
| + char_u *utf16_to_enc __ARGS((short_u *str, int *lenp)); |
| + void acp_to_enc __ARGS((char_u *str, int str_size, char_u **out, int *outlen)); |
| + /* vim: set ft=c : */ |
| |
| |
| |
| *** 1853,1859 **** |
| --- 1853,1861 ---- |
| # ifdef FEAT_GUI |
| if (!gui.in_use) |
| # endif |
| + # ifndef FEAT_CYGWIN_WIN32_CLIPBOARD |
| clip_init(FALSE); |
| + # endif |
| # endif |
| if (use_xterm_like_mouse(term)) |
| { |
| |
| |
| |
| *** 1927,1933 **** |
| GdkAtom gtk_sel_atom; /* PRIMARY/CLIPBOARD selection ID */ |
| # endif |
| |
| ! # ifdef MSWIN |
| int_u format; /* Vim's own special clipboard format */ |
| int_u format_raw; /* Vim's raw text clipboard format */ |
| # endif |
| --- 1927,1933 ---- |
| GdkAtom gtk_sel_atom; /* PRIMARY/CLIPBOARD selection ID */ |
| # endif |
| |
| ! # if defined(MSWIN) || defined(FEAT_CYGWIN_WIN32_CLIPBOARD) |
| int_u format; /* Vim's own special clipboard format */ |
| int_u format_raw; /* Vim's raw text clipboard format */ |
| # endif |
| |
| |
| |
| |
| --- 1,798 ---- |
| + /* vi:set ts=8 sts=4 sw=4: |
| + * |
| + * 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. |
| + */ |
| + |
| + #ifdef WIN16 |
| + # ifdef __BORLANDC__ |
| + # pragma warn -par |
| + # pragma warn -ucp |
| + # pragma warn -use |
| + # pragma warn -aus |
| + # endif |
| + #endif |
| + |
| + #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 = 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, |
| + 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(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, 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(str, str_size, out, outlen) |
| + char_u *str; |
| + int str_size; |
| + char_u **out; |
| + int *outlen; |
| + |
| + { |
| + LPWSTR widestr; |
| + |
| + MultiByteToWideChar_alloc(GetACP(), 0, 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); |
| + } |
| + } |
| + #endif |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 836, |
| /**/ |
| |
| -- |
| Engineers understand that their appearance only bothers other people and |
| therefore it is not worth optimizing. |
| (Scott Adams - The Dilbert principle) |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |