diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Make_bc5.mak | 2 | ||||
-rw-r--r-- | src/Make_cyg.mak | 1 | ||||
-rw-r--r-- | src/Make_ivc.mak | 5 | ||||
-rw-r--r-- | src/Make_ming.mak | 1 | ||||
-rw-r--r-- | src/Make_mvc.mak | 4 | ||||
-rw-r--r-- | src/Make_w16.mak | 1 | ||||
-rw-r--r-- | src/Makefile | 16 | ||||
-rwxr-xr-x | src/auto/configure | 21 | ||||
-rw-r--r-- | src/config.h.in | 3 | ||||
-rw-r--r-- | src/configure.in | 15 | ||||
-rw-r--r-- | src/feature.h | 5 | ||||
-rw-r--r-- | src/globals.h | 2 | ||||
-rw-r--r-- | src/mbyte.c | 4 | ||||
-rw-r--r-- | src/os_mswin.c | 730 | ||||
-rw-r--r-- | src/os_unix.c | 8 | ||||
-rw-r--r-- | src/os_win32.c | 22 | ||||
-rw-r--r-- | src/proto.h | 2 | ||||
-rw-r--r-- | src/proto/os_mswin.pro | 11 | ||||
-rw-r--r-- | src/proto/winclip.pro | 14 | ||||
-rw-r--r-- | src/term.c | 2 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 2 | ||||
-rw-r--r-- | src/winclip.c | 798 |
23 files changed, 904 insertions, 767 deletions
diff --git a/src/Make_bc5.mak b/src/Make_bc5.mak index 739fc62ed1..3eb08692d6 100644 --- a/src/Make_bc5.mak +++ b/src/Make_bc5.mak @@ -694,7 +694,7 @@ vimobj = $(vimobj) \ !if ($(OSTYPE)==WIN32) vimobj = $(vimobj) \ - $(OBJDIR)\os_win32.obj $(OBJDIR)\os_mswin.obj + $(OBJDIR)\os_win32.obj $(OBJDIR)\os_mswin.obj $(OBJDIR)\winclip.obj !elif ($(OSTYPE)==DOS16) vimobj = $(vimobj) \ $(OBJDIR)\os_msdos.obj diff --git a/src/Make_cyg.mak b/src/Make_cyg.mak index f4b27442de..2b7fce9a4b 100644 --- a/src/Make_cyg.mak +++ b/src/Make_cyg.mak @@ -547,6 +547,7 @@ OBJ = \ $(OUTDIR)/option.o \ $(OUTDIR)/os_win32.o \ $(OUTDIR)/os_mswin.o \ + $(OUTDIR)/winclip.o \ $(OUTDIR)/pathdef.o \ $(OUTDIR)/popupmnu.o \ $(OUTDIR)/quickfix.o \ diff --git a/src/Make_ivc.mak b/src/Make_ivc.mak index 91f3bb6c64..16589ea8ad 100644 --- a/src/Make_ivc.mak +++ b/src/Make_ivc.mak @@ -241,6 +241,7 @@ LINK32_OBJS= \ "$(INTDIR)/ops.obj" \ "$(INTDIR)/option.obj" \ "$(INTDIR)/os_mswin.obj" \ + "$(INTDIR)/winclip.obj" \ "$(INTDIR)/os_win32.obj" \ "$(INTDIR)/popupmnu.obj" \ "$(INTDIR)/quickfix.obj" \ @@ -600,6 +601,10 @@ SOURCE=.\os_mswin.c # 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 diff --git a/src/Make_ming.mak b/src/Make_ming.mak index 80a0c6670e..695b7e7128 100644 --- a/src/Make_ming.mak +++ b/src/Make_ming.mak @@ -523,6 +523,7 @@ OBJ = \ $(OUTDIR)/option.o \ $(OUTDIR)/os_win32.o \ $(OUTDIR)/os_mswin.o \ + $(OUTDIR)/winclip.o \ $(OUTDIR)/pathdef.o \ $(OUTDIR)/popupmnu.o \ $(OUTDIR)/quickfix.o \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 769aebf697..e0f48566a7 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -543,6 +543,7 @@ OBJ = \ $(OUTDIR)\ops.obj \ $(OUTDIR)\option.obj \ $(OUTDIR)\os_mswin.obj \ + $(OUTDIR)\winclip.obj \ $(OUTDIR)\os_win32.obj \ $(OUTDIR)\pathdef.obj \ $(OUTDIR)\popupmnu.obj \ @@ -1149,6 +1150,8 @@ $(OUTDIR)/ops.obj: $(OUTDIR) ops.c $(INCL) $(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,6 +1259,7 @@ proto.h: \ proto/ops.pro \ proto/option.pro \ proto/os_mswin.pro \ + proto/winclip.pro \ proto/os_win32.pro \ proto/popupmnu.pro \ proto/quickfix.pro \ diff --git a/src/Make_w16.mak b/src/Make_w16.mak index 4e0cdcf870..e4a6805c8e 100644 --- a/src/Make_w16.mak +++ b/src/Make_w16.mak @@ -107,6 +107,7 @@ ObjFiles = \ $(INTDIR)\os_win16.obj\ $(INTDIR)\os_msdos.obj\ $(INTDIR)\os_mswin.obj\ + $(INTDIR)\winclip.obj\ $(INTDIR)\popupmnu.obj\ $(INTDIR)\quickfix.obj\ $(INTDIR)\regexp.obj\ diff --git a/src/Makefile b/src/Makefile index 6de37aa4b6..5da8198913 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1638,7 +1638,7 @@ PRO_AUTO = \ 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) + 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,6 +1792,10 @@ os_mswin.pro: os_mswin.c $(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,6 +2646,12 @@ objects/os_mac_conv.o: os_mac_conv.c 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,6 +2980,10 @@ objects/version.o: version.c vim.h auto/config.h feature.h os_unix.h auto/osdef. 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 \ diff --git a/src/auto/configure b/src/auto/configure index 5244a2eb46..463529757f 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -8846,6 +8846,27 @@ fi +{ $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 diff --git a/src/config.h.in b/src/config.h.in index e157939380..422fd1fc79 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -439,3 +439,6 @@ /* 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 diff --git a/src/configure.in b/src/configure.in index d0fa6ffc06..3d53a43fc1 100644 --- a/src/configure.in +++ b/src/configure.in @@ -2474,6 +2474,21 @@ dnl --------------------------------------------------------------------------- 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 diff --git a/src/feature.h b/src/feature.h index f2dcca20e0..434c07f413 100644 --- a/src/feature.h +++ b/src/feature.h @@ -1129,6 +1129,11 @@ * +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 diff --git a/src/globals.h b/src/globals.h index 41eb8859f9..332fedca99 100644 --- a/src/globals.h +++ b/src/globals.h @@ -802,7 +802,7 @@ EXTERN int enc_dbcs INIT(= 0); /* One of DBCS_xxx values if 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 +# 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); diff --git a/src/mbyte.c b/src/mbyte.c index fe12c57d4f..ed12e7603d 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -613,7 +613,7 @@ codepage_invalid: enc_dbcs = enc_dbcs_new; has_mbyte = (enc_dbcs != 0 || enc_utf8); -#ifdef WIN3264 +#if defined(WIN3264) || defined(FEAT_CYGWIN_WIN32_CLIPBOARD) enc_codepage = encname2codepage(p_enc); enc_latin9 = (STRCMP(p_enc, "iso-8859-15") == 0); #endif @@ -4089,7 +4089,7 @@ enc_locale() return enc_canonize((char_u *)buf); } -#if defined(WIN3264) || defined(PROTO) +#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. diff --git a/src/os_mswin.c b/src/os_mswin.c index 912864fd6b..7cc1854530 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -905,736 +905,6 @@ mch_libcall( } #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_M |